test(medications): pin intake-history-list-v2 status render contract

Add two SSR fixtures to lock the v1.4.37 W3 fix in place: a mixed
taken+skipped seed asserts the distinct lucide icon + green styling
for taken rows and the muted outline styling for skipped rows, and a
German-locale skipped-only seed proves the table body never leaks the
"Eingenommen" label onto a skipped row. The seed helper threads the
new `status:"completed"` cache-key shard so the component reads its
own seed without firing a network call.
This commit is contained in:
Marc-André Bombeck committed 2026-05-17 14:13:39 +02:00
1 parent be399ee799
commit 6b2c63caea
1 file changed
+88 -1
@@ -61,13 +61,16 @@ function seedIntake(
const sortDir = opts.sortDir ?? "desc";
const limit = opts.limit ?? 25;
const offset = opts.offset ?? 0;
// v1.4.37 W3 — the component pins `status:"completed"` on the
// server-side query and threads it through the cache key, so the
// seed mirrors that shape verbatim.
client.setQueryData(
[
"medications",
medId,
"intake",
"list",
{ sortBy, sortDir, limit, offset },
{ sortBy, sortDir, limit, offset, status: "completed" },
],
{ events: rows, meta: { total, limit, offset } },
);
@@ -148,6 +151,90 @@ describe("<IntakeHistoryListV2> — populated rows", () => {
expect(html).toContain("Telegram / Reminder");
});
it("renders the taken row with a green Check chip and the skipped row with an outline SkipForward chip", () => {
// v1.4.37 W3 — guards the regression Marc reported on 2026-05-17:
// before the fix, every row used the same secondary badge with the
// "Eingenommen" label regardless of skipped status. The chip must
// surface a distinct icon + label per branch and never label a
// skipped row "Eingenommen".
const client = makeClient();
seedIntake(client, "med-status", [
{
id: "evt-taken",
medicationId: "med-status",
scheduledFor: "2026-05-15T08:00:00.000Z",
takenAt: "2026-05-15T08:02:00.000Z",
skipped: false,
source: "WEB",
createdAt: "2026-05-15T08:02:00.000Z",
},
{
id: "evt-skipped",
medicationId: "med-status",
scheduledFor: "2026-05-14T08:00:00.000Z",
takenAt: null,
skipped: true,
source: "REMINDER",
createdAt: "2026-05-14T20:00:00.000Z",
},
]);
const html = render(
<IntakeHistoryListV2 medicationId="med-status" />,
client,
);
// Distinct lucide icons per branch — proves the row matched the
// correct status arm and isn't just printing a label.
expect(html).toContain("lucide-check");
expect(html).toContain("lucide-skip-forward");
// The green styling pins the taken branch visually so a future
// refactor cannot silently collapse the two chips back into one
// neutral badge.
expect(html).toMatch(/bg-green-500\/20[^"]*text-green-400/);
// Skipped rows render as a muted outline chip — never as the
// secondary "Eingenommen" badge.
expect(html).toMatch(/text-muted-foreground[^"]*gap-1[^"]*text-xs/);
expect(html).toContain("Taken");
expect(html).toContain("Skipped");
});
it("renders the skipped chip in German without leaking the Eingenommen label", () => {
// v1.4.37 W3 — UAT echo. Marc reported a German row labelled
// both "übersprungen" and "eingenommen". The fix means a
// skipped-only fixture renders "Übersprungen" exactly once and
// "Eingenommen" zero times.
const client = makeClient();
seedIntake(client, "med-skipped", [
{
id: "evt-skipped",
medicationId: "med-skipped",
scheduledFor: "2026-04-29T05:00:00.000Z",
takenAt: null,
skipped: true,
source: "REMINDER",
createdAt: "2026-04-29T05:01:00.000Z",
},
]);
const html = render(
<IntakeHistoryListV2 medicationId="med-skipped" />,
client,
"de",
);
// Locate the table-body slice so we only count chip labels, not
// the column headers (which also say "Eingenommen" for the
// takenAt column header).
const tbodyMatch = html.match(/<tbody[\s\S]*?<\/tbody>/);
expect(tbodyMatch).not.toBeNull();
const body = tbodyMatch?.[0] ?? "";
expect(body).toContain("Übersprungen");
expect(body).not.toContain("Eingenommen");
});
it("renders the section title across both locales", () => {
const client = makeClient();
seedIntake(client, "med-1", []);