From 35e676b86aceb9e2de2138170accaa252fbb50e2 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 22 Jul 2026 03:54:50 +0000 Subject: [PATCH] test(ui): drop duplicate #015 content-first suites superseded by #1057 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #1054 and PR #1057 independently resolved ledger #015, landing four overlapping content-first DOM suites on main. #1057's pair is a complete functional superset: - registry-record-loader.dom.test.tsx (8) strictly supersets registry-content-first.dom.test.tsx (4) — adds governance-absent passthrough, not_found, and unauthorized states. - medication-record-page.dom.test.tsx (6) covers everything medication-content-first.dom.test.tsx (7) did, including the graceful-degradation and governance-drop-on-error invariants, via rendered-badge assertions rather than spy-on-argument (more robust, matches repo convention). Remove the two now-redundant *-content-first.dom.test.tsx files. No loss of coverage; the surviving pair (14 tests) is green and the tree is type-clean. Test-only; no source/behaviour change. RAG impact: no retrieval behaviour change — tests-only, no retrieval/ranking/selection/eval or product code touched. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01UbhUVWVJRwDibC2YtJ6aRX --- tests/medication-content-first.dom.test.tsx | 97 ------------------ tests/registry-content-first.dom.test.tsx | 104 -------------------- 2 files changed, 201 deletions(-) delete mode 100644 tests/medication-content-first.dom.test.tsx delete mode 100644 tests/registry-content-first.dom.test.tsx diff --git a/tests/medication-content-first.dom.test.tsx b/tests/medication-content-first.dom.test.tsx deleted file mode 100644 index f53bb38f..00000000 --- a/tests/medication-content-first.dom.test.tsx +++ /dev/null @@ -1,97 +0,0 @@ -import { render, screen } from "@testing-library/react"; -import { describe, expect, it, vi } from "vitest"; -import type { ReactElement } from "react"; - -import { MedicationRecordPage } from "@/components/clinical-dashboard/medication-record-page"; -import { PatientProfileProvider } from "@/components/clinical-dashboard/patient-profile-context"; -import { medicationIdentityBadges, type MedicationGovernance } from "@/lib/medication-badges"; -import { loadMedicationSnapshot } from "@/lib/medication-snapshot"; -import type { MedicationRecord } from "@/lib/medications"; - -type DetailState = { - data: { record: MedicationRecord } | null; - loading: boolean; - error: string | null; -}; - -// Mutable holder so each test can drive the mocked detail hook. -const hook = vi.hoisted(() => ({ detail: null as unknown as DetailState })); -vi.mock("@/components/clinical-dashboard/use-medication-catalog", () => ({ - useMedicationDetail: () => hook.detail, - useMedicationCatalog: () => ({ data: null, loading: false, error: null }), -})); - -// Partial mock: keep every real export (the detail body renders normally) but wrap -// medicationIdentityBadges in a spy that still calls through, so we can assert the -// exact governance MedicationRecordPage hands down — robust against badge rendering, -// ordering, and BadgeCluster overflow. -vi.mock("@/lib/medication-badges", async (importOriginal) => { - const actual = await importOriginal(); - return { ...actual, medicationIdentityBadges: vi.fn(actual.medicationIdentityBadges) }; -}); -const badgesSpy = vi.mocked(medicationIdentityBadges); - -const record = loadMedicationSnapshot()[0]; -const liveRecord: MedicationRecord = { ...record, name: `${record.name} (live)` }; - -// The detail body renders PatientProfilePanel, which reads the sessionStorage-backed -// patient-profile context — provide the real provider so the tree renders faithfully. -function renderPage(ui: ReactElement) { - return render(ui, { wrapper: PatientProfileProvider }); -} - -describe("MedicationRecordPage content-first fallback", () => { - it("paints the fallback record immediately during loading instead of the skeleton", () => { - hook.detail = { data: null, loading: true, error: null }; - renderPage(); - expect(screen.getByRole("heading", { name: record.name })).toBeInTheDocument(); - expect(screen.queryByText(/Loading medication reference/i)).not.toBeInTheDocument(); - }); - - it("swaps in the live record once the fetch resolves", () => { - hook.detail = { data: { record: liveRecord }, loading: false, error: null }; - renderPage(); - expect(screen.getByRole("heading", { name: liveRecord.name })).toBeInTheDocument(); - }); - - it("shows the skeleton while loading when there is no fallback (owner-only slug)", () => { - hook.detail = { data: null, loading: true, error: null }; - renderPage(); - expect(screen.getByText(/Loading medication reference/i)).toBeInTheDocument(); - }); - - it("shows the error/not-found state when there is no fallback and the fetch fails", () => { - hook.detail = { data: null, loading: false, error: "Could not load medication." }; - renderPage(); - expect(screen.getByText("Could not load medication.")).toBeInTheDocument(); - }); - - it("keeps showing fallback content when the live fetch fails (graceful content-first)", () => { - hook.detail = { data: null, loading: false, error: "boom" }; - renderPage(); - expect(screen.getByRole("heading", { name: record.name })).toBeInTheDocument(); - expect(screen.queryByText("boom")).not.toBeInTheDocument(); - }); - - const fallbackGovernance: MedicationGovernance = { sourceStatus: "current", validationStatus: "approved" }; - - it("presents the SSR fallback governance to the record while the live fetch is loading", () => { - hook.detail = { data: null, loading: true, error: null }; - badgesSpy.mockClear(); - renderPage(); - // Loading with no error → the fixture-derived fallback governance is shown. - expect(badgesSpy.mock.calls.at(-1)?.[1]).toEqual(fallbackGovernance); - }); - - it("drops the fallback governance (not authoritative) once the live fetch fails", () => { - hook.detail = { data: null, loading: false, error: "boom" }; - badgesSpy.mockClear(); - renderPage(); - // A failed fetch means the authoritative status is unknown, so governance must - // NOT keep presenting the fixture value — this is the `error ? undefined : ...` - // guard, and the test fails if that error check is dropped. - expect(badgesSpy.mock.calls.at(-1)?.[1]).toBeUndefined(); - // ...while the record content itself still renders (graceful content-first). - expect(screen.getByRole("heading", { name: record.name })).toBeInTheDocument(); - }); -}); diff --git a/tests/registry-content-first.dom.test.tsx b/tests/registry-content-first.dom.test.tsx deleted file mode 100644 index 96c1a243..00000000 --- a/tests/registry-content-first.dom.test.tsx +++ /dev/null @@ -1,104 +0,0 @@ -import { render, screen } from "@testing-library/react"; -import { describe, expect, it, vi } from "vitest"; - -import { RegistryRecordLoader } from "@/components/registry-record-loader"; -import { serviceRecords, type ServiceRecord } from "@/lib/services"; -import type { RegistryRecordResult } from "@/lib/use-registry-records"; - -// Mutable holder so each test can drive the mocked hook's returned state. -const hook = vi.hoisted(() => ({ state: null as unknown as RegistryRecordResult })); -vi.mock("@/lib/use-registry-records", () => ({ - useRegistryRecord: () => hook.state, -})); - -const baseRecord = serviceRecords[0]; - -function serviceRecord(locallyVerified: boolean): ServiceRecord { - return { ...baseRecord, verification: { ...baseRecord.verification, locallyVerified } }; -} - -function loaderState(overrides: Partial): RegistryRecordResult { - return { - status: "loading", - record: null, - linkedDocuments: [], - demoMode: false, - governance: null, - refetch: vi.fn(), - ...overrides, - }; -} - -// Render-prop that surfaces the verified flag + title the loader hands down, so -// the tests can assert exactly what content-first rendered. -function child(record: ServiceRecord) { - return ( -
- lv:{String(record.verification?.locallyVerified)}|{record.title} -
- ); -} - -describe("RegistryRecordLoader content-first fallback", () => { - it("paints the public fixture immediately during loading instead of a spinner", () => { - hook.state = loaderState({ status: "loading" }); - render( - - {child} - , - ); - expect(screen.getByTestId("child")).toHaveTextContent(baseRecord.title); - expect(screen.queryByText(/Loading service record/i)).not.toBeInTheDocument(); - }); - - it("neutralizes a stale 'locally verified' flag during the provisional paint", () => { - hook.state = loaderState({ status: "loading" }); - render( - - {child} - , - ); - // Fixture claims verified=true, but the pre-reconciliation paint must show false - // so a stale authoritative-looking badge can't flash in. - expect(screen.getByTestId("child")).toHaveTextContent("lv:false"); - }); - - it("reconciles the verified flag from authoritative governance when ready", () => { - hook.state = loaderState({ - status: "ready", - record: serviceRecord(true), - governance: { sourceStatus: "current", validationStatus: "unverified" }, - }); - const { rerender } = render( - - {child} - , - ); - // Fixture verified=true, but authoritative governance says unverified -> false. - expect(screen.getByTestId("child")).toHaveTextContent("lv:false"); - - hook.state = loaderState({ - status: "ready", - record: serviceRecord(false), - governance: { sourceStatus: "current", validationStatus: "locally_reviewed" }, - }); - rerender( - - {child} - , - ); - // Authoritative governance says reviewed -> true (reconciled up). - expect(screen.getByTestId("child")).toHaveTextContent("lv:true"); - }); - - it("keeps the spinner for owner-only slugs with no fixture fallback", () => { - hook.state = loaderState({ status: "loading" }); - render( - - {child} - , - ); - expect(screen.getByText(/Loading service record/i)).toBeInTheDocument(); - expect(screen.queryByTestId("child")).not.toBeInTheDocument(); - }); -});