test(medications): pin the card clock so window-status and day labels are deterministic

This commit is contained in:
Marc-André Bombeck committed 2026-06-03 01:07:36 +02:00
1 parent fbab8cfd30
commit 56e9816def
2 files changed
+33 -16

No files matched your search

@@ -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("<MedicationCard> — 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("<MedicationCard> — 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("<MedicationCard> — 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();
}
});
});
@@ -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();