fix: remove nested .git folders, re-add as normal directories
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
/**
|
||||
* Tests for src/modules/pdf-utils/injectPdfMetadata.ts
|
||||
*
|
||||
* Uses pdf-lib to create a real in-memory PDF and verifies
|
||||
* metadata injection behavior.
|
||||
*/
|
||||
|
||||
import { describe, test, expect } from "bun:test";
|
||||
import { PDFDocument } from "pdf-lib";
|
||||
import {
|
||||
injectPdfMetadata,
|
||||
type DownloadMetadata,
|
||||
} from "../../src/modules/pdf-utils/injectPdfMetadata";
|
||||
|
||||
async function createBlankPdf(keywords?: string): Promise<Uint8Array> {
|
||||
const doc = await PDFDocument.create();
|
||||
doc.addPage([612, 792]);
|
||||
if (keywords) {
|
||||
doc.setKeywords([keywords]);
|
||||
}
|
||||
return doc.save();
|
||||
}
|
||||
|
||||
describe("injectPdfMetadata", () => {
|
||||
test("injects required metadata keywords into a blank PDF", async () => {
|
||||
const pdfBytes = await createBlankPdf();
|
||||
const metadata: DownloadMetadata = {
|
||||
downloadedAt: "2026-03-01T12:00:00Z",
|
||||
downloadedById: "user-42",
|
||||
};
|
||||
|
||||
const result = await injectPdfMetadata(pdfBytes, metadata);
|
||||
|
||||
// Result should be a Uint8Array (valid PDF)
|
||||
expect(result).toBeInstanceOf(Uint8Array);
|
||||
expect(result.length).toBeGreaterThan(0);
|
||||
|
||||
// Re-parse and check keywords
|
||||
const doc = await PDFDocument.load(result);
|
||||
const keywords = doc.getKeywords();
|
||||
expect(keywords).toContain("downloadedAt:2026-03-01T12:00:00Z");
|
||||
expect(keywords).toContain("downloadedById:user-42");
|
||||
});
|
||||
|
||||
test("appends to existing keywords with separator", async () => {
|
||||
const existingKeywords = "createdBy:system; theme:default";
|
||||
const pdfBytes = await createBlankPdf(existingKeywords);
|
||||
const metadata: DownloadMetadata = {
|
||||
downloadedAt: "2026-03-01T12:00:00Z",
|
||||
downloadedById: "user-42",
|
||||
};
|
||||
|
||||
const result = await injectPdfMetadata(pdfBytes, metadata);
|
||||
const doc = await PDFDocument.load(result);
|
||||
const keywords = doc.getKeywords() ?? "";
|
||||
|
||||
// Should start with existing keywords
|
||||
expect(keywords).toContain("createdBy:system; theme:default");
|
||||
// Should have separator then new keywords
|
||||
expect(keywords).toContain("; downloadedAt:");
|
||||
expect(keywords).toContain("downloadedById:user-42");
|
||||
});
|
||||
|
||||
test("includes optional name and email when provided", async () => {
|
||||
const pdfBytes = await createBlankPdf();
|
||||
const metadata: DownloadMetadata = {
|
||||
downloadedAt: "2026-03-01T12:00:00Z",
|
||||
downloadedById: "user-42",
|
||||
downloadedByName: "Jane Doe",
|
||||
downloadedByEmail: "jane@example.com",
|
||||
};
|
||||
|
||||
const result = await injectPdfMetadata(pdfBytes, metadata);
|
||||
const doc = await PDFDocument.load(result);
|
||||
const keywords = doc.getKeywords() ?? "";
|
||||
|
||||
expect(keywords).toContain("downloadedByName:Jane Doe");
|
||||
expect(keywords).toContain("downloadedByEmail:jane@example.com");
|
||||
});
|
||||
|
||||
test("omits optional name/email when not provided", async () => {
|
||||
const pdfBytes = await createBlankPdf();
|
||||
const metadata: DownloadMetadata = {
|
||||
downloadedAt: "2026-03-01T12:00:00Z",
|
||||
downloadedById: "user-42",
|
||||
};
|
||||
|
||||
const result = await injectPdfMetadata(pdfBytes, metadata);
|
||||
const doc = await PDFDocument.load(result);
|
||||
const keywords = doc.getKeywords() ?? "";
|
||||
|
||||
expect(keywords).not.toContain("downloadedByName");
|
||||
expect(keywords).not.toContain("downloadedByEmail");
|
||||
});
|
||||
|
||||
test("updates ModificationDate (save() applies current time by default)", async () => {
|
||||
const pdfBytes = await createBlankPdf();
|
||||
const metadata: DownloadMetadata = {
|
||||
downloadedAt: "2026-03-01T12:00:00Z",
|
||||
downloadedById: "user-42",
|
||||
};
|
||||
|
||||
const before = Date.now();
|
||||
const result = await injectPdfMetadata(pdfBytes, metadata);
|
||||
const after = Date.now();
|
||||
const doc = await PDFDocument.load(result);
|
||||
const modDate = doc.getModificationDate();
|
||||
|
||||
expect(modDate).toBeInstanceOf(Date);
|
||||
// pdf-lib's save() overrides ModificationDate with current time (updateMetadata defaults to true),
|
||||
// so we just verify the date is recent rather than matching downloadedAt exactly.
|
||||
expect(modDate!.getTime()).toBeGreaterThanOrEqual(before - 2000);
|
||||
expect(modDate!.getTime()).toBeLessThanOrEqual(after + 2000);
|
||||
});
|
||||
|
||||
test("works with Buffer input", async () => {
|
||||
const pdfBytes = await createBlankPdf();
|
||||
const bufferInput = Buffer.from(pdfBytes);
|
||||
const metadata: DownloadMetadata = {
|
||||
downloadedAt: "2026-03-01T12:00:00Z",
|
||||
downloadedById: "user-1",
|
||||
};
|
||||
|
||||
const result = await injectPdfMetadata(bufferInput, metadata);
|
||||
expect(result).toBeInstanceOf(Uint8Array);
|
||||
|
||||
const doc = await PDFDocument.load(result);
|
||||
const keywords = doc.getKeywords() ?? "";
|
||||
expect(keywords).toContain("downloadedById:user-1");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user