bytelyst-devops-tools/dashboard/backend/src/lib/dashboard-alerts.test.ts

45 lines
1.8 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from 'vitest';
const appendFileMock = vi.hoisted(() => vi.fn());
vi.mock('fs/promises', () => ({ appendFile: appendFileMock }));
const { appendDashboardWarning, clearDashboardWarningDedupe } = await import('./dashboard-alerts.js');
describe('dashboard-alerts', () => {
beforeEach(() => {
vi.clearAllMocks();
clearDashboardWarningDedupe();
delete process.env.HERMES_DASHBOARD_ALERT_LOG;
});
it('does nothing when the alert log is not configured', async () => {
const wrote = await appendDashboardWarning({ severity: 'warn', instance: 'vijay', message: 'gateway down' });
expect(wrote).toBe(false);
expect(appendFileMock).not.toHaveBeenCalled();
});
it('writes a routed warning line when configured', async () => {
process.env.HERMES_DASHBOARD_ALERT_LOG = '/tmp/hermes-dashboard-warnings.log';
const wrote = await appendDashboardWarning(
{ severity: 'critical', instance: 'bheem', message: 'backup missing' },
Date.parse('2026-05-31T07:00:00Z'),
);
expect(wrote).toBe(true);
expect(appendFileMock).toHaveBeenCalledWith(
'/tmp/hermes-dashboard-warnings.log',
'2026-05-31T07:00:00.000Z CRITICAL instance=bheem backup missing\n',
'utf8',
);
});
it('deduplicates for one hour and writes again after expiry', async () => {
process.env.HERMES_DASHBOARD_ALERT_LOG = '/tmp/hermes-dashboard-warnings.log';
const input = { severity: 'warn' as const, instance: 'all' as const, message: 'shared warning' };
expect(await appendDashboardWarning(input, 1_000)).toBe(true);
expect(await appendDashboardWarning(input, 2_000)).toBe(false);
expect(await appendDashboardWarning(input, 3_602_000)).toBe(true);
expect(appendFileMock).toHaveBeenCalledTimes(2);
});
});