diff --git a/src/app/insights/medications/__tests__/page.test.tsx b/src/app/insights/medications/__tests__/page.test.tsx new file mode 100644 index 000000000..7503f44fd --- /dev/null +++ b/src/app/insights/medications/__tests__/page.test.tsx @@ -0,0 +1,81 @@ +import { describe, expect, it, vi } from "vitest"; +import { renderToStaticMarkup } from "react-dom/server"; +import type { ReactNode } from "react"; + +/** + * Insights > Medications: the efficacy summary sits below every medication + * card and asks one efficacy read per medication. On entry it holds its slot + * with a sentinel and mounts only when scrolled near, so opening the page + * sends the cards' reads and not the summary's. + */ + +vi.mock("@tanstack/react-query", () => ({ + useQuery: ({ queryKey }: { queryKey: readonly unknown[] }) => + queryKey[1] === "comprehensive" + ? { + data: { + medications: [ + { + id: "m1", + name: "Ramipril", + dose: "5 mg", + category: "BLOOD_PRESSURE", + compliance7: 100, + compliance30: 95, + streak: 7, + taken7: 7, + skipped7: 0, + missed7: 0, + }, + ], + }, + isLoading: false, + isError: false, + } + : { data: undefined, isLoading: false, isError: false }, +})); +vi.mock("@/hooks/use-auth", () => ({ + useAuth: () => ({ isAuthenticated: true }), +})); +vi.mock("@/hooks/use-ai-capability", () => ({ + useAiCapability: () => ({ available: false }), + useAiProviderState: () => ({ responseTimeoutMs: null }), +})); +vi.mock("@/components/insights/medication-efficacy-summary", () => ({ + MedicationEfficacySummary: () =>
, +})); +vi.mock("@/components/insights/sub-page-shell", () => ({ + SubPageShell: ({ children }: { children: ReactNode }) => <>{children}, +})); +vi.mock("@/components/insights/glp1-substance-curve-summary", () => ({ + Glp1SubstanceCurveSummary: () => null, +})); +vi.mock("@/components/insights/metric-target-summary", () => ({ + MetricTargetSummary: () => null, +})); +vi.mock("@/components/insights/insight-status-card", () => ({ + InsightStatusCard: () => null, +})); +vi.mock("@/components/insights/coach-launch-button", () => ({ + CoachLaunchButton: () => null, +})); +vi.mock("@/components/charts/compliance-heatmap", () => ({ + ComplianceHeatmap: () => null, +})); + +import { I18nProvider } from "@/lib/i18n/context"; +import InsightsMedikamentePage from "../page"; + +describe("/insights/medications on entry", () => { + it("renders the cards and holds the efficacy summary until scrolled near", () => { + const html = renderToStaticMarkup( + + + , + ); + + expect(html).toContain("Ramipril"); + expect(html).toContain('data-deferred-section="medication-efficacy"'); + expect(html).not.toContain("efficacy-summary-mounted"); + }); +}); diff --git a/src/app/insights/medications/page.tsx b/src/app/insights/medications/page.tsx index bd17dc53f..efe9abb03 100644 --- a/src/app/insights/medications/page.tsx +++ b/src/app/insights/medications/page.tsx @@ -24,6 +24,7 @@ import { CoachLaunchButton } from "@/components/insights/coach-launch-button"; import { InsightStatusCard } from "@/components/insights/insight-status-card"; import { MetricTargetSummary } from "@/components/insights/metric-target-summary"; import { MedicationEfficacySummary } from "@/components/insights/medication-efficacy-summary"; +import { DeferUntilNear } from "@/components/insights/defer-until-near"; import { Glp1SubstanceCurveSummary } from "@/components/insights/glp1-substance-curve-summary"; import { SubPageShell } from "@/components/insights/sub-page-shell"; import { TileHeader } from "@/components/insights/tile-header"; @@ -321,12 +322,12 @@ export default function InsightsMedikamentePage() { })}
- {/* v1.28 — compact efficacy summary: reuses the same server-computed - efficacy DTO the detail-page "Wirkung" tab reads (never a second - computation), association-only, linking through to the full view. */} - ({ id: m.id, name: m.name }))} - /> + {/* v1.28 — one efficacy read per medication, below every card: mounted when near. */} + + ({ id: m.id, name: m.name }))} + /> + {/* v1.28.20 — estimated active-substance curve for GLP-1 medications (additive; renders nothing when the user has no GLP-1 medication). */}