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