fix(status): avoid bot+app token warning for mattermost

This commit is contained in:
Echo
2026-02-16 15:08:11 -05:00
committed by Peter Steinberger
parent 82861968c2
commit 1dfacd4dd1
2 changed files with 79 additions and 3 deletions

View File

@@ -0,0 +1,51 @@
import { describe, expect, it, vi } from "vitest";
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", () => ({
listChannelPlugins: vi.fn(),
}));
function makeMattermostPlugin(): ChannelPlugin {
return {
id: "mattermost",
meta: {
id: "mattermost",
label: "Mattermost",
selectionLabel: "Mattermost",
docsPath: "/channels/mattermost",
blurb: "test",
},
config: {
listAccountIds: () => ["echo"],
defaultAccountId: () => "echo",
resolveAccount: () => ({
name: "Echo",
enabled: true,
botToken: "bot-token-value",
baseUrl: "https://mm.example.com",
}),
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()]);
const table = await buildChannelsTable({ channels: {} } as never, {
showSecrets: false,
});
const mattermostRow = table.rows.find((row) => row.id === "mattermost");
expect(mattermostRow).toBeDefined();
expect(mattermostRow?.state).toBe("ok");
expect(mattermostRow?.detail).not.toContain("need bot+app");
});
});

View File

@@ -211,14 +211,15 @@ function summarizeTokenConfig(params: {
}
const accountRecs = enabled.map((a) => asRecord(a.account));
const hasBotOrAppTokenFields = accountRecs.some((r) => "botToken" in r || "appToken" in r);
const hasBotTokenField = accountRecs.some((r) => "botToken" in r);
const hasAppTokenField = accountRecs.some((r) => "appToken" in r);
const hasTokenField = accountRecs.some((r) => "token" in r);
if (!hasBotOrAppTokenFields && !hasTokenField) {
if (!hasBotTokenField && !hasAppTokenField && !hasTokenField) {
return { state: null, detail: null };
}
if (hasBotOrAppTokenFields) {
if (hasBotTokenField && hasAppTokenField) {
const ready = enabled.filter((a) => {
const rec = asRecord(a.account);
const bot = typeof rec.botToken === "string" ? rec.botToken.trim() : "";
@@ -265,6 +266,30 @@ function summarizeTokenConfig(params: {
};
}
if (hasBotTokenField) {
const ready = enabled.filter((a) => {
const rec = asRecord(a.account);
const bot = typeof rec.botToken === "string" ? rec.botToken.trim() : "";
return Boolean(bot);
});
if (ready.length === 0) {
return { state: "setup", detail: "no bot token" };
}
const sample = ready[0]?.account ? asRecord(ready[0].account) : {};
const botToken = typeof sample.botToken === "string" ? sample.botToken : "";
const botHint = botToken.trim()
? formatTokenHint(botToken, { showSecrets: params.showSecrets })
: "";
const hint = botHint ? ` (${botHint})` : "";
return {
state: "ok",
detail: `bot token config${hint} · accounts ${ready.length}/${enabled.length || 1}`,
};
}
const ready = enabled.filter((a) => {
const rec = asRecord(a.account);
return typeof rec.token === "string" ? Boolean(rec.token.trim()) : false;