createAdminClient(); $code = $this->uniqueCode('TESTPRD'); $client->request('POST', '/api/products', [ 'headers' => ['Content-Type' => self::LD], 'json' => $this->validProductPayload(['code' => $code]), ]); self::assertResponseStatusCodeSame(201); // Meme code -> conflit (RG-6.01). $client->request('POST', '/api/products', [ 'headers' => ['Content-Type' => self::LD], 'json' => $this->validProductPayload(['code' => $code]), ]); self::assertResponseStatusCodeSame(409); } public function testNormalizedCodeCollides(): void { $client = $this->createAdminClient(); $code = $this->uniqueCode('TESTPRD'); $client->request('POST', '/api/products', [ 'headers' => ['Content-Type' => self::LD], 'json' => $this->validProductPayload(['code' => $code]), ]); self::assertResponseStatusCodeSame(201); // Variante minuscule + espaces : trim + UPPER serveur (RG-6.07) la ramene // a la meme forme normalisee -> meme collision 409. $client->request('POST', '/api/products', [ 'headers' => ['Content-Type' => self::LD], 'json' => $this->validProductPayload(['code' => ' '.strtolower($code).' ']), ]); self::assertResponseStatusCodeSame(409); } public function testSoftDeletedCodeCanBeReused(): void { $client = $this->createAdminClient(); $code = $this->uniqueCode('TESTPRD'); // Produit soft-deleted portant le code (seede directement, hors index actif). $this->seedProductEntity( code: $code, states: [Product::STATE_PURCHASE], deletedAt: new DateTimeImmutable(), ); // Le meme code est libre cote actifs -> creation acceptee (201). $client->request('POST', '/api/products', [ 'headers' => ['Content-Type' => self::LD], 'json' => $this->validProductPayload(['code' => $code]), ]); self::assertResponseStatusCodeSame(201); } }