diff --git a/src/components/medications/__tests__/medication-card-next-due.test.tsx b/src/components/medications/__tests__/medication-card-next-due.test.tsx index bb4fd48f5..d37d5ae2b 100644 --- a/src/components/medications/__tests__/medication-card-next-due.test.tsx +++ b/src/components/medications/__tests__/medication-card-next-due.test.tsx @@ -1,4 +1,4 @@ -import { describe, expect, it, vi } from "vitest"; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { renderToStaticMarkup } from "react-dom/server"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; @@ -52,6 +52,20 @@ const pastWindow = { dose: null, }; +// Pin the clock to a fixed mid-day instant so window-status ("take now" +// vs "next intake") and relative day labels are deterministic regardless +// of the CI host clock + timezone. The 01:00–02:00 windows below read as +// inactive at noon in every timezone; an unpinned run that happened to +// fall inside that window (e.g. 01:01 CEST) flipped the card to the +// take-now pill and broke these assertions. +beforeEach(() => { + vi.useFakeTimers({ toFake: ["Date"] }); + vi.setSystemTime(new Date("2026-06-02T12:00:00Z")); +}); +afterEach(() => { + vi.useRealTimers(); +}); + describe(" — next-due reads from server nextDueAt", () => { it("renders the server nextDueAt date for a rolling medication, not a today/tomorrow walker value", () => { // Rolling cadence: server anchors the next dose 35 days out. The @@ -152,17 +166,9 @@ describe(" — next-due reads from server nextDueAt", () => { it("renders the day label for a single-time daysOfWeek medication due tomorrow", () => { // A daily / weekly medication whose server next-due is tomorrow // still renders the relative "tomorrow" label — proving the ordinary - // single-time path keeps working. - // - // Pin the clock to a midday UTC instant and express `due` as a fixed - // UTC instant ~20h later: it lands on the next calendar day in every - // timezone the card might label in (UTC and the Berlin default alike), - // so the relative label is deterministic regardless of the CI host - // clock / timezone (the late-UTC run made an unpinned "tomorrow" read - // as "today" in the Berlin frame). - vi.useFakeTimers({ toFake: ["Date"] }); - try { - vi.setSystemTime(new Date("2026-06-02T12:00:00Z")); + // single-time path keeps working. `due` is a fixed UTC instant ~20h + // after the pinned clock, so it lands on the next calendar day in both + // UTC and the Berlin default — the relative label is deterministic. const now = new Date(); const due = new Date(now); due.setUTCDate(due.getUTCDate() + 1); @@ -208,8 +214,5 @@ describe(" — next-due reads from server nextDueAt", () => { expect(html).toContain("Next intake:"); // Relative day label from the server instant (capitalised "Tomorrow"). expect(html).toContain("Tomorrow,"); - } finally { - vi.useRealTimers(); - } }); }); diff --git a/src/components/medications/__tests__/medication-card-symmetry.test.tsx b/src/components/medications/__tests__/medication-card-symmetry.test.tsx index 8085c0cb7..d6d2627fe 100644 --- a/src/components/medications/__tests__/medication-card-symmetry.test.tsx +++ b/src/components/medications/__tests__/medication-card-symmetry.test.tsx @@ -1,4 +1,4 @@ -import { describe, expect, it } from "vitest"; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { renderToStaticMarkup } from "react-dom/server"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; @@ -127,6 +127,20 @@ const mounjaro: Glp1Medication = { ], }; +// Pin the clock to a fixed mid-day instant so window-status is +// deterministic: the all-day window (00:00–23:59) reads active (the +// take-now pill) and the 01:00–02:00 window reads inactive (the upcoming +// "next intake" line that carries the purple dose accent), in every +// timezone. An unpinned run that fell inside 01:00–02:00 (e.g. 01:01 CEST) +// flipped the accent test's card to the take-now pill. +beforeEach(() => { + vi.useFakeTimers({ toFake: ["Date"] }); + vi.setSystemTime(new Date("2026-06-02T12:00:00Z")); +}); +afterEach(() => { + vi.useRealTimers(); +}); + describe("medication card symmetry — Ramipril vs Mounjaro", () => { it("both cards collapse the header actions into a single kebab + navigable header link", () => { const client = makeClient();