import { describe, it, expect, beforeEach, afterEach } from "vitest"; import { resolveLineAccount, listLineAccountIds, resolveDefaultLineAccountId, normalizeAccountId, DEFAULT_ACCOUNT_ID, } from "./accounts.js"; import type { ClawdbotConfig } from "../config/config.js"; describe("LINE accounts", () => { const originalEnv = { ...process.env }; beforeEach(() => { process.env = { ...originalEnv }; delete process.env.LINE_CHANNEL_ACCESS_TOKEN; delete process.env.LINE_CHANNEL_SECRET; }); afterEach(() => { process.env = originalEnv; }); describe("resolveLineAccount", () => { it("resolves account from config", () => { const cfg: ClawdbotConfig = { channels: { line: { enabled: true, channelAccessToken: "test-token", channelSecret: "test-secret", name: "Test Bot", }, }, }; const account = resolveLineAccount({ cfg }); expect(account.accountId).toBe(DEFAULT_ACCOUNT_ID); expect(account.enabled).toBe(true); expect(account.channelAccessToken).toBe("test-token"); expect(account.channelSecret).toBe("test-secret"); expect(account.name).toBe("Test Bot"); expect(account.tokenSource).toBe("config"); }); it("resolves account from environment variables", () => { process.env.LINE_CHANNEL_ACCESS_TOKEN = "env-token"; process.env.LINE_CHANNEL_SECRET = "env-secret"; const cfg: ClawdbotConfig = { channels: { line: { enabled: true, }, }, }; const account = resolveLineAccount({ cfg }); expect(account.channelAccessToken).toBe("env-token"); expect(account.channelSecret).toBe("env-secret"); expect(account.tokenSource).toBe("env"); }); it("resolves named account", () => { const cfg: ClawdbotConfig = { channels: { line: { enabled: true, accounts: { business: { enabled: true, channelAccessToken: "business-token", channelSecret: "business-secret", name: "Business Bot", }, }, }, }, }; const account = resolveLineAccount({ cfg, accountId: "business" }); expect(account.accountId).toBe("business"); expect(account.enabled).toBe(true); expect(account.channelAccessToken).toBe("business-token"); expect(account.channelSecret).toBe("business-secret"); expect(account.name).toBe("Business Bot"); }); it("returns empty token when not configured", () => { const cfg: ClawdbotConfig = {}; const account = resolveLineAccount({ cfg }); expect(account.channelAccessToken).toBe(""); expect(account.channelSecret).toBe(""); expect(account.tokenSource).toBe("none"); }); }); describe("listLineAccountIds", () => { it("returns default account when configured at base level", () => { const cfg: ClawdbotConfig = { channels: { line: { channelAccessToken: "test-token", }, }, }; const ids = listLineAccountIds(cfg); expect(ids).toContain(DEFAULT_ACCOUNT_ID); }); it("returns named accounts", () => { const cfg: ClawdbotConfig = { channels: { line: { accounts: { business: { enabled: true }, personal: { enabled: true }, }, }, }, }; const ids = listLineAccountIds(cfg); expect(ids).toContain("business"); expect(ids).toContain("personal"); }); it("returns default from env", () => { process.env.LINE_CHANNEL_ACCESS_TOKEN = "env-token"; const cfg: ClawdbotConfig = {}; const ids = listLineAccountIds(cfg); expect(ids).toContain(DEFAULT_ACCOUNT_ID); }); }); describe("resolveDefaultLineAccountId", () => { it("returns default when configured", () => { const cfg: ClawdbotConfig = { channels: { line: { channelAccessToken: "test-token", }, }, }; const id = resolveDefaultLineAccountId(cfg); expect(id).toBe(DEFAULT_ACCOUNT_ID); }); it("returns first named account when default not configured", () => { const cfg: ClawdbotConfig = { channels: { line: { accounts: { business: { enabled: true }, }, }, }, }; const id = resolveDefaultLineAccountId(cfg); expect(id).toBe("business"); }); }); describe("normalizeAccountId", () => { it("normalizes undefined to default", () => { expect(normalizeAccountId(undefined)).toBe(DEFAULT_ACCOUNT_ID); }); it("normalizes 'default' to DEFAULT_ACCOUNT_ID", () => { expect(normalizeAccountId("default")).toBe(DEFAULT_ACCOUNT_ID); }); it("preserves other account ids", () => { expect(normalizeAccountId("business")).toBe("business"); }); it("lowercases account ids", () => { expect(normalizeAccountId("Business")).toBe("business"); }); it("trims whitespace", () => { expect(normalizeAccountId(" business ")).toBe("business"); }); }); });