import { describe, expect, test } from 'bun:test'; import { auditUnconfiguredModules } from './unconfigured-modules'; describe('auditUnconfiguredModules', () => { test('flags IMPORTED module with zero config rows', async () => { const result = await auditUnconfiguredModules({ modules: [{ id: 'authentik', state: 'IMPORTED', configCount: 0 }], }); expect(result).toHaveLength(1); expect(result[0]).toMatchObject({ category: 'unconfigured_modules', severity: 'todo', code: 'module_unconfigured', actionable: false, subject: 'authentik', }); expect(result[0].details).toContain('celilo module config get authentik'); }); test('skips module with at least one config row', async () => { const result = await auditUnconfiguredModules({ modules: [{ id: 'authentik', state: 'IMPORTED', configCount: 3 }], }); expect(result).toEqual([]); }); test('skips deployed modules even with zero config rows', async () => { const result = await auditUnconfiguredModules({ modules: [ { id: 'caddy', state: 'INSTALLED', configCount: 0 }, { id: 'iptables', state: 'VERIFIED', configCount: 0 }, ], }); expect(result).toEqual([]); }); test('mixed report — only flags qualifying modules', async () => { const result = await auditUnconfiguredModules({ modules: [ { id: 'caddy', state: 'INSTALLED', configCount: 0 }, // skip — deployed { id: 'authentik', state: 'IMPORTED', configCount: 0 }, // flag { id: 'iptables', state: 'IMPORTED', configCount: 5 }, // skip — has configs { id: 'lunacycle', state: 'VALIDATED', configCount: 0 }, // flag ], }); expect(result.map((f) => f.subject).sort()).toEqual(['authentik', 'lunacycle']); }); });