fix(test) : RBAC #344 - corrige EM stale et ajoute cas orphan=true

This commit is contained in:
Matthieu
2026-04-15 11:15:41 +02:00
parent fdb7aded82
commit f79f061131
2 changed files with 51 additions and 11 deletions

View File

@@ -1,7 +1,8 @@
api_platform:
title: Coltura API
version: 1.0.0
# Scan des modules pour decouvrir les classes ApiResource et ApiFilter.
# Scan du module Core pour decouvrir les classes ApiResource et ApiFilter.
# Ajouter un chemin par module lors de l'ajout d'entites ApiResource dans d'autres modules.
# Sans ces paths, le compile pass d'API Platform ne declare pas les
# services de filtres annotes (les filtres etaient silencieusement
# ignores sur Permission — cf. ticket #344).

View File

@@ -27,14 +27,16 @@ final class PermissionApiTest extends ApiTestCase
// eviter la deprecation emise a la creation du client de test.
protected static ?bool $alwaysBootKernel = true;
private EntityManagerInterface $em;
protected function setUp(): void
{
parent::setUp();
// On boote le kernel une fois pour pouvoir seeder les fixtures.
// ATTENTION : ne pas stocker l'EntityManager dans une propriete,
// chaque createClient() dans les tests rebootera le kernel et
// invalidera tout EM capture ici (cf. $alwaysBootKernel = true).
self::bootKernel();
$this->em = self::getContainer()->get('doctrine')->getManager();
$em = $this->getEm();
// Nettoyage defensif au cas ou un run precedent aurait laisse des restes.
$this->cleanupTestPermissions();
@@ -46,11 +48,11 @@ final class PermissionApiTest extends ApiTestCase
$p3 = new Permission('test.commercial.clients.view', 'View clients (test)', 'commercial');
$p2->markOrphan();
$this->em->persist($p1);
$this->em->persist($p2);
$this->em->persist($p3);
$this->em->flush();
$this->em->clear();
$em->persist($p1);
$em->persist($p2);
$em->persist($p3);
$em->flush();
$em->clear();
}
protected function tearDown(): void
@@ -66,6 +68,9 @@ final class PermissionApiTest extends ApiTestCase
self::assertResponseIsSuccessful();
$data = $response->toArray();
// API Platform 4 emet du JSON-LD 1.1 avec un @context qui utilise un
// @vocab : les cles sortent donc non prefixees (`member`, `totalItems`)
// au lieu des anciennes `hydra:member` / `hydra:totalItems`.
self::assertArrayHasKey('member', $data);
self::assertGreaterThanOrEqual(3, $data['totalItems']);
}
@@ -89,6 +94,26 @@ final class PermissionApiTest extends ApiTestCase
self::assertNotContains('test.commercial.clients.view', $codes);
}
public function testCollectionFilterByOrphanTrue(): void
{
$client = $this->authenticatedClient('admin', 'admin');
$response = $client->request('GET', '/api/permissions', [
'query' => ['orphan' => 'true'],
]);
self::assertResponseIsSuccessful();
$data = $response->toArray();
foreach ($data['member'] as $item) {
self::assertTrue($item['orphan']);
}
$codes = array_column($data['member'], 'code');
// La permission marquee orpheline dans setUp() doit remonter...
self::assertContains('test.core.users.manage', $codes);
// ...et celles non orphelines doivent etre exclues.
self::assertNotContains('test.core.users.view', $codes);
self::assertNotContains('test.commercial.clients.view', $codes);
}
public function testCollectionFilterByOrphanFalse(): void
{
$client = $this->authenticatedClient('admin', 'admin');
@@ -109,7 +134,7 @@ final class PermissionApiTest extends ApiTestCase
public function testGetItemAsAdminReturnsAllReadFields(): void
{
/** @var null|Permission $permission */
$permission = $this->em->getRepository(Permission::class)
$permission = $this->getEm()->getRepository(Permission::class)
->findOneBy(['code' => 'test.core.users.view'])
;
self::assertNotNull($permission);
@@ -153,9 +178,23 @@ final class PermissionApiTest extends ApiTestCase
self::assertResponseStatusCodeSame(403);
}
/**
* Recupere l'EntityManager depuis le container courant. A utiliser a
* chaque appel : apres un createClient(), le kernel est reboote et tout
* EM precedemment capture est invalide.
*/
private function getEm(): EntityManagerInterface
{
if (!self::$kernel) {
self::bootKernel();
}
return self::getContainer()->get('doctrine')->getManager();
}
private function cleanupTestPermissions(): void
{
$this->em->createQuery(
$this->getEm()->createQuery(
'DELETE FROM '.Permission::class.' p WHERE p.code LIKE :prefix'
)->setParameter('prefix', self::TEST_CODE_PREFIX.'%')->execute();
}