openclaw-matrix-multiaccounts/src/infra/outbound/deliver.test.ts
2026-01-07 01:22:55 +00:00

147 lines
4.3 KiB
TypeScript

import { describe, expect, it, vi } from "vitest";
import type { ClawdbotConfig } from "../../config/config.js";
import {
deliverOutboundPayloads,
normalizeOutboundPayloads,
} from "./deliver.js";
describe("deliverOutboundPayloads", () => {
it("chunks telegram markdown and passes config token", async () => {
const sendTelegram = vi
.fn()
.mockResolvedValue({ messageId: "m1", chatId: "c1" });
const cfg: ClawdbotConfig = {
telegram: { botToken: "tok-1", textChunkLimit: 2 },
};
const prevTelegramToken = process.env.TELEGRAM_BOT_TOKEN;
process.env.TELEGRAM_BOT_TOKEN = "";
try {
const results = await deliverOutboundPayloads({
cfg,
provider: "telegram",
to: "123",
payloads: [{ text: "abcd" }],
deps: { sendTelegram },
});
expect(sendTelegram).toHaveBeenCalledTimes(2);
for (const call of sendTelegram.mock.calls) {
expect(call[2]).toEqual(
expect.objectContaining({ token: "tok-1", verbose: false }),
);
}
expect(results).toHaveLength(2);
expect(results[0]).toMatchObject({ provider: "telegram", chatId: "c1" });
} finally {
if (prevTelegramToken === undefined) {
delete process.env.TELEGRAM_BOT_TOKEN;
} else {
process.env.TELEGRAM_BOT_TOKEN = prevTelegramToken;
}
}
});
it("uses signal media maxBytes from config", async () => {
const sendSignal = vi
.fn()
.mockResolvedValue({ messageId: "s1", timestamp: 123 });
const cfg: ClawdbotConfig = { signal: { mediaMaxMb: 2 } };
const results = await deliverOutboundPayloads({
cfg,
provider: "signal",
to: "+1555",
payloads: [{ text: "hi", mediaUrl: "https://x.test/a.jpg" }],
deps: { sendSignal },
});
expect(sendSignal).toHaveBeenCalledWith(
"+1555",
"hi",
expect.objectContaining({
mediaUrl: "https://x.test/a.jpg",
maxBytes: 2 * 1024 * 1024,
}),
);
expect(results[0]).toMatchObject({ provider: "signal", messageId: "s1" });
});
it("chunks WhatsApp text and returns all results", async () => {
const sendWhatsApp = vi
.fn()
.mockResolvedValueOnce({ messageId: "w1", toJid: "jid" })
.mockResolvedValueOnce({ messageId: "w2", toJid: "jid" });
const cfg: ClawdbotConfig = {
whatsapp: { textChunkLimit: 2 },
};
const results = await deliverOutboundPayloads({
cfg,
provider: "whatsapp",
to: "+1555",
payloads: [{ text: "abcd" }],
deps: { sendWhatsApp },
});
expect(sendWhatsApp).toHaveBeenCalledTimes(2);
expect(results.map((r) => r.messageId)).toEqual(["w1", "w2"]);
});
it("uses iMessage media maxBytes from agent fallback", async () => {
const sendIMessage = vi.fn().mockResolvedValue({ messageId: "i1" });
const cfg: ClawdbotConfig = { agent: { mediaMaxMb: 3 } };
await deliverOutboundPayloads({
cfg,
provider: "imessage",
to: "chat_id:42",
payloads: [{ text: "hello" }],
deps: { sendIMessage },
});
expect(sendIMessage).toHaveBeenCalledWith(
"chat_id:42",
"hello",
expect.objectContaining({ maxBytes: 3 * 1024 * 1024 }),
);
});
it("normalizes payloads and drops empty entries", () => {
const normalized = normalizeOutboundPayloads([
{ text: "hi" },
{ mediaUrl: "https://x.test/a.jpg" },
{ text: " ", mediaUrls: [] },
]);
expect(normalized).toEqual([
{ text: "hi", mediaUrls: [] },
{ text: "", mediaUrls: ["https://x.test/a.jpg"] },
{ text: " ", mediaUrls: [] },
]);
});
it("continues on errors when bestEffort is enabled", async () => {
const sendWhatsApp = vi
.fn()
.mockRejectedValueOnce(new Error("fail"))
.mockResolvedValueOnce({ messageId: "w2", toJid: "jid" });
const onError = vi.fn();
const cfg: ClawdbotConfig = {};
const results = await deliverOutboundPayloads({
cfg,
provider: "whatsapp",
to: "+1555",
payloads: [{ text: "a" }, { text: "b" }],
deps: { sendWhatsApp },
bestEffort: true,
onError,
});
expect(sendWhatsApp).toHaveBeenCalledTimes(2);
expect(onError).toHaveBeenCalledTimes(1);
expect(results).toEqual([
{ provider: "whatsapp", messageId: "w2", toJid: "jid" },
]);
});
});