a52e3bec34
Auto Tag Develop / tag (push) Successful in 11s
Stack de 2 tickets sur une branche (squash sur `develop`). ## ERP-76 (#500) — Validations d'adresse Client → 422 Les règles d'intégrité de l'onglet Adresse étaient soit non implémentées (RG-1.29), soit rejetées en 500 par les CHECK Postgres (RG-1.06/07/08/11). Elles sont désormais portées par des `Assert\Callback` applicatifs sur `ClientAddress`, qui remontent une **422 Hydra avant la base** ; les CHECK BDD restent en filet de sécurité. - `validateProspectExclusivity` — `isProspect` exclusif de `isDelivery`/`isBilling` (RG-1.06/07/08). - `validateBillingEmailPresence` — `billingEmail` obligatoire ssi `isBilling` (RG-1.11). - `validateCategoryTypes` — refuse une catégorie de type DISTRIBUTEUR/COURTIER sur une adresse (RG-1.29, violation `categories`), via `CategoryInterface` (règle n°1 respectée). Tests `ClientAddressTest` durcis (≥400 → **422 explicite**) + 4 cas RG-1.29. Cahier de test M1 mis à jour. ## ERP-68 (#486) — Fixtures démo Catalog + Commercial (dev only) - `CategoryFixtures` (Catalog) : 12 catégories sur les 4 types. - `ClientFixtures` (Commercial) : 14 clients couvrant les cas RG (dépendant distributeur/courtier RG-1.03, LCR + 2 RIB RG-1.13, Chèque sans RIB, multi-adresses Prospect/Livraison/Facturation RG-1.06/07/08/11, prospect seul, 3 contacts + tél. secondaire RG-1.05/1.02, archivé RG-1.22, onglet Information complet, multi-catégories M2M). Résolution inter-modules via les seuls contrats Shared (`CategoryInterface`, `SiteProviderInterface`). Valeurs brutes normalisées par `ClientFieldNormalizer`. Données conformes aux CHECK BDD **et** aux validators ERP-76. Idempotentes (lookup `companyName`/`name`). **Garde-fou** : les deux fixtures sont no-op en environnement `test` (la base de test reste un socle minimal ; pas de pollution des comptages ni des cleanups FK). ## Bonus — idempotence fixtures `AppFixtures` (admin/alice/bob) rendu idempotent via lookup par username : `doctrine:fixtures:load --append` est désormais rejouable sans erreur sur tout le jeu de fixtures. ## Vérifications - `make test` : **436/436 vert** (0 échec/erreur). - `make php-cs-fixer-allow-risky` OK. - `make db-reset` charge sans erreur ; 2 runs `--append` consécutifs = idempotent (0 doublon ; 7 users / 14 clients / 12 catégories stables). - `admin/admin` intact. --------- Co-authored-by: Matthieu <contact@malio.fr> Reviewed-on: #41 Co-authored-by: THOLOT DECHENE Matthieu <matthieu@yuno.malio.fr> Co-committed-by: THOLOT DECHENE Matthieu <matthieu@yuno.malio.fr>
8.6 KiB
8.6 KiB
Cahier de test back — M1 Répertoire clients (ticket ERP-60 / #478)
Mapping toutes les RG (§ 7) → test(s) PHPUnit, à jour après ERP-60.
Légende source : ERP-55 ERP-56 ERP-57 ERP-58 = tests écrits par les wagons
précédents ; ERP-60 = tests ajoutés par ce ticket (stratégie « combler les
trous, zéro duplication »).
Stratégie
ERP-60 n'écrit QUE les tests des RG non déjà couvertes par la stack, et mappe ici l'intégralité des RG (existantes + nouvelles + déléguées). Les tests dépendants des rôles métier (matrice RBAC bureau/compta/commerciale/usine + RG-1.04 fonctionnel) sont délégués à ERP-74 (#493) : ces rôles n'existent qu'après le merge de la stack.
Mapping RG → test
| RG | Intitulé | Test(s) | Source |
|---|---|---|---|
| RG-1.01 | Prénom OU nom obligatoire → 422 | ClientApiTest::testPostWithoutFirstOrLastNameReturns422 ; ClientProcessorTest (unit) |
ERP-55 |
| RG-1.02 | phoneSecondary persisté ; max 2 téléphones | ClientFormulaireMainTest::testPostPersistsSecondaryPhoneNormalized ; ::testThirdPhoneFieldIsIgnored |
ERP-60 |
| RG-1.03 | distributor/broker exclusifs + type catégorie | ClientApiTest::testPostWithDistributorAndBrokerReturns422 ; ::testPostDistributorReferencingNonDistributorReturns422 ; ::testPostValidDistributorReturns201 ; ClientProcessorTest (unit) |
ERP-55 |
| RG-1.04 | Onglet Information obligatoire pour rôle Commerciale | ClientProcessorTest::testCommercialeIncompleteInformationIsUnprocessable ; ::testNonCommercialeSkipsInformationCompleteness (unit, dormant). Test fonctionnel + durcissement → ERP-74 |
ERP-55 / ERP-74 |
| RG-1.05 | Contact : prénom OU nom → 422 (CHECK) | ClientSubResourceApiTest::testPostContactWithoutNameReturns422 |
ERP-57 |
| RG-1.06/07/08 | Adresse prospect exclusive de livraison/facturation → 422 (Assert\Callback + CHECK filet) | ClientAddressTest::testProspectAddressCannotBeDelivery ; ::testProspectAddressCannotBeBilling |
ERP-60 / ERP-76 |
| RG-1.09 | Code postal ^[0-9]{4,5}$ → 422 |
ClientSubResourceApiTest::testPostAddressWithInvalidPostalCodeReturns422 |
ERP-57 |
| RG-1.10 | ≥ 1 site sur adresse → 422 | ClientSubResourceApiTest::testPostAddressWithoutSiteReturns422 |
ERP-57 |
| RG-1.11 | billingEmail obligatoire ssi isBilling → 422 (Assert\Callback + CHECK filet) | ClientAddressTest::testBillingAddressRequiresBillingEmail ; ::testNonBillingAddressRejectsBillingEmail |
ERP-60 / ERP-76 |
| RG-1.12 | Virement → banque obligatoire → 422 | ClientProcessorTest::testVirementWithoutBankIsUnprocessable ; ::testVirementWithBankPasses (unit) |
ERP-55 |
| RG-1.13 | LCR → ≥ 1 RIB ; DELETE dernier RIB en LCR → 409 | ClientProcessorTest::testLcrWithoutRibIsUnprocessable / ::testLcrWithRibPasses (unit) ; ClientSubResourceApiTest::testDeleteLastRibUnderLcrReturns409 / ::testDeleteRibNonLcrReturns204 |
ERP-55 / ERP-57 |
| RG-1.14 | ≥ 1 bloc Contact pour finaliser l'onglet | Front-driven (pas de state machine back). Back voisin : ClientSubResourceApiTest::testDeleteLastContactReturns409 |
ERP-57 |
| RG-1.15 | ClientUniquenessTest::testDuplicateSirenIsAllowed ; ClientMigrationTest::testNoSirenOrEmailUniqueIndex |
ERP-60 | |
| RG-1.16 | companyName unique (case-insensitive) parmi actifs → 409 | ClientApiTest::testPostDuplicateCompanyNameReturns409 ; ClientMigrationTest::testCompanyNameActivePartialIndexExistsExactlyOnce |
ERP-55 / ERP-60 |
| RG-1.17 | ClientUniquenessTest::testDuplicateEmailIsAllowed ; ClientMigrationTest::testNoSirenOrEmailUniqueIndex |
ERP-60 | |
| RG-1.18 | companyName upper-cased serveur | ClientApiTest::testPostNormalizesTextFields ; ClientFieldNormalizerTest::testCompanyNameIsUppercased (unit) |
ERP-55 |
| RG-1.19 | firstName/lastName capitalize serveur | ClientApiTest::testPostNormalizesTextFields ; ClientFieldNormalizerTest::testPersonNameIsTitleCased (unit) ; ClientSubResourceApiTest::testPostContactNormalizesFields |
ERP-55 / ERP-57 |
| RG-1.20 | Téléphones chiffres-seuls serveur | ClientApiTest::testPostNormalizesTextFields ; ClientFieldNormalizerTest::testPhoneKeepsOnlyDigits (unit) ; ClientFormulaireMainTest::testPostPersistsSecondaryPhoneNormalized (secondary) |
ERP-55 / ERP-60 |
| RG-1.21 | email lowercase serveur | ClientApiTest::testPostNormalizesTextFields ; ClientFieldNormalizerTest::testEmailIsLowercased (unit) ; ClientSubResourceApiTest::testPostContactNormalizesFields / ::testPostAddressNormalizesBillingEmail |
ERP-55 / ERP-57 |
| RG-1.22 | Archive : permission archive + archivedAt + aucun autre champ |
ClientApiTest::testPatchArchiveSetsArchivedAtThenRestore ; ::testPatchArchiveWithOtherFieldReturns422 ; ClientProcessorTest (unit, gating archive) |
ERP-55 |
| RG-1.23 | Restauration : archivedAt=null ; 409 si conflit d'unicité | ClientApiTest::testPatchArchiveSetsArchivedAtThenRestore (cas nominal) ; ClientArchiveTest::testRestoreConflictReturns409 (409 restauration, gap P1) |
ERP-55 / ERP-60 |
| RG-1.24 | Liste exclut les archivés par défaut | ClientApiTest::testListSortedByCompanyNameAscAndExcludesArchived |
ERP-55 |
| RG-1.25 | ?includeArchived=true inclut les archivés |
ClientApiTest::testListIncludeArchivedReturnsArchived |
ERP-55 |
| RG-1.26 | Tri par défaut companyName ASC | ClientApiTest::testListSortedByCompanyNameAscAndExcludesArchived |
ERP-55 |
| RG-1.27 | Timestampable/Blamable : created* figés, updated* mis à jour | ClientAuditTest::testCreatedFrozenAndUpdatedByReflectsModifier |
ERP-60 |
| RG-1.28 | PATCH multi-groupes sans permission → 403 strict (tout le payload) | ClientProcessorTest::testStrictMixWithAccountingFieldIsForbidden / ::testAccountingFieldWithoutPermissionIsForbidden (unit) ; ClientPatchStrictTest::testMixedGroupsPatchWithoutAccountingPermissionIsForbidden (fonctionnel) |
ERP-55 / ERP-60 |
| RG-1.29 | Catégorie d'adresse limitée aux types SECTEUR/AUTRE | Filtrage LECTURE = front-driven (SearchFilter GET /api/categories?categoryType.code[]=…). Validation ÉCRITURE : ClientAddress::validateCategoryTypes (Assert\Callback) rejette une catégorie DISTRIBUTEUR/COURTIER en 422 (violation categories). Tests : ClientAddressTest::testAddressRejectsDistributorCategory / ::testAddressRejectsBrokerCategory / ::testAddressAcceptsSectorCategory / ::testAddressAcceptsOtherCategory |
ERP-76 |
Couvertures transverses
| Sujet | Test(s) | Source |
|---|---|---|
Audit iban/bic présents dans le diff (pas d'#[AuditIgnore]) |
ClientAuditTest::testRibCreateAuditIncludesIbanAndBic |
ERP-60 |
Sécurité générique : 401 anonyme + 403 sans commercial.clients.view |
ClientSecurityTest (collection + détail) ; ClientExportControllerTest::testForbiddenWithoutClientsViewPermission / ::testUnauthorizedWhenAnonymous |
ERP-60 / ERP-58 |
| Migration : index partiel unique présent (1 seul), pas de siren/email unique | ClientMigrationTest |
ERP-60 |
| Référentiels comptables read-only (405 écriture, 401/403) | ReferentialApiTest |
ERP-56 |
| Export XLSX (colonnes accounting selon permission, 401/403) | ClientExportControllerTest |
ERP-58 |
Délégué à ERP-74 (#493) — NE PAS faire dans ERP-60
- Matrice RBAC différenciée par rôle métier (Bureau / Compta / Commerciale / Usine) : 200/403 par verbe et par onglet selon le rôle.
- RG-1.04 fonctionnel : PATCH onglet Information par une Commerciale avec champs incomplets → 422 ; même PATCH par Admin → 200 (+ durcissement code/spec).
- Raison : ces rôles métier ne sont seedés qu'après le merge de la stack M1.
Gaps & suivi
RG-1.29 (validation écriture)— résolu en ERP-76. La validation d'écriture refuse désormais une catégorie de typeDISTRIBUTEUR/COURTIERsur uneClientAddress(→ 422, violationcategories) via l'Assert\CallbackClientAddress::validateCategoryTypes. Le filtrage de lecture reste front-driven (SearchFilter). Couvert parClientAddressTest.Violations CHECK → statut HTTP— résolu en ERP-76. Les règles d'adresse RG-1.06/07/08/11 sont désormais rejetées en 422 par des Assert\Callback applicatifs (validateProspectExclusivity/validateBillingEmailPresence) qui s'exécutent AVANT la base. Les CHECK Postgres (chk_client_address_prospect_exclusive/chk_client_address_billing_email) restent en filet de sécurité. Les testsClientAddressTestassertent maintenant le 422 explicite (et non plus ≥ 400).