RBAC #344 - API CRUD Roles & Permissions (Backend) #3
66
tests/Module/Core/Api/AbstractApiTestCase.php
Normal file
66
tests/Module/Core/Api/AbstractApiTestCase.php
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,10 +4,7 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace App\Tests\Module\Core\Api;
|
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\Permission;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests fonctionnels de l'exposition API Platform de l'entite Permission.
|
* Tests fonctionnels de l'exposition API Platform de l'entite Permission.
|
||||||
@@ -20,12 +17,9 @@ use Doctrine\ORM\EntityManagerInterface;
|
|||||||
*
|
*
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
final class PermissionApiTest extends ApiTestCase
|
final class PermissionApiTest extends AbstractApiTestCase
|
||||||
{
|
{
|
||||||
private const TEST_CODE_PREFIX = 'test.';
|
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
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
@@ -178,47 +172,10 @@ final class PermissionApiTest extends ApiTestCase
|
|||||||
self::assertResponseStatusCodeSame(403);
|
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
|
private function cleanupTestPermissions(): void
|
||||||
{
|
{
|
||||||
$this->getEm()->createQuery(
|
$this->getEm()->createQuery(
|
||||||
'DELETE FROM '.Permission::class.' p WHERE p.code LIKE :prefix'
|
'DELETE FROM '.Permission::class.' p WHERE p.code LIKE :prefix'
|
||||||
)->setParameter('prefix', self::TEST_CODE_PREFIX.'%')->execute();
|
)->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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,9 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace App\Tests\Module\Core\Api;
|
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\Permission;
|
||||||
use App\Module\Core\Domain\Entity\Role;
|
use App\Module\Core\Domain\Entity\Role;
|
||||||
use App\Module\Core\Domain\Security\SystemRoles;
|
use App\Module\Core\Domain\Security\SystemRoles;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests fonctionnels de l'exposition API Platform de l'entite Role (CRUD nominal).
|
* Tests fonctionnels de l'exposition API Platform de l'entite Role (CRUD nominal).
|
||||||
@@ -24,7 +21,7 @@ use Doctrine\ORM\EntityManagerInterface;
|
|||||||
*
|
*
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
final class RoleApiTest extends ApiTestCase
|
final class RoleApiTest extends AbstractApiTestCase
|
||||||
{
|
{
|
||||||
// Prefixe pour les roles de test : `test_` (underscore) parce que les
|
// Prefixe pour les roles de test : `test_` (underscore) parce que les
|
||||||
// codes de role doivent matcher `/^[a-z][a-z0-9_]*$/` (pas de point
|
// 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).
|
// module.resource.action validee dans le constructeur Permission).
|
||||||
private const TEST_PERMISSION_PREFIX = 'test.';
|
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
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
@@ -332,20 +325,6 @@ final class RoleApiTest extends ApiTestCase
|
|||||||
self::assertResponseStatusCodeSame(403);
|
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.`).
|
* Purge les donnees de test (roles et permissions prefixees `test.`).
|
||||||
* Ne touche JAMAIS aux roles systeme `admin` et `user` charges par les
|
* 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'
|
'DELETE FROM '.Permission::class.' p WHERE p.code LIKE :prefix'
|
||||||
)->setParameter('prefix', self::TEST_PERMISSION_PREFIX.'%')->execute();
|
)->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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user