src/lib/db/inbox-events.test.ts
Linked repository file from this build.
import { describe, expect, test } from "bun:test";
import { createSeed } from "@/programs/snap-negative/seed";
import { eventKinds, eventsForSave } from "./inbox-events";
import { enabledEventKinds } from "./inbox-store";
import { reviewScope } from "./scope";
import { escapeLike, searchSchema, searchWhere } from "./search-store";
import { PgDialect } from "drizzle-orm/pg-core";
import { bindReviewRules } from "@/features/reviews/review-store";
const now = "2026-09-08T12:00:00.000Z";
const review = () => ({
...createSeed(),
sampleMonth: "2026-09",
examiner: "101",
supervisor: "201",
});
const actor = { name: "Alex", role: "examiner" as const, staffId: "101", program: "SNAP" };
const dialect = new PgDialect();
describe("inbox event changes", () => {
test("only current-month active distributions produce initial news", () => {
expect(eventKinds(undefined, review(), now)).toEqual(["distributed"]);
expect(eventKinds(undefined, { ...review(), sampleMonth: "2026-08" }, now)).toEqual([]);
expect(eventKinds(undefined, { ...review(), state: "released_to_reporting" }, now)).toEqual([]);
});
test("own edits do not notify the actor; covering supervisors notify examiner", () => {
const previous = review();
const next = { ...previous, appointment: "2026-09-10T10:00" };
const value = { review: next, actor, version: 1, savedAt: now, requestId: "x" };
expect(eventsForSave(previous, value).map((event) => event.staffId)).toEqual(["201"]);
expect(
eventsForSave(previous, {
...value,
actor: { ...actor, role: "supervisor", staffId: "201" },
}).map((event) => event.staffId),
).toEqual(["101"]);
expect(eventsForSave(next, value)).toEqual([]);
expect(eventsForSave(previous, value)).toEqual(eventsForSave(previous, value));
expect(eventsForSave(previous, { ...value, requestId: "another-save" })[0]!.id).not.toBe(
eventsForSave(previous, value)[0]!.id,
);
});
test("document, workflow, and PEC changes emit distinct kinds", () => {
const previous = review();
const document = {
id: "doc",
filename: "evidence.pdf",
category: "Evidence" as const,
description: "",
mimeType: "application/pdf",
size: 1,
storageKey: "doc",
actor,
createdAt: now,
};
expect(
eventKinds(previous, { ...previous, documents: [document], state: "needs_changes" }, now),
).toEqual(["document_added", "changes_requested"]);
expect(eventKinds(previous, { ...previous, state: "dropped" }, now)).toEqual(["dropped"]);
expect(
eventKinds(
previous,
{
...previous,
pecDecision: { decision: "deny", policyNote: "Return", actor, createdAt: now },
},
now,
),
).toEqual(["pec_decision"]);
});
test("stakeholder approvals notify once per saved approval", () => {
const previous = review();
const approved = {
...previous,
state: "awaiting_manager" as const,
supervisorApproved: { actor, at: now },
};
expect(eventKinds(previous, approved, now)).toEqual(["approved"]);
expect(eventKinds(approved, approved, now)).toEqual([]);
expect(
eventKinds(
approved,
{ ...approved, state: "released_to_reporting", errorSummaryReleased: { actor, at: now } },
now,
),
).toEqual(["approved"]);
});
test("notification toggles default on and team settings are independent", () => {
const user = { ...actor, preferences: { notifyDocuments: false, notifyTeamKickbacks: false } };
expect(enabledEventKinds(user)).not.toContain("document_added");
expect(enabledEventKinds(user)).toContain("changes_requested");
expect(enabledEventKinds(user, true)).toContain("document_added");
expect(enabledEventKinds(user, true)).not.toContain("changes_requested");
});
});
describe("bounded scoped search", () => {
test("caps result limits and validates advanced filters", () => {
expect(searchSchema.safeParse({ limit: 101 }).success).toBe(false);
expect(searchSchema.safeParse({ field: "facts" }).success).toBe(false);
expect(searchSchema.parse({}).limit).toBe(30);
});
test("escapes wildcard input and binds user input as parameters", () => {
expect(escapeLike("50%_\\")).toBe("50\\%\\_\\\\");
const query = dialect.sqlToQuery(searchWhere(actor, searchSchema.parse({ q: "O'Brien 50%" })));
expect(query.sql).not.toContain("O'Brien");
expect(query.params).toContain("%O'Brien%");
expect(query.params).toContain("%50\\%%");
expect(query.params).toContain("101");
expect(query.params).toContain("SNAP");
});
test("supervisor scope is explicit staff graph, not snapshot supervisor label", () => {
const query = dialect.sqlToQuery(
reviewScope({
...actor,
role: "supervisor",
staffId: "201",
subordinateStaffIds: ["101", "102"],
}),
);
expect(query.params).toEqual(["SNAP", "201", "101", "102"]);
expect(query.sql).not.toContain('"supervisor"');
});
test("stored supervisor assignments are not overridden by demo examiner codes", () => {
expect(
bindReviewRules({ ...createSeed(), examiner: "101", supervisor: "777" }).supervisor,
).toBe("777");
});
});