Files
openclaw/extensions/slack/src/monitor/replies.test.ts
theo674 dbe7da7684 fix: prevent delivery-mirror re-delivery and raise Slack chunk limit (#45489)
Merged via squash.

Prepared head SHA: c7664c7b6e
Co-authored-by: theo674 <261068216+theo674@users.noreply.github.com>
Co-authored-by: altaywtf <9790196+altaywtf@users.noreply.github.com>
Reviewed-by: @altaywtf
2026-03-24 00:11:19 +03:00

121 lines
3.2 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from "vitest";
const sendMock = vi.fn();
vi.mock("../send.js", () => ({
sendMessageSlack: (...args: unknown[]) => sendMock(...args),
}));
let deliverReplies: typeof import("./replies.js").deliverReplies;
import { deliverSlackSlashReplies } from "./replies.js";
function baseParams(overrides?: Record<string, unknown>) {
return {
replies: [{ text: "hello" }],
target: "C123",
token: "xoxb-test",
runtime: { log: () => {}, error: () => {}, exit: () => {} },
textLimit: 4000,
replyToMode: "off" as const,
...overrides,
};
}
describe("deliverReplies identity passthrough", () => {
beforeEach(async () => {
vi.resetModules();
({ deliverReplies } = await import("./replies.js"));
sendMock.mockReset();
});
it("passes identity to sendMessageSlack for text replies", async () => {
sendMock.mockResolvedValue(undefined);
const identity = { username: "Bot", iconEmoji: ":robot:" };
await deliverReplies(baseParams({ identity }));
expect(sendMock).toHaveBeenCalledOnce();
expect(sendMock.mock.calls[0][2]).toMatchObject({ identity });
});
it("passes identity to sendMessageSlack for media replies", async () => {
sendMock.mockResolvedValue(undefined);
const identity = { username: "Bot", iconUrl: "https://example.com/icon.png" };
await deliverReplies(
baseParams({
identity,
replies: [{ text: "caption", mediaUrls: ["https://example.com/img.png"] }],
}),
);
expect(sendMock).toHaveBeenCalledOnce();
expect(sendMock.mock.calls[0][2]).toMatchObject({ identity });
});
it("omits identity key when not provided", async () => {
sendMock.mockResolvedValue(undefined);
await deliverReplies(baseParams());
expect(sendMock).toHaveBeenCalledOnce();
expect(sendMock.mock.calls[0][2]).not.toHaveProperty("identity");
});
it("delivers block-only replies through to sendMessageSlack", async () => {
sendMock.mockResolvedValue(undefined);
const blocks = [
{
type: "actions",
elements: [
{
type: "button",
action_id: "openclaw:reply_button",
text: { type: "plain_text", text: "Option A" },
value: "reply_1_option_a",
},
],
},
];
await deliverReplies(
baseParams({
replies: [
{
text: "",
channelData: {
slack: {
blocks,
},
},
},
],
}),
);
expect(sendMock).toHaveBeenCalledOnce();
expect(sendMock).toHaveBeenCalledWith(
"C123",
"",
expect.objectContaining({
blocks,
}),
);
});
});
describe("deliverSlackSlashReplies chunking", () => {
it("keeps a 4205-character reply in a single slash response by default", async () => {
const respond = vi.fn(async () => undefined);
const text = "a".repeat(4205);
await deliverSlackSlashReplies({
replies: [{ text }],
respond,
ephemeral: true,
textLimit: 8000,
});
expect(respond).toHaveBeenCalledTimes(1);
expect(respond).toHaveBeenCalledWith({
text,
response_type: "ephemeral",
});
});
});