Files
plimi/src/tools/pdf-watermark/run.test.ts
2026-06-07 20:13:05 +02:00

96 lines
3.1 KiB
TypeScript

import { describe, it, expect, vi } from "vitest";
import { PDFDocument } from "pdf-lib";
import { pdfWatermarkPlugin, type PdfWatermarkOptions } from "./index";
import { runPdfWatermark } from "./run";
import { MAX_WATERMARK_CHARS } from "./watermark";
import type { ToolContext } from "../../core/plugins/plugin-types";
const mockContext: ToolContext = {
signal: new AbortController().signal,
reportProgress: vi.fn(),
logger: { info: vi.fn(), warn: vi.fn(), error: vi.fn() },
};
const defaultOptions: PdfWatermarkOptions = {
text: "CONFIDENTIAL",
orientation: "diagonal",
opacity: 30,
color: "light-grey",
};
async function makePdfFile(): Promise<File> {
const doc = await PDFDocument.create();
doc.addPage([595, 842]);
const bytes = await doc.save();
return new File([bytes as unknown as BlobPart], "sample.pdf", {
type: "application/pdf",
});
}
describe("PDF Watermark Plugin", () => {
it("should have correct manifest", () => {
expect(pdfWatermarkPlugin.manifest.id).toBe("pdf-watermark");
expect(pdfWatermarkPlugin.manifest.category).toBe("pdf");
expect(pdfWatermarkPlugin.manifest.input.type).toBe("files");
expect(pdfWatermarkPlugin.manifest.output.type).toBe("files");
});
it("should throw if no file provided", async () => {
await expect(
runPdfWatermark({ files: [] }, defaultOptions, mockContext)
).rejects.toThrow("No PDF file provided.");
});
it("should throw if watermark text is empty", async () => {
const file = await makePdfFile();
await expect(
runPdfWatermark({ files: [file] }, { ...defaultOptions, text: " " }, mockContext)
).rejects.toThrow("Watermark text is required.");
});
it("should produce a watermarked PDF", async () => {
const file = await makePdfFile();
const result = await runPdfWatermark(
{ files: [file] },
defaultOptions,
mockContext
);
expect(result.type).toBe("files");
if (result.type !== "files") throw new Error("unexpected result");
expect(result.files).toHaveLength(1);
expect(result.files[0].name).toBe("sample_watermarked.pdf");
expect(result.files[0].mimeType).toBe("application/pdf");
expect(result.files[0].blob.size).toBeGreaterThan(0);
// Output should still be a loadable PDF with the same page count.
const out = await result.files[0].blob.arrayBuffer();
const reloaded = await PDFDocument.load(new Uint8Array(out));
expect(reloaded.getPageCount()).toBe(1);
});
it.each(["horizontal", "vertical", "diagonal"] as const)(
"should handle %s orientation",
async (orientation) => {
const file = await makePdfFile();
const result = await runPdfWatermark(
{ files: [file] },
{ ...defaultOptions, orientation },
mockContext
);
expect(result.type).toBe("files");
}
);
it("should truncate text beyond the max length", async () => {
const file = await makePdfFile();
const longText = "A".repeat(MAX_WATERMARK_CHARS + 50);
const result = await runPdfWatermark(
{ files: [file] },
{ ...defaultOptions, text: longText },
mockContext
);
expect(result.type).toBe("files");
});
});