422 (Assert\Count(min: 1)) sur le champ `states` ; * - valeur hors enum -> 422 (Assert\Choice) sur le champ `states` ; * - un seul etat valide -> 201 (borne basse acceptee) ; * - PATCH vers un tableau d'etats vide -> 422 (RG-7.08). * * @internal */ final class StorageStatesValidationTest extends AbstractStorageApiTestCase { public function testEmptyStatesIsRejected(): void { $client = $this->createAdminClient(); $response = $client->request('POST', '/api/storages', [ 'headers' => ['Content-Type' => self::LD], 'json' => $this->validStoragePayload(['states' => []]), ]); self::assertResponseStatusCodeSame(422); self::assertContains('states', $this->violationPaths($response)); } public function testUnknownStateValueIsRejected(): void { $client = $this->createAdminClient(); $response = $client->request('POST', '/api/storages', [ 'headers' => ['Content-Type' => self::LD], 'json' => $this->validStoragePayload(['states' => [Storage::STATE_RECEPTION, 'FOOBAR']]), ]); self::assertResponseStatusCodeSame(422); self::assertContains('states', $this->violationPaths($response)); } public function testSingleValidStateIsAccepted(): void { $client = $this->createAdminClient(); $client->request('POST', '/api/storages', [ 'headers' => ['Content-Type' => self::LD], 'json' => $this->validStoragePayload(['states' => [Storage::STATE_PRODUCTION]]), ]); self::assertResponseStatusCodeSame(201); } public function testPatchToEmptyStatesIsRejected(): void { $storage = $this->seedStorageEntity(); // RG-7.08 : la regle RG-7.04 vaut aussi en edition. $client = $this->createAdminClient(); $response = $client->request('PATCH', '/api/storages/'.$storage->getId(), [ 'headers' => ['Content-Type' => self::MERGE], 'json' => ['states' => []], ]); self::assertResponseStatusCodeSame(422); self::assertContains('states', $this->violationPaths($response)); } public function testDuplicateStatesAreRejected(): void { $client = $this->createAdminClient(); // Doublon dans le multi-select : 422 (Assert\Unique), pas un stockage avec un // tableau d'etats incoherent (RG-7.04 = sous-ensemble). $response = $client->request('POST', '/api/storages', [ 'headers' => ['Content-Type' => self::LD], 'json' => $this->validStoragePayload([ 'states' => [Storage::STATE_TRIAGE, Storage::STATE_TRIAGE], ]), ]); self::assertResponseStatusCodeSame(422); self::assertContains('states', $this->violationPaths($response)); } public function testNonSequentialStatesDoNotCrash(): void { $client = $this->createAdminClient(); // `states` envoye comme OBJET JSON (cle non sequentielle) : auparavant // persiste tel quel en JSONB objet -> le CHECK jsonb_array_length plantait en // 500. Doit desormais etre renormalise en liste sequentielle (array_values du // setter), donc accepte proprement sans 500. $created = $client->request('POST', '/api/storages', [ 'headers' => ['Content-Type' => self::LD], 'json' => $this->validStoragePayload([ 'states' => [7 => Storage::STATE_RECEPTION], ]), ])->toArray(); self::assertResponseStatusCodeSame(201); self::assertSame([Storage::STATE_RECEPTION], $created['states']); } }