feat(transport) : saisie assistée QUALIMAT + champs conditionnels (ERP-166)
This commit is contained in:
@@ -189,3 +189,153 @@ describe('useCarrierForm', () => {
|
||||
expect(mockPatch).toHaveBeenCalledWith('/carriers/9', { liotPlates: 'AA-123-BB' }, { toast: false })
|
||||
})
|
||||
})
|
||||
|
||||
describe('useCarrierForm — champs conditionnels (ERP-166)', () => {
|
||||
beforeEach(() => {
|
||||
mockPost.mockReset()
|
||||
mockPatch.mockReset()
|
||||
})
|
||||
|
||||
it('cas LIOT (insensible à la casse) : masque la certification, payload réduit', () => {
|
||||
const form = useCarrierForm()
|
||||
form.main.name = 'liot'
|
||||
|
||||
expect(form.isLiot.value).toBe(true)
|
||||
expect(form.showCertification.value).toBe(false)
|
||||
|
||||
form.main.liotPlates = 'AA-123-BB ; CC-456-DD'
|
||||
expect(form.buildMainPayload()).toEqual({
|
||||
name: 'liot',
|
||||
isChartered: false,
|
||||
liotPlates: 'AA-123-BB ; CC-456-DD',
|
||||
})
|
||||
})
|
||||
|
||||
it('LIOT masque les champs conditionnels (affrètement / décharge)', () => {
|
||||
const form = useCarrierForm()
|
||||
form.main.name = 'LIOT'
|
||||
form.main.isChartered = true
|
||||
form.main.certificationType = 'AUTRE'
|
||||
|
||||
expect(form.showCharteredFields.value).toBe(false)
|
||||
expect(form.showDischarge.value).toBe(false)
|
||||
})
|
||||
|
||||
it('RG-4.03 affrété : indexation / contenant / volume visibles et dans le payload', () => {
|
||||
const form = useCarrierForm()
|
||||
form.main.name = 'Acme'
|
||||
form.main.certificationType = 'GMP_PLUS'
|
||||
form.main.isChartered = true
|
||||
|
||||
expect(form.showCharteredFields.value).toBe(true)
|
||||
|
||||
form.main.indexationRate = '5'
|
||||
form.main.containerType = 'BENNE'
|
||||
form.main.volumeM3 = '30'
|
||||
|
||||
expect(form.buildMainPayload()).toEqual({
|
||||
name: 'Acme',
|
||||
certificationType: 'GMP_PLUS',
|
||||
isChartered: true,
|
||||
indexationRate: '5',
|
||||
containerType: 'BENNE',
|
||||
volumeM3: '30',
|
||||
})
|
||||
})
|
||||
|
||||
it('RG-4.03 affrété mais champs vides : omis du payload (422 NotBlank back)', () => {
|
||||
const form = useCarrierForm()
|
||||
form.main.name = 'Acme'
|
||||
form.main.certificationType = 'GMP_PLUS'
|
||||
form.main.isChartered = true
|
||||
|
||||
expect(form.buildMainPayload()).toEqual({
|
||||
name: 'Acme',
|
||||
certificationType: 'GMP_PLUS',
|
||||
isChartered: true,
|
||||
})
|
||||
})
|
||||
|
||||
it('RG-4.02 AUTRE : décharge visible + dischargeDocument dans le payload si IRI résolu', () => {
|
||||
const form = useCarrierForm()
|
||||
form.main.name = 'Acme'
|
||||
form.main.certificationType = 'AUTRE'
|
||||
|
||||
expect(form.showDischarge.value).toBe(true)
|
||||
|
||||
form.main.dischargeDocumentIri = '/api/uploaded_documents/7'
|
||||
expect(form.buildMainPayload()).toMatchObject({ dischargeDocument: '/api/uploaded_documents/7' })
|
||||
})
|
||||
})
|
||||
|
||||
describe('useCarrierForm — copie QUALIMAT (ERP-166)', () => {
|
||||
const QUALIMAT_ROW = {
|
||||
'@id': '/api/qualimat_carriers/42',
|
||||
id: '42',
|
||||
name: 'TRANSPORTS QUALIMAT',
|
||||
siret: '12345678900012',
|
||||
address: '1 rue du Port',
|
||||
postalCode: '86000',
|
||||
city: 'Poitiers',
|
||||
validityDate: '2027-01-15',
|
||||
status: 'VALIDE',
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
mockPost.mockReset()
|
||||
mockPatch.mockReset()
|
||||
})
|
||||
|
||||
it('copie name + certificationType=QUALIMAT (readonly) + IRI + adresse, sans PATCH avant création', async () => {
|
||||
const form = useCarrierForm()
|
||||
|
||||
const ok = await form.applyQualimatSelection(QUALIMAT_ROW)
|
||||
|
||||
expect(ok).toBe(true)
|
||||
expect(mockPatch).not.toHaveBeenCalled()
|
||||
expect(form.main.name).toBe('TRANSPORTS QUALIMAT')
|
||||
expect(form.main.certificationType).toBe('QUALIMAT')
|
||||
expect(form.main.qualimatCarrierIri).toBe('/api/qualimat_carriers/42')
|
||||
expect(form.isQualimat.value).toBe(true)
|
||||
expect(form.certificationReadonly.value).toBe(true)
|
||||
expect(form.qualimatAddress.value).toEqual({
|
||||
country: 'France',
|
||||
postalCode: '86000',
|
||||
city: 'Poitiers',
|
||||
street: '1 rue du Port',
|
||||
})
|
||||
})
|
||||
|
||||
it('après création : PATCH /carriers/{id} avec qualimatCarrier + name + certification', async () => {
|
||||
mockPost.mockResolvedValueOnce({ id: 9, name: 'X', certificationType: 'GMP_PLUS' })
|
||||
mockPatch.mockResolvedValueOnce({})
|
||||
const form = useCarrierForm()
|
||||
form.main.name = 'X'
|
||||
form.main.certificationType = 'GMP_PLUS'
|
||||
await form.submitMain()
|
||||
|
||||
const ok = await form.applyQualimatSelection(QUALIMAT_ROW)
|
||||
|
||||
expect(ok).toBe(true)
|
||||
expect(mockPatch).toHaveBeenCalledWith(
|
||||
'/carriers/9',
|
||||
{
|
||||
qualimatCarrier: '/api/qualimat_carriers/42',
|
||||
name: 'TRANSPORTS QUALIMAT',
|
||||
certificationType: 'QUALIMAT',
|
||||
},
|
||||
{ toast: false },
|
||||
)
|
||||
})
|
||||
|
||||
it('buildMainPayload inclut qualimatCarrier + certificationType QUALIMAT après intégration', async () => {
|
||||
const form = useCarrierForm()
|
||||
form.main.name = 'Acme'
|
||||
await form.applyQualimatSelection(QUALIMAT_ROW)
|
||||
|
||||
expect(form.buildMainPayload()).toMatchObject({
|
||||
qualimatCarrier: '/api/qualimat_carriers/42',
|
||||
certificationType: 'QUALIMAT',
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
/**
|
||||
* Tests de la saisie assistée QUALIMAT (M4 Transport, ERP-166 — RG-4.01).
|
||||
*
|
||||
* `useQualimatSearch` interroge `GET /api/qualimat_carriers?search=`. On vérifie le
|
||||
* CONTRAT (pas le timing du debounce, couvert par `debounce.test.ts`) via `fetchNow` :
|
||||
* - ressource ciblée + paramètre `search` (trimé) + header `Accept: application/ld+json` ;
|
||||
* - consommation de l'enveloppe Hydra (`member`) ;
|
||||
* - échec réseau → résultats vidés, pas de throw (recherche non bloquante).
|
||||
*/
|
||||
|
||||
const mockGet = vi.hoisted(() => vi.fn())
|
||||
vi.stubGlobal('useApi', () => ({
|
||||
get: mockGet,
|
||||
post: vi.fn(),
|
||||
put: vi.fn(),
|
||||
patch: vi.fn(),
|
||||
delete: vi.fn(),
|
||||
}))
|
||||
|
||||
const { useQualimatSearch } = await import('../useQualimatSearch')
|
||||
|
||||
describe('useQualimatSearch', () => {
|
||||
beforeEach(() => {
|
||||
mockGet.mockReset()
|
||||
})
|
||||
|
||||
it('fetchNow cible /qualimat_carriers (search trimé, ld+json) et consomme member', async () => {
|
||||
mockGet.mockResolvedValueOnce({
|
||||
member: [{ '@id': '/api/qualimat_carriers/1', id: '1', name: 'ACME', validityDate: '2027-01-01' }],
|
||||
})
|
||||
const q = useQualimatSearch()
|
||||
|
||||
await q.fetchNow(' acme ')
|
||||
|
||||
expect(mockGet).toHaveBeenCalledWith(
|
||||
'/qualimat_carriers',
|
||||
{ search: 'acme' },
|
||||
{ headers: { Accept: 'application/ld+json' }, toast: false },
|
||||
)
|
||||
expect(q.results.value).toHaveLength(1)
|
||||
expect(q.results.value[0]?.name).toBe('ACME')
|
||||
expect(q.loading.value).toBe(false)
|
||||
})
|
||||
|
||||
it('échec réseau : résultats vidés, pas de throw', async () => {
|
||||
mockGet.mockRejectedValueOnce(new Error('network'))
|
||||
const q = useQualimatSearch()
|
||||
|
||||
await expect(q.fetchNow('x')).resolves.toBeUndefined()
|
||||
expect(q.results.value).toEqual([])
|
||||
expect(q.loading.value).toBe(false)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user