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 (permissions transport.carriers.* synchronisees ?).'); self::ensureKernelShutdown(); } public function testSearchReturnsOnlyActiveOrderedByName(): void { // Marqueur unique partage par les 3 lignes : isole la recherche d'eventuelles // autres lignes du referentiel. $this->insertQualimat('QSEARCH GAMMA', true, 'A1'); $this->insertQualimat('QSEARCH ALPHA', true, 'A2'); $this->insertQualimat('QSEARCH BETA', false, 'A3'); // inactive -> exclue $client = $this->createAdminClient(); $client->request('GET', '/api/qualimat_carriers?search=qsearch', ['headers' => ['Accept' => self::LD]]); self::assertResponseIsSuccessful(); $data = $client->getResponse()->toArray(); $names = array_column($data['member'], 'name'); self::assertSame(2, $data['totalItems'], 'Seules les 2 lignes actives doivent remonter (BETA inactive exclue).'); self::assertSame(['QSEARCH ALPHA', 'QSEARCH GAMMA'], $names, 'Tri name ASC, sans la ligne inactive.'); } public function testSearchMatchesSiret(): void { // Le nom ne porte pas le marqueur : la correspondance se fait via le siret. $this->insertQualimat('TRANSPORTEUR SANS MARQUEUR', true, 'SIRETHIT1'); $client = $this->createAdminClient(); $client->request('GET', '/api/qualimat_carriers?search=testqsirethit1', ['headers' => ['Accept' => self::LD]]); self::assertResponseIsSuccessful(); $data = $client->getResponse()->toArray(); self::assertSame(1, $data['totalItems'], 'La recherche fuzzy doit aussi cibler le siret.'); self::assertSame('TRANSPORTEUR SANS MARQUEUR', $data['member'][0]['name']); } public function testCollectionExposesHydraPagination(): void { $this->insertQualimat('QPAGE UN', true, 'P1'); $this->insertQualimat('QPAGE DEUX', true, 'P2'); $this->insertQualimat('QPAGE TROIS', true, 'P3'); $client = $this->createAdminClient(); $client->request('GET', '/api/qualimat_carriers?search=qpage&itemsPerPage=2', ['headers' => ['Accept' => self::LD]]); self::assertResponseIsSuccessful(); $data = $client->getResponse()->toArray(); self::assertArrayHasKey('totalItems', $data, 'La collection doit exposer totalItems.'); self::assertArrayHasKey('view', $data, 'La collection doit exposer view quand totalItems > itemsPerPage.'); self::assertIsArray($data['member']); self::assertSame(3, $data['totalItems']); self::assertCount(2, $data['member'], 'La page doit etre bornee a itemsPerPage=2.'); } public function testForbiddenWithoutPermission(): void { // Usine : aucun acces transporteurs (matrice § 5.2) -> 403 sur la recherche. $client = $this->authenticatedClient('usine', self::PWD); $client->request('GET', '/api/qualimat_carriers', ['headers' => ['Accept' => self::LD]]); self::assertResponseStatusCodeSame(403); } /** * Insere une ligne qualimat_carrier de test en DBAL brut (l'entite mappee est * en lecture seule). SIRET prefixe TESTQ pour la purge ciblee du tearDown. */ private function insertQualimat(string $name, bool $isActive, string $siretSuffix): void { $this->getEm()->getConnection()->insert('qualimat_carrier', [ 'siret' => self::SIRET_PREFIX.$siretSuffix, 'name' => $name, 'status' => 'Valide', 'validity_date' => '2027-12-31', 'is_active' => $isActive ? 'true' : 'false', 'last_synced_at' => (new DateTimeImmutable())->format('Y-m-d H:i:s'), ]); } }