Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions backend/tests/pdf-preview-runtime.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,17 @@ test("the bundled PDF.js version decodes and paints an actual PDF page with iden
const rootRequire = createRequire(
new URL("../../package.json", import.meta.url),
);
const { createCanvas } = rootRequire("@napi-rs/canvas");
// Paint the way imports/pdf.ts reads: PDF.js's bundled standard fonts, not
// whatever fonts the runner happens to have. Without a Path2D, PDF.js cannot
// draw those font outlines on a Node canvas.
const { createCanvas, Path2D } = rootRequire("@napi-rs/canvas");
const standardFontDataUrl = new URL(
"../../node_modules/pdfjs-dist/standard_fonts/",
import.meta.url,
).pathname;
const globals = globalThis as { Path2D?: unknown };
const previousPath2D = globals.Path2D;
globals.Path2D = Path2D;
const { getDocument } =
await import("../../node_modules/pdfjs-dist/legacy/build/pdf.mjs");
const stream = "BT /F1 20 Tf 20 100 Td (Live Note preview) Tj ET";
Expand All @@ -204,7 +214,8 @@ test("the bundled PDF.js version decodes and paints an actual PDF page with iden
const task = getDocument({
data: new TextEncoder().encode(source),
isEvalSupported: false,
useSystemFonts: true,
useSystemFonts: false,
standardFontDataUrl,
useWasm: false,
});
try {
Expand Down Expand Up @@ -237,5 +248,6 @@ test("the bundled PDF.js version decodes and paints an actual PDF page with iden
);
} finally {
await task.destroy();
globals.Path2D = previousPath2D;
}
});
48 changes: 48 additions & 0 deletions backend/tests/saved-views.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -944,9 +944,56 @@ test("SQL date narrowing agrees with core across DST, source zones, spans and ti
];
try {
await db.query("BEGIN ISOLATION LEVEL REPEATABLE READ");
// Postgres and Node each ship their own tz database, and a rule change
// (such as Cuba keeping UTC-4 in November 2026) reaches them at different
// times. Where the two disagree on a zone's offset near an anchor, the
// comparison would test the tz databases rather than our SQL, so skip it.
const wallClock = (zone: string) =>
new Intl.DateTimeFormat("en-CA", {
timeZone: zone,
hourCycle: "h23",
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
});
const drifted = new Set<string>();
for (const zone of sourceZones) {
const format = wallClock(zone);
for (const day of anchors) {
const instants = Array.from(
{ length: 14 * 4 },
(_, step) =>
new Date(
Date.parse(`${addDays(day, -3)}T00:00:00Z`) +
step * 6 * 3_600_000,
),
);
const { rows } = await db.query<{ local: string }>(
`SELECT to_char(t AT TIME ZONE $2, 'YYYY-MM-DD HH24:MI') AS local
FROM unnest($1::timestamptz[]) WITH ORDINALITY AS u(t, n) ORDER BY n`,
[instants.map((instant) => instant.toISOString()), zone],
);
const node = instants.map((instant) => {
const part = Object.fromEntries(
format.formatToParts(instant).map((p) => [p.type, p.value]),
);
return `${part.year}-${part.month}-${part.day} ${part.hour}:${part.minute}`;
});
if (rows.some((row, index) => row.local !== node[index]))
drifted.add(`${zone} ${day}`);
}
}
if (drifted.size)
console.warn(
`date parity: skipped where tz databases disagree: ${[...drifted].join(", ")}`,
);
assert.ok(drifted.size <= 2, [...drifted].join(", "));
let serial = 0;
for (const zone of sourceZones)
for (const day of anchors) {
if (drifted.has(`${zone} ${day}`)) continue;
for (const offset of [-1, 0, 1]) {
const date = addDays(day, offset),
start = dayTime(date, 0, zone).toISOString();
Expand All @@ -968,6 +1015,7 @@ test("SQL date narrowing agrees with core across DST, source zones, spans and ti
}
for (const timeZone of sourceZones)
for (const anchor of anchors) {
if (drifted.has(`${timeZone} ${anchor}`)) continue;
const now = new Date(`${anchor}T12:00:00.000Z`),
today = localDateKey(now, timeZone);
const common = { text: marker, status: "any" as const };
Expand Down
Loading