






















@@ -9,6 +9,7 @@ import type { OpenClawConfig } from "../runtime-api.js";
99const mocks = vi.hoisted(() => ({
1010sendText: vi.fn(),
1111sendMedia: vi.fn(),
12+sendPayload: vi.fn(),
1213sendPoll: vi.fn(),
1314}));
1415@@ -17,6 +18,7 @@ vi.mock("./channel.runtime.js", () => ({
1718msteamsOutbound: {
1819sendText: mocks.sendText,
1920sendMedia: mocks.sendMedia,
21+sendPayload: mocks.sendPayload,
2022sendPoll: mocks.sendPoll,
2123},
2224},
@@ -55,6 +57,16 @@ function requireMediaSender(
5557return media;
5658}
575960+function requirePayloadSender(
61+adapter: MSTeamsMessageAdapter,
62+): NonNullable<MSTeamsMessageSender["payload"]> {
63+const payload = adapter.send?.payload;
64+if (!payload) {
65+throw new Error("Expected msteams message adapter payload sender");
66+}
67+return payload;
68+}
69+5870const cfg = {
5971channels: {
6072msteams: {
@@ -67,6 +79,7 @@ describe("msteams channel message adapter", () => {
6779beforeEach(() => {
6880mocks.sendText.mockReset();
6981mocks.sendMedia.mockReset();
82+mocks.sendPayload.mockReset();
7083mocks.sendPoll.mockReset();
7184mocks.sendText.mockResolvedValue({
7285channel: "msteams",
@@ -78,12 +91,18 @@ describe("msteams channel message adapter", () => {
7891messageId: "msg-media-1",
7992conversationId: "conv-1",
8093});
94+mocks.sendPayload.mockResolvedValue({
95+channel: "msteams",
96+messageId: "msg-payload-1",
97+conversationId: "conv-1",
98+});
8199});
8210083101it("backs declared durable-final capabilities with outbound send proofs", async () => {
84102const adapter = requireMSTeamsMessageAdapter();
85103const sendText = requireTextSender(adapter);
86104const sendMedia = requireMediaSender(adapter);
105+const sendPayload = requirePayloadSender(adapter);
87106expect(adapter.durableFinal?.capabilities?.replyTo).toBeUndefined();
88107expect(adapter.durableFinal?.capabilities?.thread).toBeUndefined();
89108@@ -127,12 +146,38 @@ describe("msteams channel message adapter", () => {
127146expect(result.receipt.parts[0]?.kind).toBe("media");
128147};
129148149+const provePayload = async () => {
150+mocks.sendPayload.mockClear();
151+const payload = {
152+presentation: {
153+blocks: [{ type: "text" as const, text: "card body" }],
154+},
155+};
156+const result = await sendPayload({
157+ cfg,
158+to: "conversation:abc",
159+text: "",
160+ payload,
161+accountId: "default",
162+});
163+expect(mocks.sendPayload).toHaveBeenLastCalledWith({
164+ cfg,
165+to: "conversation:abc",
166+text: "",
167+ payload,
168+accountId: "default",
169+});
170+expect(result.receipt.platformMessageIds).toEqual(["msg-payload-1"]);
171+expect(result.receipt.parts[0]?.kind).toBe("card");
172+};
173+130174await verifyChannelMessageAdapterCapabilityProofs({
131175adapterName: "msteamsMessageAdapter",
132176 adapter,
133177proofs: {
134178text: proveText,
135179media: proveMedia,
180+payload: provePayload,
136181messageSendingHooks: () => {
137182expect(sendText).toBeTypeOf("function");
138183},
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。