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

72 lines
6.2 KiB
TypeScript
Raw Normal View History

2026-10-21 16:58:38 +08:00
import ElementPlus, { ElMessageBox } from 'element-plus'
import { defineComponent, h } from 'vue'
import { flushPromises, mount } from '@vue/test-utils'
import { beforeEach, expect, it, vi } from 'vitest'
import DispatchDocumentsDialog from './DispatchDocumentsDialog.vue'
import DeliveryDocumentsDialog from './DeliveryDocumentsDialog.vue'
import { detail } from '../dispatchTestFixtures'
import { getDispatch } from '../api/dispatches'
import { deliveryDocumentCategories, getDeliveryDocuments, saveDeliveryDocuments, type DeliveryDocuments } from '../api/deliveryDocuments'
const can = vi.hoisted(() => vi.fn(() => true))
vi.mock('@/core/access/accessPreview', () => ({ useAccessPreviewStore: () => ({ can }) }))
vi.mock('../api/dispatches', () => ({ getDispatch: vi.fn() }))
vi.mock('../api/deliveryDocuments', async original => ({ ...await original<typeof import('../api/deliveryDocuments')>(), getDeliveryDocuments: vi.fn(), saveDeliveryDocuments: vi.fn() }))
const dialogStub = defineComponent({ props: ['modelValue', 'showConfirm'], emits: ['confirm'], setup(props, { slots, emit }) { return () => props.modelValue ? h('section', [slots.default?.(), props.showConfirm ? h('button', { class: 'save', onClick: () => emit('confirm') }, '保存资料') : null]) : null } })
function documents(no = 'DL-1', customerId = '101'): DeliveryDocuments {
return { deliveryNo: no, customerId, version: 1, bolNo: 'BOL-ORIGINAL', uploadedCategoryCount: 1, totalCategoryCount: 3, allowedActions: ['MANAGE_DOCUMENTS'], replayed: false, categories: deliveryDocumentCategories.map(item => ({ category: item.category, status: item.category === 'RECEIPT' ? 'UPLOADED' : 'MISSING', fileCount: item.category === 'RECEIPT' ? 1 : 0, files: item.category === 'RECEIPT' ? [{ fileId: '99', fileName: 'existing-pod.pdf', contentType: 'application/pdf', sizeBytes: 10, uploadedAt: '2026-10-21T00:00:00' }] : [] })) }
}
2026-10-21 17:22:25 +08:00
function setup() { return mount(DispatchDocumentsDialog, { props: { modelValue: true, dispatchNo: 'PC/1' }, global: { plugins: [ElementPlus], stubs: { AppDialog: dialogStub, DispatchVehicleDocuments: true, DispatchLoadingDocuments: true, DispatchEvidenceFiles: true } } }) }
2026-10-21 16:58:38 +08:00
beforeEach(() => {
vi.clearAllMocks(); can.mockReturnValue(true)
const value = detail(); value.stage = 'DELIVERING'
value.documents.deliveries = [
{ deliveryNo: 'DL-1', customerId: '101', customerName: '客户甲', groupKey: 'A', outboundNo: 'OB-1', destination: { key: 'FBA:A', type: 'FBA', warehouseId: null, warehouseCode: 'A', warehouseName: null, address: null, postalCode: null, contactName: null, contactPhone: null }, status: 'DELIVERING', packageCount: 1, palletCount: 1 },
{ deliveryNo: 'DL-2', customerId: '102', customerName: '客户乙', groupKey: 'B', outboundNo: 'OB-2', destination: { key: 'FBA:B', type: 'FBA', warehouseId: null, warehouseCode: 'B', warehouseName: null, address: null, postalCode: null, contactName: null, contactPhone: null }, status: 'DELIVERING', packageCount: 1, palletCount: 1 },
]
vi.mocked(getDispatch).mockResolvedValue(value)
vi.mocked(getDeliveryDocuments).mockImplementation(async (no, customer) => documents(no, customer))
vi.mocked(saveDeliveryDocuments).mockResolvedValue({ ...documents(), version: 2 })
})
2026-10-21 17:22:25 +08:00
it.each(['LOADING', 'AFTER_LOADING'] as const)('opens loading documents in %s before delivery orders exist and without delivery-list permission', async stage => {
vi.mocked(getDispatch).mockResolvedValue(detail({ stage }))
2026-10-21 17:08:59 +08:00
can.mockImplementation((value?: string) => value !== 'platform:overseas-warehouse:delivery:list')
const wrapper = setup(); await flushPromises()
expect(wrapper.find('dispatch-loading-documents-stub').exists()).toBe(true)
expect(wrapper.findAll('[role="tab"]').find(tab => tab.text() === '装车资料')!.attributes('aria-selected')).toBe('true')
expect(getDeliveryDocuments).not.toHaveBeenCalled(); wrapper.unmount()
})
2026-10-21 16:58:38 +08:00
it('reads existing delivery files in one dialog and saves receipt without requiring loading or BOL files', async () => {
const wrapper = setup(); await flushPromises()
expect(getDeliveryDocuments).toHaveBeenCalledWith('DL-1', '101')
expect(wrapper.text()).toContain('existing-pod.pdf')
expect(wrapper.findAllComponents(DeliveryDocumentsDialog)).toHaveLength(1)
await wrapper.get('.save').trigger('click'); await flushPromises()
expect(saveDeliveryDocuments).toHaveBeenCalledWith('DL-1', '101', expect.objectContaining({ bolNo: 'BOL-ORIGINAL', documents: [{ category: 'LOADING_PHOTO', fileIds: [] }, { category: 'BOL', fileIds: [] }, { category: 'RECEIPT', fileIds: ['99'] }] }))
expect(wrapper.emitted('saved')).toHaveLength(1)
expect(wrapper.getComponent(DeliveryDocumentsDialog).props('modelValue')).toBe(true)
wrapper.unmount()
})
it('switches customer scope exactly and keeps unsaved delivery edits when switching tabs', async () => {
const wrapper = setup(); await flushPromises()
await wrapper.findAll('[role="tab"]').find(tab => tab.text() === '装车资料')!.trigger('click')
2026-10-21 17:49:04 +08:00
expect(wrapper.getComponent(DeliveryDocumentsDialog).props('categories')).toEqual(['LOADING_PHOTO', 'BOL'])
2026-10-21 16:58:38 +08:00
await wrapper.getComponent(DeliveryDocumentsDialog).find('input').setValue('BOL-CHANGED')
await wrapper.findAll('[role="tab"]').find(tab => tab.text() === '油耗图片')!.trigger('click')
expect(getDeliveryDocuments).toHaveBeenCalledTimes(1)
const confirmation = vi.spyOn(ElMessageBox, 'confirm').mockRejectedValue('cancel')
wrapper.getComponent({ name: 'ElSelect' }).vm.$emit('update:modelValue', 'DL-2'); await flushPromises()
expect(getDeliveryDocuments).toHaveBeenCalledTimes(1)
confirmation.mockResolvedValue('confirm' as Awaited<ReturnType<typeof ElMessageBox.confirm>>)
wrapper.getComponent({ name: 'ElSelect' }).vm.$emit('update:modelValue', 'DL-2'); await flushPromises()
expect(getDeliveryDocuments).toHaveBeenLastCalledWith('DL-2', '102')
expect(saveDeliveryDocuments).not.toHaveBeenCalled()
confirmation.mockRestore(); wrapper.unmount()
})
it('does not request delivery documents without delivery list permission', async () => {
can.mockImplementation((value?: string) => value !== 'platform:overseas-warehouse:delivery:list')
const wrapper = setup(); await flushPromises()
expect(getDeliveryDocuments).not.toHaveBeenCalled()
expect(wrapper.text()).toContain('当前账号无派送资料查看权限')
wrapper.unmount()
})