import { assert } from "testing/asserts";
import { ExecuteOutput, Verify } from "./test.ts";
export interface PdfMetadataAssertion {
title?: string | RegExp;
author?: string | RegExp;
subject?: string | RegExp;
keywords?: string | RegExp | string[];
creator?: string | RegExp;
producer?: string | RegExp;
creationDate?: string | RegExp | Date;
modDate?: string | RegExp | Date;
}
function matchValue(
actual: string | undefined | null,
expected: string | RegExp | string[] | Date | undefined,
fieldName: string,
): string | null {
if (expected === undefined) return null;
const actualStr = actual ?? "";
if (expected instanceof RegExp) {
if (!expected.test(actualStr)) {
return `${fieldName}: expected to match ${expected}, got "${actualStr}"`;
}
} else if (expected instanceof Date) {
const expectedStr = expected.toISOString().slice(0, 10);
if (!actualStr.includes(expectedStr)) {
return `${fieldName}: expected to contain date ${expectedStr}, got "${actualStr}"`;
}
} else if (Array.isArray(expected)) {
for (const keyword of expected) {
if (!actualStr.toLowerCase().includes(keyword.toLowerCase())) {
return `${fieldName}: expected to contain "${keyword}", got "${actualStr}"`;
}
}
} else {
if (!actualStr.toLowerCase().includes(expected.toLowerCase())) {
return `${fieldName}: expected to contain "${expected}", got "${actualStr}"`;
}
}
return null;
}
export const ensurePdfMetadata = (
file: string,
assertions: PdfMetadataAssertion,
): Verify => {
return {
name: `Inspecting ${file} for PDF metadata`,
verify: async (_output: ExecuteOutput[]) => {
const errors: string[] = [];
const pdfjsLib = await import("pdfjs-dist") as any;
const buffer = await Deno.readFile(file);
const doc = await pdfjsLib.getDocument({ data: buffer }).promise;
const { info } = await doc.getMetadata();
const checks = [
matchValue(info?.Title, assertions.title, "title"),
matchValue(info?.Author, assertions.author, "author"),
matchValue(info?.Subject, assertions.subject, "subject"),
matchValue(info?.Keywords, assertions.keywords, "keywords"),
matchValue(info?.Creator, assertions.creator, "creator"),
matchValue(info?.Producer, assertions.producer, "producer"),
matchValue(info?.CreationDate, assertions.creationDate, "creationDate"),
matchValue(info?.ModDate, assertions.modDate, "modDate"),
];
for (const error of checks) {
if (error) {
errors.push(error);
}
}
if (errors.length > 0) {
assert(
false,
`PDF metadata assertions failed in ${file}:\n${errors.map((e, i) => ` ${i + 1}. ${e}`).join("\n")}`,
);
}
},
};
};