fix: use sanitized PDF options from validator in convert/demo routes (BUG-102)
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 12m44s
All checks were successful
Build & Deploy to Staging / Build & Deploy to Staging (push) Successful in 12m44s
This commit is contained in:
parent
c03f217690
commit
ba2e542e2a
3 changed files with 117 additions and 45 deletions
98
src/__tests__/convert-sanitized.test.ts
Normal file
98
src/__tests__/convert-sanitized.test.ts
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
||||
import express from "express";
|
||||
import request from "supertest";
|
||||
|
||||
vi.mock("node:dns/promises", () => ({
|
||||
default: { lookup: vi.fn() },
|
||||
lookup: vi.fn(),
|
||||
}));
|
||||
|
||||
let app: express.Express;
|
||||
|
||||
beforeEach(async () => {
|
||||
vi.clearAllMocks();
|
||||
vi.resetModules();
|
||||
|
||||
const { renderPdf, renderUrlPdf } = await import("../services/browser.js");
|
||||
vi.mocked(renderPdf).mockResolvedValue(Buffer.from("%PDF-1.4 mock"));
|
||||
vi.mocked(renderUrlPdf).mockResolvedValue(Buffer.from("%PDF-1.4 mock url"));
|
||||
|
||||
const dns = await import("node:dns/promises");
|
||||
vi.mocked(dns.default.lookup).mockResolvedValue({ address: "93.184.216.34", family: 4 } as any);
|
||||
|
||||
const { convertRouter } = await import("../routes/convert.js");
|
||||
const { demoRouter } = await import("../routes/demo.js");
|
||||
app = express();
|
||||
app.use(express.json({ limit: "500kb" }));
|
||||
app.use("/v1/convert", convertRouter);
|
||||
app.use("/v1/demo", demoRouter);
|
||||
});
|
||||
|
||||
describe("convert routes use sanitized PDF options", () => {
|
||||
it("POST /v1/convert/html passes sanitized format (a4 → A4)", async () => {
|
||||
const { renderPdf } = await import("../services/browser.js");
|
||||
|
||||
await request(app)
|
||||
.post("/v1/convert/html")
|
||||
.set("content-type", "application/json")
|
||||
.send({ html: "<h1>Test</h1>", format: "a4" });
|
||||
|
||||
expect(vi.mocked(renderPdf)).toHaveBeenCalledOnce();
|
||||
const opts = vi.mocked(renderPdf).mock.calls[0][1];
|
||||
expect(opts.format).toBe("A4");
|
||||
});
|
||||
|
||||
it("POST /v1/convert/markdown passes sanitized format (letter → Letter)", async () => {
|
||||
const { renderPdf } = await import("../services/browser.js");
|
||||
|
||||
await request(app)
|
||||
.post("/v1/convert/markdown")
|
||||
.set("content-type", "application/json")
|
||||
.send({ markdown: "# Test", format: "letter" });
|
||||
|
||||
expect(vi.mocked(renderPdf)).toHaveBeenCalledOnce();
|
||||
const opts = vi.mocked(renderPdf).mock.calls[0][1];
|
||||
expect(opts.format).toBe("Letter");
|
||||
});
|
||||
|
||||
it("POST /v1/convert/url passes sanitized format (a3 → A3)", async () => {
|
||||
const { renderUrlPdf } = await import("../services/browser.js");
|
||||
|
||||
await request(app)
|
||||
.post("/v1/convert/url")
|
||||
.set("content-type", "application/json")
|
||||
.send({ url: "https://example.com", format: "a3" });
|
||||
|
||||
expect(vi.mocked(renderUrlPdf)).toHaveBeenCalledOnce();
|
||||
const opts = vi.mocked(renderUrlPdf).mock.calls[0][1];
|
||||
expect(opts.format).toBe("A3");
|
||||
});
|
||||
});
|
||||
|
||||
describe("demo routes use sanitized PDF options", () => {
|
||||
it("POST /v1/demo/html passes sanitized format (a4 → A4)", async () => {
|
||||
const { renderPdf } = await import("../services/browser.js");
|
||||
|
||||
await request(app)
|
||||
.post("/v1/demo/html")
|
||||
.set("content-type", "application/json")
|
||||
.send({ html: "<h1>Test</h1>", format: "a4" });
|
||||
|
||||
expect(vi.mocked(renderPdf)).toHaveBeenCalledOnce();
|
||||
const opts = vi.mocked(renderPdf).mock.calls[0][1];
|
||||
expect(opts.format).toBe("A4");
|
||||
});
|
||||
|
||||
it("POST /v1/demo/markdown passes sanitized format (a4 → A4)", async () => {
|
||||
const { renderPdf } = await import("../services/browser.js");
|
||||
|
||||
await request(app)
|
||||
.post("/v1/demo/markdown")
|
||||
.set("content-type", "application/json")
|
||||
.send({ markdown: "# Test", format: "a4" });
|
||||
|
||||
expect(vi.mocked(renderPdf)).toHaveBeenCalledOnce();
|
||||
const opts = vi.mocked(renderPdf).mock.calls[0][1];
|
||||
expect(opts.format).toBe("A4");
|
||||
});
|
||||
});
|
||||
|
|
@ -114,18 +114,7 @@ convertRouter.post("/html", async (req: Request & { acquirePdfSlot?: () => Promi
|
|||
: wrapHtml(body.html, body.css);
|
||||
|
||||
const pdf = await renderPdf(fullHtml, {
|
||||
format: body.format,
|
||||
landscape: body.landscape,
|
||||
margin: body.margin,
|
||||
printBackground: body.printBackground,
|
||||
headerTemplate: body.headerTemplate,
|
||||
footerTemplate: body.footerTemplate,
|
||||
displayHeaderFooter: body.displayHeaderFooter,
|
||||
scale: body.scale,
|
||||
pageRanges: body.pageRanges,
|
||||
preferCSSPageSize: body.preferCSSPageSize,
|
||||
width: body.width,
|
||||
height: body.height,
|
||||
...validation.sanitized,
|
||||
});
|
||||
|
||||
const filename = sanitizeFilename(body.filename || "document.pdf");
|
||||
|
|
@ -226,18 +215,7 @@ convertRouter.post("/markdown", async (req: Request & { acquirePdfSlot?: () => P
|
|||
|
||||
const html = markdownToHtml(body.markdown, body.css);
|
||||
const pdf = await renderPdf(html, {
|
||||
format: body.format,
|
||||
landscape: body.landscape,
|
||||
margin: body.margin,
|
||||
printBackground: body.printBackground,
|
||||
headerTemplate: body.headerTemplate,
|
||||
footerTemplate: body.footerTemplate,
|
||||
displayHeaderFooter: body.displayHeaderFooter,
|
||||
scale: body.scale,
|
||||
pageRanges: body.pageRanges,
|
||||
preferCSSPageSize: body.preferCSSPageSize,
|
||||
width: body.width,
|
||||
height: body.height,
|
||||
...validation.sanitized,
|
||||
});
|
||||
|
||||
const filename = sanitizeFilename(body.filename || "document.pdf");
|
||||
|
|
@ -368,19 +346,7 @@ convertRouter.post("/url", async (req: Request & { acquirePdfSlot?: () => Promis
|
|||
}
|
||||
|
||||
const pdf = await renderUrlPdf(body.url, {
|
||||
format: body.format,
|
||||
landscape: body.landscape,
|
||||
margin: body.margin,
|
||||
printBackground: body.printBackground,
|
||||
headerTemplate: body.headerTemplate,
|
||||
footerTemplate: body.footerTemplate,
|
||||
displayHeaderFooter: body.displayHeaderFooter,
|
||||
scale: body.scale,
|
||||
pageRanges: body.pageRanges,
|
||||
preferCSSPageSize: body.preferCSSPageSize,
|
||||
width: body.width,
|
||||
height: body.height,
|
||||
waitUntil: body.waitUntil,
|
||||
...validation.sanitized,
|
||||
hostResolverRules: `MAP ${parsed.hostname} ${resolvedAddress}`,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -127,11 +127,15 @@ router.post("/html", async (req: Request & { acquirePdfSlot?: () => Promise<void
|
|||
? injectWatermark(body.html)
|
||||
: injectWatermark(wrapHtml(body.html, body.css));
|
||||
|
||||
const defaultOpts = {
|
||||
format: "A4",
|
||||
landscape: false,
|
||||
printBackground: true,
|
||||
margin: { top: "0", right: "0", bottom: "0", left: "0" },
|
||||
};
|
||||
const pdf = await renderPdf(fullHtml, {
|
||||
format: body.format || "A4",
|
||||
landscape: body.landscape || false,
|
||||
printBackground: body.printBackground !== false,
|
||||
margin: body.margin || { top: "0", right: "0", bottom: "0", left: "0" },
|
||||
...defaultOpts,
|
||||
...validation.sanitized,
|
||||
});
|
||||
|
||||
const filename = sanitizeFilename(body.filename || "demo.pdf");
|
||||
|
|
@ -227,11 +231,15 @@ router.post("/markdown", async (req: Request & { acquirePdfSlot?: () => Promise<
|
|||
const htmlContent = markdownToHtml(body.markdown);
|
||||
const fullHtml = injectWatermark(wrapHtml(htmlContent, body.css));
|
||||
|
||||
const defaultOpts = {
|
||||
format: "A4",
|
||||
landscape: false,
|
||||
printBackground: true,
|
||||
margin: { top: "0", right: "0", bottom: "0", left: "0" },
|
||||
};
|
||||
const pdf = await renderPdf(fullHtml, {
|
||||
format: body.format || "A4",
|
||||
landscape: body.landscape || false,
|
||||
printBackground: body.printBackground !== false,
|
||||
margin: body.margin || { top: "0", right: "0", bottom: "0", left: "0" },
|
||||
...defaultOpts,
|
||||
...validation.sanitized,
|
||||
});
|
||||
|
||||
const filename = sanitizeFilename(body.filename || "demo.pdf");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue