RBAC #344 - API CRUD Roles & Permissions (Backend) #3

Closed
matthieu wants to merge 25 commits from feat/rbac-api into develop
3 changed files with 68 additions and 87 deletions
Showing only changes of commit 168a47f2b8 - Show all commits

View File

@@ -0,0 +1,66 @@
<?php
declare(strict_types=1);
namespace App\Tests\Module\Core\Api;
use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
use ApiPlatform\Symfony\Bundle\Test\Client;
use Doctrine\ORM\EntityManagerInterface;
/**
* Classe de base pour les tests fonctionnels API Platform du module Core.
*
* Mutualise :
* - `$alwaysBootKernel = true` : bascule le nouveau comportement API Platform 5
* et evite la deprecation emise a la creation du client de test.
* - `authenticatedClient()` : cree un client authentifie via `/login_check`
* (cookie BEARER HTTP-only pose par lexik_jwt_authentication).
* - `getEm()` : recupere l'EntityManager depuis le container courant.
* A rappeler apres chaque createClient() car le kernel est reboote.
*
* @internal
*/
abstract class AbstractApiTestCase extends ApiTestCase
{
// Bascule explicite sur le nouveau comportement API Platform 5 pour
// eviter la deprecation emise a la creation du client de test.
protected static ?bool $alwaysBootKernel = true;
/**
* 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.
*/
protected function getEm(): EntityManagerInterface
{
if (!self::$kernel) {
self::bootKernel();
}
return self::getContainer()->get('doctrine')->getManager();
}
/**
* Cree un client authentifie via /login_check. La configuration du projet
* pose le JWT dans un cookie HTTP-only `BEARER` (cf. lexik_jwt_authentication.yaml)
* et retire le token du body de reponse ; le client BrowserKit persiste
* automatiquement le cookie pour les requetes suivantes.
*/
protected function authenticatedClient(string $username, string $password): Client
{
$client = self::createClient();
$response = $client->request('POST', '/login_check', [
'headers' => ['Content-Type' => 'application/json'],
'json' => ['username' => $username, 'password' => $password],
]);
self::assertContains(
$response->getStatusCode(),
[200, 204],
'Login failed for '.$username.': '.$response->getStatusCode(),
);
return $client;
}
}

View File

@@ -4,10 +4,7 @@ declare(strict_types=1);
namespace App\Tests\Module\Core\Api;
use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
use ApiPlatform\Symfony\Bundle\Test\Client;
use App\Module\Core\Domain\Entity\Permission;
use Doctrine\ORM\EntityManagerInterface;
/**
* Tests fonctionnels de l'exposition API Platform de l'entite Permission.
@@ -20,12 +17,9 @@ use Doctrine\ORM\EntityManagerInterface;
*
* @internal
*/
final class PermissionApiTest extends ApiTestCase
final class PermissionApiTest extends AbstractApiTestCase
{
private const TEST_CODE_PREFIX = 'test.';
// Bascule explicite sur le nouveau comportement API Platform 5 pour
// eviter la deprecation emise a la creation du client de test.
protected static ?bool $alwaysBootKernel = true;
protected function setUp(): void
{
@@ -178,47 +172,10 @@ 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->getEm()->createQuery(
'DELETE FROM '.Permission::class.' p WHERE p.code LIKE :prefix'
)->setParameter('prefix', self::TEST_CODE_PREFIX.'%')->execute();
}
/**
* Cree un client authentifie via /login_check. La configuration du projet
* pose le JWT dans un cookie HTTP-only `BEARER` (cf. lexik_jwt_authentication.yaml)
* et retire le token du body de reponse ; le client BrowserKit persiste
* automatiquement le cookie pour les requetes suivantes.
*/
private function authenticatedClient(string $username, string $password): Client
{
$client = self::createClient();
$response = $client->request('POST', '/login_check', [
'headers' => ['Content-Type' => 'application/json'],
'json' => ['username' => $username, 'password' => $password],
]);
self::assertContains(
$response->getStatusCode(),
[200, 204],
'Login failed for '.$username.': '.$response->getStatusCode(),
);
return $client;
}
}

View File

@@ -4,12 +4,9 @@ declare(strict_types=1);
namespace App\Tests\Module\Core\Api;
use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
use ApiPlatform\Symfony\Bundle\Test\Client;
use App\Module\Core\Domain\Entity\Permission;
use App\Module\Core\Domain\Entity\Role;
use App\Module\Core\Domain\Security\SystemRoles;
use Doctrine\ORM\EntityManagerInterface;
/**
* Tests fonctionnels de l'exposition API Platform de l'entite Role (CRUD nominal).
@@ -24,7 +21,7 @@ use Doctrine\ORM\EntityManagerInterface;
*
* @internal
*/
final class RoleApiTest extends ApiTestCase
final class RoleApiTest extends AbstractApiTestCase
{
// Prefixe pour les roles de test : `test_` (underscore) parce que les
// codes de role doivent matcher `/^[a-z][a-z0-9_]*$/` (pas de point
@@ -36,10 +33,6 @@ final class RoleApiTest extends ApiTestCase
// module.resource.action validee dans le constructeur Permission).
private const TEST_PERMISSION_PREFIX = 'test.';
// Bascule explicite sur le nouveau comportement API Platform 5 pour
// eviter la deprecation emise a la creation du client de test.
protected static ?bool $alwaysBootKernel = true;
protected function setUp(): void
{
parent::setUp();
@@ -332,20 +325,6 @@ final class RoleApiTest 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();
}
/**
* Purge les donnees de test (roles et permissions prefixees `test.`).
* Ne touche JAMAIS aux roles systeme `admin` et `user` charges par les
@@ -369,25 +348,4 @@ final class RoleApiTest extends ApiTestCase
'DELETE FROM '.Permission::class.' p WHERE p.code LIKE :prefix'
)->setParameter('prefix', self::TEST_PERMISSION_PREFIX.'%')->execute();
}
/**
* Cree un client authentifie via /login_check (cookie BEARER pose par
* lexik_jwt_authentication et persiste automatiquement par BrowserKit).
*/
private function authenticatedClient(string $username, string $password): Client
{
$client = self::createClient();
$response = $client->request('POST', '/login_check', [
'headers' => ['Content-Type' => 'application/json'],
'json' => ['username' => $username, 'password' => $password],
]);
self::assertContains(
$response->getStatusCode(),
[200, 204],
'Login failed for '.$username.': '.$response->getStatusCode(),
);
return $client;
}
}