d6790dd37d
Auto Tag Develop / tag (push) Successful in 7s
ERP-94 (etape front 7/7 du M2). **Stack sur #97** (base = `feature/ERP-97-suppliers-i18n-sidebar`, elle-meme sur #93) pour un diff isole. A recibler sur `develop` une fois #93 (MR #81) et #97 (MR #82) mergees. Page « Ajouter un fournisseur » — **replique a l'identique le fonctionnement de l'ecran Client** (workflow inline par onglets, blocs reutilisables, validation 422 inline ERP-101), avec les specificites M2. ## Architecture (miroir Client) - Workflow par onglets **inline dans `suppliers/new.vue`** (comme `clients/new.vue` — il n'existe pas de `useClientForm` monolithique). Helpers paralleles : `useSupplierReferentials`, `useSupplierFormErrors`, `supplierFormRules`, `supplierEdit` (payloads), `types/supplierForm`. - Blocs `SupplierContactBlock` / `SupplierAddressBlock` (miroir des blocs Client). - POST `/suppliers` puis PATCH partiels par onglet (mode strict, groupes de serialisation). Sous-ressources : `/suppliers/{id}/contacts|addresses|ribs`. - Validation ERP-101 : 422 `violations[].propertyPath` mappees inline par champ (`useFormErrors` / `mapViolationsToRecord`), `{ toast: false }`, bouton Valider toujours actif. ## Specificites M2 (vs M1) - Formulaire principal **sans contact inline** (ERP-106) : Entreprise + Categorie (type FOURNISSEUR, `?typeCode=FOURNISSEUR`). - Adresse : **radio exclusif** Prospect/Depart/Rendu (`addressType` enum, RG-2.09), champs **Bennes** (stepper) + **Prestation de triage**, **pas d'email de facturation**. - Information : champ **Volume previsionnel** (8e champ). - Compta (Admin+Compta) : banque si VIREMENT (RG-2.07), RIB si LCR (RG-2.08) ; RIB sous-ressource gardee par `accounting.manage`. ## Tests (mirroir strategie Client) - `make nuxt-test` : 338 passed (specs ajoutees : supplierFormRules, supplierEdit, useSupplierReferentials, SupplierContactBlock, SupplierAddressBlock). - ESLint propre ; `nuxi typecheck` (lance en container) : **0 erreur**. - Golden path navigateur valide end-to-end : POST /suppliers OK, companyName normalise UPPERCASE (RG-2.12), gating des onglets (Information actif, Contacts deverrouille). ## Note de revue ~30 `WARN Duplicated imports` au typecheck : les helpers Supplier exportent les memes noms generiques que leurs equivalents Client (`buildMainPayload`, `omitEmptyRequired`, `RefOption`...), tous deux auto-importes par Nuxt. **Sans impact runtime** : tous les consommateurs utilisent des imports explicites (qui priment). Consequence directe du miroir 1:1 ; une factorisation des generiques dans `shared/` pourrait etre un suivi. Reviewed-on: #83 Co-authored-by: tristan <tristan@yuno.malio.fr> Co-committed-by: tristan <tristan@yuno.malio.fr>
57 lines
2.1 KiB
TypeScript
57 lines
2.1 KiB
TypeScript
import { describe, it, expect, vi } from 'vitest'
|
|
import { mount } from '@vue/test-utils'
|
|
import { defineComponent, h, ref, computed } from 'vue'
|
|
import { emptyContact } from '~/modules/commercial/types/supplierForm'
|
|
import SupplierContactBlock from '../SupplierContactBlock.vue'
|
|
|
|
// Auto-imports Nuxt/Vue utilises sans import explicite par le composant.
|
|
vi.stubGlobal('useI18n', () => ({ t: (key: string) => key }))
|
|
vi.stubGlobal('ref', ref)
|
|
vi.stubGlobal('computed', computed)
|
|
|
|
/** Stub d'un champ Malio qui re-expose la prop `error` recue dans un data-* attribut. */
|
|
function errorProbe(testid: string) {
|
|
return defineComponent({
|
|
name: `Probe-${testid}`,
|
|
props: {
|
|
modelValue: { type: [String, Number, null], default: undefined },
|
|
error: { type: String, default: '' },
|
|
label: { type: String, default: '' },
|
|
readonly: { type: Boolean, default: false },
|
|
},
|
|
setup(props) {
|
|
return () => h('div', { 'data-testid': testid, 'data-error': props.error })
|
|
},
|
|
})
|
|
}
|
|
|
|
function mountBlock(errors?: Record<string, string>) {
|
|
return mount(SupplierContactBlock, {
|
|
props: {
|
|
modelValue: emptyContact(),
|
|
title: 'Contact 1',
|
|
...(errors ? { errors } : {}),
|
|
},
|
|
global: {
|
|
stubs: {
|
|
MalioButtonIcon: true,
|
|
MalioInputPhone: true,
|
|
MalioInputText: errorProbe('contact-text'),
|
|
MalioInputEmail: errorProbe('contact-email'),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
describe('SupplierContactBlock — mapping erreur par champ (ERP-101)', () => {
|
|
it('affiche l\'erreur serveur sur le champ email via la prop errors', () => {
|
|
const wrapper = mountBlock({ email: 'Adresse e-mail invalide.' })
|
|
expect(wrapper.find('[data-testid="contact-email"]').attributes('data-error')).toBe('Adresse e-mail invalide.')
|
|
})
|
|
|
|
it('laisse les champs sans erreur quand errors est absent', () => {
|
|
const wrapper = mountBlock()
|
|
expect(wrapper.find('[data-testid="contact-email"]').attributes('data-error')).toBe('')
|
|
})
|
|
})
|