Files
admin-web/src/modules/appointment-calendar/useWorkSyncRead.test.ts
T

46 lines
2.4 KiB
TypeScript
Raw Normal View History

import { afterEach, expect, it, vi } from 'vitest'
import { ApiResponseError } from '@/shared/api/http'
import { useWorkSyncRead } from './useWorkSyncRead'
const pending = () => new ApiResponseError('预约批次或运输关联已变化,服务端正在协调完整工作清单', 'A0409', 409, undefined, 'request-sync', 'trace-sync')
afterEach(() => vi.useRealTimers())
it('waits only for the full-work synchronization guard and returns the fresh result', async () => {
vi.useFakeTimers()
const reader = useWorkSyncRead(), load = vi.fn().mockRejectedValueOnce(pending()).mockResolvedValue('fresh')
const result = reader.read(load, new AbortController().signal)
await vi.advanceTimersByTimeAsync(0)
expect(reader.syncing.value).toBe(true)
expect(load).toHaveBeenCalledTimes(1)
await vi.advanceTimersByTimeAsync(2000)
expect(await result).toBe('fresh')
expect(reader.syncing.value).toBe(false)
})
it.each([new ApiResponseError('事项版本已变化', 'A0409', 409), new ApiResponseError('无权查看', 'A0403', 403), new Error('network')])('does not retry other failures: %s', async error => {
const reader = useWorkSyncRead(), load = vi.fn().mockRejectedValue(error)
await expect(reader.read(load, new AbortController().signal)).rejects.toBe(error)
expect(load).toHaveBeenCalledTimes(1)
expect(reader.syncing.value).toBe(false)
})
it('stops waiting at the limit and preserves diagnostic IDs on the original error', async () => {
vi.useFakeTimers()
const error = pending(), reader = useWorkSyncRead(), load = vi.fn().mockRejectedValue(error)
const result = expect(reader.read(load, new AbortController().signal)).rejects.toBe(error)
await vi.advanceTimersByTimeAsync(30000)
await result
expect(load).toHaveBeenCalledTimes(16)
expect(reader.syncing.value).toBe(false)
expect(error.traceId).toBe('trace-sync')
expect(vi.getTimerCount()).toBe(0)
})
it('cancels a waiting read without sending another request', async () => {
vi.useFakeTimers()
const controller = new AbortController(), reader = useWorkSyncRead(), load = vi.fn().mockRejectedValue(pending())
const result = expect(reader.read(load, controller.signal)).rejects.toHaveProperty('name', 'AbortError')
await vi.advanceTimersByTimeAsync(0)
controller.abort()
await result
await vi.advanceTimersByTimeAsync(30000)
expect(load).toHaveBeenCalledTimes(1)
expect(reader.syncing.value).toBe(false)
expect(vi.getTimerCount()).toBe(0)
})