46 lines
2.4 KiB
TypeScript
46 lines
2.4 KiB
TypeScript
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)
|
|
})
|