refactor(telegram-tests): share native command helpers

This commit is contained in:
Peter Steinberger 2026-03-17 06:31:29 +00:00
parent d28cb8d821
commit e184cd97cc
4 changed files with 73 additions and 84 deletions

View File

@ -0,0 +1,22 @@
import { vi } from "vitest";
export const pluginCommandMocks = {
getPluginCommandSpecs: vi.fn(() => []),
matchPluginCommand: vi.fn(() => null),
executePluginCommand: vi.fn(async () => ({ text: "ok" })),
};
vi.mock("../../../src/plugins/commands.js", () => ({
getPluginCommandSpecs: pluginCommandMocks.getPluginCommandSpecs,
matchPluginCommand: pluginCommandMocks.matchPluginCommand,
executePluginCommand: pluginCommandMocks.executePluginCommand,
}));
export function resetPluginCommandMocks() {
pluginCommandMocks.getPluginCommandSpecs.mockClear();
pluginCommandMocks.getPluginCommandSpecs.mockReturnValue([]);
pluginCommandMocks.matchPluginCommand.mockClear();
pluginCommandMocks.matchPluginCommand.mockReturnValue(null);
pluginCommandMocks.executePluginCommand.mockClear();
pluginCommandMocks.executePluginCommand.mockResolvedValue({ text: "ok" });
}

View File

@ -17,6 +17,38 @@ import {
waitForRegisteredCommands,
} from "./bot-native-commands.menu-test-support.js";
function registerPairPluginCommand(params?: {
nativeNames?: { telegram?: string; discord?: string };
}) {
expect(
registerPluginCommand("demo-plugin", {
name: "pair",
...(params?.nativeNames ? { nativeNames: params.nativeNames } : {}),
description: "Pair device",
acceptsArgs: true,
requireAuth: false,
handler: async ({ args }) => ({ text: `paired:${args ?? ""}` }),
}),
).toEqual({ ok: true });
}
async function registerPairMenu(params: {
bot: ReturnType<typeof createCommandBot>["bot"];
setMyCommands: ReturnType<typeof createCommandBot>["setMyCommands"];
nativeNames?: { telegram?: string; discord?: string };
}) {
registerPairPluginCommand({
...(params.nativeNames ? { nativeNames: params.nativeNames } : {}),
});
registerTelegramNativeCommands({
...createNativeCommandTestParams({}),
bot: params.bot,
});
return await waitForRegisteredCommands(params.setMyCommands);
}
describe("registerTelegramNativeCommands real plugin registry", () => {
beforeEach(() => {
clearPluginCommands();
@ -31,22 +63,7 @@ describe("registerTelegramNativeCommands real plugin registry", () => {
it("registers and executes plugin commands through the real plugin registry", async () => {
const { bot, commandHandlers, sendMessage, setMyCommands } = createCommandBot();
expect(
registerPluginCommand("demo-plugin", {
name: "pair",
description: "Pair device",
acceptsArgs: true,
requireAuth: false,
handler: async ({ args }) => ({ text: `paired:${args ?? ""}` }),
}),
).toEqual({ ok: true });
registerTelegramNativeCommands({
...createNativeCommandTestParams({}),
bot,
});
const registeredCommands = await waitForRegisteredCommands(setMyCommands);
const registeredCommands = await registerPairMenu({ bot, setMyCommands });
expect(registeredCommands).toEqual(
expect.arrayContaining([{ command: "pair", description: "Pair device" }]),
);
@ -67,26 +84,14 @@ describe("registerTelegramNativeCommands real plugin registry", () => {
it("round-trips Telegram native aliases through the real plugin registry", async () => {
const { bot, commandHandlers, sendMessage, setMyCommands } = createCommandBot();
expect(
registerPluginCommand("demo-plugin", {
name: "pair",
nativeNames: {
telegram: "pair_device",
discord: "pairdiscord",
},
description: "Pair device",
acceptsArgs: true,
requireAuth: false,
handler: async ({ args }) => ({ text: `paired:${args ?? ""}` }),
}),
).toEqual({ ok: true });
registerTelegramNativeCommands({
...createNativeCommandTestParams({}),
const registeredCommands = await registerPairMenu({
bot,
setMyCommands,
nativeNames: {
telegram: "pair_device",
discord: "pairdiscord",
},
});
const registeredCommands = await waitForRegisteredCommands(setMyCommands);
expect(registeredCommands).toEqual(
expect.arrayContaining([{ command: "pair_device", description: "Pair device" }]),
);
@ -107,15 +112,7 @@ describe("registerTelegramNativeCommands real plugin registry", () => {
it("keeps real plugin command handlers available when native menu registration is disabled", () => {
const { bot, commandHandlers, setMyCommands } = createCommandBot();
expect(
registerPluginCommand("demo-plugin", {
name: "pair",
description: "Pair device",
acceptsArgs: true,
requireAuth: false,
handler: async ({ args }) => ({ text: `paired:${args ?? ""}` }),
}),
).toEqual({ ok: true });
registerPairPluginCommand();
registerTelegramNativeCommands({
...createNativeCommandTestParams({}, { accountId: "default" }),
@ -130,15 +127,7 @@ describe("registerTelegramNativeCommands real plugin registry", () => {
it("allows requireAuth:false plugin commands for unauthorized senders through the real registry", async () => {
const { bot, commandHandlers, sendMessage, setMyCommands } = createCommandBot();
expect(
registerPluginCommand("demo-plugin", {
name: "pair",
description: "Pair device",
acceptsArgs: true,
requireAuth: false,
handler: async ({ args }) => ({ text: `paired:${args ?? ""}` }),
}),
).toEqual({ ok: true });
registerPairPluginCommand();
registerTelegramNativeCommands({
...createNativeCommandTestParams({

View File

@ -10,18 +10,10 @@ import {
resetNativeCommandMenuMocks,
waitForRegisteredCommands,
} from "./bot-native-commands.menu-test-support.js";
const pluginCommandMocks = vi.hoisted(() => ({
getPluginCommandSpecs: vi.fn(() => []),
matchPluginCommand: vi.fn(() => null),
executePluginCommand: vi.fn(async () => ({ text: "ok" })),
}));
vi.mock("../../../src/plugins/commands.js", () => ({
getPluginCommandSpecs: pluginCommandMocks.getPluginCommandSpecs,
matchPluginCommand: pluginCommandMocks.matchPluginCommand,
executePluginCommand: pluginCommandMocks.executePluginCommand,
}));
import {
pluginCommandMocks,
resetPluginCommandMocks,
} from "./bot-native-commands.plugin-command-test-support.js";
const tempDirs: string[] = [];
@ -34,9 +26,7 @@ async function makeWorkspace(prefix: string) {
describe("registerTelegramNativeCommands skill allowlist integration", () => {
afterEach(async () => {
resetNativeCommandMenuMocks();
pluginCommandMocks.getPluginCommandSpecs.mockClear().mockReturnValue([]);
pluginCommandMocks.matchPluginCommand.mockClear().mockReturnValue(null);
pluginCommandMocks.executePluginCommand.mockClear().mockResolvedValue({ text: "ok" });
resetPluginCommandMocks();
await Promise.all(
tempDirs
.splice(0, tempDirs.length)

View File

@ -5,6 +5,10 @@ import { STATE_DIR } from "../../../src/config/paths.js";
import { TELEGRAM_COMMAND_NAME_PATTERN } from "../../../src/config/telegram-custom-commands.js";
import type { TelegramAccountConfig } from "../../../src/config/types.js";
import type { RuntimeEnv } from "../../../src/runtime.js";
import {
pluginCommandMocks,
resetPluginCommandMocks,
} from "./bot-native-commands.plugin-command-test-support.js";
const skillCommandMocks = vi.hoisted(() => ({
listSkillCommandsForAgents: vi.fn(() => []),
}));
@ -32,29 +36,13 @@ import {
waitForRegisteredCommands,
} from "./bot-native-commands.menu-test-support.js";
const pluginCommandMocks = vi.hoisted(() => ({
getPluginCommandSpecs: vi.fn(() => []),
matchPluginCommand: vi.fn(() => null),
executePluginCommand: vi.fn(async () => ({ text: "ok" })),
}));
vi.mock("../../../src/plugins/commands.js", () => ({
getPluginCommandSpecs: pluginCommandMocks.getPluginCommandSpecs,
matchPluginCommand: pluginCommandMocks.matchPluginCommand,
executePluginCommand: pluginCommandMocks.executePluginCommand,
}));
describe("registerTelegramNativeCommands", () => {
beforeEach(() => {
skillCommandMocks.listSkillCommandsForAgents.mockClear();
skillCommandMocks.listSkillCommandsForAgents.mockReturnValue([]);
deliveryMocks.deliverReplies.mockClear();
deliveryMocks.deliverReplies.mockResolvedValue({ delivered: true });
pluginCommandMocks.getPluginCommandSpecs.mockClear();
pluginCommandMocks.getPluginCommandSpecs.mockReturnValue([]);
pluginCommandMocks.matchPluginCommand.mockClear();
pluginCommandMocks.matchPluginCommand.mockReturnValue(null);
pluginCommandMocks.executePluginCommand.mockClear();
pluginCommandMocks.executePluginCommand.mockResolvedValue({ text: "ok" });
resetPluginCommandMocks();
});
it("scopes skill commands when account binding exists", () => {