80 lines
2.3 KiB
TypeScript
80 lines
2.3 KiB
TypeScript
import { expect, test } from "@playwright/test";
|
|
import { normalizeFlowBoardSnapshot } from "@/app/api/flow-board/_utils";
|
|
import {
|
|
getSafeTopicHref,
|
|
getTopicDetails,
|
|
patchTopicDetails,
|
|
} from "@/lib/flow-board/topic-details";
|
|
|
|
test("topic notes, labels, links and resources survive snapshot serialization", () => {
|
|
const topic = {
|
|
id: "topic",
|
|
type: "mindmap",
|
|
xmind: {
|
|
notes: { plain: { content: "第一行\n第二行" } },
|
|
labels: ["标签一", "标签二"],
|
|
href: "https://example.com",
|
|
topicLinkId: "target",
|
|
attachment: {
|
|
name: "spec.txt",
|
|
url: "data:application/octet-stream;base64,eA==",
|
|
mimeType: "application/octet-stream",
|
|
},
|
|
},
|
|
data: {
|
|
image: { url: "data:image/png;base64,eA==", width: 32, height: 32 },
|
|
},
|
|
};
|
|
const snapshot = normalizeFlowBoardSnapshot(
|
|
JSON.parse(JSON.stringify({ children: [topic] }))
|
|
);
|
|
expect(snapshot.children[0]).toEqual(topic);
|
|
expect(getTopicDetails(topic)).toMatchObject({
|
|
notes: "第一行\n第二行",
|
|
labels: ["标签一", "标签二"],
|
|
topicLinkId: "target",
|
|
attachment: { name: "spec.txt" },
|
|
});
|
|
});
|
|
|
|
test("editing a note preserves image metadata and non-edited labels and links", () => {
|
|
const topic = {
|
|
id: "topic",
|
|
xmind: {
|
|
notes: { plain: { content: "旧备注" } },
|
|
labels: ["保留"],
|
|
image: { src: "xap:resources/a.png" },
|
|
href: "https://example.com",
|
|
markers: [{ markerId: "priority-1" }],
|
|
},
|
|
};
|
|
const metadata = patchTopicDetails(topic, { notes: "新备注" });
|
|
expect(metadata).toEqual({
|
|
...topic.xmind,
|
|
notes: { plain: { content: "新备注" } },
|
|
});
|
|
expect(
|
|
getTopicDetails({
|
|
...topic,
|
|
xmind: patchTopicDetails(topic, { notes: "" }),
|
|
}).notes
|
|
).toBe("");
|
|
});
|
|
|
|
test("links cannot execute script and external URLs require an allowed protocol", () => {
|
|
for (const value of [
|
|
"javascript:alert(1)",
|
|
"data:text/html,<script>x</script>",
|
|
"file:///etc/passwd",
|
|
"//example.com",
|
|
"xmind:#target",
|
|
])
|
|
expect(getSafeTopicHref(value)).toBeNull();
|
|
expect(getSafeTopicHref("https://example.com/a?q=b")).toBe(
|
|
"https://example.com/a?q=b"
|
|
);
|
|
expect(getSafeTopicHref("mailto:hello@example.com")).toBe(
|
|
"mailto:hello@example.com"
|
|
);
|
|
});
|