// @vitest-environment happy-dom // Pure prop-driven component; match the act() convention used by the // other ClaimDrawer test files (ClaimDrawerHeader / ClaimDrawerSkeleton / // ClaimDrawerError / ValidationPanel / ServiceLinesTable / DiagnosesList). (globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true; import React, { act } from "react"; import { createRoot, type Root } from "react-dom/client"; import { describe, expect, it } from "vitest"; import { PartiesGrid } from "./PartiesGrid"; import type { ClaimDetailAddress, ClaimDetailParties, } from "@/types"; function renderIntoContainer(element: React.ReactElement): { container: HTMLDivElement; unmount: () => void; } { const container = document.createElement("div"); document.body.appendChild(container); const root: Root = createRoot(container); act(() => { root.render(element); }); return { container, unmount: () => { act(() => root.unmount()); container.remove(); }, }; } function makeAddress( overrides: Partial = {} ): ClaimDetailAddress { return { line1: "100 Main St", line2: null, city: "Springfield", state: "IL", zip: "62701", ...overrides, }; } function makeParties( overrides: Partial = {} ): ClaimDetailParties { return { billingProvider: { name: "Acme Medical Group", npi: "1234567890", taxId: "12-3456789", address: makeAddress(), }, subscriber: { firstName: "Jane", lastName: "Doe", memberId: "MEM12345", dob: "1980-05-15", gender: "F", }, payer: { name: "Aetna", id: "PAYER01", }, ...overrides, }; } describe("PartiesGrid", () => { it("test_section_label_is_parties", () => { const { container, unmount } = renderIntoContainer( ); const label = container.querySelector('[data-testid="section-label"]'); expect(label).not.toBeNull(); // `uppercase` is applied via Tailwind CSS, so textContent gives the // source-case string "Parties"; assert case-insensitively and // confirm the visual transform via the className sniff below. const text = (label?.textContent ?? "").toLowerCase(); expect(text).toContain("parties"); // Eyebrow style (uppercase + tracking) — sniff the className. const cls = label?.className ?? ""; expect(cls).toContain("uppercase"); expect(cls).toContain("tracking-[0.18em]"); unmount(); }); it("test_three_cards_rendered_for_each_party", () => { const { container, unmount } = renderIntoContainer( ); const billing = container.querySelector('[data-testid="party-billing-provider"]'); const subscriber = container.querySelector('[data-testid="party-subscriber"]'); const payer = container.querySelector('[data-testid="party-payer"]'); expect(billing).not.toBeNull(); expect(subscriber).not.toBeNull(); expect(payer).not.toBeNull(); unmount(); }); it("test_billing_provider_card_shows_name_npi_taxId_and_address", () => { const { container, unmount } = renderIntoContainer( ); const card = container.querySelector( '[data-testid="party-billing-provider"]' ); expect(card).not.toBeNull(); const text = card?.textContent ?? ""; expect(text).toContain("Acme Medical Group"); expect(text).toContain("1234567890"); expect(text).toContain("12-3456789"); // Address components. expect(text).toContain("100 Main St"); expect(text).toContain("Springfield"); expect(text).toContain("IL"); expect(text).toContain("62701"); unmount(); }); it("test_subscriber_card_shows_first_last_memberId_and_gender", () => { const { container, unmount } = renderIntoContainer( ); const card = container.querySelector('[data-testid="party-subscriber"]'); expect(card).not.toBeNull(); const text = card?.textContent ?? ""; expect(text).toContain("Jane"); expect(text).toContain("Doe"); expect(text).toContain("MEM12345"); expect(text).toContain("F"); // DOB is also present in this fixture. expect(text).toContain("1980"); unmount(); }); it("test_subscriber_card_omits_dob_when_null", () => { const { container, unmount } = renderIntoContainer( ); const card = container.querySelector('[data-testid="party-subscriber"]'); expect(card).not.toBeNull(); const text = (card?.textContent ?? "").toLowerCase(); // Still renders the identity pieces. expect(text).toContain("john"); expect(text).toContain("smith"); expect(text).toContain("mem99999"); expect(text).toContain("m"); // No "undefined" or "null" stringification for the absent DOB. expect(text).not.toContain("undefined"); expect(text).not.toContain("null"); unmount(); }); it("test_payer_card_shows_name_and_id", () => { const { container, unmount } = renderIntoContainer( ); const card = container.querySelector('[data-testid="party-payer"]'); expect(card).not.toBeNull(); const text = card?.textContent ?? ""; expect(text).toContain("Aetna"); expect(text).toContain("PAYER01"); unmount(); }); it("test_billing_provider_address_line2_rendered_when_present", () => { const { container, unmount } = renderIntoContainer( ); const card = container.querySelector( '[data-testid="party-billing-provider"]' ); const text = card?.textContent ?? ""; expect(text).toContain("200 Oak Ave"); expect(text).toContain("Suite 300"); expect(text).toContain("Portland"); expect(text).toContain("OR"); expect(text).toContain("97201"); unmount(); }); it("test_empty_address_object_does_not_render_garbage", () => { // The backend can return `{}` for a missing address (per the // ClaimDetailBillingProvider type's `Record` branch). // The component must not stringify an empty object. const { container, unmount } = renderIntoContainer( ); const card = container.querySelector( '[data-testid="party-billing-provider"]' ); const text = (card?.textContent ?? "").toLowerCase(); expect(text).toContain("addrless clinic"); expect(text).toContain("2222222222"); expect(text).not.toContain("[object object]"); expect(text).not.toContain("undefined"); expect(text).not.toContain("null"); unmount(); }); it("test_responsive_grid_uses_3_columns_on_desktop", () => { const { container, unmount } = renderIntoContainer( ); // The section follows the established `flex flex-col gap-3 px-6 py-4` // pattern; the responsive grid is the inner wrapper that holds the // three party cards. Sniff its className. const grid = container.querySelector('[data-testid="parties-grid-inner"]'); expect(grid).not.toBeNull(); const cls = grid?.className ?? ""; expect(cls).toContain("grid"); expect(cls).toContain("grid-cols-1"); expect(cls).toContain("md:grid-cols-3"); expect(cls).toContain("gap-4"); unmount(); }); });