feat(transport) : onglet adresses transporteur (ERP-167)
Pull Request — Quality gate / Backend (PHP CS + PHPUnit) (pull_request) Successful in 3m7s
Pull Request — Quality gate / Frontend (lint + Vitest + build) (pull_request) Successful in 1m24s

This commit is contained in:
2026-06-17 09:15:56 +02:00
parent 40fdded7e2
commit 6a69d7cd23
8 changed files with 902 additions and 9 deletions
@@ -19,13 +19,14 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
const mockPost = vi.hoisted(() => vi.fn())
const mockPatch = vi.hoisted(() => vi.fn())
const mockDelete = vi.hoisted(() => vi.fn())
vi.stubGlobal('useApi', () => ({
get: vi.fn(),
post: mockPost,
put: vi.fn(),
patch: mockPatch,
delete: vi.fn(),
delete: mockDelete,
}))
vi.stubGlobal('useI18n', () => ({ t: (key: string) => key }))
vi.stubGlobal('useToast', () => ({
@@ -414,4 +415,126 @@ describe('useCarrierForm — copie QUALIMAT (ERP-166)', () => {
certificationType: 'QUALIMAT',
})
})
it('applyQualimatSelection pré-remplit le 1er bloc d\'adresse (RG-4.05)', async () => {
const form = useCarrierForm()
form.main.name = 'Acme'
await form.applyQualimatSelection(QUALIMAT_ROW)
expect(form.addresses.value).toHaveLength(1)
expect(form.addresses.value[0]).toEqual({
id: null,
country: 'France',
postalCode: '86000',
city: 'Poitiers',
street: '1 rue du Port',
streetComplement: null,
})
})
})
describe('useCarrierForm — onglet Adresses (ERP-167)', () => {
beforeEach(() => {
mockPost.mockReset()
mockPatch.mockReset()
mockDelete.mockReset()
})
/** Transporteur créé, onglet Adresses accessible. */
function createdForm() {
const form = useCarrierForm()
form.carrierId.value = 7
return form
}
/** Remplit un bloc adresse complet (CP + ville + rue). */
function fillAddress(form: ReturnType<typeof useCarrierForm>, index = 0): void {
const a = form.addresses.value[index]
if (a) {
a.postalCode = '86100'
a.city = 'Châtellerault'
a.street = '1 rue du Test'
}
}
it('canAddAddress : désactivé tant que la dernière adresse est incomplète', () => {
const form = createdForm()
expect(form.canAddAddress.value).toBe(false)
form.addAddress()
expect(form.addresses.value).toHaveLength(1) // no-op tant qu'incomplète
fillAddress(form)
expect(form.canAddAddress.value).toBe(true)
form.addAddress()
expect(form.addresses.value).toHaveLength(2)
})
it('submitAddresses : POST des nouvelles adresses, capture l\'id, finalise l\'onglet', async () => {
mockPost.mockResolvedValueOnce({ id: 88 })
const form = createdForm()
fillAddress(form)
const ok = await form.submitAddresses(vi.fn())
expect(ok).toBe(true)
const [url, body, opts] = mockPost.mock.calls[0] ?? []
expect(url).toBe('/carriers/7/addresses')
expect(body).toEqual({
country: 'France',
postalCode: '86100',
city: 'Châtellerault',
street: '1 rue du Test',
streetComplement: null,
})
expect(opts).toMatchObject({ toast: false, headers: { Accept: 'application/ld+json' } })
expect(form.addresses.value[0]?.id).toBe(88)
expect(form.isValidated('addresses')).toBe(true)
})
it('submitAddresses : PATCH des adresses existantes sur /carrier_addresses/{id}', async () => {
mockPatch.mockResolvedValueOnce({})
const form = createdForm()
fillAddress(form)
const first = form.addresses.value[0]
if (first) first.id = 88
await form.submitAddresses(vi.fn())
expect(mockPost).not.toHaveBeenCalled()
expect(mockPatch).toHaveBeenCalledWith('/carrier_addresses/88', expect.objectContaining({ city: 'Châtellerault' }), { toast: false })
})
it('submitAddresses : mappe les 422 PAR LIGNE et ne finalise pas l\'onglet (RG-4.05)', async () => {
mockPost.mockRejectedValueOnce({
response: {
status: 422,
_data: { violations: [{ propertyPath: 'city', message: 'La ville est obligatoire pour un transporteur affrété.' }] },
},
})
const form = createdForm()
fillAddress(form)
const ok = await form.submitAddresses(vi.fn())
expect(ok).toBe(false)
expect(form.addressErrors.value[0]?.city).toBe('La ville est obligatoire pour un transporteur affrété.')
expect(form.isValidated('addresses')).toBe(false)
})
it('removeAddress : DELETE /carrier_addresses/{id} puis retrait du bloc', async () => {
mockDelete.mockResolvedValueOnce({})
const form = createdForm()
fillAddress(form)
const first = form.addresses.value[0]
if (first) first.id = 88
form.addAddress()
fillAddress(form, 1)
await form.removeAddress(0)
expect(mockDelete).toHaveBeenCalledWith('/carrier_addresses/88', {}, { toast: false })
expect(form.addresses.value).toHaveLength(1)
})
})