Files
Classeo/backend/tests/Functional/Administration/Api/ActivationEndpointsTest.php
Mathias STRASSER 2ed60fdcc1 feat: Audit trail pour actions sensibles
Story 1.7 - Implémente un système complet d'audit trail pour tracer
toutes les actions sensibles (authentification, modifications de données,
exports) avec immuabilité garantie par PostgreSQL.

Fonctionnalités principales:
- Table audit_log append-only avec contraintes PostgreSQL (RULE)
- AuditLogger centralisé avec injection automatique du contexte
- Correlation ID pour traçabilité distribuée (HTTP + async)
- Handlers pour événements d'authentification
- Commande d'archivage des logs anciens
- Pas de PII dans les logs (emails/IPs hashés)

Infrastructure:
- Middlewares Messenger pour propagation du Correlation ID
- HTTP middleware pour génération/propagation du Correlation ID
- Support multi-tenant avec TenantResolver
2026-02-04 00:11:58 +01:00

103 lines
3.2 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Tests\Functional\Administration\Api;
use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
use PHPUnit\Framework\Attributes\Test;
/**
* [P0] Functional tests for account activation endpoints.
*
* Verifies:
* - Token info endpoint accessibility (public)
* - Activate endpoint accessibility (public)
* - Token validation
* - Password requirements validation
*/
final class ActivationEndpointsTest extends ApiTestCase
{
protected static ?bool $alwaysBootKernel = true;
#[Test]
public function activationTokenInfoEndpointIsAccessibleWithoutAuthentication(): void
{
// GIVEN: No authentication
$client = static::createClient();
// WHEN: Requesting token info for an invalid token
$response = $client->request('GET', '/api/activation-tokens/550e8400-e29b-41d4-a716-446655440000', [
'headers' => [
'Host' => 'localhost',
],
]);
// THEN: Returns 404 (not 401) because endpoint is public
// Invalid token returns 404 Not Found
self::assertResponseStatusCodeSame(404);
}
#[Test]
public function activateEndpointIsAccessibleWithoutAuthentication(): void
{
// GIVEN: No authentication
$client = static::createClient();
// WHEN: Attempting to activate with invalid token
$response = $client->request('POST', '/api/activate', [
'json' => [
'tokenValue' => '550e8400-e29b-41d4-a716-446655440000',
'password' => 'ValidPassword123!',
],
'headers' => [
'Host' => 'localhost',
],
]);
// THEN: Returns 404 (token not found) not 401 (unauthorized)
// The endpoint is accessible without JWT, it validates the token's existence
self::assertNotEquals(401, $response->getStatusCode(), 'Activation endpoint should be accessible without JWT');
self::assertResponseStatusCodeSame(404);
}
#[Test]
public function activateEndpointValidatesPasswordRequirements(): void
{
// GIVEN: No authentication
$client = static::createClient();
// WHEN: Attempting activation with weak password
$response = $client->request('POST', '/api/activate', [
'json' => [
'tokenValue' => '550e8400-e29b-41d4-a716-446655440000',
'password' => 'weak', // Too short, no uppercase, no number, no special char
],
'headers' => [
'Host' => 'localhost',
],
]);
// THEN: Returns 422 Unprocessable Entity for validation errors
self::assertResponseStatusCodeSame(422);
}
#[Test]
public function activateEndpointRequiresTokenAndPassword(): void
{
// GIVEN: No authentication
$client = static::createClient();
// WHEN: Attempting activation without required fields
$response = $client->request('POST', '/api/activate', [
'json' => [],
'headers' => [
'Host' => 'localhost',
],
]);
// THEN: Returns 422 for missing required fields
self::assertResponseStatusCodeSame(422);
}
}