clawdie-ai/setup/agent-cli-check.test.ts
Clawdie AI aba4886ed8 test: add agent-cli-check and identity-restore tests
27 new tests: detectAgentClis/requireAtLeastOneAgentCli/NoAgentCliError
with mocked commandExists, plus identity-restore run() covering all
skip conditions (missing .env, no Supabase config, fetch errors) and
happy path (canonical + legacy paths, no-overwrite guard, blank file
overwrite, header verification, quoted .env values).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---
Build: FAIL | Tests: pass — Tests  1390 passed (1390)
2026-04-15 05:14:52 +00:00

151 lines
5.1 KiB
TypeScript

/**
* setup/agent-cli-check.test.ts — agent CLI detection tests.
*
* Tests AGENT_CLIS, detectAgentClis(), NoAgentCliError, and
* requireAtLeastOneAgentCli() with mocked commandExists.
*
* Run with: npx vitest run setup/agent-cli-check.test.ts
*/
import { describe, it, expect, vi, beforeEach } from 'vitest';
// ---------------------------------------------------------------------------
// Mock commandExists from platform.js
// ---------------------------------------------------------------------------
const platformMock = vi.hoisted(() => ({
commandExists: vi.fn<[string], boolean>(() => false),
}));
vi.mock('./platform.js', () => platformMock);
import {
AGENT_CLIS,
detectAgentClis,
NoAgentCliError,
requireAtLeastOneAgentCli,
} from './agent-cli-check.js';
// ---------------------------------------------------------------------------
// AGENT_CLIS
// ---------------------------------------------------------------------------
describe('AGENT_CLIS', () => {
it('contains pi, aider, claude, codex, gemini', () => {
const commands = AGENT_CLIS.map((c) => c.command);
expect(commands).toContain('pi');
expect(commands).toContain('aider');
expect(commands).toContain('claude');
expect(commands).toContain('codex');
expect(commands).toContain('gemini');
});
it('each entry has name and command fields', () => {
for (const cli of AGENT_CLIS) {
expect(typeof cli.name).toBe('string');
expect(typeof cli.command).toBe('string');
}
});
});
// ---------------------------------------------------------------------------
// detectAgentClis
// ---------------------------------------------------------------------------
describe('detectAgentClis', () => {
beforeEach(() => {
platformMock.commandExists.mockReset().mockReturnValue(false);
});
it('returns one entry per AGENT_CLIS entry', () => {
const result = detectAgentClis();
expect(result).toHaveLength(AGENT_CLIS.length);
});
it('marks all as not present when commandExists returns false', () => {
const result = detectAgentClis();
expect(result.every((c) => !c.present)).toBe(true);
});
it('marks all as present when commandExists returns true', () => {
platformMock.commandExists.mockReturnValue(true);
const result = detectAgentClis();
expect(result.every((c) => c.present)).toBe(true);
});
it('marks only "pi" as present when only pi is available', () => {
platformMock.commandExists.mockImplementation((cmd) => cmd === 'pi');
const result = detectAgentClis();
const piEntry = result.find((c) => c.command === 'pi');
const aiderEntry = result.find((c) => c.command === 'aider');
expect(piEntry?.present).toBe(true);
expect(aiderEntry?.present).toBe(false);
});
it('passes the command string to commandExists', () => {
detectAgentClis();
const calledCommands = platformMock.commandExists.mock.calls.map((c) => c[0]);
expect(calledCommands).toContain('pi');
expect(calledCommands).toContain('aider');
});
it('returned entries include name and command from AGENT_CLIS', () => {
const result = detectAgentClis();
for (let i = 0; i < AGENT_CLIS.length; i++) {
expect(result[i].name).toBe(AGENT_CLIS[i].name);
expect(result[i].command).toBe(AGENT_CLIS[i].command);
}
});
});
// ---------------------------------------------------------------------------
// NoAgentCliError
// ---------------------------------------------------------------------------
describe('NoAgentCliError', () => {
it('is an instance of Error', () => {
expect(new NoAgentCliError()).toBeInstanceOf(Error);
});
it('has name "NoAgentCliError"', () => {
expect(new NoAgentCliError().name).toBe('NoAgentCliError');
});
it('message mentions agent CLI and install guidance', () => {
const msg = new NoAgentCliError().message;
expect(msg).toContain('No agent CLI found');
expect(msg.toLowerCase()).toContain('pi');
expect(msg.toLowerCase()).toContain('aider');
});
});
// ---------------------------------------------------------------------------
// requireAtLeastOneAgentCli
// ---------------------------------------------------------------------------
describe('requireAtLeastOneAgentCli', () => {
beforeEach(() => {
platformMock.commandExists.mockReset().mockReturnValue(false);
});
it('throws NoAgentCliError when no CLI is present', () => {
expect(() => requireAtLeastOneAgentCli()).toThrow(NoAgentCliError);
});
it('does not throw when at least one CLI is present', () => {
platformMock.commandExists.mockImplementation((cmd) => cmd === 'claude');
expect(() => requireAtLeastOneAgentCli()).not.toThrow();
});
it('returns the full list of CLIs', () => {
platformMock.commandExists.mockReturnValue(true);
const result = requireAtLeastOneAgentCli();
expect(result).toHaveLength(AGENT_CLIS.length);
});
it('returned list includes present=true for available CLIs', () => {
platformMock.commandExists.mockImplementation((cmd) => cmd === 'aider');
const result = requireAtLeastOneAgentCli();
const aider = result.find((c) => c.command === 'aider');
expect(aider?.present).toBe(true);
});
});