优化
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { enableAutoUnmount, flushPromises, mount } from '@vue/test-utils'
|
||||
import { createPinia, setActivePinia } from 'pinia'
|
||||
import ElementPlus from 'element-plus'
|
||||
import ElementPlus, { ElInputNumber } from 'element-plus'
|
||||
import AppDialog from '@/shared/components/AppDialog.vue'
|
||||
import { useAuthStore } from '@/core/auth/auth'
|
||||
import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
||||
@@ -9,14 +9,12 @@ import ProcurementWorkflowPanel from './ProcurementWorkflowPanel.vue'
|
||||
import type { PlatformProcurement } from '../procurementTypes'
|
||||
import type { ProcurementWorkflow } from '../api/procurementWorkflow'
|
||||
import { submitProcurementWorkflow } from '../api/procurementWorkflow'
|
||||
import { submitProcurementCommand, uploadProcurementFile } from '../api/procurementCommands'
|
||||
import { listOverseasPurchaseWarehouseOptions } from '../api/platformOverseasBusiness'
|
||||
import { uploadProcurementFile } from '../api/procurementCommands'
|
||||
vi.mock('../api/procurementWorkflow', () => ({ submitProcurementWorkflow: vi.fn() }))
|
||||
vi.mock('../api/procurementCommands', () => ({ submitProcurementCommand: vi.fn(), uploadProcurementFile: vi.fn() }))
|
||||
vi.mock('../api/platformOverseasBusiness', () => ({ listOverseasPurchaseWarehouseOptions: vi.fn() }))
|
||||
vi.mock('../api/procurementCommands', () => ({ uploadProcurementFile: vi.fn() }))
|
||||
vi.mock('@/core/unsaved-work/useUnsavedWorkRegistration', () => ({ useUnsavedWorkRegistration: () => ({ captureBaseline: vi.fn() }) }))
|
||||
enableAutoUnmount(afterEach)
|
||||
const workflow = (status = 'RECEIVING'): ProcurementWorkflow => ({ orderNo: 'OP-1', version: 4, status, receivedQuantity: 5, stockQuantity: 5, reservedQuantity: 0, availableQuantity: 5, receipts: [], outbounds: [] })
|
||||
const workflow = (status = 'RECEIVING'): ProcurementWorkflow => ({ orderNo: 'OP-1', version: 4, status, receivedQuantity: 5, stockQuantity: 5, reservedQuantity: 0, availableQuantity: 5, rejectionReason: null, photosNeedUpdate: false, receipts: [], outbounds: [] })
|
||||
const detail = { customerView: { order: { purchaseQuantity: 20 } }, files: [] } as unknown as PlatformProcurement
|
||||
const beforeOutbound = vi.fn<() => Promise<boolean | null>>()
|
||||
function render(status = 'RECEIVING', permissions = ['receive-overseas', 'ship-customer']) {
|
||||
@@ -24,8 +22,70 @@ function render(status = 'RECEIVING', permissions = ['receive-overseas', 'ship-c
|
||||
const auth = useAuthStore(); auth.token = 'test'; auth.permissions = permissions.map(value => `platform:overseas-business:purchase:${value}`); useAccessPreviewStore().initializeAfterLogin()
|
||||
return mount(ProcurementWorkflowPanel, { props: { detail, workflow: workflow(status), customerId: '1001', beforeOutbound }, global: { plugins: [pinia, ElementPlus] } })
|
||||
}
|
||||
beforeEach(() => { vi.clearAllMocks(); beforeOutbound.mockResolvedValue(null); vi.mocked(submitProcurementWorkflow).mockResolvedValue(workflow()); vi.mocked(listOverseasPurchaseWarehouseOptions).mockResolvedValue([]) })
|
||||
beforeEach(() => { vi.clearAllMocks(); beforeOutbound.mockResolvedValue(null); vi.mocked(submitProcurementWorkflow).mockResolvedValue(workflow()) })
|
||||
describe('simplified procurement operations', () => {
|
||||
it('allows a rejected purchase to be resubmitted without uploading photos and clears the old reason after success', async () => {
|
||||
const wrapper = render()
|
||||
const rejected = { ...workflow(), rejectionReason: '请核对', photosNeedUpdate: true, receipts: [
|
||||
{ id: 'r-1', quantity: 2, fileIds: ['old-1'], receivedAt: '' },
|
||||
{ id: 'r-2', quantity: 3, fileIds: ['old-2'], receivedAt: '' },
|
||||
] }
|
||||
await wrapper.setProps({ workflow: rejected }); await flushPromises()
|
||||
const button = wrapper.findAll('button').find(button => button.text() === '采购完成')!
|
||||
expect(button.attributes('disabled')).toBeUndefined()
|
||||
expect(wrapper.text()).toContain('请核对')
|
||||
await button.trigger('click'); await flushPromises()
|
||||
wrapper.findComponent(AppDialog).vm.$emit('confirm'); await flushPromises()
|
||||
expect(uploadProcurementFile).not.toHaveBeenCalled()
|
||||
expect(submitProcurementWorkflow).toHaveBeenCalledWith('OP-1', '1001', 'request-confirmation', { version: 4, idempotencyKey: expect.any(String) })
|
||||
expect(wrapper.emitted('changed')).toHaveLength(1)
|
||||
await wrapper.setProps({ workflow: { ...rejected, status: 'WAIT_CUSTOMER_CONFIRM', version: 5, rejectionReason: null, photosNeedUpdate: false } })
|
||||
expect(wrapper.text()).not.toContain('客户驳回原因')
|
||||
})
|
||||
it('accepts the first and subsequent receipt batches using the remaining purchase quantity', async () => {
|
||||
const wrapper = render()
|
||||
const receive = () => wrapper.findAll('button').find(button => button.text() === '登记收货')!
|
||||
await wrapper.setProps({ workflow: { ...workflow(), receivedQuantity: 0, stockQuantity: 0, availableQuantity: 0 } })
|
||||
await receive().trigger('click'); await flushPromises()
|
||||
const quantity = wrapper.findComponent(ElInputNumber)
|
||||
const increment = quantity.find('.el-input-number__increase')
|
||||
expect(increment.attributes('aria-disabled')).not.toBe('true')
|
||||
await increment.trigger('mousedown', { button: 0 })
|
||||
document.dispatchEvent(new MouseEvent('mouseup', { bubbles: true }))
|
||||
expect(quantity.props('modelValue')).toBe(2)
|
||||
await quantity.find('input').setValue('10')
|
||||
await quantity.find('input').trigger('blur')
|
||||
expect(quantity.props('modelValue')).toBe(10)
|
||||
const form = wrapper.findComponent({ name: 'ElForm' }).props('model')
|
||||
form.fileIds = ['photo-1']
|
||||
const dialog = wrapper.findComponent(AppDialog)
|
||||
dialog.vm.$emit('confirm'); await flushPromises()
|
||||
expect(submitProcurementWorkflow).toHaveBeenLastCalledWith('OP-1', '1001', 'receipts', expect.objectContaining({ version: 4, quantity: 10, fileIds: ['photo-1'] }))
|
||||
expect(wrapper.emitted('changed')).toHaveLength(1)
|
||||
|
||||
await wrapper.setProps({ workflow: { ...workflow(), version: 5, receivedQuantity: 10, stockQuantity: 10, availableQuantity: 10 } })
|
||||
await receive().trigger('click'); await flushPromises()
|
||||
await wrapper.findComponent(ElInputNumber).find('input').setValue('10')
|
||||
await wrapper.findComponent(ElInputNumber).find('input').trigger('blur')
|
||||
form.fileIds = ['photo-2']
|
||||
dialog.vm.$emit('confirm'); await flushPromises()
|
||||
expect(submitProcurementWorkflow).toHaveBeenLastCalledWith('OP-1', '1001', 'receipts', expect.objectContaining({ version: 5, quantity: 10, fileIds: ['photo-2'] }))
|
||||
expect(wrapper.emitted('changed')).toHaveLength(2)
|
||||
const calls = vi.mocked(submitProcurementWorkflow).mock.calls
|
||||
expect(calls[0]![3].idempotencyKey).not.toBe(calls[1]![3].idempotencyKey)
|
||||
})
|
||||
it.each([
|
||||
{ received: 1, input: '10', expected: 10 },
|
||||
{ received: 18, input: '3', expected: 2 },
|
||||
])('limits receipts by remaining purchase quantity after $received units were received', async ({ received, input, expected }) => {
|
||||
const wrapper = render()
|
||||
await wrapper.setProps({ workflow: { ...workflow(), receivedQuantity: received, stockQuantity: received, availableQuantity: received } })
|
||||
await wrapper.findAll('button').find(button => button.text() === '登记收货')!.trigger('click'); await flushPromises()
|
||||
const quantity = wrapper.findComponent(ElInputNumber)
|
||||
await quantity.find('input').setValue(input)
|
||||
await quantity.find('input').trigger('blur')
|
||||
expect(quantity.props('modelValue')).toBe(expected)
|
||||
})
|
||||
it('allows outbound when the fee check reports missing or unreviewed details', async () => {
|
||||
const wrapper = render('CONFIRMED')
|
||||
const button = wrapper.findAll('button').find(button => button.text() === '创建出库单')!
|
||||
@@ -68,14 +128,6 @@ describe('simplified procurement operations', () => {
|
||||
expect(form.trackingNo).toBe('TRACK-1'); expect(form.quantity).toBe(3)
|
||||
form.quantity = 6; dialog.vm.$emit('confirm'); await flushPromises(); expect(submitProcurementWorkflow).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
it('requires a rejection reason and preserves the current version and customer scope', async () => {
|
||||
const wrapper = render('PENDING_REVIEW', ['review'])
|
||||
await wrapper.findAll('button').find(button => button.text() === '审核')!.trigger('click'); await flushPromises()
|
||||
const form = wrapper.findComponent({ name: 'ElForm' }).props('model'), dialog = wrapper.findComponent(AppDialog)
|
||||
form.decision = 'REJECT'; dialog.vm.$emit('confirm'); await flushPromises(); expect(submitProcurementCommand).not.toHaveBeenCalled()
|
||||
form.reason = '商品无法采购'; dialog.vm.$emit('confirm'); await flushPromises()
|
||||
expect(submitProcurementCommand).toHaveBeenCalledWith('OP-1', '1001', 'review', expect.objectContaining({ version: 4, decision: 'REJECT', reason: '商品无法采购', purchaseWarehouseId: undefined }))
|
||||
})
|
||||
it('only completes the selected delivering batch after signature evidence is supplied', async () => {
|
||||
const wrapper = render('DELIVERING')
|
||||
await wrapper.setProps({ workflow: { ...workflow('DELIVERING'), outbounds: [{ id: '9007199254740993', outboundNo: 'OUT-1', status: 'DELIVERING', quantity: 3, trackingNo: 'TRACK-1', fileIds: [], createdAt: '', completedAt: null }] } })
|
||||
|
||||
Reference in New Issue
Block a user