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 transport.carriers.* sont-elles synchronisees (app:sync-permissions) ?', ); self::ensureKernelShutdown(); } public function testUsineIsForbiddenEverywhere(): void { $seed = $this->seedCarrier('Usine Target'); $client = $this->authAs('usine'); $client->request('GET', '/api/carriers', ['headers' => ['Accept' => self::LD]]); self::assertResponseStatusCodeSame(403); $client->request('GET', '/api/carriers/'.$seed->getId(), ['headers' => ['Accept' => self::LD]]); self::assertResponseStatusCodeSame(403); $client->request('POST', '/api/carriers', [ 'headers' => ['Content-Type' => self::LD], 'json' => $this->validMainPayload('Usine Post'), ]); self::assertResponseStatusCodeSame(403); } public function testComptaHasNoAccess(): void { $seed = $this->seedCarrier('Compta Target'); $client = $this->authAs('compta'); // PAS view (matrice § 5.2 : Compta sans acces transporteurs). $client->request('GET', '/api/carriers', ['headers' => ['Accept' => self::LD]]); self::assertResponseStatusCodeSame(403); // PAS manage : creation refusee. $client->request('POST', '/api/carriers', [ 'headers' => ['Content-Type' => self::LD], 'json' => $this->validMainPayload('Compta Post'), ]); self::assertResponseStatusCodeSame(403); $client->request('PATCH', '/api/carriers/'.$seed->getId(), [ 'headers' => ['Content-Type' => self::MERGE], 'json' => ['name' => 'Renamed By Compta'], ]); self::assertResponseStatusCodeSame(403); } public function testBureauHasViewAndManageButNoArchive(): void { $seed = $this->seedCarrier('Bureau Target'); $client = $this->authAs('bureau'); // view $client->request('GET', '/api/carriers', ['headers' => ['Accept' => self::LD]]); self::assertResponseStatusCodeSame(200); // manage : creation OK $client->request('POST', '/api/carriers', [ 'headers' => ['Content-Type' => self::LD], 'json' => $this->validMainPayload('Bureau Created'), ]); self::assertResponseStatusCodeSame(201); // manage : edition formulaire principal OK $client->request('PATCH', '/api/carriers/'.$seed->getId(), [ 'headers' => ['Content-Type' => self::MERGE], 'json' => ['name' => 'Bureau Renamed'], ]); self::assertResponseStatusCodeSame(200); // PAS archive : archivage refuse (RG-4.14, gating CarrierProcessor). $client->request('PATCH', '/api/carriers/'.$seed->getId(), [ 'headers' => ['Content-Type' => self::MERGE], 'json' => ['isArchived' => true], ]); self::assertResponseStatusCodeSame(403); } public function testCommercialeHasViewOnly(): void { $seed = $this->seedCarrier('Commerciale Target'); $client = $this->authAs('commerciale'); // view (consultation « Tout ») $client->request('GET', '/api/carriers', ['headers' => ['Accept' => self::LD]]); self::assertResponseStatusCodeSame(200); // PAS manage : creation refusee $client->request('POST', '/api/carriers', [ 'headers' => ['Content-Type' => self::LD], 'json' => $this->validMainPayload('Commerciale Post'), ]); self::assertResponseStatusCodeSame(403); // PAS manage : edition refusee $client->request('PATCH', '/api/carriers/'.$seed->getId(), [ 'headers' => ['Content-Type' => self::MERGE], 'json' => ['name' => 'Renamed By Commerciale'], ]); self::assertResponseStatusCodeSame(403); } private function authAs(string $role): Client { return $this->authenticatedClient($role, self::PWD); } }