Files
openclaw/extensions/line/src/channel.startup.test.ts
2026-03-22 03:50:41 +00:00

97 lines
2.8 KiB
TypeScript

import { describe, expect, it, vi } from "vitest";
import { createStartAccountContext } from "../../../test/helpers/extensions/start-account-context.js";
import type { PluginRuntime, ResolvedLineAccount } from "../api.js";
import { linePlugin } from "./channel.js";
import { setLineRuntime } from "./runtime.js";
function createRuntime() {
const monitorLineProvider = vi.fn(async () => ({
account: { accountId: "default" },
handleWebhook: async () => {},
stop: () => {},
}));
const runtime = {
channel: {
line: {
monitorLineProvider,
},
},
logging: {
shouldLogVerbose: () => false,
},
} as unknown as PluginRuntime;
return { runtime, monitorLineProvider };
}
function createAccount(params: { token: string; secret: string }): ResolvedLineAccount {
return {
accountId: "default",
enabled: true,
channelAccessToken: params.token,
channelSecret: params.secret,
tokenSource: "config",
config: {} as ResolvedLineAccount["config"],
};
}
function startLineAccount(params: { account: ResolvedLineAccount; abortSignal?: AbortSignal }) {
const { runtime, monitorLineProvider } = createRuntime();
setLineRuntime(runtime);
return {
monitorLineProvider,
task: linePlugin.gateway!.startAccount!(
createStartAccountContext({
account: params.account,
abortSignal: params.abortSignal,
}),
),
};
}
describe("linePlugin gateway.startAccount", () => {
it("fails startup when channel secret is missing", async () => {
const { monitorLineProvider, task } = startLineAccount({
account: createAccount({ token: "token", secret: " " }),
});
await expect(task).rejects.toThrow(
'LINE webhook mode requires a non-empty channel secret for account "default".',
);
expect(monitorLineProvider).not.toHaveBeenCalled();
});
it("fails startup when channel access token is missing", async () => {
const { monitorLineProvider, task } = startLineAccount({
account: createAccount({ token: " ", secret: "secret" }),
});
await expect(task).rejects.toThrow(
'LINE webhook mode requires a non-empty channel access token for account "default".',
);
expect(monitorLineProvider).not.toHaveBeenCalled();
});
it("starts provider when token and secret are present", async () => {
const abort = new AbortController();
const { monitorLineProvider, task } = startLineAccount({
account: createAccount({ token: "token", secret: "secret" }),
abortSignal: abort.signal,
});
await vi.waitFor(() => {
expect(monitorLineProvider).toHaveBeenCalledWith(
expect.objectContaining({
channelAccessToken: "token",
channelSecret: "secret",
accountId: "default",
}),
);
});
abort.abort();
await task;
});
});