import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import * as chai from "chai";
import JSZip from "jszip";
import chaiAsPromised from "chai-as-promised";
import { ExternalHyperlink, ImageRun, Paragraph, TextRun } from "@file/paragraph";
import { patchDocument, PatchType } from "./from-docx";
chai.use(chaiAsPromised);
const MOCK_XML = `
Hello World
Hello {{name}},
how are you?
{{paragraph_replace}}
{{table}}
{{table_heading_1}}
Item: {{item_1}}
{{image_test}}
Thank you
`;
describe("from-docx", () => {
describe("patchDocument", () => {
describe("document.xml and [Content_Types].xml", () => {
beforeEach(() => {
vi.spyOn(JSZip, "loadAsync").mockReturnValue(
new Promise((resolve) => {
const zip = new JSZip();
zip.file("word/document.xml", MOCK_XML);
zip.file("[Content_Types].xml", ``);
resolve(zip);
}),
);
});
afterEach(() => {
vi.restoreAllMocks();
});
it("should patch the document", async () => {
const output = await patchDocument(Buffer.from(""), {
patches: {
name: {
type: PatchType.PARAGRAPH,
children: [new TextRun("Sir. "), new TextRun("John Doe"), new TextRun("(The Conqueror)")],
},
item_1: {
type: PatchType.PARAGRAPH,
children: [
new TextRun("#657"),
new ExternalHyperlink({
children: [
new TextRun({
text: "BBC News Link",
}),
],
link: "https://www.bbc.co.uk/news",
}),
],
},
// eslint-disable-next-line @typescript-eslint/naming-convention
paragraph_replace: {
type: PatchType.DOCUMENT,
children: [
new Paragraph({
children: [
new TextRun("This is a "),
new ExternalHyperlink({
children: [
new TextRun({
text: "Google Link",
}),
],
link: "https://www.google.co.uk",
}),
new ImageRun({
data: Buffer.from(""),
transformation: { width: 100, height: 100 },
}),
],
}),
],
},
// eslint-disable-next-line @typescript-eslint/naming-convention
image_test: {
type: PatchType.PARAGRAPH,
children: [
new ImageRun({
data: Buffer.from(""),
transformation: { width: 100, height: 100 },
}),
],
},
},
});
expect(output).to.not.be.undefined;
});
it("should patch the document", async () => {
const output = await patchDocument(Buffer.from(""), {
patches: {},
});
expect(output).to.not.be.undefined;
});
});
describe("document.xml and [Content_Types].xml with relationships", () => {
beforeEach(() => {
vi.spyOn(JSZip, "loadAsync").mockReturnValue(
new Promise((resolve) => {
const zip = new JSZip();
zip.file("word/document.xml", MOCK_XML);
zip.file("word/_rels/document.xml.rels", ``);
zip.file("[Content_Types].xml", ``);
resolve(zip);
}),
);
});
afterEach(() => {
vi.restoreAllMocks();
});
it("should use the relationships file rather than create one", async () => {
const output = await patchDocument(Buffer.from(""), {
patches: {
// eslint-disable-next-line @typescript-eslint/naming-convention
image_test: {
type: PatchType.PARAGRAPH,
children: [
new ImageRun({
data: Buffer.from(""),
transformation: { width: 100, height: 100 },
}),
new ExternalHyperlink({
children: [
new TextRun({
text: "Google Link",
}),
],
link: "https://www.google.co.uk",
}),
],
},
},
});
expect(output).to.not.be.undefined;
});
});
describe("document.xml", () => {
beforeEach(() => {
vi.spyOn(JSZip, "loadAsync").mockReturnValue(
new Promise((resolve) => {
const zip = new JSZip();
zip.file("word/document.xml", MOCK_XML);
resolve(zip);
}),
);
});
afterEach(() => {
vi.restoreAllMocks();
});
it("should throw an error if the content types is not found", () =>
expect(
patchDocument(Buffer.from(""), {
patches: {
// eslint-disable-next-line @typescript-eslint/naming-convention
image_test: {
type: PatchType.PARAGRAPH,
children: [
new ImageRun({
data: Buffer.from(""),
transformation: { width: 100, height: 100 },
}),
],
},
},
}),
).to.eventually.be.rejected);
});
describe("Images", () => {
beforeEach(() => {
vi.spyOn(JSZip, "loadAsync").mockReturnValue(
new Promise((resolve) => {
const zip = new JSZip();
zip.file("word/document.xml", MOCK_XML);
zip.file("word/document.bmp", "");
resolve(zip);
}),
);
});
afterEach(() => {
vi.restoreAllMocks();
});
it("should throw an error if the content types is not found", () =>
expect(
patchDocument(Buffer.from(""), {
patches: {
// eslint-disable-next-line @typescript-eslint/naming-convention
image_test: {
type: PatchType.PARAGRAPH,
children: [
new ImageRun({
data: Buffer.from(""),
transformation: { width: 100, height: 100 },
}),
],
},
},
}),
).to.eventually.be.rejected);
});
});
});