Files
admin-web/src/modules/overseas-warehouse/components/TransportExecutionPanel.resourcePhotos.test.ts
T

96 lines
6.5 KiB
TypeScript

import { mount, flushPromises } from '@vue/test-utils'
import ElementPlus from 'element-plus'
import { afterEach, beforeEach, expect, it, vi } from 'vitest'
import TransportExecutionPanel from './TransportExecutionPanel.vue'
import DispatchEvidenceFiles from './DispatchEvidenceFiles.vue'
import { assignTransport, getTransport, type TransportDetail } from '../api/transportTasks'
import { getDispatchEvidence, getDispatchEvidenceContent } from '../api/dispatches'
import { getDriver, getResourcePhoto, downloadResourcePhoto, downloadDriverLicense } from '@/modules/overseas-master-data'
vi.mock('vue-router', () => ({ onBeforeRouteLeave: vi.fn() }))
vi.mock('@/core/access/accessPreview', () => ({ useAccessPreviewStore: () => ({ can: () => true }) }))
vi.mock('@/modules/overseas-master-data', () => ({ listVehicles: vi.fn(), listDrivers: vi.fn(), getDriver: vi.fn(), getResourcePhoto: vi.fn(), downloadResourcePhoto: vi.fn(), downloadDriverLicense: vi.fn(), pickupStatusLabels: { ASSIGNED: '待取货' } }))
vi.mock('../api/transportTasks', () => ({ getTransport: vi.fn(), assignTransport: vi.fn(), transportOccupancy: vi.fn(), cancelTransport: vi.fn(), releaseTransport: vi.fn(), commandTransport: vi.fn(), uploadTransport: vi.fn(), downloadTransportEvidence: vi.fn(), transportLabels: { PICKUP: '到仓取货' } }))
vi.mock('../api/dispatches', () => ({ getDispatchEvidence: vi.fn(), getDispatchEvidenceContent: vi.fn(), uploadDispatchEvidence: vi.fn() }))
const facts = (): TransportDetail => ({ dispatchNo: 'PC1', taskType: 'PICKUP', dispatchRecordVersion: 9, execution: { trip: { status: 'PLANNED', recordVersion: 4, vehicleId: '1', vehiclePlate: 'CA-1', driverId: '2', driverName: '司机甲' } }, pickups: [{ customerId: 'C1', transferNo: 'WT1', packageCount: 5, status: 'ASSIGNED', evidence: [] }], completionEvidence: [] }) as unknown as TransportDetail
const photo = (fileId: string) => ({ fileId, fileName: `${fileId}.jpg`, contentType: 'image/jpeg', sizeBytes: 5 })
const blob = () => new Blob(['photo'], { type: 'image/jpeg' })
const mountPanel = () => mount(TransportExecutionPanel, { props: { dispatchNo: 'PC1', editResources: true }, global: { plugins: [ElementPlus] } })
const saveButton = (wrapper: ReturnType<typeof mountPanel>) => wrapper.findAll('button').find(button => button.text() === '保存车辆司机')!
beforeEach(() => {
vi.resetAllMocks()
vi.stubGlobal('ResizeObserver', class { observe() {} unobserve() {} disconnect() {} })
vi.spyOn(URL, 'createObjectURL').mockReturnValue('blob:resource-photo')
vi.spyOn(URL, 'revokeObjectURL').mockImplementation(() => {})
vi.mocked(getTransport).mockImplementation(async () => facts())
vi.mocked(getDriver).mockResolvedValue({ id: '2', licenseFileId: '33' } as Awaited<ReturnType<typeof getDriver>>)
vi.mocked(getResourcePhoto).mockImplementation(async kind => ({ recordVersion: '1', photo: photo(kind === 'VEHICLE' ? '91' : '92') }))
vi.mocked(downloadResourcePhoto).mockImplementation(async () => blob())
vi.mocked(downloadDriverLicense).mockImplementation(async () => blob())
vi.mocked(getDispatchEvidence).mockImplementation(async (_no, _kind, id) => photo(id))
vi.mocked(getDispatchEvidenceContent).mockImplementation(async () => blob())
})
afterEach(() => { vi.restoreAllMocks(); vi.unstubAllGlobals() })
it('keeps automatically loaded photos available after refreshing the open form', async () => {
const wrapper = mountPanel()
try {
await flushPromises()
expect(saveButton(wrapper).attributes('disabled')).toBeUndefined()
expect(getResourcePhoto).toHaveBeenCalledTimes(2)
await wrapper.get('[aria-label="刷新运输任务"]').trigger('click')
await flushPromises()
expect(wrapper.findAll('.evidence-photo-preview')).toHaveLength(3)
expect(saveButton(wrapper).attributes('disabled')).toBeUndefined()
vi.mocked(assignTransport).mockResolvedValue(facts())
await saveButton(wrapper).trigger('click')
await flushPromises()
expect(assignTransport).toHaveBeenCalledWith('PC1', expect.objectContaining({ reviewPhotos: { vehicleFileIds: [], driverPhotoFileIds: [], licenseFileIds: [] } }))
} finally { wrapper.unmount() }
})
it('resubmits saved snapshots when reopening maintenance even if archive photos change', async () => {
const saved = facts()
saved.execution.trip.recordVersion = 5
saved.dispatchRecordVersion = 10
saved.resources = { vehicle: { vehicleId: '1', evidenceFileIds: ['101'] }, driver: { driverId: '2', evidence: { photoFileIds: ['102'], fileIds: ['33'], masterLicenseFileId: '33' } } } as TransportDetail['resources']
vi.mocked(assignTransport).mockResolvedValue(saved)
const wrapper = mountPanel()
try {
await flushPromises()
await saveButton(wrapper).trigger('click')
await flushPromises()
expect(assignTransport).toHaveBeenCalledTimes(1)
vi.mocked(getResourcePhoto).mockResolvedValue({ recordVersion: '2', photo: photo('999') })
await wrapper.findAll('button').find(button => button.text() === '维护车辆信息')!.trigger('click')
await flushPromises()
const reopened = wrapper.findAllComponents(DispatchEvidenceFiles)
expect(reopened[0]!.props('modelValue')).toEqual(['101'])
expect(reopened[1]!.props('modelValue')).toEqual(['102'])
expect(getResourcePhoto).toHaveBeenCalledTimes(2)
expect(getDispatchEvidence).toHaveBeenCalledWith('PC1', 'VEHICLE', '101')
expect(saveButton(wrapper).attributes('disabled')).toBeUndefined()
await saveButton(wrapper).trigger('click')
await flushPromises()
expect(assignTransport).toHaveBeenLastCalledWith('PC1', expect.objectContaining({ recordVersion: 5, dispatchRecordVersion: 10, reviewPhotos: { vehicleFileIds: ['101'], driverPhotoFileIds: ['102'], licenseFileIds: [] } }))
} finally { wrapper.unmount() }
})
it.each([0, 1])('requires a new photo when resource selector %s changes to an archive without a photo', async index => {
const wrapper = mountPanel()
try {
await flushPromises()
expect(saveButton(wrapper).attributes('disabled')).toBeUndefined()
vi.mocked(getResourcePhoto).mockResolvedValue({ recordVersion: '0', photo: null })
wrapper.findAllComponents({ name: 'ElSelect' })[index]!.vm.$emit('update:modelValue', '4')
await flushPromises()
expect(saveButton(wrapper).attributes('disabled')).toBeDefined()
expect(wrapper.findAllComponents(DispatchEvidenceFiles)[index]!.props('modelValue')).toEqual([])
expect(getResourcePhoto).toHaveBeenLastCalledWith(index === 0 ? 'VEHICLE' : 'DRIVER', '4')
await saveButton(wrapper).trigger('click')
expect(assignTransport).not.toHaveBeenCalled()
} finally { wrapper.unmount() }
})