mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
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.
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
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();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user