

























@@ -10,6 +10,26 @@ function createHarness(params: {
1010return createSlackOutboundPayloadHarness(params);
1111}
121213+function sendOptions(call: unknown[] | undefined): {
14+blocks?: Array<{
15+block_id?: string;
16+elements?: Array<{ action_id?: string }>;
17+type?: string;
18+}>;
19+mediaUrl?: string;
20+} {
21+const options = call?.[2];
22+expect(options).toBeDefined();
23+return options as {
24+blocks?: Array<{
25+block_id?: string;
26+elements?: Array<{ action_id?: string }>;
27+type?: string;
28+}>;
29+mediaUrl?: string;
30+};
31+}
32+1333describe("slackOutbound sendPayload", () => {
1434it("renders presentation blocks", async () => {
1535const { run, sendMock, to } = createHarness({
@@ -22,14 +42,12 @@ describe("slackOutbound sendPayload", () => {
2242const result = await run();
23432444expect(sendMock).toHaveBeenCalledTimes(1);
25-expect(sendMock).toHaveBeenCalledWith(
26-to,
27-"Fallback summary",
28-expect.objectContaining({
29-blocks: [{ type: "divider" }],
30-}),
31-);
32-expect(result).toMatchObject({ channel: "slack", messageId: "sl-1" });
45+const call = sendMock.mock.calls[0];
46+expect(call?.[0]).toBe(to);
47+expect(call?.[1]).toBe("Fallback summary");
48+expect(sendOptions(call).blocks).toEqual([{ type: "divider" }]);
49+expect(result.channel).toBe("slack");
50+expect(result.messageId).toBe("sl-1");
3351});
34523553it("sends media before a separate interactive blocks message", async () => {
@@ -52,28 +70,17 @@ describe("slackOutbound sendPayload", () => {
5270const result = await run();
53715472expect(sendMock).toHaveBeenCalledTimes(2);
55-expect(sendMock).toHaveBeenNthCalledWith(
56-1,
57-to,
58-"",
59-expect.objectContaining({
60-mediaUrl: "https://example.com/image.png",
61-}),
62-);
63-expect(sendMock.mock.calls[0]?.[2]).not.toHaveProperty("blocks");
64-expect(sendMock).toHaveBeenNthCalledWith(
65-2,
66-to,
67-"Approval required",
68-expect.objectContaining({
69-blocks: [
70-expect.objectContaining({
71-type: "actions",
72-}),
73-],
74-}),
75-);
76-expect(result).toMatchObject({ channel: "slack", messageId: "sl-controls" });
73+const mediaCall = sendMock.mock.calls[0];
74+expect(mediaCall?.[0]).toBe(to);
75+expect(mediaCall?.[1]).toBe("");
76+expect(sendOptions(mediaCall).mediaUrl).toBe("https://example.com/image.png");
77+expect(mediaCall?.[2]).not.toHaveProperty("blocks");
78+const controlsCall = sendMock.mock.calls[1];
79+expect(controlsCall?.[0]).toBe(to);
80+expect(controlsCall?.[1]).toBe("Approval required");
81+expect(sendOptions(controlsCall).blocks?.[0]?.type).toBe("actions");
82+expect(result.channel).toBe("slack");
83+expect(result.messageId).toBe("sl-controls");
7784});
78857986it("fails when merged Slack blocks exceed the platform limit", async () => {
@@ -131,23 +138,16 @@ describe("slackOutbound sendPayload", () => {
131138132139await run();
133140134-expect(sendMock).toHaveBeenCalledWith(
135-to,
136-"Deploy?",
137-expect.objectContaining({
138-blocks: [
139-expect.objectContaining({ block_id: "openclaw_reply_buttons_1" }),
140-expect.objectContaining({
141-block_id: "openclaw_reply_buttons_2",
142-elements: [expect.objectContaining({ action_id: "openclaw:reply_button:2:1" })],
143-}),
144-expect.objectContaining({
145-block_id: "openclaw_reply_buttons_3",
146-elements: [expect.objectContaining({ action_id: "openclaw:reply_button:3:1" })],
147-}),
148-],
149-}),
150-);
141+expect(sendMock).toHaveBeenCalledTimes(1);
142+const call = sendMock.mock.calls[0];
143+expect(call?.[0]).toBe(to);
144+expect(call?.[1]).toBe("Deploy?");
145+const blocks = sendOptions(call).blocks;
146+expect(blocks?.[0]?.block_id).toBe("openclaw_reply_buttons_1");
147+expect(blocks?.[1]?.block_id).toBe("openclaw_reply_buttons_2");
148+expect(blocks?.[1]?.elements?.[0]?.action_id).toBe("openclaw:reply_button:2:1");
149+expect(blocks?.[2]?.block_id).toBe("openclaw_reply_buttons_3");
150+expect(blocks?.[2]?.elements?.[0]?.action_id).toBe("openclaw:reply_button:3:1");
151151});
152152});
153153此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。