src/programs/snap-negative/policy.test.ts
Linked repository file from this build.
import { expect, test } from "bun:test";
import { initialPolicy, policyForMonth, resolveReviewPolicy } from "./policy";
import { calculate, selfEmploymentTotals } from "./calculation";
import { createSeed } from "./seed";
import { policySchema } from "@/features/policy/schema";
test("dated rows select by sample month and retain the saved review table", () => {
const later = {
...initialPolicy,
id: "future-test",
effectiveFrom: "2027-01",
errorThreshold: 59,
allotments: initialPolicy.allotments.map((amount) => amount + 100),
};
expect(policyForMonth("2026-12", [later, initialPolicy])).toBe(initialPolicy);
expect(policyForMonth("2027-01", [initialPolicy, later])).toBe(later);
expect(() => policyForMonth("2025-09", [initialPolicy])).toThrow("No published policy");
const review = createSeed();
review.policyId = initialPolicy.id;
review.policy = structuredClone(initialPolicy);
const before = calculate(
review.facts.scenarios.compI,
"2027-01",
review.calcVersion,
resolveReviewPolicy(review),
);
expect(before.policyId).toBe(initialPolicy.id);
expect(
calculate(review.facts.scenarios.compI, "2027-01", review.calcVersion, later).benefitCents,
).toBe(before.benefitCents + 10000);
expect(() => resolveReviewPolicy({ policyId: "missing" })).toThrow("missing");
});
test("policy accepts all twenty rows and money decimals, rejects incomplete tables", () => {
expect(policySchema.safeParse(initialPolicy).success).toBe(true);
expect(policySchema.safeParse({ ...initialPolicy, errorThreshold: 58.29 }).success).toBe(true);
expect(policySchema.safeParse({ ...initialPolicy, grossLimits: [2610] }).success).toBe(false);
expect(
policySchema.safeParse({ ...initialPolicy, farmExpenseAllowancePercent: 101 }).success,
).toBe(false);
});
test("AF farm gain and loss offset non-farm income before lines 1 and 8", () => {
const base = createSeed().facts.scenarios.compI;
const farm = {
...base.income[0]!,
category: "self_employment" as const,
selfEmploymentKind: "farm" as const,
amountCents: 10000,
expensesCents: 30000,
};
const nonFarm = {
...farm,
id: "non-farm",
selfEmploymentKind: "non_farm" as const,
amountCents: 18000,
expensesCents: 5000,
};
expect(selfEmploymentTotals([farm, nonFarm])).toMatchObject({
farmGainCents: 0,
farmLossCents: 20000,
netBeforeTaxesCents: 13000,
profitCents: 0,
lossCents: 7000,
});
const loss = calculate({ ...base, income: [farm, nonFarm, base.income[1]!] }, "2026-04");
expect(loss).toMatchObject({
earnedCents: 0,
selfEmploymentLossCents: 7000,
grossCents: 13000,
earnedDeductionCents: 0,
});
const zero = calculate({ ...base, income: [{ ...farm, expensesCents: 10000 }] }, "2026-04");
expect(zero).toMatchObject({ earnedCents: 0, selfEmploymentLossCents: 0, grossCents: 0 });
expect(selfEmploymentTotals([{ ...farm, expensesCents: 5000 }, nonFarm])).toMatchObject({
farmGainCents: 5000,
farmLossCents: 0,
profitCents: 18000,
lossCents: 0,
});
expect(
selfEmploymentTotals([farm], { ...initialPolicy, farmExpenseAllowancePercent: 50 }),
).toMatchObject({ lossCents: 5000 });
});