50 lines
1.7 KiB
TypeScript
50 lines
1.7 KiB
TypeScript
import { pollTaskDetailUploadJob } from '@/lib/task-detail-upload-status'
|
||
|
||
describe('task-detail-upload-status', () => {
|
||
const originalFetch = global.fetch
|
||
|
||
beforeEach(() => {
|
||
jest.useFakeTimers()
|
||
})
|
||
|
||
afterEach(() => {
|
||
jest.useRealTimers()
|
||
global.fetch = originalFetch
|
||
jest.restoreAllMocks()
|
||
})
|
||
|
||
test('正常等待结束时移除 abort listener,不在长轮询中累积', async () => {
|
||
const controller = new AbortController()
|
||
const addListenerSpy = jest.spyOn(controller.signal, 'addEventListener')
|
||
const removeListenerSpy = jest.spyOn(controller.signal, 'removeEventListener')
|
||
global.fetch = jest.fn()
|
||
.mockResolvedValueOnce({
|
||
ok: true,
|
||
json: async () => ({ jobId: 'job-1', status: 'processing' }),
|
||
})
|
||
.mockResolvedValueOnce({
|
||
ok: true,
|
||
json: async () => ({ jobId: 'job-1', status: 'processing' }),
|
||
})
|
||
.mockResolvedValueOnce({
|
||
ok: true,
|
||
json: async () => ({ jobId: 'job-1', status: 'processing' }),
|
||
})
|
||
.mockResolvedValueOnce({
|
||
ok: true,
|
||
json: async () => ({ jobId: 'job-1', status: 'completed' }),
|
||
}) as unknown as typeof fetch
|
||
|
||
const resultPromise = pollTaskDetailUploadJob('job-1', { signal: controller.signal })
|
||
await jest.advanceTimersByTimeAsync(800 + 1_000 + 1_250)
|
||
|
||
await expect(resultPromise).resolves.toMatchObject({ status: 'completed' })
|
||
expect(addListenerSpy).toHaveBeenCalledTimes(3)
|
||
expect(removeListenerSpy).toHaveBeenCalledTimes(3)
|
||
addListenerSpy.mock.calls.forEach((call, index) => {
|
||
expect(removeListenerSpy.mock.calls[index][1]).toBe(call[1])
|
||
})
|
||
expect(jest.getTimerCount()).toBe(0)
|
||
})
|
||
})
|