优化
This commit is contained in:
@@ -15,8 +15,34 @@ vi.mock('@/core/access/accessPreview', () => ({ useAccessPreviewStore: () => ({
|
||||
vi.mock('vue-router', () => ({ useRouter: () => ({ push }) }))
|
||||
vi.mock('@/modules/warehouses', () => ({ listAllPlatformWarehouses: vi.fn() }))
|
||||
vi.mock('./DispatchResourceFields.vue', () => ({ default: { template: '<div />' } }))
|
||||
vi.mock('./SmartDispatchExistingCargo.vue', () => ({ default: { name: 'SmartDispatchExistingCargo', emits: ['saved', 'busy'], template: '<div data-existing-cargo />' } }))
|
||||
vi.mock('../api/dispatches', () => ({ listDispatchDrafts: vi.fn(), listDispatchCandidates: vi.fn(), createDispatchDraft: vi.fn(), createDispatchDraftContainer: vi.fn(), lockDispatchDraftPallet: vi.fn(), unlockDispatchDraftPallet: vi.fn(), deleteDispatchDraftContainer: vi.fn(), releaseDispatchDraft: vi.fn(), convertDispatchDraft: vi.fn(), createDispatch: vi.fn(), getDispatch: vi.fn(), getDispatchCommand: vi.fn() }))
|
||||
const source = () => candidate(), draft = (): DispatchDraft => ({ draftToken: 'server-token', recordVersion: 0, status: 'ACTIVE', warehouseId: '321', containers: [{ draftContainerId: '100000000000000001', sequenceNo: 1, capacity: 30, sourceKeys: ['source-1'] }], sources: [source()], expiresAt: '2026-12-01T00:00:00Z' })
|
||||
it('switches to existing cargo inside the same dialog without creating a draft or submitting a new dispatch', async () => {
|
||||
const wrapper = mount(SmartDispatchDialog, options); await flushPromises()
|
||||
const dialog = wrapper.getComponent(AppDialog)
|
||||
await wrapper.getComponent({ name: 'ElDialogContent' }).findAll('button').find(button => button.text() === '调整已有排车货物')!.trigger('click'); await flushPromises()
|
||||
expect(wrapper.findComponent({ name: 'SmartDispatchExistingCargo' }).exists()).toBe(true)
|
||||
expect(dialog.props('showConfirm')).toBe(false)
|
||||
dialog.vm.$emit('confirm'); await flushPromises()
|
||||
expect(api.createDispatch).not.toHaveBeenCalled()
|
||||
expect(api.createDispatchDraft).not.toHaveBeenCalled()
|
||||
expect(api.convertDispatchDraft).not.toHaveBeenCalled()
|
||||
wrapper.getComponent({ name: 'SmartDispatchExistingCargo' }).vm.$emit('saved'); await flushPromises()
|
||||
expect(wrapper.emitted('created')).toHaveLength(1)
|
||||
expect(wrapper.emitted('update:modelValue')).toBeUndefined()
|
||||
wrapper.unmount()
|
||||
})
|
||||
it.each(['ADD_CARGO', 'REMOVE_CARGO'] as const)('opens %s recovery in existing cargo without reading creation drafts', async action => {
|
||||
const recovery = useDispatchCommandRecovery(() => identity.id)
|
||||
recovery.begin('PC/1', action, { recordVersion: 0, idempotencyKey: 'existing-key' })
|
||||
const wrapper = mount(SmartDispatchDialog, options); await flushPromises()
|
||||
expect(wrapper.findComponent({ name: 'SmartDispatchExistingCargo' }).exists()).toBe(true)
|
||||
expect(api.listDispatchDrafts).not.toHaveBeenCalled()
|
||||
expect(listAllPlatformWarehouses).not.toHaveBeenCalled()
|
||||
expect(recovery.pending.value?.body.idempotencyKey).toBe('existing-key')
|
||||
wrapper.unmount()
|
||||
})
|
||||
it('converts a filtered relabel group with both authoritative sources and locks it through one HTTP command', async () => {
|
||||
const [first, second] = sharedPalletCandidates(), original = draft()
|
||||
original.sources = [first!]; original.containers[0]!.sourceKeys = [first!.sourceKey]
|
||||
@@ -100,19 +126,19 @@ it('accepts a partial candidate page without requiring the filtered whole set',
|
||||
vi.mocked(api.listDispatchCandidates).mockResolvedValue({ total: 21, page: 1, size: 20, pages: 2, candidates: [source()], complete: false, snapshotAt: '' })
|
||||
const wrapper = mount(SmartDispatchDialog, options); await flushPromises(); const state = wrapper.vm as unknown as { restoreDraft: (token: string) => void }; state.restoreDraft('server-token'); await flushPromises(); expect(wrapper.getComponent({ name: 'ElDialogContent' }).text()).not.toContain('尚未完整返回'); wrapper.unmount()
|
||||
})
|
||||
it('keeps vehicle assignments independent between containers and reuses a proven conversion after a detail read fails', async () => {
|
||||
it('keeps planning remarks independent with unassigned resources and reuses a proven conversion after a detail read fails', async () => {
|
||||
const original = draft(); original.containers.push({ draftContainerId: 'container-B', sequenceNo: 2, capacity: 15, sourceKeys: ['source-B'] }); original.sources.push(candidate({ sourceKey: 'source-B', customerId: 'B' }))
|
||||
vi.mocked(api.listDispatchDrafts).mockResolvedValue([original])
|
||||
vi.mocked(api.convertDispatchDraft).mockImplementation(async request => ({ draftToken: request.draftToken, replayed: false, vehicles: request.groups.map((group, index) => ({ draftContainerId: group.draftContainerId, dispatch: command('CREATE', group.dispatch.idempotencyKey, `PC/${index + 1}`) })) }))
|
||||
vi.mocked(api.getDispatch).mockRejectedValueOnce(new Error('detail unavailable')).mockImplementation(async no => detail({ dispatchNo: no, recordVersion: 1 }))
|
||||
const wrapper = mount(SmartDispatchDialog, options); await flushPromises()
|
||||
const state = wrapper.vm as unknown as { restoreDraft(token: string): void; submit(): Promise<void>; activeContainerId: string; vehicle: { vehicleId: string | null }; form: { remark: string } }
|
||||
state.restoreDraft('server-token'); await flushPromises(); state.vehicle.vehicleId = 'vehicle-A'; state.form.remark = '车甲'
|
||||
state.activeContainerId = 'container-B'; state.vehicle.vehicleId = 'vehicle-B'; state.form.remark = '车乙'
|
||||
const state = wrapper.vm as unknown as { restoreDraft(token: string): void; submit(): Promise<void>; activeContainerId: string; form: { remark: string } }
|
||||
state.restoreDraft('server-token'); await flushPromises(); state.form.remark = '车甲'
|
||||
state.activeContainerId = 'container-B'; state.form.remark = '车乙'
|
||||
await state.submit(); expect(wrapper.emitted('created')).toBeUndefined()
|
||||
await state.submit(); expect(api.convertDispatchDraft).toHaveBeenCalledTimes(1)
|
||||
const groups = vi.mocked(api.convertDispatchDraft).mock.calls[0]![0].groups
|
||||
expect(groups.map(group => [group.dispatch.vehicle?.vehicleId, group.dispatch.remark])).toEqual([['vehicle-A', '车甲'], ['vehicle-B', '车乙']])
|
||||
expect(groups.map(group => [group.dispatch.vehicle, group.dispatch.driver, group.dispatch.remark])).toEqual([[null, null, '车甲'], [null, null, '车乙']])
|
||||
expect(wrapper.emitted('created')).toHaveLength(1); wrapper.unmount()
|
||||
})
|
||||
it('never sends an existing departure command through the empty creation transport', async () => {
|
||||
|
||||
Reference in New Issue
Block a user