import { describe, it, expect } from 'vitest'; import { setupAutomation } from './automation.js'; import { ConfigBuilder } from './config.js'; import type { Prompter } from './prompts.js'; function makePrompter(answers: { confirms?: boolean[]; asks?: string[]; }): Prompter { const confirms = [...(answers.confirms ?? [])]; const asks = [...(answers.asks ?? [])]; return { ask: async (_question: string, defaultValue?: string) => { if (asks.length > 0) { return asks.shift() ?? ''; } return defaultValue ?? ''; }, confirm: async (_question: string, defaultYes?: boolean) => { if (confirms.length > 0) { return confirms.shift() ?? false; } return defaultYes ?? false; }, choose: async (_question: string, options: Array<{ value: T }>) => options[0].value, password: async () => '', println: () => {}, }; } describe('setupAutomation', () => { it('applies operator pack defaults when enabled', async () => { const builder = new ConfigBuilder(); builder.setTelegram('123:ABC', [987654321]); const p = makePrompter({ confirms: [ true, // enable operator pack true, // include minio sync false, // enable cron scheduler false, // enable webhook receiver false, // configure google services ], asks: [ 'telegram', // output channel '987654321', // output peer '0 3 * * *', // backup schedule '0 7 * * 1-5', // daily briefing schedule ], }); await setupAutomation(p, builder); const config = builder.build() as Record; const backup = config.backup as Record; const automation = config.automation as Record; const heartbeat = automation.heartbeat as Record; const briefing = automation.daily_briefing as Record; const minioSync = automation.minio_sync as Record; expect(backup.enabled).toBe(true); expect(backup.schedule).toBe('0 3 * * *'); expect(heartbeat.enabled).toBe(true); expect(heartbeat.notify_cooldown).toBe('30m'); expect((heartbeat.notify as Record).channel).toBe('telegram'); expect((heartbeat.notify as Record).peer).toBe('987654321'); expect(briefing.enabled).toBe(true); expect(briefing.schedule).toBe('0 7 * * 1-5'); expect(minioSync.enabled).toBe(true); }); it('allows overriding operator pack output routing', async () => { const builder = new ConfigBuilder(); const p = makePrompter({ confirms: [ true, // enable operator pack false, // include minio sync false, // enable cron scheduler false, // enable webhook receiver false, // configure google services ], asks: [ 'discord', // output channel 'ops-room', // output peer '0 4 * * *', // backup schedule '0 9 * * *', // daily briefing schedule ], }); await setupAutomation(p, builder); const config = builder.build() as Record; const backup = config.backup as Record; const automation = config.automation as Record; const heartbeat = automation.heartbeat as Record; const briefing = automation.daily_briefing as Record; expect((backup.notify as Record).channel).toBe('discord'); expect((backup.notify as Record).peer).toBe('ops-room'); expect((heartbeat.notify as Record).channel).toBe('discord'); expect((briefing.output as Record).peer).toBe('ops-room'); expect(automation.minio_sync).toBeUndefined(); }); it('leaves operator pack disabled when not selected', async () => { const builder = new ConfigBuilder(); const p = makePrompter({ confirms: [ false, // enable operator pack false, // enable cron scheduler false, // enable webhook receiver false, // configure google services ], }); await setupAutomation(p, builder); const config = builder.build() as Record; const backup = config.backup as Record | undefined; const automation = config.automation as Record | undefined; expect(backup).toBeUndefined(); expect(automation?.daily_briefing).toBeUndefined(); expect(automation?.heartbeat).toBeUndefined(); expect(automation?.minio_sync).toBeUndefined(); }); it('skips operator-pack reconfiguration prompts when already configured and not reconfigured', async () => { const builder = new ConfigBuilder(); builder.applyOperatorPack({ outputChannel: 'telegram', outputPeer: '123', backupSchedule: '0 2 * * *', dailyBriefingSchedule: '0 8 * * *', enableMinioSync: true, }); const p = makePrompter({ confirms: [ false, // reconfigure operator pack? false, // enable cron scheduler false, // enable webhook receiver false, // configure google services ], }); await setupAutomation(p, builder); const config = builder.build() as Record; const backup = config.backup as Record; const automation = config.automation as Record; const briefing = automation.daily_briefing as Record; expect(backup.schedule).toBe('0 2 * * *'); expect(briefing.schedule).toBe('0 8 * * *'); }); });