fix(dispatch): guard unsaved evidence without disabling uploads
This commit is contained in:
@@ -3,9 +3,10 @@ import { ApiResponseError } from '@/shared/api/http'
|
||||
import { flushPromises, mount } from '@vue/test-utils'
|
||||
import { beforeEach, expect, it, vi } from 'vitest'
|
||||
import DispatchWorkflowDialog from './DispatchWorkflowDialog.vue'
|
||||
import DispatchEvidenceFiles from './DispatchEvidenceFiles.vue'
|
||||
import * as api from '../api/dispatches'
|
||||
import { command, detail, loadingPreview } from '../dispatchTestFixtures'
|
||||
import type { CommandResult, DispatchAction, DispatchDetail } from '../dispatchContracts'
|
||||
import type { CommandResult, DispatchAction, DispatchDetail, Driver, Vehicle } from '../dispatchContracts'
|
||||
import { useDispatchCommandRecovery } from '../dispatchCommandRecovery'
|
||||
const identity = vi.hoisted(() => ({ id: '' }))
|
||||
vi.mock('@/core/auth/auth', () => ({ useAuthStore: () => ({ user: identity }) }))
|
||||
@@ -280,3 +281,45 @@ it('saves a cleared unavailable master vehicle as an empty draft resource', asyn
|
||||
expect(api.submitDispatchReview).not.toHaveBeenCalled()
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
it.each(['VEHICLE', 'DRIVER_PHOTO', 'DRIVER'] as const)('does not silently discard %s files when the master resource is missing', async kind => {
|
||||
const { wrapper, state } = await open('EDIT')
|
||||
const editor = wrapper.vm as unknown as { vehicle: Vehicle; driver: Driver }
|
||||
editor.vehicle.mode = 'MASTER'; editor.vehicle.vehicleId = null
|
||||
editor.driver.mode = 'MASTER'; editor.driver.driverId = null
|
||||
await flushPromises()
|
||||
const card = wrapper.findAllComponents(DispatchEvidenceFiles).find(item => item.props('kind') === kind)!
|
||||
expect(card.get('.evidence-upload-button').attributes('disabled')).toBeUndefined()
|
||||
expect(wrapper.text()).not.toContain('请先在“排车信息”')
|
||||
// A pending reference must also be guarded at save time, rather than being converted to null.
|
||||
card.vm.$emit('update:modelValue', ['301'])
|
||||
await state.submit(); await flushPromises()
|
||||
expect(api.updateDispatch).not.toHaveBeenCalled()
|
||||
expect(wrapper.emitted('saved')).toBeUndefined()
|
||||
expect(card.props('modelValue')).toEqual(['301'])
|
||||
expect(wrapper.text()).toContain(kind === 'VEHICLE' ? '请先选择车辆' : '请先选择司机')
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
it.each(['MASTER', 'EXTERNAL'] as const)('keeps all three %s photo references after saving, reopening and saving again', async mode => {
|
||||
const { wrapper, state } = await open('EDIT')
|
||||
const editor = wrapper.vm as unknown as { vehicle: Vehicle; driver: Driver }
|
||||
editor.vehicle.mode = mode; editor.vehicle.vehicleId = mode === 'MASTER' ? '11' : null
|
||||
editor.driver.mode = mode; editor.driver.driverId = mode === 'MASTER' ? '12' : null
|
||||
const expected = { VEHICLE: ['301'], DRIVER_PHOTO: ['302'], DRIVER: ['303'] }
|
||||
for (const card of wrapper.findAllComponents(DispatchEvidenceFiles)) card.vm.$emit('update:modelValue', expected[card.props('kind') as keyof typeof expected])
|
||||
let saved: DispatchDetail | undefined
|
||||
vi.mocked(api.updateDispatch).mockImplementation(async (_, body) => {
|
||||
saved = detail({ recordVersion: 1, actions: { EDIT: { allowed: true, blockCode: null, blockReason: null } }, vehicleInfo: JSON.parse(JSON.stringify({ vehicle: body.vehicle, driver: body.driver, maintenance: body.maintenance })) })
|
||||
vi.mocked(api.getDispatch).mockImplementation(async () => JSON.parse(JSON.stringify(saved)))
|
||||
return command('EDIT', body.idempotencyKey)
|
||||
})
|
||||
await state.submit(); await flushPromises()
|
||||
expect(wrapper.emitted('saved')).toHaveLength(1)
|
||||
await wrapper.setProps({ modelValue: false }); await wrapper.setProps({ modelValue: true }); await flushPromises()
|
||||
for (const card of wrapper.findAllComponents(DispatchEvidenceFiles)) expect(card.props('modelValue')).toEqual(expected[card.props('kind') as keyof typeof expected])
|
||||
await state.submit()
|
||||
expect(api.updateDispatch).toHaveBeenCalledTimes(2)
|
||||
expect(vi.mocked(api.updateDispatch).mock.calls[1]![1]).toMatchObject({ vehicle: { evidenceFileIds: ['301'] }, driver: { evidence: { photoFileIds: ['302'], fileIds: ['303'] } } })
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user