From e19e94ef072f37fb7ca7a041ec0a764442af673c Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 17 Apr 2026 07:36:37 +0100 Subject: [PATCH] test: split channels list auth profile coverage --- ....adds-non-default-telegram-account.test.ts | 56 +------------- .../channels.list.auth-profiles.test.ts | 76 +++++++++++++++++++ src/commands/channels.mock-harness.ts | 30 +++++--- 3 files changed, 100 insertions(+), 62 deletions(-) create mode 100644 src/commands/channels.list.auth-profiles.test.ts diff --git a/src/commands/channels.adds-non-default-telegram-account.test.ts b/src/commands/channels.adds-non-default-telegram-account.test.ts index 223390579ed..b05cd550837 100644 --- a/src/commands/channels.adds-non-default-telegram-account.test.ts +++ b/src/commands/channels.adds-non-default-telegram-account.test.ts @@ -6,21 +6,11 @@ import { createScopedChannelConfigAdapter } from "../plugin-sdk/channel-config-h import { setActivePluginRegistry } from "../plugins/runtime.js"; import { DEFAULT_ACCOUNT_ID, normalizeAccountId } from "../routing/session-key.js"; import { createChannelTestPluginBase, createTestRegistry } from "../test-utils/channel-plugins.js"; -import { configMocks, offsetMocks } from "./channels.mock-harness.js"; -import { baseConfigSnapshot, createTestRuntime } from "./test-runtime-config-helpers.js"; - -const authMocks = vi.hoisted(() => ({ - loadAuthProfileStore: vi.fn(), -})); - -vi.mock("../agents/auth-profiles.js", () => ({ - loadAuthProfileStore: authMocks.loadAuthProfileStore, -})); - +import { configMocks, offsetMocks, secretMocks } from "./channels.mock-harness.js"; import { channelsAddCommand } from "./channels/add.js"; -import { channelsListCommand } from "./channels/list.js"; import { channelsRemoveCommand } from "./channels/remove.js"; import { formatGatewayChannelsStatusLines } from "./channels/status.js"; +import { baseConfigSnapshot, createTestRuntime } from "./test-runtime-config-helpers.js"; const runtime = createTestRuntime(); let clackPrompterModule: typeof import("../wizard/clack-prompter.js"); @@ -307,15 +297,11 @@ describe("channels command", () => { beforeEach(() => { configMocks.readConfigFileSnapshot.mockClear(); configMocks.writeConfigFile.mockClear(); - authMocks.loadAuthProfileStore.mockClear(); + secretMocks.resolveCommandConfigWithSecrets.mockClear(); offsetMocks.deleteTelegramUpdateOffset.mockClear(); runtime.log.mockClear(); runtime.error.mockClear(); runtime.exit.mockClear(); - authMocks.loadAuthProfileStore.mockReturnValue({ - version: 1, - profiles: {}, - }); setMinimalChannelsCommandRegistryForTests(); }); @@ -563,42 +549,6 @@ describe("channels command", () => { expect(next.channels?.discord?.enabled).toBe(false); }); - it("includes external auth profiles in JSON output", async () => { - configMocks.readConfigFileSnapshot.mockResolvedValue({ - ...baseConfigSnapshot, - config: {}, - }); - authMocks.loadAuthProfileStore.mockReturnValue({ - version: 1, - profiles: { - "anthropic:default": { - type: "oauth", - provider: "anthropic", - access: "token", - refresh: "refresh", - expires: 0, - created: 0, - }, - "openai-codex:default": { - type: "oauth", - provider: "openai", - access: "token", - refresh: "refresh", - expires: 0, - created: 0, - }, - }, - }); - - await channelsListCommand({ json: true, usage: false }, runtime); - const payload = JSON.parse(runtime.log.mock.calls[0]?.[0] as string) as { - auth?: Array<{ id: string }>; - }; - const ids = payload.auth?.map((entry) => entry.id) ?? []; - expect(ids).toContain("anthropic:default"); - expect(ids).toContain("openai-codex:default"); - }); - it("stores default account names in accounts when multiple accounts exist", async () => { configMocks.readConfigFileSnapshot.mockResolvedValue({ ...baseConfigSnapshot, diff --git a/src/commands/channels.list.auth-profiles.test.ts b/src/commands/channels.list.auth-profiles.test.ts new file mode 100644 index 00000000000..a1e5e72a7b1 --- /dev/null +++ b/src/commands/channels.list.auth-profiles.test.ts @@ -0,0 +1,76 @@ +import { describe, expect, it, vi } from "vitest"; +import { baseConfigSnapshot, createTestRuntime } from "./test-runtime-config-helpers.js"; + +const mocks = vi.hoisted(() => ({ + readConfigFileSnapshot: vi.fn(), + resolveCommandConfigWithSecrets: vi.fn(async ({ config }: { config: unknown }) => ({ + resolvedConfig: config, + effectiveConfig: config, + diagnostics: [], + })), + loadAuthProfileStore: vi.fn(), + listChannelPlugins: vi.fn(() => []), +})); + +vi.mock("../config/config.js", () => ({ + readConfigFileSnapshot: mocks.readConfigFileSnapshot, +})); + +vi.mock("../cli/command-config-resolution.js", () => ({ + resolveCommandConfigWithSecrets: mocks.resolveCommandConfigWithSecrets, +})); + +vi.mock("../cli/command-secret-targets.js", () => ({ + getChannelsCommandSecretTargetIds: () => new Set(), +})); + +vi.mock("../agents/auth-profiles.js", () => ({ + loadAuthProfileStore: mocks.loadAuthProfileStore, +})); + +vi.mock("../channels/plugins/index.js", () => ({ + listChannelPlugins: mocks.listChannelPlugins, +})); + +import { channelsListCommand } from "./channels/list.js"; + +describe("channels list auth profiles", () => { + it("includes external auth profiles in JSON output", async () => { + const runtime = createTestRuntime(); + mocks.readConfigFileSnapshot.mockResolvedValue({ + ...baseConfigSnapshot, + config: {}, + }); + mocks.loadAuthProfileStore.mockReturnValue({ + version: 1, + profiles: { + "anthropic:default": { + type: "oauth", + provider: "anthropic", + access: "token", + refresh: "refresh", + expires: 0, + created: 0, + }, + "openai-codex:default": { + type: "oauth", + provider: "openai", + access: "token", + refresh: "refresh", + expires: 0, + created: 0, + }, + }, + }); + + await channelsListCommand({ json: true, usage: false }, runtime); + + expect(mocks.resolveCommandConfigWithSecrets).toHaveBeenCalledTimes(1); + const payload = JSON.parse(runtime.log.mock.calls[0]?.[0] as string) as { + auth?: Array<{ id: string }>; + }; + const ids = payload.auth?.map((entry) => entry.id) ?? []; + expect(ids).toContain("anthropic:default"); + expect(ids).toContain("openai-codex:default"); + }); +}); diff --git a/src/commands/channels.mock-harness.ts b/src/commands/channels.mock-harness.ts index 3c712a1a277..477048f6908 100644 --- a/src/commands/channels.mock-harness.ts +++ b/src/commands/channels.mock-harness.ts @@ -27,15 +27,27 @@ export const offsetMocks: { deleteTelegramUpdateOffset: vi.fn().mockResolvedValue(undefined) as unknown as MockFn, }; -vi.mock("../config/config.js", async () => { - const actual = await vi.importActual("../config/config.js"); - return { - ...actual, - readConfigFileSnapshot: configMocks.readConfigFileSnapshot, - writeConfigFile: configMocks.writeConfigFile, - replaceConfigFile: configMocks.replaceConfigFile, - }; -}); +export const secretMocks = { + resolveCommandConfigWithSecrets: vi.fn(async ({ config }: { config: unknown }) => ({ + resolvedConfig: config, + effectiveConfig: config, + diagnostics: [], + })) as unknown as MockFn, +}; + +vi.mock("../config/config.js", () => ({ + readConfigFileSnapshot: configMocks.readConfigFileSnapshot, + writeConfigFile: configMocks.writeConfigFile, + replaceConfigFile: configMocks.replaceConfigFile, +})); + +vi.mock("../cli/command-config-resolution.js", () => ({ + resolveCommandConfigWithSecrets: secretMocks.resolveCommandConfigWithSecrets, +})); + +vi.mock("../cli/command-secret-targets.js", () => ({ + getChannelsCommandSecretTargetIds: () => new Set(), +})); vi.mock(buildBundledPluginModuleId("telegram", "update-offset-runtime-api.js"), async () => { const actual: Record = await vi.importActual(