7075f0f95d
- Storage.setStates() renormalise en liste séquentielle (array_values) : un states posté en objet JSON ne peut plus être persisté en JSONB objet (jsonb_array_length → 500). Doublons rejetés en 422 via Assert\Unique. - PhpSpreadsheetExporter écrit les cellules chaîne en TYPE_STRING explicite : neutralise l'injection de formules/DDE sur toutes les valeurs saisies (corrige aussi Produit/Client/Logistique/Supplier/Provider/Carrier). - StorageListFilters : source unique de parsing des filtres (?search, ?siteId[], ?storageTypeId, ?state), consommée par le provider ET l'export → fin des divergences (numéro « 0 » coercé à null, param tableau en 400, id non positif). - Export en streaming (toIterable + clear par lot) au lieu de getResult() : mémoire bornée. - Tests : doublon/objet states, normalisation trim RG-7.06, 422 relations nulles, absence de deletedAt, soft-delete liste discriminant, neutralisation formule, parité ?search=0, robustesse param tableau ; garde-fou Assert\Unique enregistré.
84 lines
3.1 KiB
PHP
84 lines
3.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Tests\Module\Catalog\Api;
|
|
|
|
/**
|
|
* Validation et normalisation serveur a l'ecriture du stockage (M7, POST / PATCH) :
|
|
* - RG-7.06 : le numero est trimme cote serveur (et SANS changement de casse) ;
|
|
* - numero vide -> 422 (Assert\NotBlank) sur `numero` ;
|
|
* - relation nulle (site / storageType) -> 422 (Assert\NotNull, via le chemin de
|
|
* denormalisation `collectDenormalizationErrors`) portant le bon propertyPath, et
|
|
* NON un 400 qui court-circuiterait le mapping inline front (useFormErrors,
|
|
* ERP-101).
|
|
*
|
|
* Pendant ces RG, le contrat de violation 422 (propertyPath aligne sur le champ
|
|
* front) est ce que le front consomme : on l'asserte explicitement.
|
|
*
|
|
* @internal
|
|
*/
|
|
final class StorageWriteValidationTest extends AbstractStorageApiTestCase
|
|
{
|
|
public function testNumeroIsTrimmedServerSide(): void
|
|
{
|
|
$client = $this->createAdminClient();
|
|
|
|
// RG-7.06 : numero saisi avec des espaces autour -> stocke trimme.
|
|
$created = $client->request('POST', '/api/storages', [
|
|
'headers' => ['Content-Type' => self::LD],
|
|
'json' => $this->validStoragePayload(['numero' => ' A1 ']),
|
|
])->toArray();
|
|
|
|
self::assertResponseStatusCodeSame(201);
|
|
self::assertSame('A1', $created['numero'], 'Le numero doit etre trimme cote serveur (RG-7.06).');
|
|
|
|
// Relecture : la normalisation est bien persistee, pas seulement reflechie.
|
|
$detail = $client->request('GET', '/api/storages/'.$created['id'], [
|
|
'headers' => ['Accept' => self::LD],
|
|
])->toArray();
|
|
self::assertSame('A1', $detail['numero']);
|
|
}
|
|
|
|
public function testBlankNumeroIsRejected(): void
|
|
{
|
|
$client = $this->createAdminClient();
|
|
|
|
$response = $client->request('POST', '/api/storages', [
|
|
'headers' => ['Content-Type' => self::LD],
|
|
'json' => $this->validStoragePayload(['numero' => ' ']),
|
|
]);
|
|
|
|
self::assertResponseStatusCodeSame(422);
|
|
self::assertContains('numero', $this->violationPaths($response));
|
|
}
|
|
|
|
public function testNullSiteReturns422WithPropertyPath(): void
|
|
{
|
|
$client = $this->createAdminClient();
|
|
|
|
// Relation obligatoire a null : doit ressortir en 422 (NotNull) avec un
|
|
// propertyPath `site`, pas en 400 (collectDenormalizationErrors).
|
|
$response = $client->request('POST', '/api/storages', [
|
|
'headers' => ['Content-Type' => self::LD],
|
|
'json' => $this->validStoragePayload(['site' => null]),
|
|
]);
|
|
|
|
self::assertResponseStatusCodeSame(422);
|
|
self::assertContains('site', $this->violationPaths($response));
|
|
}
|
|
|
|
public function testNullStorageTypeReturns422WithPropertyPath(): void
|
|
{
|
|
$client = $this->createAdminClient();
|
|
|
|
$response = $client->request('POST', '/api/storages', [
|
|
'headers' => ['Content-Type' => self::LD],
|
|
'json' => $this->validStoragePayload(['storageType' => null]),
|
|
]);
|
|
|
|
self::assertResponseStatusCodeSame(422);
|
|
self::assertContains('storageType', $this->violationPaths($response));
|
|
}
|
|
}
|