Files
openclaw/src/infra/exec-approval-surface.test.ts
2026-03-28 00:02:09 +00:00

191 lines
5.3 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from "vitest";
const loadConfigMock = vi.hoisted(() => vi.fn());
const getChannelPluginMock = vi.hoisted(() => vi.fn());
const listChannelPluginsMock = vi.hoisted(() => vi.fn());
const normalizeMessageChannelMock = vi.hoisted(() => vi.fn());
type ExecApprovalSurfaceModule = typeof import("./exec-approval-surface.js");
let hasConfiguredExecApprovalDmRoute: ExecApprovalSurfaceModule["hasConfiguredExecApprovalDmRoute"];
let resolveExecApprovalInitiatingSurfaceState: ExecApprovalSurfaceModule["resolveExecApprovalInitiatingSurfaceState"];
async function loadExecApprovalSurfaceModule() {
vi.resetModules();
loadConfigMock.mockReset();
getChannelPluginMock.mockReset();
listChannelPluginsMock.mockReset();
normalizeMessageChannelMock.mockReset();
normalizeMessageChannelMock.mockImplementation((value?: string | null) =>
typeof value === "string" ? value.trim().toLowerCase() : undefined,
);
vi.doMock("../config/config.js", () => ({
loadConfig: (...args: unknown[]) => loadConfigMock(...args),
}));
vi.doMock("../channels/plugins/index.js", () => ({
getChannelPlugin: (...args: unknown[]) => getChannelPluginMock(...args),
listChannelPlugins: (...args: unknown[]) => listChannelPluginsMock(...args),
}));
vi.doMock("../utils/message-channel.js", () => ({
INTERNAL_MESSAGE_CHANNEL: "web",
normalizeMessageChannel: (...args: unknown[]) => normalizeMessageChannelMock(...args),
}));
({ hasConfiguredExecApprovalDmRoute, resolveExecApprovalInitiatingSurfaceState } =
await import("./exec-approval-surface.js"));
}
describe("resolveExecApprovalInitiatingSurfaceState", () => {
beforeEach(async () => {
await loadExecApprovalSurfaceModule();
});
it.each([
{
channel: null,
expected: {
kind: "enabled",
channel: undefined,
channelLabel: "this platform",
},
},
{
channel: "tui",
expected: {
kind: "enabled",
channel: "tui",
channelLabel: "terminal UI",
},
},
{
channel: "web",
expected: {
kind: "enabled",
channel: "web",
channelLabel: "Web UI",
},
},
])("treats built-in initiating surface %j", ({ channel, expected }) => {
expect(resolveExecApprovalInitiatingSurfaceState({ channel })).toEqual(expected);
});
it("uses the provided cfg for telegram and discord client enablement", () => {
getChannelPluginMock.mockImplementation((channel: string) =>
channel === "telegram"
? {
execApprovals: {
getInitiatingSurfaceState: () => ({ kind: "enabled" }),
},
}
: channel === "discord"
? {
execApprovals: {
getInitiatingSurfaceState: () => ({ kind: "disabled" }),
},
}
: undefined,
);
const cfg = { channels: {} };
expect(
resolveExecApprovalInitiatingSurfaceState({
channel: "telegram",
accountId: "main",
cfg: cfg as never,
}),
).toEqual({
kind: "enabled",
channel: "telegram",
channelLabel: "Telegram",
});
expect(
resolveExecApprovalInitiatingSurfaceState({
channel: "discord",
accountId: "main",
cfg: cfg as never,
}),
).toEqual({
kind: "disabled",
channel: "discord",
channelLabel: "Discord",
});
expect(loadConfigMock).not.toHaveBeenCalled();
});
it("loads config lazily when cfg is omitted and marks unsupported channels", () => {
loadConfigMock.mockReturnValueOnce({ loaded: true });
getChannelPluginMock.mockImplementation((channel: string) =>
channel === "telegram"
? {
execApprovals: {
getInitiatingSurfaceState: () => ({ kind: "disabled" }),
},
}
: undefined,
);
expect(
resolveExecApprovalInitiatingSurfaceState({
channel: "telegram",
accountId: "main",
}),
).toEqual({
kind: "disabled",
channel: "telegram",
channelLabel: "Telegram",
});
expect(loadConfigMock).toHaveBeenCalledOnce();
expect(resolveExecApprovalInitiatingSurfaceState({ channel: "signal" })).toEqual({
kind: "unsupported",
channel: "signal",
channelLabel: "Signal",
});
});
});
describe("hasConfiguredExecApprovalDmRoute", () => {
beforeEach(async () => {
await loadExecApprovalSurfaceModule();
});
it.each([
{
plugins: [
{
execApprovals: {
hasConfiguredDmRoute: () => false,
},
},
{
execApprovals: {
hasConfiguredDmRoute: () => true,
},
},
],
expected: true,
},
{
plugins: [
{
execApprovals: {
hasConfiguredDmRoute: () => false,
},
},
{
execApprovals: {
hasConfiguredDmRoute: () => false,
},
},
{
execApprovals: undefined,
},
],
expected: false,
},
])("reports whether any plugin routes approvals to DM for %j", ({ plugins, expected }) => {
listChannelPluginsMock.mockReturnValueOnce(plugins);
expect(hasConfiguredExecApprovalDmRoute({} as never)).toBe(expected);
});
});