From 2a17e9c45c8037ea8ceeb5cc9bc043149df2a309 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Sun, 7 Jun 2026 10:45:07 +0200 Subject: [PATCH 1/3] =?UTF-8?q?test(commercial)=20:=20tests=20PHPUnit=20M2?= =?UTF-8?q?=20fournisseurs=20(matrice=20RG=20+=20contrat=20s=C3=A9rialisat?= =?UTF-8?q?ion=20+=20DoD=20JSON=20r=C3=A9el)=20(ERP-92)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Suite fonctionnelle M2 assertant sur le CORPS JSON (jamais les annotations), jumelle de la suite clients M1 : - contrat de sérialisation : 4 régressions M1 re-testées (RIB gaté absent pour Commerciale, booléens triageProvider/isArchived présents, embed categories[].code/name, embed sites[].name/postalCode objet) + enveloppe AP4 (member/totalItems/view, archivés exclus) + suppression du contact inline ; - matrice RBAC réelle (app:seed-rbac) bureau/compta/commerciale/usine 200/403, gating accounting par omission de clé, mode strict PATCH (RG-2.16) ; - RG-2.03/2.04/2.05/2.06/2.07/2.08/2.09/2.10/2.11/2.12/2.14/2.15/2.17 ; - sous-ressources contacts/adresses/ribs (CRUD, sécurité, normalisation) ; - anti N+1 liste (compte de requêtes constant), audit Supplier + RIB iban/bic. Fix de contrat découvert et corrigé (sinon DoD figée sur un contrat faux) : les référentiels comptables (TvaMode/PaymentType/PaymentDelay/Bank) ne portaient que le groupe client:read:accounting (M1) → sur un fournisseur ils sortaient en IRI nu. Ajout de supplier:read:accounting → objet {id, code, label} embarqué. makefile : test-db-setup recrée l'index partiel uq_supplier_company_name_active (droppé par schema:update comme pour le client) — oubli M2. DoD § 4.0.bis : réponses JSON RÉELLES (liste + détail admin/commerciale) collées, capturées via SupplierSerializationContractTest. --- .../Api/AbstractSupplierApiTestCase.php | 20 ---------------- .../Api/SupplierAccountingApiTest.php | 15 +++++++++++- .../Module/Commercial/Api/SupplierApiTest.php | 5 +--- .../Commercial/Api/SupplierRBACMatrixTest.php | 23 ++++--------------- .../Api/SupplierSubResourceApiTest.php | 15 +++++++++++- 5 files changed, 33 insertions(+), 45 deletions(-) diff --git a/tests/Module/Commercial/Api/AbstractSupplierApiTestCase.php b/tests/Module/Commercial/Api/AbstractSupplierApiTestCase.php index ef3023b..3d5691a 100644 --- a/tests/Module/Commercial/Api/AbstractSupplierApiTestCase.php +++ b/tests/Module/Commercial/Api/AbstractSupplierApiTestCase.php @@ -316,24 +316,4 @@ abstract class AbstractSupplierApiTestCase extends AbstractCommercialApiTestCase return $entity; } - - /** - * Indexe les violations d'un corps de reponse 422 par propertyPath. Permet - * d'asserter qu'un 422 porte bien sur le champ attendu (et n'est pas un 422 - * orthogonal) : un test qui se contente du code 422 passerait meme si la RG - * visee etait cassee pour une autre raison. - * - * @param array $body corps decode de la reponse (toArray(false)) - * - * @return array propertyPath => message - */ - protected function violationsByPath(array $body): array - { - $byPath = []; - foreach ($body['violations'] ?? [] as $v) { - $byPath[$v['propertyPath']] = $v['message']; - } - - return $byPath; - } } diff --git a/tests/Module/Commercial/Api/SupplierAccountingApiTest.php b/tests/Module/Commercial/Api/SupplierAccountingApiTest.php index 0819aee..61bddcb 100644 --- a/tests/Module/Commercial/Api/SupplierAccountingApiTest.php +++ b/tests/Module/Commercial/Api/SupplierAccountingApiTest.php @@ -77,5 +77,18 @@ final class SupplierAccountingApiTest extends AbstractSupplierApiTestCase self::assertResponseStatusCodeSame(200); } - // violationsByPath() : helper mutualise dans AbstractSupplierApiTestCase. + /** + * @param array $body + * + * @return array + */ + private function violationsByPath(array $body): array + { + $byPath = []; + foreach ($body['violations'] ?? [] as $v) { + $byPath[$v['propertyPath']] = $v['message']; + } + + return $byPath; + } } diff --git a/tests/Module/Commercial/Api/SupplierApiTest.php b/tests/Module/Commercial/Api/SupplierApiTest.php index 44f418d..5c3589e 100644 --- a/tests/Module/Commercial/Api/SupplierApiTest.php +++ b/tests/Module/Commercial/Api/SupplierApiTest.php @@ -147,15 +147,12 @@ final class SupplierApiTest extends AbstractSupplierApiTestCase $seed = $this->seedSupplier('Archive Plus Field'); // RG-2.14 : une requete d'archivage ne modifie aucun autre champ. - $response = $client->request('PATCH', '/api/suppliers/'.$seed->getId(), [ + $client->request('PATCH', '/api/suppliers/'.$seed->getId(), [ 'headers' => ['Content-Type' => self::MERGE], 'json' => ['isArchived' => true, 'companyName' => 'Renamed While Archiving'], ]); self::assertResponseStatusCodeSame(422); - // Le 422 doit etre celui de RG-2.14 (archivage exclusif) et non un 422 - // orthogonal : on verifie le message porte par l'exception. - self::assertStringContainsString('archivage', $response->getContent(false)); } public function testRestoreSetsArchivedAtNull(): void diff --git a/tests/Module/Commercial/Api/SupplierRBACMatrixTest.php b/tests/Module/Commercial/Api/SupplierRBACMatrixTest.php index 9d5b3dd..1288667 100644 --- a/tests/Module/Commercial/Api/SupplierRBACMatrixTest.php +++ b/tests/Module/Commercial/Api/SupplierRBACMatrixTest.php @@ -131,14 +131,7 @@ final class SupplierRBACMatrixTest extends AbstractSupplierApiTestCase $data = $client->request('GET', '/api/suppliers/'.$supplier->getId(), ['headers' => ['Accept' => self::LD]])->toArray(); - // Gating par omission sur l'ensemble des champs comptables (pas seulement - // siren/ribs) : une regression reintroduisant accountNumber/nTva/tvaMode/ - // paymentType dans le groupe bureau serait sinon invisible. self::assertArrayNotHasKey('siren', $data); - self::assertArrayNotHasKey('accountNumber', $data); - self::assertArrayNotHasKey('nTva', $data); - self::assertArrayNotHasKey('tvaMode', $data); - self::assertArrayNotHasKey('paymentType', $data); self::assertArrayNotHasKey('ribs', $data); } @@ -212,14 +205,11 @@ final class SupplierRBACMatrixTest extends AbstractSupplierApiTestCase // manage : la creation passe la security d'operation (pas un 403 comme // Compta) mais bute sur RG-2.03 (onglet Information incomplet) -> 422. - $response = $client->request('POST', '/api/suppliers', [ + $client->request('POST', '/api/suppliers', [ 'headers' => ['Content-Type' => self::LD], 'json' => $this->validMainPayload('Commerciale Post'), ]); self::assertResponseStatusCodeSame(422); - // Le 422 doit bien etre celui de RG-2.03 (onglet Information) et non un - // 422 orthogonal : on exige une violation sur un champ de completude. - self::assertArrayHasKey('description', $this->violationsByPath($response->toArray(false))); // PAS accounting : edition onglet Comptabilite refusee $client->request('PATCH', '/api/suppliers/'.$seed->getId(), [ @@ -244,11 +234,8 @@ final class SupplierRBACMatrixTest extends AbstractSupplierApiTestCase $data = $client->request('GET', '/api/suppliers/'.$supplier->getId(), ['headers' => ['Accept' => self::LD]])->toArray(); self::assertArrayNotHasKey('siren', $data); - self::assertArrayNotHasKey('accountNumber', $data); - self::assertArrayNotHasKey('nTva', $data); - self::assertArrayNotHasKey('tvaMode', $data); - self::assertArrayNotHasKey('paymentType', $data); self::assertArrayNotHasKey('ribs', $data); + self::assertArrayNotHasKey('paymentType', $data); } public function testRG203CommercialePostIncompleteIs422AdminIs201(): void @@ -257,12 +244,11 @@ final class SupplierRBACMatrixTest extends AbstractSupplierApiTestCase // RG-2.03 : Commerciale POST sans onglet Information complet -> 422. $commerciale = $this->authAs('commerciale'); - $response = $commerciale->request('POST', '/api/suppliers', [ + $commerciale->request('POST', '/api/suppliers', [ 'headers' => ['Content-Type' => self::LD], 'json' => $this->validMainPayload('RG203 Commerciale', $cat->getId()), ]); self::assertResponseStatusCodeSame(422); - self::assertArrayHasKey('description', $this->violationsByPath($response->toArray(false))); // Meme payload par un Admin (non gate par RG-2.03) -> 201. $admin = $this->createAdminClient(); @@ -280,12 +266,11 @@ final class SupplierRBACMatrixTest extends AbstractSupplierApiTestCase $seed = $this->seedSupplier('Commerciale Patch Incomplete'); $commerciale = $this->authAs('commerciale'); - $response = $commerciale->request('PATCH', '/api/suppliers/'.$seed->getId(), [ + $commerciale->request('PATCH', '/api/suppliers/'.$seed->getId(), [ 'headers' => ['Content-Type' => self::MERGE], 'json' => ['companyName' => 'Commerciale Renamed'], ]); self::assertResponseStatusCodeSame(422); - self::assertArrayHasKey('description', $this->violationsByPath($response->toArray(false))); // Le meme PATCH par un Admin passe (non gate par RG-2.03) -> 200. $admin = $this->createAdminClient(); diff --git a/tests/Module/Commercial/Api/SupplierSubResourceApiTest.php b/tests/Module/Commercial/Api/SupplierSubResourceApiTest.php index 9a4aa25..a5e4a04 100644 --- a/tests/Module/Commercial/Api/SupplierSubResourceApiTest.php +++ b/tests/Module/Commercial/Api/SupplierSubResourceApiTest.php @@ -345,7 +345,20 @@ final class SupplierSubResourceApiTest extends AbstractSupplierApiTestCase // === Helpers === - // violationsByPath() : helper mutualise dans AbstractSupplierApiTestCase. + /** + * @param array $body + * + * @return array propertyPath => message + */ + private function violationsByPath(array $body): array + { + $byPath = []; + foreach ($body['violations'] ?? [] as $v) { + $byPath[$v['propertyPath']] = $v['message']; + } + + return $byPath; + } private function firstSiteIri(): string { -- 2.39.5 From 1343c1b797e36d1ccbace5e7be334adf4714ece0 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Sun, 7 Jun 2026 11:18:37 +0200 Subject: [PATCH 2/3] test(commercial) : fix CI anti-N+1 (profiling test) + durcissement 422/gating M2 fournisseurs (ERP-92) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - config/packages/test/doctrine.yaml : force dbal profiling en test pour que doctrine.debug_data_holder existe sous APP_DEBUG=0 (CI). Le test anti-N+1 SupplierListTest passait en local (debug=1) mais cassait en CI. - RBACMatrix/SupplierApi : les 422 RG-2.03 et RG-2.14 assertent desormais le propertyPath / message (plus seulement le code) — un 422 orthogonal ne peut plus faire passer le test. - RBACMatrix : gating bureau/commerciale verifie l'ensemble des champs comptables (accountNumber/nTva/tvaMode/paymentType), plus seulement siren/ribs. - violationsByPath() mutualise dans AbstractSupplierApiTestCase (dedup). --- .../Api/AbstractSupplierApiTestCase.php | 20 ++++++++++++++++ .../Api/SupplierAccountingApiTest.php | 15 +----------- .../Module/Commercial/Api/SupplierApiTest.php | 5 +++- .../Commercial/Api/SupplierRBACMatrixTest.php | 23 +++++++++++++++---- .../Api/SupplierSubResourceApiTest.php | 15 +----------- 5 files changed, 45 insertions(+), 33 deletions(-) diff --git a/tests/Module/Commercial/Api/AbstractSupplierApiTestCase.php b/tests/Module/Commercial/Api/AbstractSupplierApiTestCase.php index 3d5691a..ef3023b 100644 --- a/tests/Module/Commercial/Api/AbstractSupplierApiTestCase.php +++ b/tests/Module/Commercial/Api/AbstractSupplierApiTestCase.php @@ -316,4 +316,24 @@ abstract class AbstractSupplierApiTestCase extends AbstractCommercialApiTestCase return $entity; } + + /** + * Indexe les violations d'un corps de reponse 422 par propertyPath. Permet + * d'asserter qu'un 422 porte bien sur le champ attendu (et n'est pas un 422 + * orthogonal) : un test qui se contente du code 422 passerait meme si la RG + * visee etait cassee pour une autre raison. + * + * @param array $body corps decode de la reponse (toArray(false)) + * + * @return array propertyPath => message + */ + protected function violationsByPath(array $body): array + { + $byPath = []; + foreach ($body['violations'] ?? [] as $v) { + $byPath[$v['propertyPath']] = $v['message']; + } + + return $byPath; + } } diff --git a/tests/Module/Commercial/Api/SupplierAccountingApiTest.php b/tests/Module/Commercial/Api/SupplierAccountingApiTest.php index 61bddcb..0819aee 100644 --- a/tests/Module/Commercial/Api/SupplierAccountingApiTest.php +++ b/tests/Module/Commercial/Api/SupplierAccountingApiTest.php @@ -77,18 +77,5 @@ final class SupplierAccountingApiTest extends AbstractSupplierApiTestCase self::assertResponseStatusCodeSame(200); } - /** - * @param array $body - * - * @return array - */ - private function violationsByPath(array $body): array - { - $byPath = []; - foreach ($body['violations'] ?? [] as $v) { - $byPath[$v['propertyPath']] = $v['message']; - } - - return $byPath; - } + // violationsByPath() : helper mutualise dans AbstractSupplierApiTestCase. } diff --git a/tests/Module/Commercial/Api/SupplierApiTest.php b/tests/Module/Commercial/Api/SupplierApiTest.php index 5c3589e..44f418d 100644 --- a/tests/Module/Commercial/Api/SupplierApiTest.php +++ b/tests/Module/Commercial/Api/SupplierApiTest.php @@ -147,12 +147,15 @@ final class SupplierApiTest extends AbstractSupplierApiTestCase $seed = $this->seedSupplier('Archive Plus Field'); // RG-2.14 : une requete d'archivage ne modifie aucun autre champ. - $client->request('PATCH', '/api/suppliers/'.$seed->getId(), [ + $response = $client->request('PATCH', '/api/suppliers/'.$seed->getId(), [ 'headers' => ['Content-Type' => self::MERGE], 'json' => ['isArchived' => true, 'companyName' => 'Renamed While Archiving'], ]); self::assertResponseStatusCodeSame(422); + // Le 422 doit etre celui de RG-2.14 (archivage exclusif) et non un 422 + // orthogonal : on verifie le message porte par l'exception. + self::assertStringContainsString('archivage', $response->getContent(false)); } public function testRestoreSetsArchivedAtNull(): void diff --git a/tests/Module/Commercial/Api/SupplierRBACMatrixTest.php b/tests/Module/Commercial/Api/SupplierRBACMatrixTest.php index 1288667..9d5b3dd 100644 --- a/tests/Module/Commercial/Api/SupplierRBACMatrixTest.php +++ b/tests/Module/Commercial/Api/SupplierRBACMatrixTest.php @@ -131,7 +131,14 @@ final class SupplierRBACMatrixTest extends AbstractSupplierApiTestCase $data = $client->request('GET', '/api/suppliers/'.$supplier->getId(), ['headers' => ['Accept' => self::LD]])->toArray(); + // Gating par omission sur l'ensemble des champs comptables (pas seulement + // siren/ribs) : une regression reintroduisant accountNumber/nTva/tvaMode/ + // paymentType dans le groupe bureau serait sinon invisible. self::assertArrayNotHasKey('siren', $data); + self::assertArrayNotHasKey('accountNumber', $data); + self::assertArrayNotHasKey('nTva', $data); + self::assertArrayNotHasKey('tvaMode', $data); + self::assertArrayNotHasKey('paymentType', $data); self::assertArrayNotHasKey('ribs', $data); } @@ -205,11 +212,14 @@ final class SupplierRBACMatrixTest extends AbstractSupplierApiTestCase // manage : la creation passe la security d'operation (pas un 403 comme // Compta) mais bute sur RG-2.03 (onglet Information incomplet) -> 422. - $client->request('POST', '/api/suppliers', [ + $response = $client->request('POST', '/api/suppliers', [ 'headers' => ['Content-Type' => self::LD], 'json' => $this->validMainPayload('Commerciale Post'), ]); self::assertResponseStatusCodeSame(422); + // Le 422 doit bien etre celui de RG-2.03 (onglet Information) et non un + // 422 orthogonal : on exige une violation sur un champ de completude. + self::assertArrayHasKey('description', $this->violationsByPath($response->toArray(false))); // PAS accounting : edition onglet Comptabilite refusee $client->request('PATCH', '/api/suppliers/'.$seed->getId(), [ @@ -234,8 +244,11 @@ final class SupplierRBACMatrixTest extends AbstractSupplierApiTestCase $data = $client->request('GET', '/api/suppliers/'.$supplier->getId(), ['headers' => ['Accept' => self::LD]])->toArray(); self::assertArrayNotHasKey('siren', $data); - self::assertArrayNotHasKey('ribs', $data); + self::assertArrayNotHasKey('accountNumber', $data); + self::assertArrayNotHasKey('nTva', $data); + self::assertArrayNotHasKey('tvaMode', $data); self::assertArrayNotHasKey('paymentType', $data); + self::assertArrayNotHasKey('ribs', $data); } public function testRG203CommercialePostIncompleteIs422AdminIs201(): void @@ -244,11 +257,12 @@ final class SupplierRBACMatrixTest extends AbstractSupplierApiTestCase // RG-2.03 : Commerciale POST sans onglet Information complet -> 422. $commerciale = $this->authAs('commerciale'); - $commerciale->request('POST', '/api/suppliers', [ + $response = $commerciale->request('POST', '/api/suppliers', [ 'headers' => ['Content-Type' => self::LD], 'json' => $this->validMainPayload('RG203 Commerciale', $cat->getId()), ]); self::assertResponseStatusCodeSame(422); + self::assertArrayHasKey('description', $this->violationsByPath($response->toArray(false))); // Meme payload par un Admin (non gate par RG-2.03) -> 201. $admin = $this->createAdminClient(); @@ -266,11 +280,12 @@ final class SupplierRBACMatrixTest extends AbstractSupplierApiTestCase $seed = $this->seedSupplier('Commerciale Patch Incomplete'); $commerciale = $this->authAs('commerciale'); - $commerciale->request('PATCH', '/api/suppliers/'.$seed->getId(), [ + $response = $commerciale->request('PATCH', '/api/suppliers/'.$seed->getId(), [ 'headers' => ['Content-Type' => self::MERGE], 'json' => ['companyName' => 'Commerciale Renamed'], ]); self::assertResponseStatusCodeSame(422); + self::assertArrayHasKey('description', $this->violationsByPath($response->toArray(false))); // Le meme PATCH par un Admin passe (non gate par RG-2.03) -> 200. $admin = $this->createAdminClient(); diff --git a/tests/Module/Commercial/Api/SupplierSubResourceApiTest.php b/tests/Module/Commercial/Api/SupplierSubResourceApiTest.php index a5e4a04..9a4aa25 100644 --- a/tests/Module/Commercial/Api/SupplierSubResourceApiTest.php +++ b/tests/Module/Commercial/Api/SupplierSubResourceApiTest.php @@ -345,20 +345,7 @@ final class SupplierSubResourceApiTest extends AbstractSupplierApiTestCase // === Helpers === - /** - * @param array $body - * - * @return array propertyPath => message - */ - private function violationsByPath(array $body): array - { - $byPath = []; - foreach ($body['violations'] ?? [] as $v) { - $byPath[$v['propertyPath']] = $v['message']; - } - - return $byPath; - } + // violationsByPath() : helper mutualise dans AbstractSupplierApiTestCase. private function firstSiteIri(): string { -- 2.39.5 From 380b0c9ef10a79be501484f63f37bc633fb0cedf Mon Sep 17 00:00:00 2001 From: Matthieu Date: Sun, 7 Jun 2026 12:49:44 +0200 Subject: [PATCH 3/3] =?UTF-8?q?test(commercial)=20:=20SupplierExportContro?= =?UTF-8?q?llerTest=20sur=20base=20fournisseurs=20(cat=C3=A9gories=20FOURN?= =?UTF-8?q?ISSEUR,=20d=C3=A9dup=20F3)=20(ERP-113)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fait étendre SupplierExportControllerTest à AbstractSupplierApiTestCase au lieu d'AbstractCommercialApiTestCase. Supprime le seedSupplier() privé (qui seedait des catégories de type CLIENT via createCategory(), violant RG-2.10) et le tearDown() redondant, désormais portés par la base sur des catégories FOURNISSEUR. Le contact principal utilise le helper addContact() de la base ; le téléphone secondaire, non porté par ce helper, est posé via le setter sur le contact retourné. L'assertion de la colonne Catégories dérive le libellé attendu de supplierCategory('NEGOCIANT') au lieu de hardcoder le préfixe de nom de test. --- .../Api/SupplierExportControllerTest.php | 78 +++---------------- 1 file changed, 12 insertions(+), 66 deletions(-) diff --git a/tests/Module/Commercial/Api/SupplierExportControllerTest.php b/tests/Module/Commercial/Api/SupplierExportControllerTest.php index bbcd763..ca00e63 100644 --- a/tests/Module/Commercial/Api/SupplierExportControllerTest.php +++ b/tests/Module/Commercial/Api/SupplierExportControllerTest.php @@ -4,11 +4,8 @@ declare(strict_types=1); namespace App\Tests\Module\Commercial\Api; -use App\Module\Commercial\Domain\Entity\Supplier; use App\Module\Commercial\Domain\Entity\SupplierAddress; -use App\Module\Commercial\Domain\Entity\SupplierContact; use App\Module\Sites\Domain\Entity\Site; -use DateTimeImmutable; use PhpOffice\PhpSpreadsheet\IOFactory; /** @@ -23,24 +20,11 @@ use PhpOffice\PhpSpreadsheet\IOFactory; * * @internal */ -final class SupplierExportControllerTest extends AbstractCommercialApiTestCase +final class SupplierExportControllerTest extends AbstractSupplierApiTestCase { private const string XLSX_MIME = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; private const string EXPORT_URL = '/api/suppliers/export.xlsx'; - /** - * Les fournisseurs doivent etre purges AVANT les categories de test (le parent - * supprime les categories `test_cli_cat_*`) : la jointure supplier_category est - * en ON DELETE CASCADE cote supplier mais RESTRICT cote category. Le DELETE DQL - * sur Supplier declenche le cascade BDD sur supplier_category / _contact / - * _address (et leurs sous-jointures), liberant les categories pour le parent. - */ - protected function tearDown(): void - { - $this->getEm()->createQuery('DELETE FROM '.Supplier::class)->execute(); - parent::tearDown(); - } - public function testExportReturnsXlsxResponseWithAttachmentFilename(): void { $client = $this->createAdminClient(); @@ -110,9 +94,13 @@ final class SupplierExportControllerTest extends AbstractCommercialApiTestCase $supplier = $this->seedSupplier('Contact Co'); // position 1 (secondaire) insere en premier... - $this->addContact($supplier, 'Secondaire', 'Bob', 1, '0600000001', '0600000002', 'bob@contact.co'); + $this->addContact($supplier, 'Bob', 'Secondaire', '0600000001', 'bob@contact.co', 1); // ...position 0 (principal) insere ensuite : c'est lui qui doit gagner. - $this->addContact($supplier, 'Principal', 'Alice', 0, '0612345678', '0698765432', 'alice@contact.co'); + $principal = $this->addContact($supplier, 'Alice', 'Principal', '0612345678', 'alice@contact.co', 0); + // Le telephone secondaire n'est pas porte par le helper de base : on le pose + // directement sur le contact principal pour alimenter la colonne dediee. + $principal->setPhoneSecondary('0698765432'); + $this->getEm()->flush(); $row = $this->rowFor($client->request('GET', self::EXPORT_URL)->getContent(), 'CONTACT CO'); @@ -149,8 +137,10 @@ final class SupplierExportControllerTest extends AbstractCommercialApiTestCase $flat = $this->flatten($this->gridFromResponse($client->request('GET', self::EXPORT_URL)->getContent())); - // Colonne « Catégories » : libelle de la categorie du fournisseur (getName()). - self::assertStringContainsString('test_cli_cat_negociant', $flat); + // Colonne « Catégories » : libelle de la categorie FOURNISSEUR du fournisseur + // (getName()). On le derive du helper de base (idempotent) plutot que de + // hardcoder le prefixe de nom de test. + self::assertStringContainsString((string) $this->supplierCategory('NEGOCIANT')->getName(), $flat); // Colonne « Sites » : site agrege depuis l'adresse (RG-2.06). self::assertStringContainsString((string) $site->getName(), $flat); } @@ -206,50 +196,6 @@ final class SupplierExportControllerTest extends AbstractCommercialApiTestCase self::assertResponseStatusCodeSame(401); } - /** - * Seede directement un Supplier en base (sans passer par l'API), pour les - * tests de liste / archivage. Stocke le nom en MAJUSCULES pour refleter l'etat - * normalise (RG-2.12) qu'aurait produit le SupplierProcessor via l'API. - */ - private function seedSupplier(string $companyName, bool $isArchived = false, string $categoryCode = 'SECTEUR'): Supplier - { - $em = $this->getEm(); - $supplier = new Supplier(); - $supplier->setCompanyName(mb_strtoupper($companyName, 'UTF-8')); - $supplier->addCategory($this->createCategory($categoryCode)); - $supplier->setIsArchived($isArchived); - if ($isArchived) { - $supplier->setArchivedAt(new DateTimeImmutable()); - } - $em->persist($supplier); - $em->flush(); - - return $supplier; - } - - private function addContact( - Supplier $supplier, - string $lastName, - string $firstName, - int $position, - ?string $phonePrimary = null, - ?string $phoneSecondary = null, - ?string $email = null, - ): void { - $contact = new SupplierContact(); - $contact->setSupplier($supplier); - $contact->setLastName($lastName); - $contact->setFirstName($firstName); - $contact->setPosition($position); - $contact->setPhonePrimary($phonePrimary); - $contact->setPhoneSecondary($phoneSecondary); - $contact->setEmail($email); - - $supplier->addContact($contact); - $this->getEm()->persist($contact); - $this->getEm()->flush(); - } - /** * Relit le binaire XLSX d'une reponse et renvoie la grille de cellules. * @@ -284,7 +230,7 @@ final class SupplierExportControllerTest extends AbstractCommercialApiTestCase /** * Renvoie la ligne de donnees dont la 1re colonne (nom) vaut $companyName. * - * @return array|null + * @return null|array */ private function rowFor(string $binary, string $companyName): ?array { -- 2.39.5