mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-11 13:52:20 +00:00
test(dashboard-hero): cover hero-ring-order default + reorder; i18n hint
Add resolveHeroRingOrder unit coverage (default health-score-first, reconcile against selected set, drop/append, dedupe) plus resolver/serializer round-trip; hero SSR tests for the default lead + a persisted custom order + dropped-when-unrendered; Settings picker tests for the pinned health-score anchor row, its locked-on switch, drag/arrow reorder, and a persisted non-leading order. Extend the score-rings picker description across six locales.
This commit is contained in:
1 parent
abe688caba
commit
abb2db37ee
13 files changed
+317
-26
No files matched your search
@@ -7,6 +7,8 @@ import {
|
||||
DASHBOARD_IOS_ONLY_WIDGET_IDS,
|
||||
DASHBOARD_WIDGET_CATALOGUE_IDS,
|
||||
IOS_PIN_ONLY_WIDGET_IDS,
|
||||
DEFAULT_HERO_RING_ORDER,
|
||||
resolveHeroRingOrder,
|
||||
type DashboardLayout,
|
||||
} from "@/lib/dashboard-layout";
|
||||
|
||||
@@ -746,3 +748,119 @@ describe("resolveDashboardLayout() — selectedScoreRings", () => {
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* v1.27.27 — hero ring ORDER (`heroRingOrder`). The health-score ring is a
|
||||
* first-class, always-present, reorderable member of the hero row that
|
||||
* leads by default. The order rides the layout blob (no migration) and the
|
||||
* resolver reconciles it against the selected set on every read/serialize.
|
||||
*/
|
||||
describe("resolveHeroRingOrder()", () => {
|
||||
it("defaults a missing / malformed order to health-score-first", () => {
|
||||
for (const bad of [undefined, null, "READINESS", 3, { a: 1 }]) {
|
||||
expect(
|
||||
resolveHeroRingOrder(bad, ["READINESS", "MED_COMPLIANCE"]),
|
||||
).toEqual(["HEALTH_SCORE", "READINESS", "MED_COMPLIANCE"]);
|
||||
}
|
||||
});
|
||||
|
||||
it("honours a stored order that moves the health-score ring off the lead", () => {
|
||||
expect(
|
||||
resolveHeroRingOrder(
|
||||
["READINESS", "HEALTH_SCORE", "MED_COMPLIANCE"],
|
||||
["READINESS", "MED_COMPLIANCE"],
|
||||
),
|
||||
).toEqual(["READINESS", "HEALTH_SCORE", "MED_COMPLIANCE"]);
|
||||
});
|
||||
|
||||
it("drops an ordered id whose ring is no longer selected", () => {
|
||||
expect(
|
||||
resolveHeroRingOrder(
|
||||
["READINESS", "HEALTH_SCORE", "SLEEP_SCORE"],
|
||||
["READINESS"], // SLEEP_SCORE deselected
|
||||
),
|
||||
).toEqual(["READINESS", "HEALTH_SCORE"]);
|
||||
});
|
||||
|
||||
it("appends a newly-selected ring the stored order didn't place", () => {
|
||||
expect(
|
||||
resolveHeroRingOrder(
|
||||
["HEALTH_SCORE", "READINESS"],
|
||||
["READINESS", "MED_COMPLIANCE"], // MED_COMPLIANCE freshly added
|
||||
),
|
||||
).toEqual(["HEALTH_SCORE", "READINESS", "MED_COMPLIANCE"]);
|
||||
});
|
||||
|
||||
it("drops unknown ids and collapses duplicates, always keeping the health-score ring", () => {
|
||||
expect(
|
||||
resolveHeroRingOrder(
|
||||
["READINESS", "BOGUS", "READINESS", "HEALTH_SCORE"],
|
||||
["READINESS"],
|
||||
),
|
||||
).toEqual(["READINESS", "HEALTH_SCORE"]);
|
||||
});
|
||||
|
||||
it("appends the health-score ring when a corrupt order omits it entirely", () => {
|
||||
expect(resolveHeroRingOrder(["READINESS"], ["READINESS"])).toEqual([
|
||||
"READINESS",
|
||||
"HEALTH_SCORE",
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveDashboardLayout() / serialize — heroRingOrder", () => {
|
||||
const base = {
|
||||
version: 1,
|
||||
widgets: [{ id: "weight", visible: true, tileVisible: true, order: 0 }],
|
||||
};
|
||||
|
||||
it("a legacy blob (field missing) resolves to health-score-first over the selected rings", () => {
|
||||
const resolved = resolveDashboardLayout({
|
||||
...base,
|
||||
selectedScoreRings: ["READINESS", "SLEEP_SCORE"],
|
||||
});
|
||||
expect(resolved.heroRingOrder).toEqual([
|
||||
"HEALTH_SCORE",
|
||||
"READINESS",
|
||||
"SLEEP_SCORE",
|
||||
]);
|
||||
});
|
||||
|
||||
it("reconciles a stored order against the selected set on read", () => {
|
||||
const resolved = resolveDashboardLayout({
|
||||
...base,
|
||||
selectedScoreRings: ["READINESS", "MED_COMPLIANCE"],
|
||||
heroRingOrder: ["MED_COMPLIANCE", "HEALTH_SCORE", "READINESS"],
|
||||
});
|
||||
expect(resolved.heroRingOrder).toEqual([
|
||||
"MED_COMPLIANCE",
|
||||
"HEALTH_SCORE",
|
||||
"READINESS",
|
||||
]);
|
||||
});
|
||||
|
||||
it("serialize persists a reconciled order and round-trips", () => {
|
||||
const serialized = serializeDashboardLayout({
|
||||
...DEFAULT_DASHBOARD_LAYOUT,
|
||||
selectedScoreRings: ["READINESS", "MED_COMPLIANCE"],
|
||||
heroRingOrder: ["READINESS", "HEALTH_SCORE", "MED_COMPLIANCE"],
|
||||
} as DashboardLayout);
|
||||
expect(serialized.heroRingOrder).toEqual([
|
||||
"READINESS",
|
||||
"HEALTH_SCORE",
|
||||
"MED_COMPLIANCE",
|
||||
]);
|
||||
expect(resolveDashboardLayout(serialized).heroRingOrder).toEqual([
|
||||
"READINESS",
|
||||
"HEALTH_SCORE",
|
||||
"MED_COMPLIANCE",
|
||||
]);
|
||||
});
|
||||
|
||||
it("the default layout leads with the health-score ring", () => {
|
||||
expect(DEFAULT_DASHBOARD_LAYOUT.heroRingOrder).toEqual(
|
||||
DEFAULT_HERO_RING_ORDER,
|
||||
);
|
||||
expect(DEFAULT_HERO_RING_ORDER[0]).toBe("HEALTH_SCORE");
|
||||
});
|
||||
});
|
||||
@@ -372,10 +372,7 @@ export const DEFAULT_SELECTED_SCORE_RINGS: ScoreRingId[] = ["MED_COMPLIANCE"];
|
||||
* rings; `HeroRingId` is the union the persisted order carries.
|
||||
*/
|
||||
export const HEALTH_SCORE_RING_ID = "HEALTH_SCORE" as const;
|
||||
export const HERO_RING_IDS = [
|
||||
HEALTH_SCORE_RING_ID,
|
||||
...SCORE_RING_IDS,
|
||||
] as const;
|
||||
export const HERO_RING_IDS = [HEALTH_SCORE_RING_ID, ...SCORE_RING_IDS] as const;
|
||||
export type HeroRingId = (typeof HERO_RING_IDS)[number];
|
||||
|
||||
/** The order carries the health-score ring plus up to three score rings. */
|
||||
|
||||
Reference in new issue
Block a user