fix(dispatch): align dispatch actions and native return workflows
This commit is contained in:
@@ -1,22 +1,24 @@
|
||||
import ElementPlus from 'element-plus'
|
||||
import ElementPlus, { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { resolve } from 'node:path'
|
||||
import { flushPromises, mount } from '@vue/test-utils'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { listOutbounds } from '../api/outbounds'
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { cancelOutbound, listOutbounds } from '../api/outbounds'
|
||||
import OutboundsView from './OutboundsView.vue'
|
||||
import StatusBadge from '@/shared/components/StatusBadge.vue'
|
||||
|
||||
const canPermission = vi.hoisted(() => vi.fn((_code: string) => true))
|
||||
const routerPush = vi.hoisted(() => vi.fn())
|
||||
const routeQuery = vi.hoisted(() => ({} as Record<string, string>))
|
||||
vi.mock('@/core/access/accessPreview', () => ({ useAccessPreviewStore: () => ({ can: canPermission }) }))
|
||||
vi.mock('vue-router', () => ({ useRouter: () => ({ push: routerPush }) }))
|
||||
vi.mock('vue-router', () => ({ useRoute: () => ({ query: routeQuery }), useRouter: () => ({ push: routerPush }) }))
|
||||
vi.mock('../api/outbounds', () => ({ listOutbounds: vi.fn(), cancelOutbound: vi.fn(), createOneClickDropshipOutbound: vi.fn() }))
|
||||
vi.mock('../api/inventory', () => ({ listInventoryBalances: vi.fn(), listInventoryPositions: vi.fn() }))
|
||||
|
||||
class ResizeObserverStub { observe() {} unobserve() {} disconnect() {} }
|
||||
|
||||
describe('OutboundsView permissions and navigation', () => {
|
||||
afterEach(() => vi.restoreAllMocks())
|
||||
it('distinguishes outbound stages and does not present unknown states as picking', async () => {
|
||||
const statuses = [
|
||||
['WAIT_PICK', '待拣货', 'warning'], ['WAIT_OUTBOUND', '待出库', 'warning'], ['PICKING', '拣货中', 'info'],
|
||||
@@ -36,6 +38,8 @@ describe('OutboundsView permissions and navigation', () => {
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
Object.keys(routeQuery).forEach(key => delete routeQuery[key])
|
||||
vi.mocked(cancelOutbound).mockReset().mockResolvedValue(null)
|
||||
vi.stubGlobal('ResizeObserver', ResizeObserverStub)
|
||||
vi.stubGlobal('localStorage', { getItem: () => null, setItem: () => undefined, removeItem: () => undefined })
|
||||
vi.mocked(listOutbounds).mockReset().mockResolvedValue({ records: [{ id: '1', outboundNo: 'OUT-1', dispatchNo: 'PC-1', status: 'WAIT_PICK', palletCount: 1, packageCount: 2 }], page: 1, size: 20, total: 1, pages: 1 })
|
||||
@@ -43,6 +47,27 @@ describe('OutboundsView permissions and navigation', () => {
|
||||
routerPush.mockReset()
|
||||
})
|
||||
|
||||
it('uses an original outbound deep link as the server query', async () => {
|
||||
routeQuery.documentNo = 'OUT/FROM-DELIVERY'
|
||||
const wrapper = mount(OutboundsView, { global: { plugins: [ElementPlus] } }); await flushPromises()
|
||||
expect(listOutbounds).toHaveBeenCalledWith(expect.objectContaining({ documentNo: 'OUT/FROM-DELIVERY' }))
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
it('explains the cancellation order and routes the cancelled outbound to its original dispatch', async () => {
|
||||
const prompt = vi.spyOn(ElMessageBox, 'prompt').mockResolvedValue({ value: '重新排车', action: 'confirm' } as Awaited<ReturnType<typeof ElMessageBox.prompt>>)
|
||||
const success = vi.spyOn(ElMessage, 'success')
|
||||
const wrapper = mount(OutboundsView, { global: { plugins: [ElementPlus] } }); await flushPromises()
|
||||
vi.mocked(listOutbounds).mockResolvedValue({ records: [{ id: '1', outboundNo: 'OUT-1', dispatchNo: 'PC-1', status: 'CANCELLED', palletCount: 1, packageCount: 2 }], page: 1, size: 20, total: 1, pages: 1 })
|
||||
await wrapper.findAll('.el-table__body-wrapper button').find(button => button.text() === '取消')!.trigger('click'); await flushPromises()
|
||||
expect(prompt).toHaveBeenCalledWith(expect.stringContaining('出库取消后再取消原排车'), '取消出库单', expect.any(Object))
|
||||
expect(cancelOutbound).toHaveBeenCalledExactlyOnceWith('OUT-1', '重新排车')
|
||||
expect(success).toHaveBeenCalledWith(expect.stringContaining('再从入仓单或换标单重新预排'))
|
||||
await wrapper.findAll('button').find(button => button.text() === '处理原排车')!.trigger('click')
|
||||
expect(routerPush).toHaveBeenCalledWith({ name: 'overseas-dispatches', query: { dispatchNo: 'PC-1' } })
|
||||
wrapper.unmount()
|
||||
})
|
||||
|
||||
it('uses list access for detail and independent create/cancel permissions', async () => {
|
||||
canPermission.mockImplementation((code: string) => code.endsWith(':list'))
|
||||
const wrapper = mount(OutboundsView, { global: { plugins: [ElementPlus] } })
|
||||
|
||||
Reference in New Issue
Block a user