import { periodYearOf } from "./ops.service"; /** * `periodYearOf` is the upload allowlist for prior-period archives, so it is * doing two jobs at once: deciding what counts as a period file, and keeping a * caller-supplied name from escaping the ingest directory. Both are pinned here. */ describe("periodYearOf", () => { it("accepts a four-digit year archive", () => { expect(periodYearOf("2025.accdb")).toBe(2025); expect(periodYearOf("1999.accdb")).toBe(1999); }); it("is case-insensitive on the extension", () => { expect(periodYearOf("2025.ACCDB")).toBe(2025); }); it("rejects a path that would escape the ingest directory", () => { // The name is joined onto the ingest path, so anything with a separator or // a parent reference has to fail before it reaches the filesystem. expect(periodYearOf("../2025.accdb")).toBeNull(); expect(periodYearOf("../../etc/passwd")).toBeNull(); expect(periodYearOf("sub/2025.accdb")).toBeNull(); expect(periodYearOf("2025.accdb/../../x")).toBeNull(); }); it("rejects names that only look like a period", () => { expect(periodYearOf("202.accdb")).toBeNull(); expect(periodYearOf("20255.accdb")).toBeNull(); expect(periodYearOf("2025.mdb")).toBeNull(); expect(periodYearOf("copia 2025.accdb")).toBeNull(); expect(periodYearOf("2025.accdb.bak")).toBeNull(); expect(periodYearOf("UTILITIES.accdb")).toBeNull(); }); it("rejects years outside the plausible range", () => { // A typo'd year would otherwise mint a period nobody can ever reconcile: // there is no BALANCE FORWARD for the year after it to check against. expect(periodYearOf("1889.accdb")).toBeNull(); expect(periodYearOf(`${new Date().getUTCFullYear() + 1}.accdb`)).toBeNull(); }); it("accepts the current year, which is the earliest a period can be cut", () => { expect(periodYearOf(`${new Date().getUTCFullYear()}.accdb`)).toBe( new Date().getUTCFullYear(), ); }); });