import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime"; import { describe, expect, it } from "vitest"; import type { ResolvedTelegramAccount } from "./accounts.js"; import { createTelegramPluginBase } from "./shared.js"; const telegramPluginBase = createTelegramPluginBase({ setupWizard: {} as never, setup: {} as never, }); function createCfg(): OpenClawConfig { return { channels: { telegram: { enabled: true, accounts: { alerts: { botToken: "token-shared" }, work: { botToken: "token-shared" }, ops: { botToken: "token-ops" }, }, }, }, } as OpenClawConfig; } function resolveAccount(cfg: OpenClawConfig, accountId: string): ResolvedTelegramAccount { return telegramPluginBase.config.resolveAccount(cfg, accountId) as ResolvedTelegramAccount; } describe("createTelegramPluginBase config duplicate token guard", () => { it("marks secondary account as not configured when token is shared", async () => { const cfg = createCfg(); const alertsAccount = resolveAccount(cfg, "alerts"); const workAccount = resolveAccount(cfg, "work"); const opsAccount = resolveAccount(cfg, "ops"); expect(await telegramPluginBase.config.isConfigured!(alertsAccount, cfg)).toBe(true); expect(await telegramPluginBase.config.isConfigured!(workAccount, cfg)).toBe(false); expect(await telegramPluginBase.config.isConfigured!(opsAccount, cfg)).toBe(true); expect(telegramPluginBase.config.unconfiguredReason?.(workAccount, cfg)).toContain( 'account "alerts"', ); }); it("ignores accounts with missing tokens during duplicate-token checks", async () => { const cfg = createCfg(); cfg.channels!.telegram!.accounts!.ops = {} as never; const alertsAccount = resolveAccount(cfg, "alerts"); expect(await telegramPluginBase.config.isConfigured!(alertsAccount, cfg)).toBe(true); }); it("reports configured for single-bot setup with channel-level token", async () => { const cfg = { channels: { telegram: { botToken: "single-bot-token", enabled: true, }, }, } as OpenClawConfig; const account = resolveAccount(cfg, "default"); expect(await telegramPluginBase.config.isConfigured!(account, cfg)).toBe(true); }); it("reports configured for binding-created accountId in single-bot setup", async () => { const cfg = { channels: { telegram: { botToken: "single-bot-token", enabled: true, }, }, } as OpenClawConfig; const account = resolveAccount(cfg, "bot-main"); expect(account.token).toBe("single-bot-token"); expect(await telegramPluginBase.config.isConfigured!(account, cfg)).toBe(true); }); it("reports not configured for unknown binding-created accountId in multi-bot setup", async () => { const cfg = { channels: { telegram: { botToken: "channel-level-token", enabled: true, accounts: { knownBot: { botToken: "known-bot-token" }, }, }, }, } as OpenClawConfig; const account = resolveAccount(cfg, "unknownBot"); expect(await telegramPluginBase.config.isConfigured!(account, cfg)).toBe(false); expect(telegramPluginBase.config.unconfiguredReason?.(account, cfg)).toContain( "unknown accountId", ); }); it("normalizes account keys with spaces and mixed case", async () => { const cfg = { channels: { telegram: { botToken: "channel-level-token", enabled: true, accounts: { "Carey Notifications": { botToken: "carey-token" }, }, }, }, } as OpenClawConfig; const account = resolveAccount(cfg, "carey-notifications"); expect(await telegramPluginBase.config.isConfigured!(account, cfg)).toBe(true); }); it("reports not configured when token is configured_unavailable", async () => { const cfg = { channels: { telegram: { tokenFile: "/nonexistent/path/to/token", enabled: true, }, }, } as OpenClawConfig; const account = resolveAccount(cfg, "default"); expect(await telegramPluginBase.config.isConfigured!(account, cfg)).toBe(false); expect(telegramPluginBase.config.unconfiguredReason?.(account, cfg)).toContain("unavailable"); }); });