Files
admin-web/src/modules/overseas-warehouse/pages/ExceptionOrdersView.test.ts
T

82 lines
4.2 KiB
TypeScript

import ElementPlus from 'element-plus'
import { flushPromises, mount } from '@vue/test-utils'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { createExceptionOrder, listExceptionOrders, resolveExceptionRelation } from '../api/exceptionOrders'
import ExceptionOrdersView from './ExceptionOrdersView.vue'
import { commonPhase5Stubs } from './phase5TestStubs'
const canPermission = vi.hoisted(() => vi.fn((_code: string) => false))
vi.mock('@/core/access/accessPreview', () => ({ useAccessPreviewStore: () => ({ can: canPermission }) }))
vi.mock('../api/exceptionOrders', () => ({ listExceptionOrders: vi.fn(), resolveExceptionRelation: vi.fn(), createExceptionOrder: vi.fn() }))
function mountView() { return mount(ExceptionOrdersView, { global: { plugins: [ElementPlus], stubs: commonPhase5Stubs } }) }
describe('ExceptionOrdersView permissions and creation', () => {
beforeEach(() => {
canPermission.mockReset().mockReturnValue(false)
vi.mocked(listExceptionOrders).mockReset().mockResolvedValue({ records: [], page: 1, size: 10, total: 0, pages: 0 })
vi.mocked(resolveExceptionRelation).mockReset().mockResolvedValue({ inboundOrderId: '9', inboundCode: 'IN-1', lastMileOrderId: '8', lastMileOrderNo: 'LM-1', customerId: '100' })
vi.mocked(createExceptionOrder).mockReset().mockResolvedValue({ id: '19', exceptionNo: 'EXC-1', status: 'PENDING' })
})
it('hides creation without the independent permission', async () => {
const wrapper = mountView()
await flushPromises()
expect(wrapper.find('[data-testid="data-table"]').text()).not.toContain('新增异常订单')
wrapper.unmount()
})
it('keeps the detail action available and hides numeric operator identifiers', async () => {
vi.mocked(listExceptionOrders).mockResolvedValue({
records: [{
id: '19', exceptionNo: 'EXC-1', exceptionType: 'DAMAGED', status: 'PROCESSING', reason: '包装破损',
customerId: '100', customerName: '示例客户', overseasWarehouseName: '洛杉矶仓', handlerName: '1000001',
exceptionAt: '2026-09-03T09:00:00', updatedAt: '2026-09-03T10:00:00',
}],
page: 1, size: 10, total: 1, pages: 1,
})
const wrapper = mountView()
await flushPromises()
const table = wrapper.find('[data-testid="data-table"]')
expect(table.text()).toContain('查看')
await table.find('button').trigger('click')
await flushPromises()
const detail = wrapper.find('[data-dialog="异常订单详情"]')
expect(detail.text()).toContain('示例客户')
expect(detail.text()).toContain('包装破损')
expect(detail.text()).not.toContain('1000001')
wrapper.unmount()
})
it('validates the required relation before submitting', async () => {
canPermission.mockImplementation(code => code.endsWith(':create'))
const wrapper = mountView()
await flushPromises()
await wrapper.findAll('button').find(button => button.text().includes('新增异常订单'))!.trigger('click')
await wrapper.find('[data-dialog="新增异常订单"] .dialog-confirm').trigger('click')
await flushPromises()
expect(resolveExceptionRelation).not.toHaveBeenCalled()
expect(createExceptionOrder).not.toHaveBeenCalled()
wrapper.unmount()
})
it('resolves and submits trimmed business fields', async () => {
canPermission.mockImplementation(code => code.endsWith(':create'))
const wrapper = mountView()
await flushPromises()
await wrapper.findAll('button').find(button => button.text().includes('新增异常订单'))!.trigger('click')
const dialog = wrapper.find('[data-dialog="新增异常订单"]')
await dialog.find('input[placeholder="请输入入仓码"]').setValue(' IN-1 ')
await dialog.find('select').setValue('RETURN')
await dialog.find('textarea').setValue(' 包裹破损 ')
await dialog.find('.dialog-confirm').trigger('click')
await flushPromises()
expect(resolveExceptionRelation).toHaveBeenCalledWith({ customerId: undefined, inboundCode: 'IN-1', lastMileOrderNo: undefined })
expect(createExceptionOrder).toHaveBeenCalledWith({
customerId: undefined, inboundCode: 'IN-1', lastMileOrderNo: 'LM-1',
exceptionType: 'RETURN', reason: '包裹破损', packageCount: undefined, skuCode: undefined,
})
wrapper.unmount()
})
})