2026-10-15 17:11:03 +08:00
|
|
|
import { flushPromises, mount } from '@vue/test-utils'
|
|
|
|
|
import { beforeEach, expect, it, vi } from 'vitest'
|
|
|
|
|
import WorkExistingDispatchForm from './WorkExistingDispatchForm.vue'
|
|
|
|
|
import { getDispatch } from '@/modules/overseas-warehouse'
|
|
|
|
|
const state = vi.hoisted(() => ({ allowed: true }))
|
|
|
|
|
vi.mock('@/core/access/accessPreview', () => ({ useAccessPreviewStore: () => ({ can: () => state.allowed }) }))
|
|
|
|
|
vi.mock('@/modules/overseas-warehouse', async original => ({ ...await original<typeof import('@/modules/overseas-warehouse')>(), getDispatch: vi.fn() }))
|
|
|
|
|
function render() { return mount(WorkExistingDispatchForm, { props: { dispatches: [{ batchKey: 'DISPATCH:9007199254740999', dispatchNo: 'DS-ORIGINAL' }], canWrite: true }, global: { stubs: { ElButton: { props: ['disabled'], template: '<button :disabled="disabled"><slot /></button>' }, LoadErrorState: { props: ['message'], template: '<p>{{ message }}</p>' }, ApiErrorMeta: true, TripPreparationDialog: { name: 'TripPreparationDialog', props: ['warehouseId', 'dispatchNos'], template: '<div />' } } } }) }
|
2026-10-16 15:41:56 +08:00
|
|
|
beforeEach(() => { vi.clearAllMocks(); state.allowed = true; vi.mocked(getDispatch).mockResolvedValue({ id: '9007199254740999', dispatchNo: 'DS-ORIGINAL', appointmentBatches: [], overseasWarehouseId: 'origin-1', overseasWarehouseName: '原起运仓', status: 'PENDING_DEPARTURE', packageCount: 12 }) })
|
2026-10-15 17:11:03 +08:00
|
|
|
it('reads the original dispatch and passes its existing cargo and origin to trip preparation', async () => {
|
|
|
|
|
const wrapper = render(); await flushPromises()
|
|
|
|
|
expect(getDispatch).toHaveBeenCalledExactlyOnceWith('DS-ORIGINAL')
|
2026-10-16 15:41:56 +08:00
|
|
|
await wrapper.findAll('button').find(button => button.text() === '继续安排本批车辆')!.trigger('click')
|
2026-10-15 17:11:03 +08:00
|
|
|
const dialog = wrapper.getComponent({ name: 'TripPreparationDialog' }); expect(dialog.props()).toMatchObject({ warehouseId: 'origin-1', dispatchNos: ['DS-ORIGINAL'] })
|
|
|
|
|
dialog.vm.$emit('saved', { trip: { tripNo: 'TR/001' } }); expect(wrapper.emitted('external')).toEqual([['/overseas-master-data/trips/TR%2F001']])
|
|
|
|
|
expect(wrapper.text()).not.toContain('9007199254740999'); wrapper.unmount()
|
|
|
|
|
})
|
|
|
|
|
it('rejects mismatched dispatch identity instead of arranging unrelated cargo', async () => {
|
2026-10-16 15:41:56 +08:00
|
|
|
vi.mocked(getDispatch).mockResolvedValue({ id: '9007199254740998', dispatchNo: 'DS-ORIGINAL', appointmentBatches: [], status: 'PENDING_DEPARTURE' })
|
2026-10-15 17:11:03 +08:00
|
|
|
const wrapper = render(); await flushPromises(); expect(wrapper.text()).toContain('排车单与工作批次关联不一致'); expect(wrapper.find('table').exists()).toBe(false); wrapper.unmount()
|
|
|
|
|
})
|
|
|
|
|
it('opens an already bound real trip instead of preparing another one', async () => {
|
2026-10-16 15:41:56 +08:00
|
|
|
vi.mocked(getDispatch).mockResolvedValue({ id: '9007199254740999', dispatchNo: 'DS-ORIGINAL', appointmentBatches: [], workflow: { tripNo: 'TR-EXISTING', dispatchReview: { status: 'PENDING', reason: null, reviewedAt: null }, loadingReview: { status: 'PENDING', reason: null, reviewedAt: null } } })
|
|
|
|
|
const wrapper = render(); await flushPromises(); expect(wrapper.text()).not.toContain('继续安排本批车辆')
|
2026-10-15 17:11:03 +08:00
|
|
|
await wrapper.findAll('button').find(button => button.text() === 'TR-EXISTING')!.trigger('click'); expect(wrapper.emitted('external')).toEqual([['/overseas-master-data/trips/TR-EXISTING']]); wrapper.unmount()
|
|
|
|
|
})
|
|
|
|
|
it('does not read the dispatch without its original list permission', async () => {
|
|
|
|
|
state.allowed = false; const wrapper = render(); await flushPromises(); expect(getDispatch).not.toHaveBeenCalled(); wrapper.unmount()
|
|
|
|
|
})
|