test(transport) : rigueur RG sous-ressources (propertyPath, 404 parent, 401, certif)
Pull Request — Quality gate / Backend (PHP CS + PHPUnit) (pull_request) Failing after 54s
Pull Request — Quality gate / Frontend (lint + Vitest + build) (pull_request) Successful in 1m33s

Repond aux retours de review (rigueur d'assertion transversale) :
- mutualise assertViolationOnPath dans AbstractCarrierApiTestCase (au lieu d'un
  duplicata local a CarrierWriteApiTest) ;
- asserte le propertyPath des 422 des sous-ressources (adresses city/street/postalCode,
  contacts firstName/phones/email, prix clientDeliveryAddress/supplierSupplyAddress/price)
  -> evite les faux-verts du mapping inline (ERP-101) ;
- 404 parent (POST sur /carriers/999999/{addresses,contacts,prices}) ;
- 401 anonyme + filtre ?certificationType= sur la collection (trous releves sur le
  contrat de lecture).
This commit is contained in:
Matthieu
2026-06-16 14:57:45 +02:00
parent 18c88156e5
commit c1fcd9a7c8
6 changed files with 170 additions and 29 deletions
@@ -99,8 +99,8 @@ final class CarrierPriceApiTest extends AbstractCarrierApiTestCase
$this->getEm()->flush();
$siteId = $this->aSiteId();
$client = $this->createAdminClient();
$client->request('POST', '/api/carriers/'.$carrier->getId().'/prices', [
$client = $this->createAdminClient();
$response = $client->request('POST', '/api/carriers/'.$carrier->getId().'/prices', [
'headers' => ['Content-Type' => self::LD],
'json' => [
'direction' => 'CLIENT',
@@ -114,6 +114,9 @@ final class CarrierPriceApiTest extends AbstractCarrierApiTestCase
],
]);
self::assertResponseStatusCodeSame(422);
// Faux-vert evite : la 422 doit prouver l'integrite referentielle adresse<->tiers
// (violation sur clientDeliveryAddress), pas une autre cause (RG-4.10, ERP-101).
self::assertViolationOnPath($response, 'clientDeliveryAddress');
}
public function testForeignSupplierAddressReturns422(): void
@@ -125,8 +128,8 @@ final class CarrierPriceApiTest extends AbstractCarrierApiTestCase
$this->getEm()->flush();
$siteId = $this->aSiteId();
$client = $this->createAdminClient();
$client->request('POST', '/api/carriers/'.$carrier->getId().'/prices', [
$client = $this->createAdminClient();
$response = $client->request('POST', '/api/carriers/'.$carrier->getId().'/prices', [
'headers' => ['Content-Type' => self::LD],
'json' => [
'direction' => 'FOURNISSEUR',
@@ -140,6 +143,7 @@ final class CarrierPriceApiTest extends AbstractCarrierApiTestCase
],
]);
self::assertResponseStatusCodeSame(422);
self::assertViolationOnPath($response, 'supplierSupplyAddress');
}
public function testValidClientPriceIsCreated(): void
@@ -192,6 +196,54 @@ final class CarrierPriceApiTest extends AbstractCarrierApiTestCase
self::assertJsonContains(['direction' => 'FOURNISSEUR', 'priceState' => 'EN_COURS']);
}
public function testNegativePriceReturns422(): void
{
// Le prix porte un Assert\PositiveOrZero : une valeur negative -> 422 sur `price`
// (la branche CLIENT est par ailleurs complete pour isoler la cause).
$carrier = $this->seedCarrier('Prix Negatif');
$addr = $this->seedClientWithAddress('Client Prix Negatif');
$this->getEm()->flush();
$siteId = $this->aSiteId();
$client = $this->createAdminClient();
$response = $client->request('POST', '/api/carriers/'.$carrier->getId().'/prices', [
'headers' => ['Content-Type' => self::LD],
'json' => [
'direction' => 'CLIENT',
'client' => '/api/clients/'.$addr->getClient()?->getId(),
'clientDeliveryAddress' => '/api/client_addresses/'.$addr->getId(),
'departureSite' => '/api/sites/'.$siteId,
'containerType' => 'BENNE',
'pricingUnit' => 'TONNE',
'price' => '-5.00',
'priceState' => 'VALIDE',
],
]);
self::assertResponseStatusCodeSame(422);
self::assertViolationOnPath($response, 'price');
}
public function testPostPriceOnUnknownCarrierReturns404(): void
{
// Parent introuvable (read:false) -> 404 explicite du processor (linkParent
// s'execute avant validateBranch). Le payload porte les scalaires NotBlank
// (containerType/pricingUnit/price/priceState) pour passer la validation
// d'entite et atteindre le processor, ou le 404 prime.
$client = $this->createAdminClient();
$client->request('POST', '/api/carriers/999999/prices', [
'headers' => ['Content-Type' => self::LD],
'json' => [
'direction' => 'CLIENT',
'containerType' => 'BENNE',
'pricingUnit' => 'TONNE',
'price' => '42.50',
'priceState' => 'VALIDE',
],
]);
self::assertResponseStatusCodeSame(404);
}
public function testPatchAndDeleteSucceedWithManage(): void
{
$price = $this->seedClientPrice('Patch Delete');