// @vitest-environment jsdom import { describe, expect, it } from "vitest"; import { bodyToHtml, htmlToBody } from "./article-html"; describe("article body ↔ Quill HTML", () => { it("round-trips clauses and bullets unchanged", () => { const body = [ "Provide written instructions for each shipment.", "Prepare all necessary documents.", "- Commercial invoice", "- Packing list", "Pay 100% in advance.", ].join("\n"); expect(htmlToBody(bodyToHtml(body))).toBe(body); }); it("keeps a single paragraph a single paragraph", () => { const body = "The contract is valid once signed by both parties."; expect(htmlToBody(bodyToHtml(body))).toBe(body); }); it("preserves placeholders verbatim through a round trip", () => { const body = "Valid until August 31, {{contractYear}} for {{client.companyName}}."; expect(htmlToBody(bodyToHtml(body))).toBe(body); }); it("escapes and restores characters that are HTML-significant", () => { const body = "Rates < 100 & > 50 apply to the Client's cargo."; expect(htmlToBody(bodyToHtml(body))).toBe(body); }); it("maps Quill indent classes onto sub-clause depth", () => { const html = "

Top level clause.

" + '

Nested one level.

' + '

Nested two levels.

'; expect(htmlToBody(html)).toBe( ["Top level clause.", "1.1. Nested one level.", "1.1.1. Nested two levels."].join( "\n", ), ); }); it("turns Quill bullet lists into '- ' lines", () => { const html = "

Documents:

"; expect(htmlToBody(html)).toBe("Documents:\n- Invoice\n- Waybill"); }); it("treats an ordered list as clause lines, not bullets", () => { const html = "
  1. First clause.
  2. Second clause.
"; expect(htmlToBody(html)).toBe("1. First clause.\n1. Second clause."); }); it("normalises the nbsp Quill inserts and drops empty blocks", () => { const html = "

Payment in advance.


"; expect(htmlToBody(html)).toBe("Payment in advance."); }); it("returns an empty editor for an empty body", () => { expect(bodyToHtml("")).toBe("


"); expect(htmlToBody("


")).toBe(""); }); });