openclaw / src /chat /canvas-render.test.ts
SaylorTwift's picture
SaylorTwift HF Staff
Add files using upload-large-folder tool
e18726e verified
Raw History Blame Contribute Delete
4.39 kB
// Canvas-render tests cover [embed] shortcode extraction and text stripping.
import { describe, expect, it } from "vitest";
import {
extractCanvasFromDetails,
extractCanvasFromText,
extractCanvasShortcodes,
} from "./canvas-render.ts";
describe("extractCanvasFromText", () => {
it("preserves a valid pinned board widget identity", () => {
expect(
extractCanvasFromText(
JSON.stringify({
kind: "canvas",
view: {
id: "cv_status",
url: "/__openclaw__/canvas/documents/cv_status/index.html",
boardWidgetName: "release-status",
},
}),
),
).toMatchObject({ viewId: "cv_status", boardWidgetName: "release-status" });
});
it("preserves node-panel presentation metadata", () => {
expect(
extractCanvasFromText(
JSON.stringify({
kind: "canvas",
presentation: { target: "node_panel", title: "Status" },
view: { id: "cv_status", url: "/__openclaw__/canvas/documents/cv_status/index.html" },
}),
),
).toMatchObject({ surface: "node_panel", viewId: "cv_status", title: "Status" });
});
it("extracts safe MCP App preview metadata from tool details", () => {
expect(
extractCanvasFromDetails({
mcpAppPreview: {
kind: "canvas",
view: { id: "cv_app" },
presentation: { target: "assistant_message", sandbox: "scripts" },
mcpApp: {
viewId: "cv_app",
serverName: "demo",
toolName: "show",
uiResourceUri: "ui://demo/app",
toolCallId: "call-1",
originSessionKey: "agent:main:main",
resultMetaState: "unavailable",
},
},
}),
).toMatchObject({
viewId: "cv_app",
mcpApp: {
viewId: "cv_app",
serverName: "demo",
toolName: "show",
uiResourceUri: "ui://demo/app",
toolCallId: "call-1",
originSessionKey: "agent:main:main",
resultMetaState: "unavailable",
},
});
});
it("keeps MCP App previews opaque while preserving model-visible results", () => {
const preview = extractCanvasFromText(
JSON.stringify({
kind: "canvas",
view: { id: "cv_app" },
presentation: { target: "assistant_message", sandbox: "scripts" },
mcpApp: { viewId: "cv_app" },
result: [{ type: "text", text: "model-visible result" }],
}),
);
expect(preview).toMatchObject({
viewId: "cv_app",
sandbox: "scripts",
mcpApp: { viewId: "cv_app" },
});
});
});
describe("extractCanvasShortcodes", () => {
it("does not let a self-closing embed start a greedy block match", () => {
// Regression: the block regex used to greedily swallow the span from a
// self-closing "[embed ... /]" open tag up to a later stray "[/embed]",
// deleting the visible text in between (" keep me ") from channel delivery.
const input = '[embed url="https://a.com" /] keep me [/embed]';
const { text, previews } = extractCanvasShortcodes(input);
expect(previews).toHaveLength(1);
expect(previews[0]?.url).toBe("https://a.com");
// The visible text between the self-closing embed and the stray close
// marker must be preserved, not silently stripped.
expect(text).toContain("keep me");
expect(text).toBe(" keep me [/embed]");
});
it("still extracts a normal block embed and strips only the shortcode span", () => {
const input = 'before [embed ref="doc1"] hi [/embed] after';
const { text, previews } = extractCanvasShortcodes(input);
expect(previews).toHaveLength(1);
expect(previews[0]?.viewId).toBe("doc1");
expect(text).toBe("before after");
});
it("still extracts a plain self-closing embed and keeps surrounding text", () => {
const input = 'see [embed url="https://b.com" /] end';
const { text, previews } = extractCanvasShortcodes(input);
expect(previews).toHaveLength(1);
expect(previews[0]?.url).toBe("https://b.com");
expect(text).toBe("see end");
});
});
it("removes a shortcode without rewriting surrounding literal whitespace", () => {
const source = ' a\n\n\n b\n\n[embed ref="doc1" /]';
expect(extractCanvasShortcodes(source)).toMatchObject({
text: " a\n\n\n b\n\n",
previews: [{ viewId: "doc1" }],
});
});