import { createElement } from "react"; import { renderToStaticMarkup } from "react-dom/server"; import { describe, expect, it } from "vitest"; import { createUniqueOutlineAnchorId, normalizeOutlineText, OutlinePresentation, readOutlineLevel, resolveViewportActiveOutlineHeading, type OutlineItem, } from "@/shared/editor/presentation"; describe("shared outline rendering", () => { it("normalizes outline text, heading levels, and duplicate-safe anchor ids", () => { const used = new Set(); expect(normalizeOutlineText(" Intro\n\tsection ")).toBe("Intro section"); expect(readOutlineLevel(2)).toBe(2); expect(readOutlineLevel("3")).toBe(3); expect(readOutlineLevel(9)).toBe(1); expect(createUniqueOutlineAnchorId("Intro!", used)).toBe("intro"); expect(createUniqueOutlineAnchorId("Intro", used)).toBe("intro-2"); expect(createUniqueOutlineAnchorId("你好", used)).toBe("section"); expect(createUniqueOutlineAnchorId("?!", used)).toBe("section-2"); }); it("renders matching button and link outline markup", () => { const items: OutlineItem[] = [ { id: "intro", text: "Intro", level: 1, href: "#intro" }, { id: "deep", text: "Deep section", level: 3, href: "#custom-deep" }, ]; const buttonHtml = renderToStaticMarkup( createElement(OutlinePresentation, { items, activeId: "deep", mode: "button", title: "On this page", }), ); expect(buttonHtml).toContain('class="tiptap-outline"'); expect(buttonHtml).toContain('aria-label="On this page"'); expect(buttonHtml).toContain('