Skip to content
File

Blob: tests/worker/lib/yjs-text.test.ts

typescript59 lines
1import { describe, expect, it } from "vitest";
2import * as Y from "yjs";
3import { extractCanvasPlaintext } from "@/shared/editor/yjs-text";
4import { YJS_CANVAS_ELEMENTS, YJS_PAGE_TITLE } from "@/shared/constants";
5 
6function seedElement(ydoc: Y.Doc, id: string, element: Record<string, unknown>): void {
7 const map = ydoc.getMap<Y.Map<unknown>>(YJS_CANVAS_ELEMENTS);
8 const entry = new Y.Map<unknown>();
9 entry.set("element", element);
10 map.set(id, entry);
11}
12 
13describe("extractCanvasPlaintext", () => {
14 it("returns the title and empty body for an empty canvas", () => {
15 const ydoc = new Y.Doc();
16 ydoc.getText(YJS_PAGE_TITLE).insert(0, "Blank canvas");
17 expect(extractCanvasPlaintext(ydoc)).toEqual({ title: "Blank canvas", bodyText: "" });
18 });
19 
20 it("falls back to default title when the page title is blank", () => {
21 const ydoc = new Y.Doc();
22 expect(extractCanvasPlaintext(ydoc)).toEqual({ title: "Untitled", bodyText: "" });
23 });
24 
25 it("collects text from text elements and frame names", () => {
26 const ydoc = new Y.Doc();
27 ydoc.getText(YJS_PAGE_TITLE).insert(0, "Mixed");
28 seedElement(ydoc, "el-1", { id: "el-1", type: "text", text: "Hello world" });
29 seedElement(ydoc, "el-2", { id: "el-2", type: "frame", name: "System Diagram" });
30 seedElement(ydoc, "el-3", { id: "el-3", type: "rectangle" });
31 
32 expect(extractCanvasPlaintext(ydoc)).toEqual({
33 title: "Mixed",
34 bodyText: "Hello world System Diagram",
35 });
36 });
37 
38 it("skips deleted elements (tombstones)", () => {
39 const ydoc = new Y.Doc();
40 ydoc.getText(YJS_PAGE_TITLE).insert(0, "Tombstones");
41 seedElement(ydoc, "el-keep", { id: "el-keep", type: "text", text: "alive" });
42 seedElement(ydoc, "el-dead", { id: "el-dead", type: "text", text: "removed", isDeleted: true });
43 
44 expect(extractCanvasPlaintext(ydoc)).toEqual({ title: "Tombstones", bodyText: "alive" });
45 });
46 
47 it("trims and ignores whitespace-only text elements", () => {
48 const ydoc = new Y.Doc();
49 ydoc.getText(YJS_PAGE_TITLE).insert(0, "Whitespace");
50 seedElement(ydoc, "a", { id: "a", type: "text", text: " " });
51 seedElement(ydoc, "b", { id: "b", type: "text", text: " real content " });
52 
53 expect(extractCanvasPlaintext(ydoc)).toEqual({
54 title: "Whitespace",
55 bodyText: "real content",
56 });
57 });
58});