src/features/exports/month-export.test.ts
Linked repository file from this build.
import { expect, test } from "bun:test";
import { generateSeedBatch } from "@/programs/snap-negative/seed-generator";
import type { Actor } from "@/features/reviews/types";
import {
escapeTsvCell,
exportMonthSummary,
generateMonthExport,
parseExportMonths,
} from "./month-export";
const generated = generateSeedBatch({
ffyFrom: 2026,
ffyTo: 2026,
perMonth: 5,
seed: 11,
asOf: new Date("2026-09-08T12:00:00Z"),
preserveReviewNumbers: [],
}).reviews;
const source = generated.find(
(review) => review.state === "released_to_reporting" && review.outcome === "clean",
)!;
const statistics: Actor = {
role: "statistics",
name: "Statistics",
staffId: "501",
program: source.program,
};
const supervisor: Actor = {
role: "supervisor",
name: "Supervisor",
staffId: "201",
subordinateStaffIds: ["101"],
program: source.program,
};
const first = {
...structuredClone(source),
state: "released_to_reporting" as const,
errorSummaryReleased: { actor: statistics, at: "2026-09-13T12:00:00Z" },
reviewNumber: "first",
sampleMonth: "2026-04",
examiner: "101",
};
const second = {
...structuredClone(source),
state: "released_to_reporting" as const,
errorSummaryReleased: { actor: statistics, at: "2026-09-13T12:00:00Z" },
reviewNumber: "second",
sampleMonth: "2026-05",
examiner: "102",
};
test("month sets validate, deduplicate and select only current completed reviews", () => {
expect(parseExportMonths(["2026-05", "2026-04", "2026-05"])).toEqual(["2026-04", "2026-05"]);
expect(() => parseExportMonths([])).toThrow();
expect(() => parseExportMonths(["2026-13"])).toThrow();
const incomplete = {
...first,
reviewNumber: "incomplete",
state: "new_active" as const,
errorSummaryReleased: undefined,
};
const stale = {
...first,
reviewNumber: "stale",
state: "awaiting_cao_response" as const,
errorSummaryReleased: undefined,
};
const drop = {
...first,
reviewNumber: "drop",
state: "dropped" as const,
outcome: "drop" as const,
};
const reviews = [first, second, incomplete, stale, drop];
expect(exportMonthSummary(reviews, statistics)[0]).toEqual({
month: "2026-04",
total: 4,
eligible: 1,
incomplete: 1,
dropped: 1,
awaitingRelease: 1,
});
const result = generateMonthExport(reviews, statistics, "fns", ["2026-04"]);
expect(result.count).toBe(1);
expect(result.content).toContain("first\t");
for (const excluded of ["second", "incomplete", "stale", "drop"])
expect(result.content).not.toContain(`${excluded}\t`);
});
test("export kinds enforce roles and EPP exports preserve team scope", () => {
expect(() => generateMonthExport([first], supervisor, "fns", ["2026-04"])).toThrow("role");
expect(() => generateMonthExport([first], statistics, "epp", ["2026-04"])).toThrow("role");
expect(() => exportMonthSummary([first], { ...statistics, role: "admin" })).toThrow("role");
const result = generateMonthExport([first, second], supervisor, "epp", ["2026-04", "2026-05"]);
expect(result.count).toBe(1);
expect(result.content).toContain(
"QC_Record_Number\tProgram_Type\tFFY\tRecord_Number\tReview_Month",
);
expect(result.content).toContain("first\tSNAP\t2026\t");
expect(result.content).not.toContain("second");
expect(exportMonthSummary([first, second], supervisor)).toHaveLength(1);
expect(() => generateMonthExport([second], supervisor, "epp", ["2026-05"])).toThrow(
"No released",
);
});
test("TSV preserves controls safely and transmittal exposes one historic variance pair", () => {
expect(escapeTsvCell('a\tb\n"c"')).toBe('"a\tb\n""c"""');
expect(escapeTsvCell("=SUM(A1:A2)")).toBe("'=SUM(A1:A2)");
const review = structuredClone(first);
review.facts.answers.variances = Array.from({ length: 8 }, (_, index) => ({
element: "111",
nature: index === 7 ? "002" : "001",
}));
// Keep the stored validation bindings current; this test targets serialization, not review editing.
const result = generateMonthExport([review], statistics, "fns", ["2026-04"]);
expect(result.content).not.toContain("element2");
expect(result.content).not.toContain("111\t002\t");
const lines = result.content.trimEnd().split("\r\n");
expect(lines[0]!.split("\t").length).toBe(33);
expect(lines[1]!.split("\t").length).toBe(33);
});
test("FNS TSV golden identifiers, inventory labels and quoted agency names use current mappings", () => {
const review = { ...structuredClone(first), localAgency: 'District "North, East"' };
const result = generateMonthExport([review], statistics, "fns", ["2026-04"]);
expect(result.disclaimer).toContain("FNS-245 TSV");
expect(result.disclaimer).toContain("Not a legacy federal");
const lines = result.content.split("\r\n");
const headers = lines[0]!.split("\t");
const labels = lines[1]!.split("\t");
const cells = lines[2]!.split("\t");
const value = (header: string) => cells[headers.indexOf(header)];
expect(headers.slice(0, 5)).toEqual([
"reviewNumber",
"caseNumber",
"stateCode",
"localAgency",
"sampleMonth",
]);
expect(labels[headers.indexOf("finding")]).toBe("11 Finding");
expect(value("reviewNumber")).toBe(review.reviewNumber);
expect(value("caseNumber")).toBe(review.caseNumber);
expect(value("stateCode")).toBe("42");
expect(value("localAgency")).toBe('"District ""North, East"""');
expect(value("sampleMonth")).toBe("04");
expect(value("sampleYear")).toBe("2026");
expect(value("finding")).toBe(review.facts.answers.finding);
expect(value("contactResponse")).toBe(review.facts.answers.contactResponse);
expect(value("actionInitiatedBy")).toBe(review.facts.answers.actionInitiatedBy);
expect(headers).toHaveLength(33);
expect(cells).toHaveLength(33);
});
test("manager-approved drops enter only the transmittal file", () => {
const drop = {
...first,
outcome: "drop" as const,
state: "dropped" as const,
errorSummaryReleased: undefined,
dropApproved: {
actor: { ...statistics, role: "program_manager" as const },
at: "2026-09-13T12:00:00Z",
},
};
expect(generateMonthExport([drop], statistics, "fns", ["2026-04"]).count).toBe(1);
expect(exportMonthSummary([drop], statistics)[0].eligible).toBe(1);
});