























@@ -1,13 +1,20 @@
11import { describe, expect, it, vi } from "vitest";
22import type { OpenClawConfig } from "../../config/types.openclaw.js";
33import { createChannelMessageAdapterFromOutbound } from "./outbound-bridge.js";
4-import type { MessageReceipt } from "./types.js";
4+import type {
5+ChannelMessageSendPayloadContext,
6+ChannelMessageSendTextContext,
7+MessageReceipt,
8+} from "./types.js";
59610const cfg = {} as OpenClawConfig;
711812describe("createChannelMessageAdapterFromOutbound", () => {
913it("wraps outbound text sends with a message receipt", async () => {
10-const sendText = vi.fn(async () => ({ channel: "demo", messageId: "msg-1" }));
14+const sendText = vi.fn(async (_request: ChannelMessageSendTextContext) => ({
15+channel: "demo",
16+messageId: "msg-1",
17+}));
1118const adapter = createChannelMessageAdapterFromOutbound({
1219id: "demo",
1320outbound: {
@@ -24,37 +31,34 @@ describe("createChannelMessageAdapterFromOutbound", () => {
2431threadId: "thread-1",
2532});
263327-expect(adapter).toEqual(
28-expect.objectContaining({
29-id: "demo",
30-durableFinal: { capabilities: { text: true, replyTo: true } },
31-}),
32-);
33-expect(sendText).toHaveBeenCalledWith(
34-expect.objectContaining({
35-to: "room-1",
36-text: "hello",
37-replyToId: "parent-1",
38-threadId: "thread-1",
39-}),
40-);
41-expect(result).toEqual({
42-messageId: "msg-1",
43-receipt: expect.objectContaining({
44-primaryPlatformMessageId: "msg-1",
45-platformMessageIds: ["msg-1"],
34+expect(adapter.id).toBe("demo");
35+expect(adapter.durableFinal).toEqual({ capabilities: { text: true, replyTo: true } });
36+expect(sendText).toHaveBeenCalledTimes(1);
37+const sendTextRequest = sendText.mock.calls[0]?.[0];
38+expect(sendTextRequest?.to).toBe("room-1");
39+expect(sendTextRequest?.text).toBe("hello");
40+expect(sendTextRequest?.replyToId).toBe("parent-1");
41+expect(sendTextRequest?.threadId).toBe("thread-1");
42+expect(result?.messageId).toBe("msg-1");
43+expect(result?.receipt.primaryPlatformMessageId).toBe("msg-1");
44+expect(result?.receipt.platformMessageIds).toEqual(["msg-1"]);
45+expect(result?.receipt.threadId).toBe("thread-1");
46+expect(result?.receipt.replyToId).toBe("parent-1");
47+expect(
48+result?.receipt.parts.map(({ platformMessageId, kind, threadId, replyToId }) => ({
49+ platformMessageId,
50+ kind,
51+ threadId,
52+ replyToId,
53+})),
54+).toEqual([
55+{
56+platformMessageId: "msg-1",
57+kind: "text",
4658threadId: "thread-1",
4759replyToId: "parent-1",
48-parts: [
49-expect.objectContaining({
50-platformMessageId: "msg-1",
51-kind: "text",
52-threadId: "thread-1",
53-replyToId: "parent-1",
54-}),
55-],
56-}),
57-});
60+},
61+]);
5862});
59636064it("preserves an outbound receipt instead of rebuilding it", async () => {
@@ -85,7 +89,10 @@ describe("createChannelMessageAdapterFromOutbound", () => {
8589});
86908791it("wraps rich payload sends and infers the receipt part kind", async () => {
88-const sendPayload = vi.fn(async () => ({ channel: "demo", messageId: "card-1" }));
92+const sendPayload = vi.fn(async (_request: ChannelMessageSendPayloadContext) => ({
93+channel: "demo",
94+messageId: "card-1",
95+}));
8996const adapter = createChannelMessageAdapterFromOutbound({
9097capabilities: { payload: true, batch: true },
9198outbound: { sendPayload },
@@ -101,16 +108,12 @@ describe("createChannelMessageAdapterFromOutbound", () => {
101108});
102109103110expect(adapter.durableFinal?.capabilities).toEqual({ payload: true, batch: true });
104-expect(sendPayload).toHaveBeenCalledWith(
105-expect.objectContaining({
106-payload: {
107-presentation: { blocks: [{ type: "text", text: "ready" }] },
108-},
109-}),
110-);
111-expect(result?.receipt.parts[0]).toEqual(
112-expect.objectContaining({ platformMessageId: "card-1", kind: "card" }),
113-);
111+expect(sendPayload).toHaveBeenCalledTimes(1);
112+expect(sendPayload.mock.calls[0]?.[0].payload).toEqual({
113+presentation: { blocks: [{ type: "text", text: "ready" }] },
114+});
115+expect(result?.receipt.parts[0]?.platformMessageId).toBe("card-1");
116+expect(result?.receipt.parts[0]?.kind).toBe("card");
114117});
115118116119it("exposes only send methods backed by outbound handlers", async () => {
@@ -125,13 +128,10 @@ describe("createChannelMessageAdapterFromOutbound", () => {
125128throw new Error("expected text send adapter");
126129}
127130128-await expect(sendText({ cfg, to: "room-1", text: "hello" })).resolves.toEqual({
129-messageId: "msg-1",
130-receipt: expect.objectContaining({
131-primaryPlatformMessageId: "msg-1",
132-platformMessageIds: ["msg-1"],
133-}),
134-});
131+const result = await sendText({ cfg, to: "room-1", text: "hello" });
132+expect(result.messageId).toBe("msg-1");
133+expect(result.receipt.primaryPlatformMessageId).toBe("msg-1");
134+expect(result.receipt.platformMessageIds).toEqual(["msg-1"]);
135135expect(adapter.send?.media).toBeUndefined();
136136expect(adapter.send?.payload).toBeUndefined();
137137});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。