























@@ -1,5 +1,6 @@
11import { describe, expect, it } from "vitest";
2-import { buildSlackInteractiveBlocks } from "./blocks-render.js";
2+import { buildSlackInteractiveBlocks, buildSlackPresentationBlocks } from "./blocks-render.js";
3+import { resolveSlackReplyBlocks } from "./reply-blocks.js";
3445describe("buildSlackInteractiveBlocks", () => {
56it("renders shared interactive blocks in authored order", () => {
@@ -306,3 +307,87 @@ describe("buildSlackInteractiveBlocks", () => {
306307expect(buttonBlock.elements?.[3]).not.toHaveProperty("style");
307308});
308309});
310+311+describe("buildSlackPresentationBlocks", () => {
312+it("renders presentation controls without requiring legacy interactive payloads", () => {
313+const blocks = buildSlackPresentationBlocks({
314+blocks: [
315+{ type: "text", text: "Pick" },
316+{
317+type: "buttons",
318+buttons: [{ label: "Approve", value: "approve", style: "success" }],
319+},
320+],
321+});
322+323+expect(blocks).toEqual([
324+{
325+type: "section",
326+text: { type: "mrkdwn", text: "Pick" },
327+},
328+{
329+type: "actions",
330+block_id: "openclaw_reply_buttons_1",
331+elements: [
332+{
333+type: "button",
334+action_id: "openclaw:reply_button:1:1",
335+text: {
336+type: "plain_text",
337+text: "Approve",
338+emoji: true,
339+},
340+value: "approve",
341+style: "primary",
342+},
343+],
344+},
345+]);
346+});
347+});
348+349+describe("resolveSlackReplyBlocks", () => {
350+it("offsets legacy interactive blocks after channel and presentation controls", () => {
351+const blocks = resolveSlackReplyBlocks({
352+channelData: {
353+slack: {
354+blocks: [
355+{
356+type: "actions",
357+block_id: "openclaw_reply_buttons_1",
358+elements: [],
359+},
360+],
361+},
362+},
363+presentation: {
364+blocks: [
365+{
366+type: "buttons",
367+buttons: [{ label: "Stage", value: "stage" }],
368+},
369+],
370+},
371+interactive: {
372+blocks: [
373+{
374+type: "buttons",
375+buttons: [{ label: "Approve", value: "approve" }],
376+},
377+],
378+},
379+});
380+381+const presentationButtonBlock = blocks?.[1] as
382+| { elements?: Array<{ action_id?: string }> }
383+| undefined;
384+const legacyButtonBlock = blocks?.[2] as
385+| { elements?: Array<{ action_id?: string }> }
386+| undefined;
387+expect(blocks?.[0]?.block_id).toBe("openclaw_reply_buttons_1");
388+expect(blocks?.[1]?.block_id).toBe("openclaw_reply_buttons_2");
389+expect(presentationButtonBlock?.elements?.[0]?.action_id).toBe("openclaw:reply_button:2:1");
390+expect(blocks?.[2]?.block_id).toBe("openclaw_reply_buttons_3");
391+expect(legacyButtonBlock?.elements?.[0]?.action_id).toBe("openclaw:reply_button:3:1");
392+});
393+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。