feat(front) : écran ajouter un ticket de pesée (blocs vide/plein, pesée, masque immat) (ERP-189)
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||||
|
||||
// useApi / useI18n sont des auto-imports Nuxt : on les expose en globals.
|
||||
const mockPost = vi.hoisted(() => vi.fn())
|
||||
vi.stubGlobal('useApi', () => ({ post: mockPost }))
|
||||
vi.stubGlobal('useI18n', () => ({ t: (key: string) => key }))
|
||||
|
||||
const { useWeighbridge } = await import('../useWeighbridge')
|
||||
|
||||
describe('useWeighbridge', () => {
|
||||
beforeEach(() => {
|
||||
mockPost.mockReset()
|
||||
})
|
||||
|
||||
it('AUTO : POST { mode: AUTO } sans toast et renvoie la lecture', async () => {
|
||||
mockPost.mockResolvedValue({ weight: 23187, dsd: 42, mode: 'AUTO' })
|
||||
const { triggerAuto } = useWeighbridge()
|
||||
|
||||
const reading = await triggerAuto()
|
||||
|
||||
expect(mockPost).toHaveBeenCalledWith(
|
||||
'/weighbridge_readings',
|
||||
{ mode: 'AUTO' },
|
||||
expect.objectContaining({ toast: false }),
|
||||
)
|
||||
expect(reading).toEqual({ weight: 23187, dsd: 42, mode: 'AUTO' })
|
||||
})
|
||||
|
||||
it('MANUAL : POST { mode: MANUAL, weight, manualNumber } et renvoie la lecture', async () => {
|
||||
mockPost.mockResolvedValue({ weight: 5000, dsd: 43, manualNumber: 'PAP-555', mode: 'MANUAL' })
|
||||
const { triggerManual } = useWeighbridge()
|
||||
|
||||
const reading = await triggerManual(5000, 'PAP-555')
|
||||
|
||||
expect(mockPost).toHaveBeenCalledWith(
|
||||
'/weighbridge_readings',
|
||||
{ mode: 'MANUAL', weight: 5000, manualNumber: 'PAP-555' },
|
||||
expect.objectContaining({ toast: false }),
|
||||
)
|
||||
expect(reading.dsd).toBe(43)
|
||||
})
|
||||
|
||||
it('erreur (RG-5.06) : extractWeighbridgeError privilégie le detail du 503', () => {
|
||||
const { extractWeighbridgeError } = useWeighbridge()
|
||||
const error = { response: { status: 503, _data: { title: 'Pont bascule indisponible', detail: 'Passez en pesée manuelle.' } } }
|
||||
expect(extractWeighbridgeError(error)).toBe('Passez en pesée manuelle.')
|
||||
})
|
||||
|
||||
it('erreur sans payload exploitable : retombe sur le libellé i18n générique', () => {
|
||||
const { extractWeighbridgeError } = useWeighbridge()
|
||||
expect(extractWeighbridgeError(new Error('network')))
|
||||
.toBe('logistique.weighingTickets.form.weighbridge.unavailable')
|
||||
})
|
||||
|
||||
it('triggerAuto propage l\'erreur API (gestion par l\'écran)', async () => {
|
||||
mockPost.mockRejectedValue({ response: { status: 503 } })
|
||||
const { triggerAuto } = useWeighbridge()
|
||||
await expect(triggerAuto()).rejects.toBeDefined()
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,105 @@
|
||||
import { describe, it, expect, vi } from 'vitest'
|
||||
|
||||
// `todayIso` est importé par le composable : on le stubbe pour une date déterministe.
|
||||
vi.mock('~/shared/utils/date', () => ({ todayIso: () => '2026-06-22' }))
|
||||
|
||||
const { useWeighingTicketForm } = await import('../useWeighingTicketForm')
|
||||
|
||||
describe('useWeighingTicketForm', () => {
|
||||
it('initialise les 2 blocs à la date du jour (RG-5.07), sans poids ni DSD', () => {
|
||||
const form = useWeighingTicketForm()
|
||||
expect(form.empty.date).toBe('2026-06-22')
|
||||
expect(form.full.date).toBe('2026-06-22')
|
||||
expect(form.empty.weight).toBeNull()
|
||||
expect(form.empty.dsd).toBeNull()
|
||||
expect(form.counterpartyType.value).toBeNull()
|
||||
})
|
||||
|
||||
// ── Contrepartie conditionnelle (RG-5.03) ────────────────────────────────
|
||||
it('CLIENT : ne conserve que le client, purge supplier et otherLabel', () => {
|
||||
const form = useWeighingTicketForm()
|
||||
form.supplierIri.value = '/api/suppliers/3'
|
||||
form.otherLabel.value = 'Particulier'
|
||||
|
||||
form.setCounterpartyType('CLIENT')
|
||||
form.clientIri.value = '/api/clients/629'
|
||||
|
||||
expect(form.counterpartyField.value).toBe('client')
|
||||
expect(form.supplierIri.value).toBeNull()
|
||||
expect(form.otherLabel.value).toBeNull()
|
||||
|
||||
const payload = form.buildCreatePayload()
|
||||
expect(payload.counterpartyType).toBe('CLIENT')
|
||||
expect(payload.client).toBe('/api/clients/629')
|
||||
expect(payload).not.toHaveProperty('supplier')
|
||||
expect(payload).not.toHaveProperty('otherLabel')
|
||||
})
|
||||
|
||||
it('FOURNISSEUR : ne conserve que le supplier', () => {
|
||||
const form = useWeighingTicketForm()
|
||||
form.clientIri.value = '/api/clients/1'
|
||||
form.setCounterpartyType('FOURNISSEUR')
|
||||
form.supplierIri.value = '/api/suppliers/7'
|
||||
|
||||
expect(form.counterpartyField.value).toBe('supplier')
|
||||
expect(form.clientIri.value).toBeNull()
|
||||
expect(form.buildCreatePayload().supplier).toBe('/api/suppliers/7')
|
||||
})
|
||||
|
||||
it('AUTRE : ne conserve que le libellé libre', () => {
|
||||
const form = useWeighingTicketForm()
|
||||
form.clientIri.value = '/api/clients/1'
|
||||
form.setCounterpartyType('AUTRE')
|
||||
form.otherLabel.value = 'Reprise interne'
|
||||
|
||||
expect(form.counterpartyField.value).toBe('other')
|
||||
expect(form.clientIri.value).toBeNull()
|
||||
expect(form.buildCreatePayload().otherLabel).toBe('Reprise interne')
|
||||
})
|
||||
|
||||
// ── Immatriculation / « Tout format » partagés entre blocs (RG-5.01) ──────
|
||||
it('immatriculation et plateFreeFormat sont partagés (une seule valeur)', () => {
|
||||
const form = useWeighingTicketForm()
|
||||
form.immatriculation.value = 'AB-123-CD'
|
||||
form.plateFreeFormat.value = true
|
||||
|
||||
// Les 2 payloads (création + finalisation) reflètent la même valeur.
|
||||
expect(form.buildCreatePayload().immatriculation).toBe('AB-123-CD')
|
||||
expect(form.buildCreatePayload().plateFreeFormat).toBe(true)
|
||||
expect(form.buildFullPayload().immatriculation).toBe('AB-123-CD')
|
||||
expect(form.buildFullPayload().plateFreeFormat).toBe(true)
|
||||
})
|
||||
|
||||
// ── Application d'une lecture de pesée ────────────────────────────────────
|
||||
it('applyReading remplit poids / DSD / mode du bloc visé', () => {
|
||||
const form = useWeighingTicketForm()
|
||||
form.applyReading(form.empty, { weight: 7150, dsd: 1, mode: 'AUTO' })
|
||||
expect(form.empty.weight).toBe(7150)
|
||||
expect(form.empty.dsd).toBe(1)
|
||||
expect(form.empty.mode).toBe('AUTO')
|
||||
expect(form.empty.manualNumber).toBeNull()
|
||||
|
||||
form.applyReading(form.full, { weight: 14300, dsd: 2, mode: 'MANUAL', manualNumber: 'PAP-555' })
|
||||
expect(form.full.weight).toBe(14300)
|
||||
expect(form.full.manualNumber).toBe('PAP-555')
|
||||
})
|
||||
|
||||
it('buildCreatePayload porte la pesée à vide, buildFullPayload la pesée à plein', () => {
|
||||
const form = useWeighingTicketForm()
|
||||
form.setCounterpartyType('CLIENT')
|
||||
form.clientIri.value = '/api/clients/1'
|
||||
form.applyReading(form.empty, { weight: 7150, dsd: 1, mode: 'AUTO' })
|
||||
form.applyReading(form.full, { weight: 14300, dsd: 2, mode: 'AUTO' })
|
||||
|
||||
const create = form.buildCreatePayload()
|
||||
expect(create.emptyWeight).toBe(7150)
|
||||
expect(create.emptyDsd).toBe(1)
|
||||
expect(create.emptyMode).toBe('AUTO')
|
||||
expect(create).not.toHaveProperty('fullWeight')
|
||||
|
||||
const full = form.buildFullPayload()
|
||||
expect(full.fullWeight).toBe(14300)
|
||||
expect(full.fullDsd).toBe(2)
|
||||
expect(full.fullMode).toBe('AUTO')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user