feat(catalog) : add stable auto-generated code to Category
Nouvelle colonne Category.code (NOT NULL, unique partiel uq_category_code), slug MAJUSCULE du nom genere par CategoryCodeGenerator et fige a la creation, expose en lecture seule. CategoryInterface::getCode() ajoute au contrat Shared. Retrofit COMMENT (Version20260528120000) rendu conscient des colonnes pour tolerer l'ajout de code au catalogue.
This commit is contained in:
@@ -83,6 +83,9 @@ abstract class AbstractCatalogApiTestCase extends AbstractApiTestCase
|
||||
$suffix = substr(bin2hex(random_bytes(4)), 0, 8);
|
||||
$category = new Category();
|
||||
$category->setName($name ?? self::TEST_CATEGORY_PREFIX.$suffix);
|
||||
// ERP-78 : code NOT NULL + unique parmi les actifs (uq_category_code).
|
||||
// Nonce aleatoire -> unicite garantie entre seeds successifs du test.
|
||||
$category->setCode('TEST_'.strtoupper($suffix));
|
||||
$category->setCategoryType($type);
|
||||
if (null !== $deletedAt) {
|
||||
$category->setDeletedAt($deletedAt);
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Module\Catalog\Api;
|
||||
|
||||
/**
|
||||
* Tests ERP-78 : le `code` technique stable de Category.
|
||||
*
|
||||
* Cas couverts :
|
||||
* - POST : le code est auto-genere (slug MAJUSCULE du nom) et expose en lecture ;
|
||||
* - le code est en lecture seule : un `code` envoye dans le payload est ignore
|
||||
* (genere depuis le nom) ;
|
||||
* - deux noms produisant le meme slug recoivent des codes distincts (suffixe).
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class CategoryCodeTest extends AbstractCatalogApiTestCase
|
||||
{
|
||||
public function testPostGeneratesAndExposesCode(): void
|
||||
{
|
||||
$type = $this->createCategoryType();
|
||||
$client = $this->createAdminClient();
|
||||
|
||||
$response = $client->request('POST', '/api/categories', [
|
||||
'headers' => ['Content-Type' => 'application/ld+json'],
|
||||
'json' => [
|
||||
'name' => self::TEST_CATEGORY_PREFIX.'Agro-alimentaire',
|
||||
'categoryType' => '/api/category_types/'.$type->getId(),
|
||||
],
|
||||
]);
|
||||
self::assertResponseStatusCodeSame(201);
|
||||
|
||||
$payload = $response->toArray();
|
||||
// Slug MAJUSCULE du nom, separateurs non alphanumeriques -> `_`.
|
||||
self::assertSame(
|
||||
strtoupper(self::TEST_CATEGORY_PREFIX).'AGRO_ALIMENTAIRE',
|
||||
$payload['code'],
|
||||
);
|
||||
}
|
||||
|
||||
public function testCodeIsReadOnlyAndIgnoredFromPayload(): void
|
||||
{
|
||||
$type = $this->createCategoryType();
|
||||
$client = $this->createAdminClient();
|
||||
|
||||
$response = $client->request('POST', '/api/categories', [
|
||||
'headers' => ['Content-Type' => 'application/ld+json'],
|
||||
'json' => [
|
||||
'name' => self::TEST_CATEGORY_PREFIX.'readonly',
|
||||
'categoryType' => '/api/category_types/'.$type->getId(),
|
||||
// Le client tente d'imposer un code : doit etre ignore.
|
||||
'code' => 'CLIENT_FORGED',
|
||||
],
|
||||
]);
|
||||
self::assertResponseStatusCodeSame(201);
|
||||
|
||||
$payload = $response->toArray();
|
||||
self::assertNotSame('CLIENT_FORGED', $payload['code']);
|
||||
self::assertSame(strtoupper(self::TEST_CATEGORY_PREFIX).'READONLY', $payload['code']);
|
||||
}
|
||||
|
||||
public function testCollidingSlugsGetDistinctCodes(): void
|
||||
{
|
||||
$type = $this->createCategoryType();
|
||||
$client = $this->createAdminClient();
|
||||
|
||||
// Deux noms differents (donc autorises par uq_category_name_type_active)
|
||||
// mais qui produisent le meme slug -> codes distincts (suffixe `_2`).
|
||||
$first = $client->request('POST', '/api/categories', [
|
||||
'headers' => ['Content-Type' => 'application/ld+json'],
|
||||
'json' => [
|
||||
'name' => self::TEST_CATEGORY_PREFIX.'Agro Plus',
|
||||
'categoryType' => '/api/category_types/'.$type->getId(),
|
||||
],
|
||||
])->toArray();
|
||||
|
||||
$second = $client->request('POST', '/api/categories', [
|
||||
'headers' => ['Content-Type' => 'application/ld+json'],
|
||||
'json' => [
|
||||
'name' => self::TEST_CATEGORY_PREFIX.'Agro-Plus',
|
||||
'categoryType' => '/api/category_types/'.$type->getId(),
|
||||
],
|
||||
])->toArray();
|
||||
|
||||
self::assertResponseStatusCodeSame(201);
|
||||
self::assertNotSame($first['code'], $second['code']);
|
||||
self::assertStringEndsWith('_2', (string) $second['code']);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user