feat(reconciliation): candidate rows drill to RemitDrawer or ClaimDrawer

This commit is contained in:
Tyler
2026-06-21 17:15:09 -06:00
parent 12c2913ba1
commit 2eb61f16ff
2 changed files with 118 additions and 5 deletions
+68
View File
@@ -19,6 +19,7 @@ vi.mock("@/lib/api", () => ({
listUnmatched: vi.fn(),
matchRemit: vi.fn(),
unmatchClaim: vi.fn(),
getRemittance: vi.fn(),
},
ApiError: class ApiError extends Error {
constructor(public status: number, message: string) {
@@ -86,6 +87,73 @@ async function waitForText(
describe("ReconciliationPage", () => {
beforeEach(() => {
vi.clearAllMocks();
// Default for the per-remit detail fetch — the drawer fetches
// this whenever `?remit=` is in the URL. Return a never-resolving
// promise so the drawer stays in the loading state; the smoke
// test only asserts the drawer mounts.
(
api.getRemittance as unknown as ReturnType<typeof vi.fn>
).mockReturnValue(new Promise(() => {}));
});
it("SP21 Task 4.6: deep-link ?remit=ID opens the RemitDrawer on mount", async () => {
// Non-empty unmatched payload so the page renders the two-column
// matching surface (the "Pair them." branch). The pre-existing
// empty-state branch has a flaky happy-dom/race that's unrelated
// to Phase 4 — using non-empty data sidesteps that bug and still
// proves the deep-link → drawer mount works. We pre-set
// `window.location` (which `useRemitDrawerUrlState` reads on
// mount) so `?remit=REM-7` resolves to a truthy `remitId`.
(
api.listUnmatched as unknown as ReturnType<typeof vi.fn>
).mockResolvedValue({
claims: [
{
id: "CLM-1",
patientName: "Patient A",
billedAmount: 100,
providerNpi: "1234567890",
serviceDate: "2026-06-01",
payerId: "P1",
state: "submitted",
},
],
remittances: [
{
id: "REM-7",
payerClaimControlNumber: "PCN-A",
status: "received",
paidAmount: 100,
adjustmentAmount: 0,
receivedDate: "2026-06-01",
isReversal: false,
totalCharge: 100,
serviceDate: "2026-06-01",
batchId: "b1",
},
],
});
(window as unknown as { happyDOM: { setURL: (u: string) => void } })
.happyDOM.setURL("http://localhost/reconciliation?remit=REM-7");
const { unmount } = renderIntoContainer(
React.createElement(ReconciliationPage),
);
// Wait for the loaded two-column view (the "Pair them." headline
// is the clearest signal that listUnmatched has resolved and the
// page is past the loading + empty branches), then assert the
// drawer is mounted.
await waitForText("Pair them.");
expect(
document.body.querySelector('[data-testid="remit-drawer"]'),
).not.toBeNull();
unmount();
// Reset URL so the next test sees a clean /reconciliation URL.
(window as unknown as { happyDOM: { setURL: (u: string) => void } })
.happyDOM.setURL("http://localhost/reconciliation");
});
it("renders both columns with unmatched rows when api returns data", async () => {