mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-11 05:42:19 +00:00
The intake pickers chose their default from every active medication, so a course that had ended but was not archived could be the preselected dose. The default now reads the server's intakeActionable answer; the medications page dialog still lists ended courses for back-filling a past dose, they are just never the default. Both pickers also graded "due" against the fixed 120 / 240-minute defaults while the cards beside them used the account's own late and missed thresholds. They read the same thresholds now.
117 lines
3.2 KiB
TypeScript
117 lines
3.2 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import {
|
|
pickDefaultMedicationId,
|
|
resolveMedicationSelectionId,
|
|
type DefaultMedicationOption,
|
|
} from "@/lib/medications/default-medication";
|
|
|
|
function medication(
|
|
id: string,
|
|
overrides: Partial<DefaultMedicationOption> = {},
|
|
): DefaultMedicationOption {
|
|
return {
|
|
id,
|
|
name: `Medication ${id}`,
|
|
active: true,
|
|
intakeActionable: true,
|
|
schedules: [],
|
|
lastTakenAt: null,
|
|
todayEventCount: 0,
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
const currentWindow = {
|
|
windowStart: "08:00",
|
|
windowEnd: "11:00",
|
|
daysOfWeek: null,
|
|
};
|
|
|
|
describe("pickDefaultMedicationId", () => {
|
|
it("prefers a current-window medication over the first array item", () => {
|
|
const now = new Date("2026-05-12T08:00:00.000Z");
|
|
|
|
expect(
|
|
pickDefaultMedicationId(
|
|
[
|
|
medication("first", { name: "Alpha" }),
|
|
medication("due", {
|
|
name: "Zulu",
|
|
schedules: [currentWindow],
|
|
nextDueAt: "2026-05-12T07:00:00.000Z",
|
|
nextDueOverdue: false,
|
|
}),
|
|
],
|
|
now,
|
|
),
|
|
).toBe("due");
|
|
});
|
|
|
|
it("keeps the alphabetical fallback stable when next due is in the future", () => {
|
|
const now = new Date("2026-05-12T08:00:00.000Z");
|
|
const options = [
|
|
medication("z", {
|
|
name: "Zolpidem",
|
|
schedules: [currentWindow],
|
|
nextDueAt: "2026-05-13T07:00:00.000Z",
|
|
nextDueOverdue: false,
|
|
}),
|
|
medication("r", { name: "Ramipril" }),
|
|
];
|
|
|
|
expect(pickDefaultMedicationId(options, now)).toBe("r");
|
|
expect(pickDefaultMedicationId([...options].reverse(), now)).toBe("r");
|
|
});
|
|
|
|
it("never preselects an ended course, even when it is the only active one", () => {
|
|
// Still active (not archived) but the course ended: the server answers
|
|
// `intakeActionable: false`, the list keeps it for back-filling, and the
|
|
// default lands on the medication that offers a dose today.
|
|
const options = [
|
|
medication("ended", {
|
|
name: "Amoxicillin",
|
|
active: true,
|
|
intakeActionable: false,
|
|
}),
|
|
medication("current", { name: "Ramipril" }),
|
|
];
|
|
expect(pickDefaultMedicationId(options)).toBe("current");
|
|
expect(
|
|
pickDefaultMedicationId([
|
|
medication("ended", { active: true, intakeActionable: false }),
|
|
]),
|
|
).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe("resolveMedicationSelectionId", () => {
|
|
it("preserves an explicit user selection when due data changes on re-render", () => {
|
|
const now = new Date("2026-05-12T08:00:00.000Z");
|
|
const initial = [
|
|
medication("manual", { name: "Alpha" }),
|
|
medication("due", {
|
|
name: "Zulu",
|
|
schedules: [currentWindow],
|
|
nextDueAt: "2026-05-12T07:00:00.000Z",
|
|
nextDueOverdue: false,
|
|
}),
|
|
];
|
|
|
|
expect(resolveMedicationSelectionId(initial, null, now)).toBe("due");
|
|
|
|
const rerendered = [
|
|
medication("other-due", {
|
|
name: "Beta",
|
|
schedules: [currentWindow],
|
|
nextDueAt: "2026-05-12T07:00:00.000Z",
|
|
nextDueOverdue: true,
|
|
}),
|
|
...initial,
|
|
];
|
|
expect(resolveMedicationSelectionId(rerendered, "manual", now)).toBe(
|
|
"manual",
|
|
);
|
|
});
|
|
});
|