import assert from "node:assert/strict";
import { readFile } from "node:fs/promises";
import test from "node:test";
import {
canvasNodeClipboardMime,
canvasNodeFromClipboardData,
canvasNodeFromClipboardItems,
createPastedCanvasNode,
parseCanvasNodeClipboard,
serializeCanvasNodeClipboard,
serializeCanvasNodeClipboardSvg
} from "../src/ui/pages/CanvasWorkspace/canvas/canvasNodeClipboard.ts";
const pathNode = {
id: "path-1",
type: "frame",
title: "Circle",
x: 100,
y: 200,
width: 300,
height: 180,
content: JSON.stringify({ kind: "path", pathData: [1, 0, 0.5, 5, 0.25, 0, 0.75, 1, 1, 0.5, 11] }),
tone: "shape",
status: "draft",
layerRole: "shape",
fillColor: "transparent",
strokeColor: "#111827",
strokeWidth: 2
};
test("round-trips editable path nodes through the internal clipboard format", () => {
const parsed = parseCanvasNodeClipboard(serializeCanvasNodeClipboard(pathNode));
assert.deepEqual(parsed, pathNode);
assert.equal(JSON.parse(parsed.content).kind, "path");
});
test("creates a pasted path node at the clipboard anchor without rasterizing it", () => {
const pasted = createPastedCanvasNode(pathNode, "path-copy", { x: 800, y: 600 });
assert.equal(pasted.id, "path-copy");
assert.equal(pasted.type, "frame");
assert.equal(pasted.layerRole, "shape");
assert.equal(pasted.title, pathNode.title);
assert.equal(pasted.status, pathNode.status);
assert.equal(JSON.parse(pasted.content).kind, "path");
assert.equal(pasted.x, 650);
assert.equal(pasted.y, 510);
});
test("prefers internal path data when the clipboard also contains a PNG preview", async () => {
const serialized = serializeCanvasNodeClipboard(pathNode);
const dataTransfer = {
files: [new File(["png"], "preview.png", { type: "image/png" })],
getData: (type) => (type === canvasNodeClipboardMime ? serialized : "")
};
const clipboardItem = {
types: ["image/png", canvasNodeClipboardMime],
getType: async (type) => new Blob([type === canvasNodeClipboardMime ? serialized : "png"], { type })
};
assert.deepEqual(canvasNodeFromClipboardData(dataTransfer), pathNode);
assert.deepEqual(await canvasNodeFromClipboardItems([clipboardItem]), pathNode);
});
test("restores path data from the standard SVG clipboard fallback", () => {
const svg = serializeCanvasNodeClipboardSvg(pathNode, '');
const dataTransfer = {
getData: (type) => (type === "text/plain" ? svg : "")
};
assert.match(svg, /^