refactor: extract buildPdfOptions to DRY up renderPdf/renderUrlPdf (TDD)
Some checks failed
Build & Deploy to Staging / Build & Deploy to Staging (push) Has been cancelled

- Extract shared PDF options construction into buildPdfOptions()
- Both renderPdf and renderUrlPdf now use the shared builder
- 5 TDD tests added (pdf-options-builder.test.ts)
- 633 tests passing, 0 tsc errors
This commit is contained in:
DocFast CEO 2026-03-10 14:04:19 +01:00
parent b1a09f7b3f
commit 4e00feb860
3 changed files with 98 additions and 31 deletions

View file

@ -0,0 +1,68 @@
import { describe, it, expect } from "vitest";
import { buildPdfOptions, PdfRenderOptions } from "../services/browser.js";
describe("buildPdfOptions", () => {
it("returns sensible defaults when no options given", () => {
const result = buildPdfOptions({});
expect(result).toEqual({
format: "A4",
landscape: false,
printBackground: true,
margin: { top: "0", right: "0", bottom: "0", left: "0" },
});
});
it("passes through all provided options", () => {
const opts: PdfRenderOptions = {
format: "Letter",
landscape: true,
printBackground: false,
margin: { top: "10mm", bottom: "10mm" },
scale: 1.5,
pageRanges: "1-3",
preferCSSPageSize: true,
width: "210mm",
height: "297mm",
headerTemplate: "<span>Header</span>",
footerTemplate: "<span>Footer</span>",
displayHeaderFooter: true,
};
const result = buildPdfOptions(opts);
expect(result.format).toBe("Letter");
expect(result.landscape).toBe(true);
expect(result.printBackground).toBe(false);
expect(result.margin).toEqual({ top: "10mm", bottom: "10mm" });
expect(result.scale).toBe(1.5);
expect(result.pageRanges).toBe("1-3");
expect(result.preferCSSPageSize).toBe(true);
expect(result.width).toBe("210mm");
expect(result.height).toBe("297mm");
expect(result.headerTemplate).toBe("<span>Header</span>");
expect(result.footerTemplate).toBe("<span>Footer</span>");
expect(result.displayHeaderFooter).toBe(true);
});
it("omits undefined optional fields from output", () => {
const result = buildPdfOptions({ format: "A4" });
expect(result).not.toHaveProperty("scale");
expect(result).not.toHaveProperty("pageRanges");
expect(result).not.toHaveProperty("preferCSSPageSize");
expect(result).not.toHaveProperty("width");
expect(result).not.toHaveProperty("height");
expect(result).not.toHaveProperty("headerTemplate");
expect(result).not.toHaveProperty("footerTemplate");
});
it("handles printBackground false explicitly", () => {
const result = buildPdfOptions({ printBackground: false });
expect(result.printBackground).toBe(false);
});
it("defaults displayHeaderFooter to false only when explicitly set", () => {
const r1 = buildPdfOptions({});
expect(r1).not.toHaveProperty("displayHeaderFooter");
const r2 = buildPdfOptions({ displayHeaderFooter: false });
expect(r2.displayHeaderFooter).toBe(false);
});
});

View file

@ -53,7 +53,10 @@ vi.mock("../services/keys.js", () => {
});
// Mock browser service
vi.mock("../services/browser.js", () => ({
vi.mock("../services/browser.js", async (importOriginal) => {
const actual = await importOriginal<Record<string, unknown>>();
return {
buildPdfOptions: actual.buildPdfOptions,
initBrowser: vi.fn().mockResolvedValue(undefined),
closeBrowser: vi.fn().mockResolvedValue(undefined),
renderPdf: vi.fn().mockResolvedValue({ pdf: Buffer.from("%PDF-1.4 mock pdf content here"), durationMs: 10 }),
@ -68,7 +71,8 @@ vi.mock("../services/browser.js", () => ({
uptimeMs: 10000,
browsers: [],
}),
}));
};
});
// Mock verification service
vi.mock("../services/verification.js", () => ({