955f9a436f
- Layout maquette : en-tete avec retour, grille 3 colonnes (gap-x-[80px]), cartes ombrees pour les onglets, boutons Valider centres, libelles ajustes. - Telephones du formulaire principal en tableau (1 par defaut, + revele le 2e). - Information : Description en row-span-2 (alignement corrige via pt-1), Nombre de salaries en MalioInputText masque chiffres. - Adresse : carte ombree, suppression en absolute, sites en cases a cocher inline, pays France/Espagne, exclusivite Prospect appliquee au toggle. - Onglets : icones par onglet (TAB_ICONS) ; Statistiques / Rapports / Echanges passent en edit-only (absents a la creation, option includeEditOnlyTabs pour la modification).
153 lines
5.8 KiB
TypeScript
153 lines
5.8 KiB
TypeScript
import { describe, it, expect } from 'vitest'
|
|
import {
|
|
applyProspectExclusivity,
|
|
buildClientFormTabKeys,
|
|
canSelectDeliveryOrBilling,
|
|
canSelectProspect,
|
|
hasAtLeastOneValidContact,
|
|
isBankRequiredForPaymentType,
|
|
isBillingEmailRequired,
|
|
isContactNamed,
|
|
isRibRequiredForPaymentType,
|
|
type ContactDraft,
|
|
} from '../clientFormRules'
|
|
|
|
describe('buildClientFormTabKeys (gating onglet Comptabilite + onglets edit-only)', () => {
|
|
it('inclut l onglet accounting si l utilisateur a accounting.view', () => {
|
|
expect(buildClientFormTabKeys(true)).toContain('accounting')
|
|
})
|
|
|
|
it('exclut l onglet accounting sinon (Bureau / Commerciale)', () => {
|
|
expect(buildClientFormTabKeys(false)).not.toContain('accounting')
|
|
})
|
|
|
|
it('a la creation, exclut Statistiques / Rapports / Echanges', () => {
|
|
const keys = buildClientFormTabKeys(true)
|
|
expect(keys).toEqual(['information', 'contact', 'address', 'transport', 'accounting'])
|
|
expect(keys).not.toContain('statistics')
|
|
expect(keys).not.toContain('reports')
|
|
expect(keys).not.toContain('exchanges')
|
|
})
|
|
|
|
it('en modification (includeEditOnlyTabs), ajoute les onglets edit-only en fin', () => {
|
|
const keys = buildClientFormTabKeys(true, { includeEditOnlyTabs: true })
|
|
expect(keys).toEqual([
|
|
'information',
|
|
'contact',
|
|
'address',
|
|
'transport',
|
|
'accounting',
|
|
'statistics',
|
|
'reports',
|
|
'exchanges',
|
|
])
|
|
})
|
|
})
|
|
|
|
describe('isContactNamed (RG-1.05)', () => {
|
|
it('vrai si le prenom est renseigne', () => {
|
|
expect(isContactNamed({ firstName: 'Alice', lastName: null })).toBe(true)
|
|
})
|
|
|
|
it('vrai si le nom est renseigne', () => {
|
|
expect(isContactNamed({ firstName: null, lastName: 'Martin' })).toBe(true)
|
|
})
|
|
|
|
it('faux si les deux sont vides ou espaces uniquement', () => {
|
|
expect(isContactNamed({ firstName: null, lastName: null })).toBe(false)
|
|
expect(isContactNamed({ firstName: ' ', lastName: '' })).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('hasAtLeastOneValidContact (RG-1.14)', () => {
|
|
it('faux sur une liste vide', () => {
|
|
expect(hasAtLeastOneValidContact([])).toBe(false)
|
|
})
|
|
|
|
it('faux si aucun contact n a de nom ni prenom', () => {
|
|
const contacts: ContactDraft[] = [
|
|
{ firstName: null, lastName: null },
|
|
{ firstName: '', lastName: ' ' },
|
|
]
|
|
expect(hasAtLeastOneValidContact(contacts)).toBe(false)
|
|
})
|
|
|
|
it('vrai des qu un contact a un nom ou un prenom', () => {
|
|
const contacts: ContactDraft[] = [
|
|
{ firstName: null, lastName: null },
|
|
{ firstName: 'Bob', lastName: null },
|
|
]
|
|
expect(hasAtLeastOneValidContact(contacts)).toBe(true)
|
|
})
|
|
})
|
|
|
|
describe('exclusivite Prospect / Livraison / Facturation (RG-1.06/07/08)', () => {
|
|
it('Prospect est selectionnable tant que ni Livraison ni Facturation', () => {
|
|
expect(canSelectProspect({ isProspect: false, isDelivery: false, isBilling: false })).toBe(true)
|
|
expect(canSelectProspect({ isProspect: false, isDelivery: true, isBilling: false })).toBe(false)
|
|
expect(canSelectProspect({ isProspect: false, isDelivery: false, isBilling: true })).toBe(false)
|
|
})
|
|
|
|
it('Livraison / Facturation selectionnables tant que pas Prospect', () => {
|
|
expect(canSelectDeliveryOrBilling({ isProspect: false, isDelivery: false, isBilling: false })).toBe(true)
|
|
expect(canSelectDeliveryOrBilling({ isProspect: true, isDelivery: false, isBilling: false })).toBe(false)
|
|
})
|
|
|
|
it('cocher Prospect efface Livraison et Facturation', () => {
|
|
const next = applyProspectExclusivity(
|
|
{ isProspect: false, isDelivery: true, isBilling: true },
|
|
'isProspect',
|
|
true,
|
|
)
|
|
expect(next).toEqual({ isProspect: true, isDelivery: false, isBilling: false })
|
|
})
|
|
|
|
it('cocher Livraison efface Prospect', () => {
|
|
const next = applyProspectExclusivity(
|
|
{ isProspect: true, isDelivery: false, isBilling: false },
|
|
'isDelivery',
|
|
true,
|
|
)
|
|
expect(next).toEqual({ isProspect: false, isDelivery: true, isBilling: false })
|
|
})
|
|
|
|
it('cocher Facturation efface Prospect mais conserve Livraison', () => {
|
|
const next = applyProspectExclusivity(
|
|
{ isProspect: true, isDelivery: true, isBilling: false },
|
|
'isBilling',
|
|
true,
|
|
)
|
|
expect(next).toEqual({ isProspect: false, isDelivery: true, isBilling: true })
|
|
})
|
|
|
|
it('decocher un drapeau ne reactive rien d autre', () => {
|
|
const next = applyProspectExclusivity(
|
|
{ isProspect: false, isDelivery: true, isBilling: true },
|
|
'isBilling',
|
|
false,
|
|
)
|
|
expect(next).toEqual({ isProspect: false, isDelivery: true, isBilling: false })
|
|
})
|
|
})
|
|
|
|
describe('isBillingEmailRequired (RG-1.11)', () => {
|
|
it('obligatoire uniquement si Facturation est coche', () => {
|
|
expect(isBillingEmailRequired({ isProspect: false, isDelivery: false, isBilling: true })).toBe(true)
|
|
expect(isBillingEmailRequired({ isProspect: false, isDelivery: true, isBilling: false })).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('regles type de reglement (RG-1.12 / RG-1.13)', () => {
|
|
it('banque obligatoire si VIREMENT', () => {
|
|
expect(isBankRequiredForPaymentType('VIREMENT')).toBe(true)
|
|
expect(isBankRequiredForPaymentType('LCR')).toBe(false)
|
|
expect(isBankRequiredForPaymentType(null)).toBe(false)
|
|
})
|
|
|
|
it('RIB obligatoire si LCR', () => {
|
|
expect(isRibRequiredForPaymentType('LCR')).toBe(true)
|
|
expect(isRibRequiredForPaymentType('VIREMENT')).toBe(false)
|
|
expect(isRibRequiredForPaymentType(null)).toBe(false)
|
|
})
|
|
})
|