import { describe, expect, it } from "vitest"; import { exportDocxBlob, htmlToWordBlocks, importDocxFile } from "./wordOffice"; const tinyPngBase64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+/p9sAAAAASUVORK5CYII="; const tinyPngDataUri = `data:image/png;base64,${tinyPngBase64}`; describe("wordOffice DOCX import", () => { it("imports DOCX text color and highlight from OOXML", async () => { const blob = await exportDocxBlob( "Color.docx", '

Color fragment

' ); const file = new File([blob], "Color.docx", { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }); const imported = await importDocxFile(file); expect(imported.html).toContain("color: #0F5FAE;"); expect(imported.html).toContain("background-color: #FFF2CC;"); expect(htmlToWordBlocks(imported.html)).toEqual([ { type: "paragraph", text: "Color fragment", runs: [{ text: "Color fragment", color: "0F5FAE", highlightColor: "FFF2CC" }] } ]); }); it("imports DOCX paragraph alignment from OOXML", async () => { const blob = await exportDocxBlob( "Alignment.docx", '

Centered

Right

Justified

' ); const file = new File([blob], "Alignment.docx", { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }); const imported = await importDocxFile(file); expect(imported.html).toContain('style="text-align: center;"'); expect(imported.html).toContain('style="text-align: right;"'); expect(imported.html).toContain('style="text-align: justify;"'); expect(htmlToWordBlocks(imported.html)).toEqual([ { type: "paragraph", text: "Centered", runs: [{ text: "Centered" }], alignment: "center" }, { type: "paragraph", text: "Right", runs: [{ text: "Right" }], alignment: "right" }, { type: "paragraph", text: "Justified", runs: [{ text: "Justified" }], alignment: "both" } ]); }); it("imports DOCX font size from OOXML", async () => { const blob = await exportDocxBlob("FontSize.docx", '

Large text

'); const file = new File([blob], "FontSize.docx", { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }); const imported = await importDocxFile(file); expect(imported.html).toContain("font-size: 18pt;"); expect(htmlToWordBlocks(imported.html)).toEqual([ { type: "paragraph", text: "Large text", runs: [{ text: "Large text", fontSize: 18 }] } ]); }); it("imports DOCX font family from OOXML", async () => { const blob = await exportDocxBlob("FontFamily.docx", '

Arial text

'); const file = new File([blob], "FontFamily.docx", { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }); const imported = await importDocxFile(file); expect(imported.html).toContain("font-family: 'Arial';"); expect(htmlToWordBlocks(imported.html)).toEqual([ { type: "paragraph", text: "Arial text", runs: [{ text: "Arial text", fontFamily: "Arial" }] } ]); }); it("imports DOCX strikethrough from OOXML", async () => { const blob = await exportDocxBlob("Strike.docx", "

Deleted text

"); const file = new File([blob], "Strike.docx", { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }); const imported = await importDocxFile(file); expect(imported.html).toContain("Deleted text"); expect(htmlToWordBlocks(imported.html)).toEqual([ { type: "paragraph", text: "Deleted text", runs: [{ text: "Deleted text", strike: true }] } ]); }); it("imports DOCX line breaks from OOXML", async () => { const blob = await exportDocxBlob("LineBreak.docx", "

Line 1
Line 2

"); const file = new File([blob], "LineBreak.docx", { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }); const imported = await importDocxFile(file); expect(imported.html).toContain("Line 1
Line 2"); expect(htmlToWordBlocks(imported.html)).toEqual([ { type: "paragraph", text: "Line 1 Line 2", runs: [{ text: "Line 1\nLine 2" }] } ]); }); it("imports DOCX tabs from OOXML", async () => { const blob = await exportDocxBlob("Tab.docx", '

Before\tAfter

'); const file = new File([blob], "Tab.docx", { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }); const imported = await importDocxFile(file); expect(imported.html).toContain('data-qoffice-tab="true"'); expect(htmlToWordBlocks(imported.html)).toEqual([ { type: "paragraph", text: "Before After", runs: [{ text: "Before\tAfter" }] } ]); }); it("imports DOCX external hyperlinks from OOXML relationships", async () => { const blob = await exportDocxBlob("Hyperlink.docx", '

Open report.

'); const file = new File([blob], "Hyperlink.docx", { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }); const imported = await importDocxFile(file); expect(imported.html).toContain(''); expect(htmlToWordBlocks(imported.html)).toEqual([ { type: "paragraph", text: "Open report.", runs: [ { text: "Open " }, { text: "report", bold: true, href: "https://example.com/report" }, { text: "." } ] } ]); }); it("imports simple DOCX tables from OOXML", async () => { const blob = await exportDocxBlob( "Table.docx", "

Before table

StageOwner
PlanAnna

After table

" ); const file = new File([blob], "Table.docx", { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }); const imported = await importDocxFile(file); expect(imported.html).toContain(""); expect(imported.html).toContain(""); expect(imported.html).toContain(""); expect(htmlToWordBlocks(imported.html)).toEqual([ { type: "paragraph", text: "Before table", runs: [{ text: "Before table" }] }, { type: "table", rows: [ ["Stage", "Owner"], ["Plan", "Anna"] ] }, { type: "paragraph", text: "After table", runs: [{ text: "After table" }] } ]); }); it("imports styled DOCX content when the document also contains images", async () => { const blob = await exportDocxBlob( "Mixed.docx", `

Color fragment

Logo

Stage

Anna

StageDone
` ); const file = new File([blob], "Mixed.docx", { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document" }); const imported = await importDocxFile(file); const blocks = htmlToWordBlocks(imported.html); expect(imported.html).toContain("color: #0F5FAE;"); expect(imported.html).toContain(""); expect(imported.html).toContain(`src="${tinyPngDataUri}"`); expect(blocks[0]).toEqual({ type: "paragraph", text: "Color fragment", runs: [{ text: "Color fragment", color: "0F5FAE" }] }); expect(blocks[1]).toMatchObject({ type: "image", src: tinyPngDataUri, alt: "Logo", width: 32, height: 32 }); expect(blocks[2]).toEqual({ type: "table", rows: [["Stage", "Done"]] }); }); });