fix(appointments): handle synchronization and transport continuation

This commit is contained in:
2026-10-18 22:29:06 +08:00
parent a5a1976924
commit 67d917010d
9 changed files with 226 additions and 11 deletions
@@ -1,11 +1,24 @@
import { flushPromises, mount } from '@vue/test-utils'
import { beforeEach, expect, it, vi } from 'vitest'
import { afterEach, beforeEach, expect, it, vi } from 'vitest'
import { ApiResponseError } from '@/shared/api/http'
import WorkBatchContinuation from './WorkBatchContinuation.vue'
import { resolveBatchWork } from './workApi'
import { workDetail, workItem } from './work.test-support'
vi.mock('./workApi', async original => ({ ...await original<typeof import('./workApi')>(), resolveBatchWork: vi.fn() }))
function render() { return mount(WorkBatchContinuation, { props: { batchKey: 'FBA_APPOINTMENT:40', labels: [{ customerId: 'customer-a', label: 'IN-A' }] }, global: { stubs: { ElButton: { props: ['disabled'], template: '<button :disabled="disabled"><slot /></button>' }, LoadErrorState: { props: ['message'], template: '<div role="alert">{{ message }}<button @click="$emit(\'retry\')">重试读取</button></div>' }, ApiErrorMeta: true } } }) }
beforeEach(() => vi.clearAllMocks())
afterEach(() => vi.useRealTimers())
it('shows synchronization after a successful save and continues by reading without resubmitting', async () => {
vi.useFakeTimers()
vi.mocked(resolveBatchWork).mockRejectedValueOnce(new ApiResponseError('预约批次或运输关联已变化,服务端正在协调完整工作清单', 'A0409', 409)).mockResolvedValue({ batchKey: 'FBA_APPOINTMENT:40', customerId: null, detail: workDetail({ item: workItem({ workItemKey: 'actual-key' }) }), candidates: [] })
const wrapper = render(); await flushPromises()
expect(wrapper.text()).toContain('同步中')
expect(wrapper.text()).toContain('无需重复提交')
expect(wrapper.find('[role="alert"]').exists()).toBe(false)
await vi.advanceTimersByTimeAsync(2000); await flushPromises()
expect(wrapper.emitted('open')).toEqual([['actual-key']])
wrapper.unmount()
})
it('requires a customer selection for multiple real work candidates and uses the selected resolver result', async () => {
vi.mocked(resolveBatchWork).mockResolvedValueOnce({ batchKey: 'FBA_APPOINTMENT:40', customerId: null, detail: null, candidates: [{ customerId: 'customer-a', workItemKey: 'real-work-a', batchNo: 'AP-40' }, { customerId: 'customer-b', workItemKey: 'real-work-b', batchNo: 'AP-40' }] }).mockResolvedValue({ batchKey: 'FBA_APPOINTMENT:40', customerId: 'customer-a', detail: workDetail({ item: workItem({ workItemKey: 'current-work-a' }) }), candidates: [] })
const wrapper = render(); await flushPromises()