diff --git a/src/components/charts/__tests__/medication-compliance-chart-empty-state-gate.test.tsx b/src/components/charts/__tests__/medication-compliance-chart-empty-state-gate.test.tsx new file mode 100644 index 000000000..e8e0196ff --- /dev/null +++ b/src/components/charts/__tests__/medication-compliance-chart-empty-state-gate.test.tsx @@ -0,0 +1,93 @@ +import { describe, it, expect, vi, beforeEach } from "vitest"; +import { renderToStaticMarkup } from "react-dom/server"; + +/** + * v1.4.43 W2-CHART-GATE — medication-compliance empty-state copy split. + * + * The chart aggregates per-day compliance buckets, so a user with 20 + * scheduled doses on 2 calendar days collapses to `chartData.length = + * 2`. The pre-v1.4.43 "log more measurements" hint misled — they + * logged plenty, just on too few days. The gate now keys on + * `rawCount = Σ scheduled` so the second message paints whenever the + * user has enough raw doses but the chart is < 3 buckets wide. + */ + +vi.mock("@/hooks/use-auth", () => ({ + useAuth: () => ({ + isAuthenticated: true, + user: null, + isLoading: false, + }), +})); + +describe(" — empty-state gate by raw count", () => { + beforeEach(() => { + vi.resetModules(); + }); + + + it("renders need-more-days copy when chartData.length < 3 but rawCount >= 3", async () => { + const data = [ + { date: "2026-05-19", scheduled: 10, taken: 8 }, + { date: "2026-05-20", scheduled: 10, taken: 9 }, + ]; + + vi.doMock("@tanstack/react-query", () => ({ + useQuery: () => ({ data, isLoading: false }), + useQueryClient: () => ({ + cancelQueries: () => Promise.resolve(), + getQueryData: () => undefined, + setQueryData: () => undefined, + invalidateQueries: () => Promise.resolve(), + }), + useMutation: () => ({ mutate: () => undefined, isPending: false }), + })); + + const { I18nProvider } = await import("@/lib/i18n/context"); + const { MedicationComplianceChart } = await import( + "../medication-compliance-chart" + ); + + const html = renderToStaticMarkup( + + + , + ); + + expect(html).toContain("Mehr Messtage erforderlich"); + expect(html).not.toContain("Erfasse mindestens 3 Einträge"); + + vi.doUnmock("@tanstack/react-query"); + }); + + it("renders no-data copy when rawCount < 3", async () => { + const data = [{ date: "2026-05-20", scheduled: 1, taken: 1 }]; + + vi.doMock("@tanstack/react-query", () => ({ + useQuery: () => ({ data, isLoading: false }), + useQueryClient: () => ({ + cancelQueries: () => Promise.resolve(), + getQueryData: () => undefined, + setQueryData: () => undefined, + invalidateQueries: () => Promise.resolve(), + }), + useMutation: () => ({ mutate: () => undefined, isPending: false }), + })); + + const { I18nProvider } = await import("@/lib/i18n/context"); + const { MedicationComplianceChart } = await import( + "../medication-compliance-chart" + ); + + const html = renderToStaticMarkup( + + + , + ); + + expect(html).toContain("Erfasse mindestens 3 Einträge"); + expect(html).not.toContain("Mehr Messtage erforderlich"); + + vi.doUnmock("@tanstack/react-query"); + }); +}); diff --git a/src/components/charts/medication-compliance-chart.tsx b/src/components/charts/medication-compliance-chart.tsx index 5f62e30dc..e791a09c2 100644 --- a/src/components/charts/medication-compliance-chart.tsx +++ b/src/components/charts/medication-compliance-chart.tsx @@ -252,6 +252,21 @@ export function MedicationComplianceChart({ [data, tzFmt], ); + // v1.4.43 W2-CHART-GATE — raw scheduled-dose count across every day + // in the window. The chart bucket aggregates per-day compliance, so + // a user with 20 scheduled doses on 2 calendar days collapses to + // `chartData.length = 2`. Sum the `scheduled` field across the raw + // daily points so the empty-state gate can distinguish "no doses + // tracked" from "doses tracked but on too few days". + const rawCount = useMemo(() => { + if (!data?.length) return 0; + return data.reduce( + (acc, point) => + acc + (Number.isFinite(point.scheduled) ? point.scheduled : 0), + 0, + ); + }, [data]); + // v1.4.16 A6 — 7-day trend chip. Computed off the *full* range so a // user toggled to "7 days" still sees a trend (which would otherwise // be empty if we only used the visible window). The 14-day cap inside @@ -391,10 +406,23 @@ export function MedicationComplianceChart({ ) : chartData.length < 3 ? ( // v1.4.16 B1a — sparse-data placeholder consistent with the // BP/weight/pulse/mood charts. - + // + // v1.4.43 W2-CHART-GATE — split the copy on the raw scheduled- + // dose count. A user with 20 scheduled doses on 2 calendar + // days has `chartData.length = 2`; the legacy "log more" hint + // misled — they logged plenty, just on too few days. Surface + // "need more days" when the raw count is already enough. + rawCount >= 3 ? ( + + ) : ( + + ) ) : (