import { beforeEach, describe, expect, it, vi } from "vitest"; import type { RuntimeEnv } from "../runtime.js"; const configMocks = vi.hoisted(() => ({ readConfigFileSnapshot: vi.fn(), writeConfigFile: vi.fn().mockResolvedValue(undefined), })); const authMocks = vi.hoisted(() => ({ loadAuthProfileStore: vi.fn(), })); vi.mock("../config/config.js", async (importOriginal) => { const actual = await importOriginal(); return { ...actual, readConfigFileSnapshot: configMocks.readConfigFileSnapshot, writeConfigFile: configMocks.writeConfigFile, }; }); vi.mock("../agents/auth-profiles.js", async (importOriginal) => { const actual = await importOriginal(); return { ...actual, loadAuthProfileStore: authMocks.loadAuthProfileStore, }; }); import { formatGatewayChannelsStatusLines } from "./channels.js"; const runtime: RuntimeEnv = { log: vi.fn(), error: vi.fn(), exit: vi.fn(), }; const _baseSnapshot = { path: "/tmp/clawdbot.json", exists: true, raw: "{}", parsed: {}, valid: true, config: {}, issues: [], legacyIssues: [], }; describe("channels command", () => { beforeEach(() => { configMocks.readConfigFileSnapshot.mockReset(); configMocks.writeConfigFile.mockClear(); authMocks.loadAuthProfileStore.mockReset(); runtime.log.mockClear(); runtime.error.mockClear(); runtime.exit.mockClear(); authMocks.loadAuthProfileStore.mockReturnValue({ version: 1, profiles: {}, }); }); it("surfaces Signal runtime errors in channels status output", () => { const lines = formatGatewayChannelsStatusLines({ channelAccounts: { signal: [ { accountId: "default", enabled: true, configured: true, running: false, lastError: "signal-cli unreachable", }, ], }, }); expect(lines.join("\n")).toMatch(/Warnings:/); expect(lines.join("\n")).toMatch(/signal/i); expect(lines.join("\n")).toMatch(/Channel error/i); }); it("surfaces iMessage runtime errors in channels status output", () => { const lines = formatGatewayChannelsStatusLines({ channelAccounts: { imessage: [ { accountId: "default", enabled: true, configured: true, running: false, lastError: "imsg permission denied", }, ], }, }); expect(lines.join("\n")).toMatch(/Warnings:/); expect(lines.join("\n")).toMatch(/imessage/i); expect(lines.join("\n")).toMatch(/Channel error/i); }); });