import { expect, test } from "@playwright/test"; import JSZip from "jszip"; import { readFile } from "node:fs/promises"; import { exportXmind } from "@/lib/flow-board/xmind-export"; import { importXmind } from "@/lib/flow-board/xmind-import"; import { getTopicEntries } from "@/lib/flow-board/topic-details"; import { getXmindMarkerIds, toggleXmindMarker, XMIND_MARKER_GROUPS } from "@/lib/flow-board/xmind-markers"; test("all installed marker IDs and artwork exist and round-trip through XMind", async () => { const markers = XMIND_MARKER_GROUPS.flatMap(group => group.markers); expect(markers).toHaveLength(219); expect(new Set(markers.map(marker => marker.id)).size).toBe(197); expect(XMIND_MARKER_GROUPS.filter(group => !group.hidden).flatMap(group => group.markers.filter(marker => !marker.hidden))).toHaveLength(58); for (const marker of markers) expect((await readFile(`public${marker.asset}`)).length).toBeGreaterThan(50); const zip = new JSZip(); zip.file("content.json", JSON.stringify([{ title: "标记", rootTopic: { id: "root", title: "全标记验证", children: { attached: markers.map(marker => ({ id: marker.id, title: marker.id, markers: [{ markerId: marker.id }] })) }, } }])); const imported = await importXmind(new File([await zip.generateAsync({ type: "uint8array" })], "markers.xmind"), "标记"); const entries = getTopicEntries(imported.sheets[0].children).slice(1); expect(entries.map(entry => getXmindMarkerIds(entry.element.data.emojis)[0])).toEqual(markers.map(marker => marker.id)); expect(imported.warnings).not.toContain("部分图标已保留为数据,暂不显示"); const exported = await exportXmind({ children: imported.sheets[0].children }, "标记"); const output = await JSZip.loadAsync(await exported.blob.arrayBuffer()); const sheets = JSON.parse(await output.file("content.json")!.async("string")); expect(sheets[0].rootTopic.children.attached.map((topic: { markers: { markerId: string }[] }) => topic.markers[0].markerId)).toEqual(markers.map(marker => marker.id)); expect(exported.warnings).toEqual([]); }); test("legacy emoji markers replace within their group and preserve other groups and custom emoji", () => { const original = [{ name: "1️⃣" }, { name: "✅" }, { name: "🦄" }]; const replaced = toggleXmindMarker(original, "priority-2", false); expect(getXmindMarkerIds(replaced)).toEqual(["task-done", "priority-2"]); expect(replaced).toContainEqual({ name: "🦄" }); expect(getXmindMarkerIds(toggleXmindMarker(replaced, "priority-2", true))).toEqual(["task-done"]); expect(original).toEqual([{ name: "1️⃣" }, { name: "✅" }, { name: "🦄" }]); });