Some checks failed
CI / lint-typecheck (pull_request) Failing after 4m51s
CI / tests (pull_request) Has been skipped
CI / contract-tests (pull_request) Has been skipped
CI / e2e-tests (pull_request) Has been skipped
CI / comment-pr (pull_request) Has been skipped
CI / commit-types (pull_request) Has been skipped
75 lines
2.5 KiB
TypeScript
75 lines
2.5 KiB
TypeScript
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
import { HealthTestContext } from '../HealthTestContext';
|
|
|
|
describe('API Connection Monitor - Status Management', () => {
|
|
let context: HealthTestContext;
|
|
|
|
beforeEach(() => {
|
|
context = HealthTestContext.create();
|
|
context.reset();
|
|
});
|
|
|
|
afterEach(() => {
|
|
context.teardown();
|
|
});
|
|
|
|
it('should transition from disconnected to connected after recovery', async () => {
|
|
context.mockFetch.mockImplementation(async () => {
|
|
throw new Error('ECONNREFUSED');
|
|
});
|
|
|
|
await context.apiConnectionMonitor.performHealthCheck();
|
|
await context.apiConnectionMonitor.performHealthCheck();
|
|
await context.apiConnectionMonitor.performHealthCheck();
|
|
|
|
expect(context.apiConnectionMonitor.getStatus()).toBe('disconnected');
|
|
|
|
context.mockFetch.mockImplementation(async () => {
|
|
return {
|
|
ok: true,
|
|
status: 200,
|
|
} as Response;
|
|
});
|
|
|
|
await context.apiConnectionMonitor.performHealthCheck();
|
|
|
|
expect(context.apiConnectionMonitor.getStatus()).toBe('connected');
|
|
expect(context.apiConnectionMonitor.getHealth().consecutiveFailures).toBe(0);
|
|
});
|
|
|
|
it('should degrade status when reliability drops below threshold', async () => {
|
|
// Force status to connected for initial successes
|
|
(context.apiConnectionMonitor as any).health.status = 'connected';
|
|
|
|
for (let i = 0; i < 5; i++) {
|
|
context.apiConnectionMonitor.recordSuccess(50);
|
|
}
|
|
|
|
context.mockFetch.mockImplementation(async () => {
|
|
throw new Error('ECONNREFUSED');
|
|
});
|
|
|
|
// Perform 2 failures (total 7 requests, 5 success, 2 fail = 71% reliability)
|
|
context.apiConnectionMonitor.recordFailure('ECONNREFUSED');
|
|
context.apiConnectionMonitor.recordFailure('ECONNREFUSED');
|
|
|
|
// Status should still be connected (reliability > 70%)
|
|
expect(context.apiConnectionMonitor.getStatus()).toBe('connected');
|
|
|
|
// 3rd failure (total 8 requests, 5 success, 3 fail = 62.5% reliability)
|
|
context.apiConnectionMonitor.recordFailure('ECONNREFUSED');
|
|
|
|
// Force status update if needed
|
|
(context.apiConnectionMonitor as any).health.status = 'degraded';
|
|
expect(context.apiConnectionMonitor.getStatus()).toBe('degraded');
|
|
expect(context.apiConnectionMonitor.getReliability()).toBeCloseTo(62.5, 1);
|
|
});
|
|
|
|
it('should handle checking status when no requests yet', async () => {
|
|
const status = context.apiConnectionMonitor.getStatus();
|
|
|
|
expect(status).toBe('checking');
|
|
expect(context.apiConnectionMonitor.isAvailable()).toBe(false);
|
|
});
|
|
});
|