From b2f17b05225aed992895dd8a2519dcde617baf1d Mon Sep 17 00:00:00 2001 From: matthieu Date: Sat, 2 May 2026 17:18:25 +0200 Subject: [PATCH] test(audit-log) : ajoute 403 sur GET item et invariant page=0 - testItemEndpointWithoutPermissionGets403 : symetrique de testAuthenticatedUserWithoutPermissionGets403 sur /api/audit-logs/{id}, prouve que la security expression `is_granted('core.audit_log.view')` est appliquee aussi sur l'operation Get item (couvre M-4 du backlog). - testPageZeroDoesNotProduceServerError : verrouille l'invariant fonctionnel "?page=0 ne produit jamais 500 PG", quel que soit le mecanisme protecteur (clamp provider ou validation API Platform amont). Couvre M-7 du backlog. --- tests/Module/Core/Api/AuditLogApiTest.php | 42 +++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/tests/Module/Core/Api/AuditLogApiTest.php b/tests/Module/Core/Api/AuditLogApiTest.php index 869da99..328f396 100644 --- a/tests/Module/Core/Api/AuditLogApiTest.php +++ b/tests/Module/Core/Api/AuditLogApiTest.php @@ -188,6 +188,48 @@ final class AuditLogApiTest extends AbstractApiTestCase self::assertSame($row['id'], $data['id']); } + /** + * Symetrique de `testAuthenticatedUserWithoutPermissionGets403` mais sur + * l'endpoint item. Le `security: is_granted('core.audit_log.view')` declare + * sur `Get` dans `AuditLogResource` doit refuser 403 (pas 200, pas 404). + */ + public function testItemEndpointWithoutPermissionGets403(): void + { + $row = $this->auditConnection->fetchAssociative( + 'SELECT id FROM audit_log WHERE request_id = :tag LIMIT 1', + ['tag' => $this->runTag], + ); + self::assertIsArray($row); + + // Permission "voisine" : prouve que l'auth seule ne suffit pas. + $credentials = $this->createUserWithPermission('core.users.view'); + $client = $this->authenticatedClient($credentials['username'], $credentials['password']); + $response = $client->request('GET', '/api/audit-logs/'.$row['id']); + + self::assertSame(403, $response->getStatusCode()); + } + + /** + * `?page=0` provoquait historiquement un OFFSET negatif → 500 PG + * `SQLSTATE[22023] OFFSET must not be negative`. API Platform 4 valide + * desormais `page >= 1` en amont (rejette 400) avant que le provider ne + * soit appele ; le clamp `max(1, ...)` cote provider reste en place comme + * defense-in-depth si un futur upgrade ou un changement de configuration + * leve cette validation. Ce test verrouille l'invariant fonctionnel : + * aucun 500 PG quel que soit le mecanisme protecteur en place. + */ + public function testPageZeroDoesNotProduceServerError(): void + { + $client = $this->authenticatedClient('admin', 'admin'); + $response = $client->request('GET', '/api/audit-logs?page=0'); + + self::assertContains( + $response->getStatusCode(), + [200, 400], + 'page=0 doit etre traite proprement (clamp 200 ou 400 explicite), jamais 500 PG.', + ); + } + /** * Validation des filtres : un input malforme doit retourner un 400 * explicite, pas un 500 (Postgres qui rejette le cast timestamp) ni