Files
gridpilot.gg/apps/website/lib/gateways/api/base/ApiConnectionMonitor.test.ts
2026-01-24 12:44:57 +01:00

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');
});
});
});