Files
telegram-ai-support/tests/utils/retry.test.ts
kappa 1d6b64c9e4 Initial implementation of Telegram AI customer support bot
Cloudflare Workers + Hono + D1 + KV + R2 stack with 4 specialized AI agents
(onboarding, troubleshoot, asset, billing), OpenAI function calling with
7 tool definitions, human escalation, pending action approval workflow,
feedback collection, audit logging, i18n (ko/en), and Workers AI fallback.

43 source files, 45 tests passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 13:21:38 +09:00

67 lines
2.0 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import { retryWithBackoff, RetryError } from '../../src/utils/retry';
describe('retryWithBackoff', () => {
it('succeeds on first attempt without retrying', async () => {
let callCount = 0;
const result = await retryWithBackoff(async () => {
callCount++;
return 'ok';
}, { maxRetries: 3, initialDelayMs: 1, jitter: false });
expect(result).toBe('ok');
expect(callCount).toBe(1);
});
it('retries and succeeds on 2nd attempt', async () => {
let callCount = 0;
const result = await retryWithBackoff(async () => {
callCount++;
if (callCount < 2) throw new Error('transient');
return 'recovered';
}, { maxRetries: 3, initialDelayMs: 1, jitter: false });
expect(result).toBe('recovered');
expect(callCount).toBe(2);
});
it('throws RetryError after all attempts exhausted', async () => {
let callCount = 0;
await expect(
retryWithBackoff(async () => {
callCount++;
throw new Error('permanent');
}, { maxRetries: 2, initialDelayMs: 1, jitter: false })
).rejects.toThrow(RetryError);
// 1 initial + 2 retries = 3 total
expect(callCount).toBe(3);
});
it('respects maxRetries option', async () => {
let callCount = 0;
await expect(
retryWithBackoff(async () => {
callCount++;
throw new Error('fail');
}, { maxRetries: 1, initialDelayMs: 1, jitter: false })
).rejects.toThrow(RetryError);
// 1 initial + 1 retry = 2 total
expect(callCount).toBe(2);
});
it('RetryError contains attempt count and last error', async () => {
try {
await retryWithBackoff(async () => {
throw new Error('specific failure');
}, { maxRetries: 2, initialDelayMs: 1, jitter: false });
} catch (error) {
expect(error).toBeInstanceOf(RetryError);
const retryErr = error as RetryError;
expect(retryErr.attempts).toBe(3);
expect(retryErr.lastError.message).toBe('specific failure');
}
});
});