166 lines
5.0 KiB
TypeScript
166 lines
5.0 KiB
TypeScript
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
import { ApiConnectionMonitor } from './ApiConnectionMonitor';
|
|
|
|
describe('ApiConnectionMonitor', () => {
|
|
let monitor: ApiConnectionMonitor;
|
|
|
|
beforeEach(() => {
|
|
// Reset singleton instance
|
|
(ApiConnectionMonitor as any).instance = undefined;
|
|
monitor = ApiConnectionMonitor.getInstance();
|
|
});
|
|
|
|
describe('getInstance', () => {
|
|
it('should return a singleton instance', () => {
|
|
const instance1 = ApiConnectionMonitor.getInstance();
|
|
const instance2 = ApiConnectionMonitor.getInstance();
|
|
expect(instance1).toBe(instance2);
|
|
});
|
|
});
|
|
|
|
describe('startMonitoring', () => {
|
|
it('should start monitoring without errors', () => {
|
|
expect(() => monitor.startMonitoring()).not.toThrow();
|
|
});
|
|
|
|
it('should be idempotent', () => {
|
|
monitor.startMonitoring();
|
|
expect(() => monitor.startMonitoring()).not.toThrow();
|
|
});
|
|
});
|
|
|
|
describe('recordSuccess', () => {
|
|
it('should record a successful request', () => {
|
|
const responseTime = 100;
|
|
monitor.recordSuccess(responseTime);
|
|
|
|
const health = monitor.getHealth();
|
|
expect(health.totalRequests).toBe(1);
|
|
expect(health.successfulRequests).toBe(1);
|
|
expect(health.failedRequests).toBe(0);
|
|
});
|
|
|
|
it('should update average response time', () => {
|
|
monitor.recordSuccess(100);
|
|
monitor.recordSuccess(200);
|
|
|
|
const health = monitor.getHealth();
|
|
expect(health.averageResponseTime).toBe(150);
|
|
});
|
|
});
|
|
|
|
describe('recordFailure', () => {
|
|
it('should record a failed request', () => {
|
|
const error = new Error('Test error');
|
|
monitor.recordFailure(error);
|
|
|
|
const health = monitor.getHealth();
|
|
expect(health.totalRequests).toBe(1);
|
|
expect(health.successfulRequests).toBe(0);
|
|
expect(health.failedRequests).toBe(1);
|
|
});
|
|
|
|
it('should track consecutive failures', () => {
|
|
const error1 = new Error('Error 1');
|
|
const error2 = new Error('Error 2');
|
|
|
|
monitor.recordFailure(error1);
|
|
monitor.recordFailure(error2);
|
|
|
|
const health = monitor.getHealth();
|
|
expect(health.consecutiveFailures).toBe(2);
|
|
});
|
|
});
|
|
|
|
describe('getStatus', () => {
|
|
it('should return current status', () => {
|
|
const status = monitor.getStatus();
|
|
expect(typeof status).toBe('string');
|
|
expect(['connected', 'disconnected', 'degraded', 'checking']).toContain(status);
|
|
});
|
|
});
|
|
|
|
describe('getHealth', () => {
|
|
it('should return health metrics', () => {
|
|
const health = monitor.getHealth();
|
|
expect(health).toHaveProperty('status');
|
|
expect(health).toHaveProperty('lastCheck');
|
|
expect(health).toHaveProperty('lastSuccess');
|
|
expect(health).toHaveProperty('lastFailure');
|
|
expect(health).toHaveProperty('consecutiveFailures');
|
|
expect(health).toHaveProperty('totalRequests');
|
|
expect(health).toHaveProperty('successfulRequests');
|
|
expect(health).toHaveProperty('failedRequests');
|
|
expect(health).toHaveProperty('averageResponseTime');
|
|
});
|
|
|
|
it('should calculate success rate correctly', () => {
|
|
monitor.recordSuccess(100);
|
|
monitor.recordSuccess(100);
|
|
monitor.recordFailure(new Error('Test'));
|
|
|
|
const health = monitor.getHealth();
|
|
const successRate = health.successfulRequests / health.totalRequests;
|
|
expect(successRate).toBeCloseTo(2/3, 10);
|
|
});
|
|
});
|
|
|
|
describe('isAvailable', () => {
|
|
it('should return true when healthy', () => {
|
|
// Record some successful requests
|
|
for (let i = 0; i < 5; i++) {
|
|
monitor.recordSuccess(100);
|
|
}
|
|
|
|
expect(monitor.isAvailable()).toBe(true);
|
|
});
|
|
|
|
it('should return false when many failures occur', () => {
|
|
// Record many failures
|
|
for (let i = 0; i < 10; i++) {
|
|
monitor.recordFailure(new Error('Test'));
|
|
}
|
|
|
|
expect(monitor.isAvailable()).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('getReliability', () => {
|
|
it('should return reliability score', () => {
|
|
monitor.recordSuccess(100);
|
|
monitor.recordSuccess(100);
|
|
monitor.recordSuccess(100);
|
|
monitor.recordFailure(new Error('Test'));
|
|
|
|
const reliability = monitor.getReliability();
|
|
expect(reliability).toBeGreaterThanOrEqual(0);
|
|
expect(reliability).toBeLessThanOrEqual(100);
|
|
});
|
|
|
|
it('should return 1 for perfect reliability', () => {
|
|
for (let i = 0; i < 10; i++) {
|
|
monitor.recordSuccess(100);
|
|
}
|
|
|
|
expect(monitor.getReliability()).toBe(100);
|
|
});
|
|
|
|
it('should return 0 for complete failure', () => {
|
|
for (let i = 0; i < 10; i++) {
|
|
monitor.recordFailure(new Error('Test'));
|
|
}
|
|
|
|
expect(monitor.getReliability()).toBe(0);
|
|
});
|
|
});
|
|
|
|
describe('performHealthCheck', () => {
|
|
it('should return health check result', async () => {
|
|
const result = await monitor.performHealthCheck();
|
|
expect(result).toHaveProperty('timestamp');
|
|
expect(result).toHaveProperty('healthy');
|
|
expect(result).toHaveProperty('responseTime');
|
|
});
|
|
});
|
|
});
|