409 (RG-7.08). * * @internal */ final class StorageUniquenessTest extends AbstractStorageApiTestCase { public function testDuplicateActiveTripletReturns409(): void { $site = $this->firstSite(); $type = $this->seedStorageType(); $this->seedStorageEntity('A1', site: $site, storageType: $type); $client = $this->createAdminClient(); $client->request('POST', '/api/storages', [ 'headers' => ['Content-Type' => self::LD], 'json' => $this->tripletPayload($site, $type, 'A1'), ]); self::assertResponseStatusCodeSame(409); } public function testSameNumeroOnAnotherTypeIsAccepted(): void { $site = $this->firstSite(); $typeA = $this->seedStorageType(); $typeB = $this->seedStorageType(); $this->seedStorageEntity('A1', site: $site, storageType: $typeA); $client = $this->createAdminClient(); $client->request('POST', '/api/storages', [ 'headers' => ['Content-Type' => self::LD], 'json' => $this->tripletPayload($site, $typeB, 'A1'), ]); self::assertResponseStatusCodeSame(201); } public function testSameNumeroOnAnotherSiteIsAccepted(): void { $sites = $this->getEm()->getRepository(Site::class)->findAll(); if (count($sites) < 2) { self::markTestSkipped('Au moins 2 sites fixtures requis pour ce cas.'); } $type = $this->seedStorageType(); $this->seedStorageEntity('A1', site: $sites[0], storageType: $type); $client = $this->createAdminClient(); $client->request('POST', '/api/storages', [ 'headers' => ['Content-Type' => self::LD], 'json' => $this->tripletPayload($sites[1], $type, 'A1'), ]); self::assertResponseStatusCodeSame(201); } public function testSoftDeletedTripletCanBeReused(): void { $site = $this->firstSite(); $type = $this->seedStorageType(); $this->seedStorageEntity('B2', deletedAt: new DateTimeImmutable(), site: $site, storageType: $type); $client = $this->createAdminClient(); $client->request('POST', '/api/storages', [ 'headers' => ['Content-Type' => self::LD], 'json' => $this->tripletPayload($site, $type, 'B2'), ]); self::assertResponseStatusCodeSame(201); } public function testPatchToExistingTripletReturns409(): void { $site = $this->firstSite(); $type = $this->seedStorageType(); $this->seedStorageEntity('A1', site: $site, storageType: $type); $target = $this->seedStorageEntity('B2', site: $site, storageType: $type); // RG-7.08 : PATCH du numero B2 -> A1 (meme site+type) collisionne -> 409. $client = $this->createAdminClient(); $client->request('PATCH', '/api/storages/'.$target->getId(), [ 'headers' => ['Content-Type' => self::MERGE], 'json' => ['numero' => 'A1'], ]); self::assertResponseStatusCodeSame(409); } /** * Payload POST minimal pour un triplet (site, type, numero) donne. * * @return array */ private function tripletPayload(Site $site, StorageType $type, string $numero): array { return [ 'site' => $this->iri('sites', (int) $site->getId()), 'storageType' => $this->iri('storage_types', (int) $type->getId()), 'numero' => $numero, 'states' => [Storage::STATE_RECEPTION], ]; } }