/** * Unit tests for src/services/ComplianceStatusStore.ts * * Uses jest.isolateModules to reset module-level state between test groups * since the store is a module-level Map singleton. */ describe('ComplianceStatusStore', () => { // Re-import the module fresh for each describe block to reset state let updateControlStatus: (id: string, status: string) => void; let getAllControlStatuses: () => unknown[]; let getControlStatus: (id: string) => unknown; beforeEach(() => { jest.resetModules(); // eslint-disable-next-line @typescript-eslint/no-var-requires const store = require('../../../src/services/ComplianceStatusStore'); updateControlStatus = store.updateControlStatus; getAllControlStatuses = store.getAllControlStatuses; getControlStatus = store.getControlStatus; }); describe('getAllControlStatuses()', () => { it('should return 5 controls on fresh module load', () => { const statuses = getAllControlStatuses(); expect(statuses).toHaveLength(5); }); it('should default all controls to unknown status', () => { const statuses = getAllControlStatuses() as Array<{ status: string }>; expect(statuses.every((s) => s.status === 'unknown')).toBe(true); }); it('should return controls in canonical order', () => { const statuses = getAllControlStatuses() as Array<{ id: string }>; const ids = statuses.map((s) => s.id); expect(ids).toEqual(['CC6.1', 'CC6.7', 'CC7.2', 'CC9.2', 'CC7.1']); }); it('should include name and lastChecked fields on each control', () => { const statuses = getAllControlStatuses() as Array<{ id: string; name: string; lastChecked: string }>; for (const s of statuses) { expect(typeof s.name).toBe('string'); expect(s.name.length).toBeGreaterThan(0); expect(typeof s.lastChecked).toBe('string'); expect(() => new Date(s.lastChecked)).not.toThrow(); } }); it('should map CC6.1 to Encryption at Rest', () => { const statuses = getAllControlStatuses() as Array<{ id: string; name: string }>; const cc61 = statuses.find((s) => s.id === 'CC6.1'); expect(cc61?.name).toBe('Encryption at Rest'); }); }); describe('updateControlStatus()', () => { it('should update a control to passing', () => { updateControlStatus('CC6.1', 'passing'); const status = getControlStatus('CC6.1') as { status: string }; expect(status.status).toBe('passing'); }); it('should update a control to failing', () => { updateControlStatus('CC7.2', 'failing'); const status = getControlStatus('CC7.2') as { status: string }; expect(status.status).toBe('failing'); }); it('should overwrite a previous status', () => { updateControlStatus('CC9.2', 'passing'); updateControlStatus('CC9.2', 'failing'); const status = getControlStatus('CC9.2') as { status: string }; expect(status.status).toBe('failing'); }); it('should update lastChecked timestamp on each update', async () => { const before = Date.now(); updateControlStatus('CC7.1', 'passing'); const status = getControlStatus('CC7.1') as { lastChecked: string }; const after = new Date(status.lastChecked).getTime(); expect(after).toBeGreaterThanOrEqual(before); }); it('should not affect other controls when one is updated', () => { updateControlStatus('CC6.1', 'passing'); const all = getAllControlStatuses() as Array<{ id: string; status: string }>; const others = all.filter((s) => s.id !== 'CC6.1'); expect(others.every((s) => s.status === 'unknown')).toBe(true); }); }); describe('getControlStatus()', () => { it('should return the correct control record', () => { updateControlStatus('CC6.7', 'passing'); const status = getControlStatus('CC6.7') as { id: string; name: string; status: string }; expect(status.id).toBe('CC6.7'); expect(status.name).toBe('TLS Enforcement'); expect(status.status).toBe('passing'); }); }); });