Skip to article
Documentation

src/features/reviews/income-validation.test.ts

Linked repository file from this build.

import { expect, test } from "bun:test";
import { MAX_MONEY_CENTS } from "@/programs/snap-negative/input-limits";
import { createSeed } from "@/programs/snap-negative/seed";
import { incomeFieldErrors } from "./income-validation";
import type { IncomeStream } from "@/programs/snap-negative/types";

const members = createSeed().facts.members;
const row: IncomeStream = {
  id: "test",
  memberId: members[0]!.id,
  typeCode: "WAGES",
  category: "earned",
  amountCents: 0,
  expensesCents: 0,
  description: "",
};

test("income errors identify missing type, stale member and malformed amounts together", () => {
  const errors = incomeFieldErrors(
    { ...row, memberId: "removed", typeCode: " ", amountCents: 12.5 },
    members,
  );
  expect(errors.memberId).toBeTruthy();
  expect(errors.typeCode).toBeTruthy();
  expect(errors.amountCents).toBeTruthy();
});

test("zero is valid; negative and excessive amounts are rejected", () => {
  for (const amountCents of [NaN, -1, MAX_MONEY_CENTS + 1])
    expect(incomeFieldErrors({ ...row, amountCents }, members).amountCents).toBeTruthy();
  for (const amountCents of [0, 1230, MAX_MONEY_CENTS])
    expect(incomeFieldErrors({ ...row, amountCents }, members).amountCents).toBeUndefined();
});

test("business and expenses are validated only for self-employment", () => {
  const errors = incomeFieldErrors({ ...row, category: "self_employment" }, members);
  expect(errors.selfEmploymentKind).toBeTruthy();
  expect(errors.expensesCents).toBeUndefined();
  expect(incomeFieldErrors(row, members).expensesCents).toBeUndefined();
  expect(
    incomeFieldErrors({ ...row, category: "self_employment", selfEmploymentKind: "farm" }, members)
      .selfEmploymentKind,
  ).toBeUndefined();
});