1193832505
- clientFormRules : RG-1.05/1.14 (contacts), RG-1.06/07/08/11 (exclusivite adresse + email facturation), RG-1.12/1.13 (banque/RIB selon type de reglement), construction des onglets (gating Comptabilite). 18 tests Vitest. - types/clientForm : brouillons locaux (contact/adresse/RIB) + fabriques. - useAddressAutocomplete : STUB ERP-63 conforme a la signature ERP-66 (mode degrade), a remplacer par l'implementation BAN d'ERP-66. Note : RG-1.04 (Information obligatoire pour la Commerciale) volontairement non miroitee cote front (le payload /api/me ne porte pas le code de role ; Bureau et Commerciale partagent les memes permissions). Le back l'applique de maniere fiable.
145 lines
5.3 KiB
TypeScript
145 lines
5.3 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)', () => {
|
|
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('place accounting entre transport et statistics quand present', () => {
|
|
const keys = buildClientFormTabKeys(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)
|
|
})
|
|
})
|