import { describe, it, beforeEach, afterEach } from 'node:test'; import assert from 'node:assert'; import { GeminiHealthService } from './gemini.health.service.mjs'; describe('GeminiHealthService', () => { let service; let originalEnv; beforeEach(() => { // Sauvegarder l'environnement original originalEnv = { ...process.env }; service = new GeminiHealthService(); }); afterEach(() => { // Restaurer l'environnement process.env = originalEnv; }); describe('getStatus()', () => { it('should return NOT_CONFIGURED when GEMINI_API_KEY is missing', () => { delete process.env.GEMINI_API_KEY; const status = service.getStatus(); assert.strictEqual(status.status, 'NOT_CONFIGURED'); assert.strictEqual(status.details.reason, 'missing_key'); assert.strictEqual(status.details.httpCode, null); }); it('should return NOT_CONFIGURED when GEMINI_API_KEY is empty string', () => { process.env.GEMINI_API_KEY = ''; const status = service.getStatus(); assert.strictEqual(status.status, 'NOT_CONFIGURED'); assert.strictEqual(status.details.reason, 'missing_key'); }); it('should return NOT_CONFIGURED when GEMINI_API_KEY is only whitespace', () => { process.env.GEMINI_API_KEY = ' '; const status = service.getStatus(); assert.strictEqual(status.status, 'NOT_CONFIGURED'); assert.strictEqual(status.details.reason, 'missing_key'); }); it('should return CONFIGURED_UNVERIFIED when key is present but never tested', () => { process.env.GEMINI_API_KEY = 'test-key'; service.tested = false; const status = service.getStatus(); assert.strictEqual(status.status, 'CONFIGURED_UNVERIFIED'); assert.strictEqual(status.details.reason, 'not_tested'); assert.strictEqual(status.details.httpCode, null); }); it('should return cached status when already tested', () => { process.env.GEMINI_API_KEY = 'test-key'; service.tested = true; service.cache = { status: 'WORKING', lastCheckedAt: '2025-01-01T00:00:00.000Z', details: { reason: 'ok', httpCode: 200 } }; const status = service.getStatus(); assert.strictEqual(status.status, 'WORKING'); assert.strictEqual(status.details.reason, 'ok'); assert.strictEqual(status.details.httpCode, 200); }); }); describe('canRunTest()', () => { it('should allow test on first call', () => { const result = service.canRunTest('127.0.0.1'); assert.strictEqual(result.allowed, true); }); it('should block test if called too soon', () => { const clientIp = '127.0.0.1'; service.lastTestByIp.set(clientIp, Date.now()); const result = service.canRunTest(clientIp); assert.strictEqual(result.allowed, false); assert.strictEqual(result.reason, 'rate_limited'); assert.ok(result.waitSeconds > 0); }); it('should allow test after minimum interval', (t, done) => { const clientIp = '127.0.0.1'; // Simuler un test ancien (31 secondes) service.lastTestByIp.set(clientIp, Date.now() - 31000); const result = service.canRunTest(clientIp); assert.strictEqual(result.allowed, true); done(); }); }); describe('reset()', () => { it('should reset all state to initial values', () => { // Modifier l'état service.tested = true; service.cache = { status: 'WORKING', lastCheckedAt: '2025-01-01T00:00:00.000Z', details: { reason: 'ok', httpCode: 200 } }; service.lastTestByIp.set('127.0.0.1', Date.now()); // Reset service.reset(); // Vérifier assert.strictEqual(service.tested, false); assert.strictEqual(service.cache.status, 'CONFIGURED_UNVERIFIED'); assert.strictEqual(service.cache.lastCheckedAt, null); assert.strictEqual(service.cache.details.reason, 'not_tested'); assert.strictEqual(service.lastTestByIp.size, 0); }); }); describe('runLiveTest() - edge cases', () => { it('should return NOT_CONFIGURED if key is missing', async () => { delete process.env.GEMINI_API_KEY; const result = await service.runLiveTest('127.0.0.1'); assert.strictEqual(result.status, 'NOT_CONFIGURED'); assert.strictEqual(result.details.reason, 'missing_key'); assert.strictEqual(service.tested, false); }); it('should respect rate limiting', async () => { process.env.GEMINI_API_KEY = 'test-key'; service.lastTestByIp.set('127.0.0.1', Date.now()); service.cache = { status: 'WORKING', lastCheckedAt: '2025-01-01T00:00:00.000Z', details: { reason: 'ok', httpCode: 200 } }; const result = await service.runLiveTest('127.0.0.1'); assert.strictEqual(result.details.reason, 'rate_limited'); assert.ok(result.details.waitSeconds); }); }); });