- Implemented multi-selection for notes with Ctrl+click, long-press, and keyboard shortcuts (Ctrl+A, Escape) - Added Gemini API integration with environment configuration and routes - Enhanced code block UI with improved copy feedback animation and visual polish - Added sort order toggle (asc/desc) for note lists with persistent state
154 lines
4.9 KiB
JavaScript
154 lines
4.9 KiB
JavaScript
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);
|
|
});
|
|
});
|
|
});
|