fix(commercial) : billingEmail vide rejete en 422 et non en 500 (RG-1.11)
Le callback validateBillingEmailPresence testait null === billingEmail. Une chaine vide "" (champ vide envoye par le client) passait donc les validators ; le ClientAddressProcessor la normalisait ensuite en null APRES la validation, puis la persistance d'une adresse is_billing=true avec billing_email=null violait le CHECK chk_client_address_billing_email -> 500 DBAL au lieu du 422 attendu. Symetriquement, "" sur une adresse non facturable etait rejete a tort en 422 alors qu'un champ vide equivaut a une absence d'email. Le callback raisonne desormais sur la presence effective (null OU chaine vide apres trim = absent), coheremment avec la normalisation du processor. Deux cas de test ajoutes : adresse facturable + "" -> 422, adresse non facturable + "" -> 201.
This commit is contained in:
@@ -202,18 +202,28 @@ class ClientAddress implements TimestampableInterface, BlamableInterface
|
||||
* RG-1.11 : l'email de facturation est obligatoire si l'adresse est de
|
||||
* facturation, et interdit sinon. Mirror applicatif (422) du CHECK
|
||||
* chk_client_address_billing_email.
|
||||
*
|
||||
* On raisonne sur la PRESENCE effective de l'email : null ET chaine vide
|
||||
* sont traites comme « absent », car le ClientAddressProcessor normalise une
|
||||
* chaine vide en null APRES la validation (RG-1.21). Sans ce traitement,
|
||||
* billingEmail="" passerait les callbacks (null === "" est faux) puis serait
|
||||
* persiste en null avec is_billing=true -> violation du CHECK -> 500 au lieu
|
||||
* du 422 attendu (et symetriquement, "" sur une adresse non facturable
|
||||
* serait rejete a tort).
|
||||
*/
|
||||
#[Assert\Callback]
|
||||
public function validateBillingEmailPresence(ExecutionContextInterface $context): void
|
||||
{
|
||||
if ($this->isBilling && null === $this->billingEmail) {
|
||||
$hasBillingEmail = null !== $this->billingEmail && '' !== trim($this->billingEmail);
|
||||
|
||||
if ($this->isBilling && !$hasBillingEmail) {
|
||||
$context->buildViolation('L\'email de facturation est obligatoire pour une adresse de facturation.')
|
||||
->atPath('billingEmail')
|
||||
->addViolation()
|
||||
;
|
||||
}
|
||||
|
||||
if (!$this->isBilling && null !== $this->billingEmail) {
|
||||
if (!$this->isBilling && $hasBillingEmail) {
|
||||
$context->buildViolation('L\'email de facturation n\'est autorisé que sur une adresse de facturation.')
|
||||
->atPath('billingEmail')
|
||||
->addViolation()
|
||||
|
||||
@@ -106,6 +106,33 @@ final class ClientAddressTest extends AbstractCommercialApiTestCase
|
||||
self::assertResponseStatusCodeSame(422);
|
||||
}
|
||||
|
||||
/**
|
||||
* RG-1.11 (cas chaine vide) : une adresse de facturation avec un billingEmail
|
||||
* vide ("") doit etre rejetee en 422, et NON passer la validation pour finir
|
||||
* en 500 sur le CHECK BDD. Le ClientAddressProcessor normalise "" -> null
|
||||
* APRES la validation : le callback doit donc traiter "" comme « absent ».
|
||||
*/
|
||||
public function testBillingAddressRejectsEmptyBillingEmail(): void
|
||||
{
|
||||
$this->skipIfSitesModuleDisabled();
|
||||
$client = $this->createAdminClient();
|
||||
$seed = $this->seedClient('Billing Empty Email');
|
||||
|
||||
$client->request('POST', '/api/clients/'.$seed->getId().'/addresses', [
|
||||
'headers' => ['Content-Type' => self::LD],
|
||||
'json' => [
|
||||
'isBilling' => true,
|
||||
'billingEmail' => '',
|
||||
'postalCode' => '86100',
|
||||
'city' => 'Châtellerault',
|
||||
'street' => '1 rue du Test',
|
||||
'sites' => [$this->firstSiteIri()],
|
||||
],
|
||||
]);
|
||||
|
||||
self::assertResponseStatusCodeSame(422);
|
||||
}
|
||||
|
||||
/**
|
||||
* RG-1.11 (sens inverse) : une adresse NON facturable ne peut pas porter un
|
||||
* billingEmail -> 422.
|
||||
@@ -131,6 +158,33 @@ final class ClientAddressTest extends AbstractCommercialApiTestCase
|
||||
self::assertResponseStatusCodeSame(422);
|
||||
}
|
||||
|
||||
/**
|
||||
* RG-1.11 (sens inverse, cas chaine vide) : une adresse NON facturable avec
|
||||
* un billingEmail vide ("") est ACCEPTEE (201). Le "" equivaut a « pas
|
||||
* d'email » : il ne doit pas declencher la violation « email interdit hors
|
||||
* facturation » (sinon un champ simplement vide serait refuse a tort).
|
||||
*/
|
||||
public function testNonBillingAddressAcceptsEmptyBillingEmail(): void
|
||||
{
|
||||
$this->skipIfSitesModuleDisabled();
|
||||
$client = $this->createAdminClient();
|
||||
$seed = $this->seedClient('Non Billing Empty Email');
|
||||
|
||||
$client->request('POST', '/api/clients/'.$seed->getId().'/addresses', [
|
||||
'headers' => ['Content-Type' => self::LD],
|
||||
'json' => [
|
||||
'isBilling' => false,
|
||||
'billingEmail' => '',
|
||||
'postalCode' => '86100',
|
||||
'city' => 'Châtellerault',
|
||||
'street' => '1 rue du Test',
|
||||
'sites' => [$this->firstSiteIri()],
|
||||
],
|
||||
]);
|
||||
|
||||
self::assertResponseStatusCodeSame(201);
|
||||
}
|
||||
|
||||
/**
|
||||
* RG-1.29 : poster une categorie de type DISTRIBUTEUR sur une adresse -> 422
|
||||
* avec violation sur le champ `categories`.
|
||||
|
||||
Reference in New Issue
Block a user