diff --git a/src/commands/status-all/channels.mattermost-token-summary.test.ts b/src/commands/status-all/channels.mattermost-token-summary.test.ts index c36bacca74f..57c5cc71627 100644 --- a/src/commands/status-all/channels.mattermost-token-summary.test.ts +++ b/src/commands/status-all/channels.mattermost-token-summary.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, vi } from "vitest"; -import { listChannelPlugins } from "../../channels/plugins/index.js"; import type { ChannelPlugin } from "../../channels/plugins/types.js"; +import { listChannelPlugins } from "../../channels/plugins/index.js"; import { buildChannelsTable } from "./channels.js"; vi.mock("../../channels/plugins/index.js", () => ({ @@ -35,6 +35,61 @@ function makeMattermostPlugin(): ChannelPlugin { }; } +function makeSlackPlugin(params?: { botToken?: string; appToken?: string }): ChannelPlugin { + return { + id: "slack", + meta: { + id: "slack", + label: "Slack", + selectionLabel: "Slack", + docsPath: "/channels/slack", + blurb: "test", + }, + config: { + listAccountIds: () => ["primary"], + defaultAccountId: () => "primary", + resolveAccount: () => ({ + name: "Primary", + enabled: true, + botToken: params?.botToken ?? "bot-token", + appToken: params?.appToken ?? "app-token", + }), + isConfigured: () => true, + isEnabled: () => true, + }, + actions: { + listActions: () => ["send"], + }, + }; +} + +function makeTokenPlugin(): ChannelPlugin { + return { + id: "token-only", + meta: { + id: "token-only", + label: "TokenOnly", + selectionLabel: "TokenOnly", + docsPath: "/channels/token-only", + blurb: "test", + }, + config: { + listAccountIds: () => ["primary"], + defaultAccountId: () => "primary", + resolveAccount: () => ({ + name: "Primary", + enabled: true, + token: "token-value", + }), + isConfigured: () => true, + isEnabled: () => true, + }, + actions: { + listActions: () => ["send"], + }, + }; +} + describe("buildChannelsTable - mattermost token summary", () => { it("does not require appToken for mattermost accounts", async () => { vi.mocked(listChannelPlugins).mockReturnValue([makeMattermostPlugin()]); @@ -48,4 +103,32 @@ describe("buildChannelsTable - mattermost token summary", () => { expect(mattermostRow?.state).toBe("ok"); expect(mattermostRow?.detail).not.toContain("need bot+app"); }); + + it("keeps bot+app requirement when both fields exist", async () => { + vi.mocked(listChannelPlugins).mockReturnValue([ + makeSlackPlugin({ botToken: "bot-token", appToken: "" }), + ]); + + const table = await buildChannelsTable({ channels: {} } as never, { + showSecrets: false, + }); + + const slackRow = table.rows.find((row) => row.id === "slack"); + expect(slackRow).toBeDefined(); + expect(slackRow?.state).toBe("warn"); + expect(slackRow?.detail).toContain("need bot+app"); + }); + + it("still reports single-token channels as ok", async () => { + vi.mocked(listChannelPlugins).mockReturnValue([makeTokenPlugin()]); + + const table = await buildChannelsTable({ channels: {} } as never, { + showSecrets: false, + }); + + const tokenRow = table.rows.find((row) => row.id === "token-only"); + expect(tokenRow).toBeDefined(); + expect(tokenRow?.state).toBe("ok"); + expect(tokenRow?.detail).toContain("token"); + }); });