201) suppose un site courant (numerotation + cloisonnement, * § 2.3) : on le positionne pour chaque role autorise a ecrire. * * @internal */ final class WeighingTicketRBACMatrixTest extends AbstractWeighingTicketApiTestCase { private const string PWD = RbacDemoFixtures::DEMO_PASSWORD; protected function setUp(): void { parent::setUp(); // Seed idempotent des roles metier + matrice § 5.2 + comptes demo (meme // chemin qu'en recette). self::bootKernel(); $application = new Application(self::$kernel); $application->setAutoExit(false); $exit = $application->run( new ArrayInput([ 'command' => 'app:seed-rbac', '--with-demo-users' => true, '--password' => self::PWD, ]), new NullOutput(), ); self::assertSame( 0, $exit, 'app:seed-rbac a echoue : les permissions logistique.weighing_tickets.* sont-elles synchronisees (app:sync-permissions) ?', ); self::ensureKernelShutdown(); } public function testAdminCanViewAndManage(): void { $this->assertCanViewAndManage('admin', 'admin'); } public function testBureauCanViewAndManage(): void { $this->assertCanViewAndManage('bureau', self::PWD); } public function testUsineCanViewAndManage(): void { $this->assertCanViewAndManage('usine', self::PWD); } public function testComptaHasNoAccess(): void { $this->assertHasNoAccess('compta'); } public function testCommercialeHasNoAccess(): void { $this->assertHasNoAccess('commerciale'); } public function testAnonymousIsUnauthorized(): void { $client = self::createClient(); $client->request('GET', '/api/weighing_tickets', ['headers' => ['Accept' => self::LD]]); self::assertResponseStatusCodeSame(401); } /** * Role autorise : GET 200 (view) + POST 201 (manage). Le site courant est * positionne avant le POST pour permettre la numerotation. */ private function assertCanViewAndManage(string $username, string $password): void { $site = $this->firstSite(); $this->setCurrentSite($username, $site); $clientEntity = $this->seedTestClient('Rbac '.$username); $http = $this->authenticatedClient($username, $password); $http->request('GET', '/api/weighing_tickets', ['headers' => ['Accept' => self::LD]]); self::assertResponseStatusCodeSame(200); $this->postTicket($http, $this->validClientTicketPayload($clientEntity)); self::assertResponseStatusCodeSame(201); } /** * Role sans acces : 403 en lecture (view absent) ET en ecriture (manage absent). */ private function assertHasNoAccess(string $username): void { $clientEntity = $this->seedTestClient('Rbac '.$username); $http = $this->authenticatedClient($username, self::PWD); $http->request('GET', '/api/weighing_tickets', ['headers' => ['Accept' => self::LD]]); self::assertResponseStatusCodeSame(403); $this->postTicket($http, $this->validClientTicketPayload($clientEntity)); self::assertResponseStatusCodeSame(403); } }