test: fix channel interaction/media regressions

This commit is contained in:
Ayaan Zaidi
2026-03-22 11:56:19 +05:30
parent ec0e4ff218
commit 537115bbdc
2 changed files with 55 additions and 57 deletions

View File

@@ -12,6 +12,7 @@ import type { DiscordAccountConfig } from "openclaw/plugin-sdk/config-runtime";
import { buildPluginBindingApprovalCustomId } from "openclaw/plugin-sdk/conversation-runtime";
import { buildAgentSessionKey } from "openclaw/plugin-sdk/routing";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { peekSystemEvents, resetSystemEventsForTest } from "../../../../src/infra/system-events.js";
import {
clearDiscordComponentEntries,
registerDiscordComponentEntries,
@@ -50,7 +51,6 @@ import {
const readAllowFromStoreMock = vi.hoisted(() => vi.fn());
const upsertPairingRequestMock = vi.hoisted(() => vi.fn());
const enqueueSystemEventMock = vi.hoisted(() => vi.fn());
const dispatchReplyMock = vi.hoisted(() => vi.fn());
const recordInboundSessionMock = vi.hoisted(() => vi.fn());
const readSessionUpdatedAtMock = vi.hoisted(() => vi.fn());
@@ -90,14 +90,6 @@ vi.mock("openclaw/plugin-sdk/conversation-runtime", async (importOriginal) => {
};
});
vi.mock("openclaw/plugin-sdk/infra-runtime", async (importOriginal) => {
const actual = await importOriginal<typeof import("openclaw/plugin-sdk/infra-runtime")>();
return {
...actual,
enqueueSystemEvent: (...args: unknown[]) => enqueueSystemEventMock(...args),
};
});
vi.mock("openclaw/plugin-sdk/reply-runtime", async (importOriginal) => {
const actual = await importOriginal<typeof import("openclaw/plugin-sdk/reply-runtime")>();
return {
@@ -147,6 +139,12 @@ vi.mock("openclaw/plugin-sdk/plugin-runtime", async (importOriginal) => {
describe("agent components", () => {
const createCfg = (): OpenClawConfig => ({}) as OpenClawConfig;
const dmSessionKey = buildAgentSessionKey({
agentId: "main",
channel: "discord",
accountId: "default",
peer: { kind: "direct", id: "123456789" },
});
const createBaseDmInteraction = (overrides: Record<string, unknown> = {}) => {
const reply = vi.fn().mockResolvedValue(undefined);
@@ -187,7 +185,7 @@ describe("agent components", () => {
beforeEach(() => {
readAllowFromStoreMock.mockClear().mockResolvedValue([]);
upsertPairingRequestMock.mockClear().mockResolvedValue({ code: "PAIRCODE", created: true });
enqueueSystemEventMock.mockClear();
resetSystemEventsForTest();
});
it("sends pairing reply when DM sender is not allowlisted", async () => {
@@ -207,7 +205,7 @@ describe("agent components", () => {
const code = pairingText.match(/Pairing code:\s*([A-Z2-9]{8})/)?.[1];
expect(code).toBeDefined();
expect(pairingText).toContain(`openclaw pairing approve discord ${code}`);
expect(enqueueSystemEventMock).not.toHaveBeenCalled();
expect(peekSystemEvents(dmSessionKey)).toEqual([]);
expect(readAllowFromStoreMock).toHaveBeenCalledWith("discord", "default");
});
@@ -226,7 +224,7 @@ describe("agent components", () => {
content: "You are not authorized to use this button.",
ephemeral: true,
});
expect(enqueueSystemEventMock).not.toHaveBeenCalled();
expect(peekSystemEvents(dmSessionKey)).toEqual([]);
expect(readAllowFromStoreMock).not.toHaveBeenCalled();
});
@@ -243,7 +241,9 @@ describe("agent components", () => {
expect(defer).not.toHaveBeenCalled();
expect(reply).toHaveBeenCalledWith({ content: "✓", ephemeral: true });
expect(enqueueSystemEventMock).toHaveBeenCalled();
expect(peekSystemEvents(dmSessionKey)).toEqual([
"[Discord component: hello clicked by Alice#1234 (123456789)]",
]);
expect(upsertPairingRequestMock).not.toHaveBeenCalled();
expect(readAllowFromStoreMock).toHaveBeenCalledWith("discord", "default");
});
@@ -261,7 +261,9 @@ describe("agent components", () => {
expect(defer).not.toHaveBeenCalled();
expect(reply).toHaveBeenCalledWith({ content: "✓", ephemeral: true });
expect(enqueueSystemEventMock).toHaveBeenCalled();
expect(peekSystemEvents(dmSessionKey)).toEqual([
"[Discord component: hello clicked by Alice#1234 (123456789)]",
]);
expect(readAllowFromStoreMock).not.toHaveBeenCalled();
});
@@ -281,7 +283,7 @@ describe("agent components", () => {
content: "DM interactions are disabled.",
ephemeral: true,
});
expect(enqueueSystemEventMock).not.toHaveBeenCalled();
expect(peekSystemEvents(dmSessionKey)).toEqual([]);
expect(readAllowFromStoreMock).not.toHaveBeenCalled();
});
@@ -299,7 +301,9 @@ describe("agent components", () => {
expect(defer).not.toHaveBeenCalled();
expect(reply).toHaveBeenCalledWith({ content: "✓", ephemeral: true });
expect(enqueueSystemEventMock).toHaveBeenCalled();
expect(peekSystemEvents(dmSessionKey)).toEqual([
"[Discord select menu: hello interacted by Alice#1234 (123456789) (selected: alpha)]",
]);
expect(readAllowFromStoreMock).not.toHaveBeenCalled();
});
@@ -316,10 +320,9 @@ describe("agent components", () => {
expect(defer).not.toHaveBeenCalled();
expect(reply).toHaveBeenCalledWith({ content: "✓", ephemeral: true });
expect(enqueueSystemEventMock).toHaveBeenCalledWith(
expect.stringContaining("hello_cid"),
expect.any(Object),
);
expect(peekSystemEvents(dmSessionKey)).toEqual([
"[Discord component: hello_cid clicked by Alice#1234 (123456789)]",
]);
expect(readAllowFromStoreMock).not.toHaveBeenCalled();
});
@@ -336,10 +339,9 @@ describe("agent components", () => {
expect(defer).not.toHaveBeenCalled();
expect(reply).toHaveBeenCalledWith({ content: "✓", ephemeral: true });
expect(enqueueSystemEventMock).toHaveBeenCalledWith(
expect.stringContaining("hello%2G"),
expect.any(Object),
);
expect(peekSystemEvents(dmSessionKey)).toEqual([
"[Discord component: hello%2G clicked by Alice#1234 (123456789)]",
]);
expect(readAllowFromStoreMock).not.toHaveBeenCalled();
});
});
@@ -498,7 +500,7 @@ describe("discord component interactions", () => {
lastDispatchCtx = undefined;
readAllowFromStoreMock.mockClear().mockResolvedValue([]);
upsertPairingRequestMock.mockClear().mockResolvedValue({ code: "PAIRCODE", created: true });
enqueueSystemEventMock.mockClear();
resetSystemEventsForTest();
dispatchReplyMock.mockClear().mockImplementation(async (params: DispatchParams) => {
lastDispatchCtx = params.ctx;
await params.dispatcherOptions.deliver({ text: "ok" });

View File

@@ -12,6 +12,7 @@ const {
botCtorSpy,
commandSpy,
dispatchReplyWithBufferedBlockDispatcher,
getLoadWebMediaMock,
getLoadConfigMock,
getOnHandler,
getReadChannelAllowFromStoreMock,
@@ -1258,44 +1259,39 @@ describe("createTelegramBot", () => {
});
it("sends GIF replies as animations", async () => {
const loadWebMedia = getLoadWebMediaMock();
replySpy.mockResolvedValueOnce({
text: "caption",
mediaUrl: "https://example.com/fun",
});
const fetchSpy = vi.spyOn(globalThis, "fetch").mockResolvedValue(
new Response(Buffer.from("GIF89a"), {
status: 200,
headers: {
"content-type": "image/gif",
},
}),
);
try {
createTelegramBot({ token: "tok" });
const handler = getOnHandler("message") as (ctx: Record<string, unknown>) => Promise<void>;
loadWebMedia.mockResolvedValueOnce({
buffer: Buffer.from("GIF89a"),
contentType: "image/gif",
fileName: "fun.gif",
});
await handler({
message: {
chat: { id: 1234, type: "private" },
text: "hello world",
date: 1736380800,
message_id: 5,
from: { first_name: "Ada" },
},
me: { username: "openclaw_bot" },
getFile: async () => ({ download: async () => new Uint8Array() }),
});
createTelegramBot({ token: "tok" });
const handler = getOnHandler("message") as (ctx: Record<string, unknown>) => Promise<void>;
expect(sendAnimationSpy).toHaveBeenCalledTimes(1);
expect(sendAnimationSpy).toHaveBeenCalledWith("1234", expect.anything(), {
caption: "caption",
parse_mode: "HTML",
reply_to_message_id: undefined,
});
expect(sendPhotoSpy).not.toHaveBeenCalled();
} finally {
fetchSpy.mockRestore();
}
await handler({
message: {
chat: { id: 1234, type: "private" },
text: "hello world",
date: 1736380800,
message_id: 5,
from: { first_name: "Ada" },
},
me: { username: "openclaw_bot" },
getFile: async () => ({ download: async () => new Uint8Array() }),
});
expect(sendAnimationSpy).toHaveBeenCalledTimes(1);
expect(sendAnimationSpy).toHaveBeenCalledWith("1234", expect.anything(), {
caption: "caption",
parse_mode: "HTML",
reply_to_message_id: undefined,
});
expect(sendPhotoSpy).not.toHaveBeenCalled();
});
function resetHarnessSpies() {