openclaw/extensions/telegram/src/bot-native-commands.menu-test-support.ts

159 lines
4.8 KiB
TypeScript

import { expect, vi } from "vitest";
import type { OpenClawConfig } from "../../../src/config/config.js";
import type { TelegramAccountConfig } from "../../../src/config/types.js";
import type { RuntimeEnv } from "../../../src/runtime.js";
type NativeCommandBot = {
api: {
setMyCommands: ReturnType<typeof vi.fn>;
sendMessage: ReturnType<typeof vi.fn>;
};
command: ReturnType<typeof vi.fn>;
};
type RegisterTelegramNativeCommandsParams = {
bot: NativeCommandBot;
cfg: OpenClawConfig;
runtime: RuntimeEnv;
accountId: string;
telegramCfg: TelegramAccountConfig;
allowFrom: string[];
groupAllowFrom: string[];
replyToMode: string;
textLimit: number;
useAccessGroups: boolean;
nativeEnabled: boolean;
nativeSkillsEnabled: boolean;
nativeDisabledExplicit: boolean;
resolveGroupPolicy: () => { allowlistEnabled: boolean; allowed: boolean };
resolveTelegramGroupConfig: () => {
groupConfig: undefined;
topicConfig: undefined;
};
shouldSkipUpdate: () => boolean;
opts: { token: string };
};
type RegisteredCommand = {
command: string;
description: string;
};
const skillCommandMocks = vi.hoisted(() => ({
listSkillCommandsForAgents: vi.fn(() => []),
}));
const deliveryMocks = vi.hoisted(() => ({
deliverReplies: vi.fn(async () => ({ delivered: true })),
}));
export const listSkillCommandsForAgents = skillCommandMocks.listSkillCommandsForAgents;
export const deliverReplies = deliveryMocks.deliverReplies;
vi.mock("../../../src/auto-reply/skill-commands.js", async (importOriginal) => {
const actual = await importOriginal<typeof import("../../../src/auto-reply/skill-commands.js")>();
return {
...actual,
listSkillCommandsForAgents,
};
});
vi.mock("./bot/delivery.js", () => ({
deliverReplies,
}));
export async function waitForRegisteredCommands(
setMyCommands: ReturnType<typeof vi.fn>,
): Promise<RegisteredCommand[]> {
await vi.waitFor(() => {
expect(setMyCommands).toHaveBeenCalled();
});
return setMyCommands.mock.calls[0]?.[0] as RegisteredCommand[];
}
export function resetNativeCommandMenuMocks() {
listSkillCommandsForAgents.mockClear();
listSkillCommandsForAgents.mockReturnValue([]);
deliverReplies.mockClear();
deliverReplies.mockResolvedValue({ delivered: true });
}
export function createCommandBot() {
const commandHandlers = new Map<string, (ctx: unknown) => Promise<void>>();
const sendMessage = vi.fn().mockResolvedValue(undefined);
const setMyCommands = vi.fn().mockResolvedValue(undefined);
const bot = {
api: {
setMyCommands,
sendMessage,
},
command: vi.fn((name: string, cb: (ctx: unknown) => Promise<void>) => {
commandHandlers.set(name, cb);
}),
} as unknown as RegisterTelegramNativeCommandsParams["bot"];
return { bot, commandHandlers, sendMessage, setMyCommands };
}
export function createNativeCommandTestParams(
cfg: OpenClawConfig,
params: Partial<RegisterTelegramNativeCommandsParams> = {},
): RegisterTelegramNativeCommandsParams {
return {
bot:
params.bot ??
({
api: {
setMyCommands: vi.fn().mockResolvedValue(undefined),
sendMessage: vi.fn().mockResolvedValue(undefined),
},
command: vi.fn(),
} as unknown as RegisterTelegramNativeCommandsParams["bot"]),
cfg,
runtime: params.runtime ?? ({} as RuntimeEnv),
accountId: params.accountId ?? "default",
telegramCfg: params.telegramCfg ?? ({} as TelegramAccountConfig),
allowFrom: params.allowFrom ?? [],
groupAllowFrom: params.groupAllowFrom ?? [],
replyToMode: params.replyToMode ?? "off",
textLimit: params.textLimit ?? 4000,
useAccessGroups: params.useAccessGroups ?? false,
nativeEnabled: params.nativeEnabled ?? true,
nativeSkillsEnabled: params.nativeSkillsEnabled ?? true,
nativeDisabledExplicit: params.nativeDisabledExplicit ?? false,
resolveGroupPolicy:
params.resolveGroupPolicy ??
(() =>
({
allowlistEnabled: false,
allowed: true,
}) as ReturnType<RegisterTelegramNativeCommandsParams["resolveGroupPolicy"]>),
resolveTelegramGroupConfig:
params.resolveTelegramGroupConfig ??
(() => ({
groupConfig: undefined,
topicConfig: undefined,
})),
shouldSkipUpdate: params.shouldSkipUpdate ?? (() => false),
opts: params.opts ?? { token: "token" },
};
}
export function createPrivateCommandContext(params?: {
match?: string;
messageId?: number;
date?: number;
chatId?: number;
userId?: number;
username?: string;
}) {
return {
match: params?.match ?? "",
message: {
message_id: params?.messageId ?? 1,
date: params?.date ?? Math.floor(Date.now() / 1000),
chat: { id: params?.chatId ?? 123, type: "private" as const },
from: { id: params?.userId ?? 456, username: params?.username ?? "alice" },
},
};
}