Files
SnapOtterandGitHub 301e6eb01a test: coverage campaign and mutation testing across five packages (#628)
Coverage 83.6 to 87.36% lines, 81.63 to 84.14% branches. Mutation testing across five packages: image-engine 85, media-engine 92, doc-engine 87, shared+enterprise 86, apps/api security and jobs slice. Runs all five lanes weekly. Fixes the silently-broken mutation CI (babel pin), a redact-pdf envelope-shape test bug, an untested enterprise license valid-signature path, and an audit test that only exercised a hand-copied reproduction. Test and config only, no product code changes beyond the babel pin and one test-only oidc export. Full suite: 16,712 pass, 0 fail.
2026-07-24 17:36:57 +08:00

69 lines
2.9 KiB
TypeScript

import { existsSync } from "node:fs";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
vi.mock("node:fs", () => ({ existsSync: vi.fn() }));
const DEJAVU = "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf";
const ARIAL = "/System/Library/Fonts/Supplemental/Arial.ttf";
const HELVETICA = "/System/Library/Fonts/Helvetica.ttc";
describe("resolveFontFile", () => {
beforeEach(() => {
vi.resetModules();
vi.mocked(existsSync).mockReset();
delete process.env.SNAPOTTER_FONT_FILE;
delete process.env.SNAPOTTER_FONT_FAMILY;
});
afterEach(() => {
vi.restoreAllMocks();
delete process.env.SNAPOTTER_FONT_FILE;
delete process.env.SNAPOTTER_FONT_FAMILY;
});
it("env override wins without touching the filesystem, default family 'Sans'", async () => {
process.env.SNAPOTTER_FONT_FILE = "/custom/MyFont.ttf";
const { resolveFontFile } = await import("../src/fonts.js");
expect(resolveFontFile()).toEqual({ file: "/custom/MyFont.ttf", family: "Sans" });
expect(vi.mocked(existsSync)).not.toHaveBeenCalled();
});
it("env override uses SNAPOTTER_FONT_FAMILY when set", async () => {
process.env.SNAPOTTER_FONT_FILE = "/custom/MyFont.ttf";
process.env.SNAPOTTER_FONT_FAMILY = "My Font";
const { resolveFontFile } = await import("../src/fonts.js");
expect(resolveFontFile()).toEqual({ file: "/custom/MyFont.ttf", family: "My Font" });
});
it("returns the first existing candidate (DejaVu) with its exact family", async () => {
vi.mocked(existsSync).mockImplementation((p) => p === DEJAVU);
const { resolveFontFile } = await import("../src/fonts.js");
expect(resolveFontFile()).toEqual({ file: DEJAVU, family: "DejaVu Sans" });
});
it("falls through to Arial when DejaVu is missing", async () => {
vi.mocked(existsSync).mockImplementation((p) => p === ARIAL);
const { resolveFontFile } = await import("../src/fonts.js");
expect(resolveFontFile()).toEqual({ file: ARIAL, family: "Arial" });
});
it("falls through to Helvetica when DejaVu and Arial are missing", async () => {
vi.mocked(existsSync).mockImplementation((p) => p === HELVETICA);
const { resolveFontFile } = await import("../src/fonts.js");
expect(resolveFontFile()).toEqual({ file: HELVETICA, family: "Helvetica" });
});
it("returns the earliest match when several candidates exist (order matters)", async () => {
// Both Arial and Helvetica present, DejaVu absent: Arial comes first.
vi.mocked(existsSync).mockImplementation((p) => p === ARIAL || p === HELVETICA);
const { resolveFontFile } = await import("../src/fonts.js");
expect(resolveFontFile()).toEqual({ file: ARIAL, family: "Arial" });
});
it("returns null when no candidate file exists", async () => {
vi.mocked(existsSync).mockReturnValue(false);
const { resolveFontFile } = await import("../src/fonts.js");
expect(resolveFontFile()).toBeNull();
});
});