























@@ -0,0 +1,103 @@
1+import { sendDurableMessageBatch } from "openclaw/plugin-sdk/channel-message";
2+import {
3+createEmptyPluginRegistry,
4+createTestRegistry,
5+resetPluginRuntimeStateForTest,
6+setActivePluginRegistry,
7+} from "openclaw/plugin-sdk/plugin-test-runtime";
8+import { afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
9+import {
10+createDiscordOutboundHoisted,
11+installDiscordOutboundModuleSpies,
12+resetDiscordOutboundMocks,
13+} from "./outbound-adapter.test-harness.js";
14+15+const hoisted = createDiscordOutboundHoisted();
16+await installDiscordOutboundModuleSpies(hoisted);
17+18+let discordPlugin: typeof import("./channel.js").discordPlugin;
19+20+beforeAll(async () => {
21+({ discordPlugin } = await import("./channel.js"));
22+});
23+24+describe("durable Discord delivery", () => {
25+beforeEach(() => {
26+resetDiscordOutboundMocks(hoisted);
27+setActivePluginRegistry(
28+createTestRegistry([
29+{
30+pluginId: "discord",
31+source: "test",
32+plugin: discordPlugin,
33+},
34+]),
35+);
36+});
37+38+afterEach(() => {
39+resetPluginRuntimeStateForTest();
40+setActivePluginRegistry(createEmptyPluginRegistry());
41+});
42+43+it("fans out planned text chunks and retries a transient failure on a later chunk", async () => {
44+hoisted.sendMessageDiscordMock
45+.mockResolvedValueOnce({
46+messageId: "msg-chunk-1",
47+channelId: "ch-1",
48+})
49+.mockRejectedValueOnce(Object.assign(new Error("discord 500"), { status: 500 }))
50+.mockResolvedValueOnce({
51+messageId: "msg-chunk-2",
52+channelId: "ch-1",
53+});
54+55+const result = await sendDurableMessageBatch({
56+cfg: {
57+channels: {
58+discord: {
59+token: "test-token",
60+retry: { attempts: 2, minDelayMs: 0, maxDelayMs: 0, jitter: 0 },
61+},
62+},
63+},
64+channel: "discord",
65+to: "channel:123456",
66+payloads: [{ text: "first chunk\nsecond chunk" }],
67+formatting: {
68+chunkMode: "newline",
69+maxLinesPerMessage: 1,
70+textLimit: 2000,
71+},
72+skipQueue: true,
73+});
74+75+expect(result.status).toBe("sent");
76+if (result.status !== "sent") {
77+throw new Error("expected durable Discord send to succeed");
78+}
79+expect(
80+result.results.map((entry) => ({
81+channel: entry.channel,
82+messageId: entry.messageId,
83+})),
84+).toEqual([
85+{ channel: "discord", messageId: "msg-chunk-1" },
86+{ channel: "discord", messageId: "msg-chunk-2" },
87+]);
88+expect(result.receipt.platformMessageIds).toEqual(["msg-chunk-1", "msg-chunk-2"]);
89+expect(result.payloadOutcomes).toEqual([
90+{
91+index: 0,
92+status: "sent",
93+results: result.results,
94+},
95+]);
96+expect(hoisted.sendMessageDiscordMock).toHaveBeenCalledTimes(3);
97+expect(hoisted.sendMessageDiscordMock.mock.calls.map((call) => call[1])).toEqual([
98+"first chunk",
99+"second chunk",
100+"second chunk",
101+]);
102+});
103+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。