优化
This commit is contained in:
@@ -42,10 +42,106 @@ function mountManager(permissions: string[]) {
|
||||
}
|
||||
|
||||
describe('InboundFeeDetailManager', () => {
|
||||
it.each([80, null])('refreshes the default price on reopening the editor: %s', async (defaultPrice) => {
|
||||
const item = { id: '31', feeTypeName: '操作费', feeCode: 'OPERATION', defaultPrice: 60, supplierCategory: null, warehouseReceivable: true, warehousePayable: false }
|
||||
vi.mocked(listInboundFeeItemOptions).mockResolvedValue([item])
|
||||
const wrapper = mountManager(['firstleg:inbound:fee-detail:view', 'firstleg:inbound:fee-detail:edit', 'firstleg:fee-item:view'])
|
||||
await flushPromises()
|
||||
const state = (wrapper.vm.$ as unknown as { setupState: {
|
||||
openEditor(mode: string, row?: InboundFeeDetail): Promise<void>
|
||||
editorOpen: boolean
|
||||
form: { feeItemId: string; unitPrice: number; amount: number }
|
||||
} }).setupState
|
||||
await state.openEditor('create'); await flushPromises()
|
||||
state.editorOpen = false; await flushPromises()
|
||||
vi.mocked(listInboundFeeItemOptions).mockResolvedValue([{ ...item, defaultPrice }])
|
||||
await state.openEditor('create'); await flushPromises()
|
||||
const select = wrapper.findAllComponents({ name: 'ElFormItem' }).find((field) => field.props('prop') === 'feeItemId')!.findComponent({ name: 'ElSelect' })
|
||||
select.vm.$emit('update:modelValue', '31'); select.vm.$emit('change', '31')
|
||||
await flushPromises()
|
||||
expect(state.form).toMatchObject({ unitPrice: defaultPrice ?? 0, amount: defaultPrice ?? 0 })
|
||||
expect(listInboundFeeItemOptions).toHaveBeenCalledTimes(2)
|
||||
state.editorOpen = false; await flushPromises()
|
||||
await state.openEditor('edit', pending); await flushPromises()
|
||||
expect(state.form).toMatchObject({ unitPrice: 10, amount: 100 })
|
||||
})
|
||||
|
||||
it('clears cached choices and blocks saving while refresh is pending or has failed', async () => {
|
||||
const wrapper = mountManager(['firstleg:inbound:fee-detail:view', 'firstleg:inbound:fee-detail:edit', 'firstleg:fee-item:view'])
|
||||
await flushPromises()
|
||||
const state = (wrapper.vm.$ as unknown as { setupState: {
|
||||
openEditor(mode: string, row?: InboundFeeDetail): Promise<void>
|
||||
save(): Promise<void>
|
||||
editorOpen: boolean
|
||||
feeItems: unknown[]
|
||||
feeItemsLoading: boolean
|
||||
feeItemsError: { message: string } | null
|
||||
actionError: { message: string } | null
|
||||
form: { unitPrice: number; amount: number }
|
||||
} }).setupState
|
||||
await state.openEditor('edit', pending); await flushPromises()
|
||||
expect(state.feeItems).toHaveLength(1)
|
||||
state.editorOpen = false; await flushPromises()
|
||||
let rejectRefresh!: (reason: Error) => void
|
||||
vi.mocked(listInboundFeeItemOptions).mockImplementationOnce(() => new Promise((_, reject) => { rejectRefresh = reject }))
|
||||
const opening = state.openEditor('edit', pending)
|
||||
await flushPromises()
|
||||
expect(state.feeItems).toEqual([])
|
||||
expect(state.feeItemsLoading).toBe(true)
|
||||
const select = wrapper.findAllComponents({ name: 'ElFormItem' }).find((field) => field.props('prop') === 'feeItemId')!.findComponent({ name: 'ElSelect' })
|
||||
expect(select.props('disabled')).toBe(true)
|
||||
await state.save()
|
||||
expect(state.actionError?.message).toContain('正在加载')
|
||||
rejectRefresh(new Error('加载失败'))
|
||||
await opening; await flushPromises()
|
||||
expect(state.feeItems).toEqual([])
|
||||
expect(state.feeItemsError).not.toBeNull()
|
||||
expect(state.form).toMatchObject({ unitPrice: 10, amount: 100 })
|
||||
await state.save()
|
||||
expect(updateInboundFeeDetail).not.toHaveBeenCalled()
|
||||
state.feeItemsError = null
|
||||
await state.save()
|
||||
expect(updateInboundFeeDetail).not.toHaveBeenCalled()
|
||||
expect(state.actionError?.message).toContain('不可用')
|
||||
})
|
||||
|
||||
it('prefills only on user selection and saves a manually overridden price', async () => {
|
||||
vi.mocked(listInboundFeeItemOptions).mockResolvedValue([
|
||||
{ id: '31', feeTypeName: '操作费', feeCode: 'OPERATION', defaultPrice: 60, supplierCategory: null, warehouseReceivable: true, warehousePayable: false },
|
||||
{ id: '32', feeTypeName: '手工费', feeCode: 'MANUAL', defaultPrice: null, supplierCategory: null, warehouseReceivable: true, warehousePayable: false },
|
||||
{ id: '33', feeTypeName: '零元费', feeCode: 'ZERO', defaultPrice: 0, supplierCategory: null, warehouseReceivable: true, warehousePayable: false },
|
||||
])
|
||||
const wrapper = mountManager(['firstleg:inbound:fee-detail:view', 'firstleg:inbound:fee-detail:edit', 'firstleg:fee-item:view'])
|
||||
await flushPromises()
|
||||
const state = (wrapper.vm.$ as unknown as { setupState: {
|
||||
openEditor(mode: string, row?: InboundFeeDetail): Promise<void>
|
||||
save(): Promise<void>
|
||||
form: { feeItemId: string; unitPrice: number; amount: number }
|
||||
} }).setupState
|
||||
await state.openEditor('edit', pending)
|
||||
await flushPromises()
|
||||
expect(state.form).toMatchObject({ unitPrice: 10, amount: 100 })
|
||||
await state.openEditor('create')
|
||||
await flushPromises()
|
||||
const select = wrapper.findAllComponents({ name: 'ElFormItem' }).find((item) => item.props('prop') === 'feeItemId')!.findComponent({ name: 'ElSelect' })
|
||||
for (const [id, price] of [['31', 60], ['32', 0], ['33', 0]] as const) {
|
||||
select.vm.$emit('update:modelValue', id)
|
||||
select.vm.$emit('change', id)
|
||||
await flushPromises()
|
||||
expect(state.form).toMatchObject({ unitPrice: price, amount: price })
|
||||
}
|
||||
select.vm.$emit('update:modelValue', '31')
|
||||
select.vm.$emit('change', '31')
|
||||
await flushPromises()
|
||||
state.form.unitPrice = 65; state.form.amount = 75
|
||||
await state.save(); await flushPromises()
|
||||
expect(createInboundFeeDetail).toHaveBeenCalledWith('100', '88', expect.objectContaining({ feeItemId: '31', unitPrice: 65, amount: 75 }))
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks(); document.body.innerHTML = ''
|
||||
vi.mocked(listInboundFeeDetails).mockResolvedValue([pending, approved])
|
||||
vi.mocked(listInboundFeeItemOptions).mockResolvedValue([{ id: '31', feeTypeName: '操作费', feeCode: 'OPERATION', supplierCategory: 'TRUCKING', warehouseReceivable: true, warehousePayable: true }])
|
||||
vi.mocked(listInboundFeeItemOptions).mockResolvedValue([{ id: '31', feeTypeName: '操作费', feeCode: 'OPERATION', defaultPrice: null, supplierCategory: 'TRUCKING', warehouseReceivable: true, warehousePayable: true }])
|
||||
vi.mocked(listInboundFeeSupplierOptions).mockResolvedValue([{ id: '41', supplierName: '测试供应商', category: 'TRUCKING' }])
|
||||
vi.mocked(createInboundFeeDetail).mockResolvedValue(pending)
|
||||
vi.mocked(updateInboundFeeDetail).mockResolvedValue(pending)
|
||||
@@ -227,7 +323,7 @@ describe('InboundFeeDetailManager', () => {
|
||||
})
|
||||
|
||||
it('allows any loaded ACTIVE supplier when a payable fee item has no supplier category', async () => {
|
||||
vi.mocked(listInboundFeeItemOptions).mockResolvedValue([{ id: '31', feeTypeName: '未映射费用', feeCode: 'UNMAPPED', supplierCategory: null, warehouseReceivable: false, warehousePayable: true }])
|
||||
vi.mocked(listInboundFeeItemOptions).mockResolvedValue([{ id: '31', feeTypeName: '未映射费用', feeCode: 'UNMAPPED', defaultPrice: null, supplierCategory: null, warehouseReceivable: false, warehousePayable: true }])
|
||||
vi.mocked(listInboundFeeSupplierOptions).mockResolvedValue([{ id: '41', supplierName: '测试供应商', category: 'CUSTOMS' }])
|
||||
const wrapper = mountManager([
|
||||
'firstleg:inbound:fee-detail:view', 'firstleg:inbound:fee-detail:edit',
|
||||
|
||||
Reference in New Issue
Block a user