mirror of
https://github.com/Gitlawb/openclaude.git
synced 2026-11-06 20:58:14 -04:00
test(aimlapi): drive polling retries with fake timers (#2393)
* test(aimlapi): drive polling retries with fake timers * test(aimlapi): await rate-limit retry timer registration
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { afterAll, afterEach, expect, mock, test } from 'bun:test'
|
||||
import { afterAll, afterEach, expect, jest, mock, test } from 'bun:test'
|
||||
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
@@ -78,6 +78,7 @@ afterAll(() => {
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
jest.useRealTimers()
|
||||
globalThis.fetch = originalFetch
|
||||
lastSavedProfileEnv = undefined
|
||||
setClaudeConfigHomeDirForTesting(undefined)
|
||||
@@ -1950,6 +1951,7 @@ test('a terminal poll error awaits onSession before rejecting, not racing ahead
|
||||
})
|
||||
|
||||
test('polling retries a transient transport failure', async () => {
|
||||
jest.useFakeTimers()
|
||||
process.env.AIMLAPI_APP_URL = 'https://app.example.test'
|
||||
let attempts = 0
|
||||
globalThis.fetch = mock(async () => {
|
||||
@@ -1965,13 +1967,22 @@ test('polling retries a transient transport failure', async () => {
|
||||
verificationBaseUrl: 'https://front.example.test',
|
||||
})
|
||||
|
||||
await expect(pollUntilPaid(client, 'session')).resolves.toEqual(
|
||||
const polling = pollUntilPaid(client, 'session')
|
||||
// Let the failed request schedule its retry before advancing the poll timer.
|
||||
await new Promise<void>(resolve => setImmediate(resolve))
|
||||
jest.advanceTimersByTime(2999)
|
||||
await new Promise<void>(resolve => setImmediate(resolve))
|
||||
expect(attempts).toBe(1)
|
||||
jest.advanceTimersByTime(1)
|
||||
|
||||
await expect(polling).resolves.toEqual(
|
||||
expect.objectContaining({ status: 'paid' }),
|
||||
)
|
||||
expect(attempts).toBe(2)
|
||||
})
|
||||
|
||||
test('polling retains and retries the same session after a rate limit', async () => {
|
||||
jest.useFakeTimers()
|
||||
process.env.AIMLAPI_APP_URL = 'https://app.example.test'
|
||||
let attempts = 0
|
||||
globalThis.fetch = mock(async () => {
|
||||
@@ -1988,9 +1999,23 @@ test('polling retains and retries the same session after a rate limit', async ()
|
||||
})
|
||||
const sessions: string[] = []
|
||||
|
||||
await expect(
|
||||
pollUntilPaid(client, 'session', undefined, value => { sessions.push(value) }),
|
||||
).resolves.toEqual(expect.objectContaining({ status: 'paid' }))
|
||||
const setTimeoutSpy = jest.spyOn(globalThis, 'setTimeout')
|
||||
const polling = pollUntilPaid(client, 'session', undefined, value => { sessions.push(value) })
|
||||
try {
|
||||
// Reading the 429 body may take multiple turns before the retry is scheduled.
|
||||
for (let tick = 0; tick < 100 && !setTimeoutSpy.mock.calls.some(call => call[1] === 3000); tick++) {
|
||||
await new Promise<void>(resolve => setImmediate(resolve))
|
||||
}
|
||||
expect(setTimeoutSpy).toHaveBeenCalledWith(expect.any(Function), 3000)
|
||||
} finally {
|
||||
setTimeoutSpy.mockRestore()
|
||||
}
|
||||
jest.advanceTimersByTime(2999)
|
||||
await new Promise<void>(resolve => setImmediate(resolve))
|
||||
expect(attempts).toBe(1)
|
||||
jest.advanceTimersByTime(1)
|
||||
|
||||
await expect(polling).resolves.toEqual(expect.objectContaining({ status: 'paid' }))
|
||||
expect(attempts).toBe(2)
|
||||
expect(sessions).toEqual([])
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user