import { describe, expect, it } from 'vitest'; import { aggregateStatus, BACKUP_STALE_AFTER_SECONDS, backupPresentation, overviewTitle, STALE_AFTER_MS, statusProblems, type SystemStatus, type SystemStatusSnapshot } from '../../src/systemStatus'; const observedAt = Date.parse('2026-08-10T04:00:00Z'); function status(overrides: Partial = {}): SystemStatus { return { version: '1', generatedAt: new Date(observedAt).toISOString(), overallState: 'healthy', components: [], backup: { state: 'disabled', reason: 'not_configured' }, sourceLag: [], ...overrides, }; } function ready(value: SystemStatus): SystemStatusSnapshot { return { state: 'ready', status: value, fetchedAt: observedAt }; } describe('aggregateStatus ADR-0008 invariant', () => { it.each([ { state: 'loading', status: null, fetchedAt: 0 }, { state: 'error', status: null, fetchedAt: observedAt }, { state: 'unauthorized', status: null, fetchedAt: observedAt }, { state: 'forbidden', status: null, fetchedAt: observedAt }, ] satisfies SystemStatusSnapshot[])('maps $state without telemetry to Unknown', (snapshot) => { expect(aggregateStatus(snapshot, observedAt)).toMatchObject({ state: 'unknown', tone: 'unknown', stale: false }); }); it('allows healthy only for a fresh ready payload that explicitly says healthy', () => { expect(aggregateStatus(ready(status()), observedAt + 1_000)).toMatchObject({ state: 'healthy', tone: 'ready', stale: false }); }); it.each(['unknown', 'degraded', 'disabled'])('never maps %s to a ready tone', (overallState) => { expect(aggregateStatus(ready(status({ overallState })), observedAt + 1_000).tone).toBe('unknown'); }); it('expires a formerly healthy payload to Unknown', () => { expect(aggregateStatus(ready(status()), observedAt + STALE_AFTER_MS + 1)).toMatchObject({ state: 'unknown', tone: 'unknown', stale: true }); }); }); describe('statusProblems', () => { it('keeps non-healthy signals bounded and omits disabled components', () => { const value = status({ components: [ { id: 'database', state: 'healthy', reason: 'ok' }, { id: 'prometheus', state: 'unknown', reason: 'stale' }, { id: 'optional', state: 'disabled', reason: 'not_configured' }, ], sourceLag: Array.from({ length: 12 }, (_, index) => ({ sourceId: `source-${index}`, state: 'unknown', reason: 'missing' })), }); const problems = statusProblems(value); expect(problems).toHaveLength(10); expect(problems[0]).toEqual({ id: 'component:prometheus', label: 'Prometheus', reason: 'De laatste meting is verouderd; controleer de bronverbinding en collector.' }); expect(problems.some((problem) => problem.label === 'optional')).toBe(false); }); it('does not repeat a source that is already represented by its component', () => { const value = status({ components: [{ id: 'prometheus', state: 'unknown', reason: 'stale' }], sourceLag: [{ sourceId: 'prometheus', state: 'unknown', reason: 'stale' }], }); expect(statusProblems(value)).toEqual([{ id: 'component:prometheus', label: 'Prometheus', reason: 'De laatste meting is verouderd; controleer de bronverbinding en collector.' }]); }); it('keeps a disabled required source actionable while omitting optional disabled features', () => { const value = status({ components: [ { id: 'unraid', state: 'disabled', reason: 'not_configured' }, { id: 'notifications', state: 'disabled', reason: 'not_configured' }, ] }); expect(statusProblems(value)).toEqual([{ id: 'component:unraid', label: 'Unraid', reason: 'Dit onderdeel is nog niet geconfigureerd; open de instellingen om het te activeren.' }]); }); it('promotes an old allegedly healthy backup to an actionable problem', () => { const value = status({ backup: { state: 'healthy', reason: 'backup_verified', ageSeconds: BACKUP_STALE_AFTER_SECONDS + 1 } }); expect(statusProblems(value)).toEqual([{ id: 'backup', label: 'Backupstatus', reason: 'De laatste geverifieerde backup is verlopen; maak en verifieer een nieuwe backup.' }]); }); }); describe('backupPresentation', () => { it('allows healthy only while a verified backup is within the 24-hour boundary', () => { expect(backupPresentation({ state: 'healthy', reason: 'backup_verified', ageSeconds: 3600 })).toMatchObject({ state: 'healthy', reason: 'backup_verified' }); expect(backupPresentation({ state: 'healthy', reason: 'backup_verified', ageSeconds: BACKUP_STALE_AFTER_SECONDS + 1 })).toMatchObject({ state: 'degraded', reason: 'backup_stale' }); }); it('fails closed when a healthy claim has no age or timestamp', () => { expect(backupPresentation({ state: 'healthy', reason: 'backup_verified' })).toMatchObject({ state: 'unknown', reason: 'no_verified_backup' }); }); }); describe('overviewTitle', () => { it('reserves the optimistic title for a healthy issue-free snapshot', () => { const healthy = aggregateStatus(ready(status()), observedAt + 1_000); expect(overviewTitle(healthy, 0)).toBe('Alles onder controle'); expect(overviewTitle(healthy, 1)).toBe('Aandacht vereist'); expect(overviewTitle(healthy, 0, true)).toBe('Aandacht vereist'); }); it('uses a conservative title for unknown telemetry', () => { const unknown = aggregateStatus(ready(status({ overallState: 'unknown' })), observedAt + 1_000); expect(overviewTitle(unknown, 0)).toBe('Status nog niet bevestigd'); }); it('does not claim that no sources exist when an unknown status has live sources', () => { const unknown = aggregateStatus(ready(status({ overallState: 'unknown', sourceLag: [{ sourceId: 'unraid', state: 'healthy', reason: 'fresh' }] })), observedAt + 1_000); expect(unknown.detail).toContain('Databronnen zijn verbonden'); }); });