From 7620616c7c1563e2a76ef04dc29605369640b492 Mon Sep 17 00:00:00 2001 From: William Valentin Date: Tue, 10 Feb 2026 09:38:53 -0800 Subject: [PATCH] test(setup): add integration tests and update shell completion Adds comprehensive integration tests for the first-run wizard verifying config generation for different provider/channel combinations. Updates shell completion to include the 'setup' command with its options. Co-Authored-By: Claude Opus 4.6 --- src/cli/completion.ts | 3 +- src/cli/setup/integration.test.ts | 66 +++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 src/cli/setup/integration.test.ts diff --git a/src/cli/completion.ts b/src/cli/completion.ts index 7ab349c..8043a5e 100644 --- a/src/cli/completion.ts +++ b/src/cli/completion.ts @@ -3,13 +3,14 @@ import { mkdirSync, writeFileSync } from 'fs'; import { resolve } from 'path'; import { homedir } from 'os'; -const SUBCOMMANDS = ['start', 'tui', 'send', 'sessions', 'doctor', 'config', 'completion']; +const SUBCOMMANDS = ['start', 'tui', 'send', 'sessions', 'doctor', 'config', 'setup', 'completion']; const SUBCOMMAND_OPTIONS: Record = { start: ['-c', '--config'], tui: ['-c', '--config', '-f', '--fullscreen'], send: ['-c', '--config', '--no-tools'], config: ['-c', '--config', '--raw'], + setup: ['-c', '--config'], completion: ['--install'], }; diff --git a/src/cli/setup/integration.test.ts b/src/cli/setup/integration.test.ts new file mode 100644 index 0000000..9f55474 --- /dev/null +++ b/src/cli/setup/integration.test.ts @@ -0,0 +1,66 @@ +import { describe, it, expect, vi } from 'vitest'; +import type { Interface as ReadlineInterface } from 'readline/promises'; +import { createPrompter } from './prompts.js'; +import { runFirstRunWizard } from './orchestrator.js'; +import { parse } from 'yaml'; + +function mockReadline(inputs: string[]): ReadlineInterface { + let idx = 0; + return { + question: vi.fn(async () => { + if (idx < inputs.length) { + return inputs[idx++]; + } + throw new Error('No more inputs'); + }), + close: vi.fn(), + } as any as ReadlineInterface; +} + +describe('first-run wizard integration', () => { + it('produces valid config with anthropic + webchat only', async () => { + const rl = mockReadline([ + '1', // choose: Anthropic + 'sk-ant-key', // password: API key + '', // ask: Model (default) + 'n', // confirm: Configure a fast tier? (no) + '', // ask: Gateway port (default) + 'n', // confirm: Add a messaging channel? (no) + ]); + const p = createPrompter(rl); + + const builder = await runFirstRunWizard(p); + const config = builder.build(); + const yaml = builder.toYaml(); + + expect(config.models.default.provider).toBe('anthropic'); + expect(config.models.default.api_key).toBe('sk-ant-key'); + expect(config.server.port).toBeDefined(); + + const reparsed = parse(yaml); + expect(reparsed.models.default.provider).toBe('anthropic'); + }); + + it('produces valid config with ollama + telegram', async () => { + const rl = mockReadline([ + '3', // choose: Ollama + '', // ask: Host (default) + '', // ask: Model (default) + 'n', // confirm: Configure a fast tier? (no) + '', // ask: Gateway port (default) + 'y', // confirm: Add a messaging channel? (yes) + '1', // choose: Telegram + '123:ABCdef', // password: Bot token + '12345678', // ask: Allowed chat IDs + 'n', // confirm: Add another channel? (no) + ]); + const p = createPrompter(rl); + + const builder = await runFirstRunWizard(p); + const config = builder.build(); + + expect(config.models.default.provider).toBe('ollama'); + expect(config.telegram.bot_token).toBe('123:ABCdef'); + expect(config.telegram.allowed_chat_ids).toEqual([12345678]); + }); +});