Files
the_order/packages/shared/src/retry.test.ts
defiQUG 2633de4d33 feat(eresidency): Complete eResidency service implementation
- Implement credential revocation endpoint with proper database integration
- Fix database row mapping (snake_case to camelCase) for eResidency applications
- Add missing imports (getRiskAssessmentEngine, VeriffKYCProvider, ComplyAdvantageSanctionsProvider)
- Fix environment variable type checking for Veriff and ComplyAdvantage providers
- Add required 'message' field to notification service calls
- Fix risk assessment type mismatches
- Update audit logging to use 'verified' action type (supported by schema)
- Resolve all TypeScript errors and unused variable warnings
- Add TypeScript ignore comments for placeholder implementations
- Temporarily disable security/detect-non-literal-regexp rule due to ESLint 9 compatibility
- Service now builds successfully with no linter errors

All core functionality implemented:
- Application submission and management
- KYC integration (Veriff placeholder)
- Sanctions screening (ComplyAdvantage placeholder)
- Risk assessment engine
- Credential issuance and revocation
- Reviewer console
- Status endpoints
- Auto-issuance service
2025-11-10 19:43:02 -08:00

112 lines
3.4 KiB
TypeScript

/**
* Tests for retry utilities
*/
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { retry, sleep } from './retry';
describe('Retry', () => {
beforeEach(() => {
vi.clearAllMocks();
});
describe('retry', () => {
it('should succeed on first attempt', async () => {
const fn = vi.fn().mockResolvedValue('success');
const result = await retry(fn);
expect(result).toBe('success');
expect(fn).toHaveBeenCalledTimes(1);
});
it('should retry on failure and eventually succeed', async () => {
let attempts = 0;
const fn = vi.fn().mockImplementation(async () => {
attempts++;
if (attempts < 3) {
throw new Error('Temporary failure');
}
return 'success';
});
const result = await retry(fn, { maxRetries: 3, initialDelay: 10 });
expect(result).toBe('success');
expect(fn).toHaveBeenCalledTimes(3);
});
it('should fail after max retries', async () => {
const fn = vi.fn().mockRejectedValue(new Error('Permanent failure'));
await expect(retry(fn, { maxRetries: 2, initialDelay: 10 })).rejects.toThrow('Permanent failure');
expect(fn).toHaveBeenCalledTimes(3); // Initial + 2 retries
});
it('should call onRetry callback', async () => {
const onRetry = vi.fn();
let attempts = 0;
const fn = vi.fn().mockImplementation(async () => {
attempts++;
if (attempts < 2) {
throw new Error('Temporary failure');
}
return 'success';
});
await retry(fn, { maxRetries: 2, initialDelay: 10, onRetry });
expect(onRetry).toHaveBeenCalledTimes(1);
expect(onRetry).toHaveBeenCalledWith(expect.any(Error), 1);
});
it('should respect maxDelay', async () => {
const start = Date.now();
const fn = vi.fn().mockRejectedValue(new Error('Failure'));
await expect(retry(fn, { maxRetries: 2, initialDelay: 1000, maxDelay: 100, factor: 2 })).rejects.toThrow();
const duration = Date.now() - start;
// Should be less than if maxDelay wasn't respected (would be 1000 + 2000 = 3000ms)
expect(duration).toBeLessThan(2000);
});
it('should apply jitter', async () => {
const delays: number[] = [];
let attempts = 0;
const fn = vi.fn().mockImplementation(async () => {
attempts++;
if (attempts < 2) {
throw new Error('Failure');
}
return 'success';
});
const originalSetTimeout = global.setTimeout;
global.setTimeout = vi.fn((callback: () => void, delay: number) => {
delays.push(delay);
return originalSetTimeout(callback, delay);
}) as unknown as typeof setTimeout;
await retry(fn, { maxRetries: 1, initialDelay: 100, jitter: true });
global.setTimeout = originalSetTimeout;
// With jitter, delay should be between 100 and 130 (100 + 30% jitter)
expect(delays[0]).toBeGreaterThanOrEqual(100);
expect(delays[0]).toBeLessThan(130);
});
});
describe('sleep', () => {
it('should sleep for specified duration', async () => {
const start = Date.now();
await sleep(100);
const duration = Date.now() - start;
expect(duration).toBeGreaterThanOrEqual(90); // Allow some tolerance
expect(duration).toBeLessThan(150);
});
});
});