test(score): pin the weight yardstick, the mood gate and rollup/live parity

Covers what the required parameters now make impossible to forget: the
scorer takes the band whole and never widens it, a missing target scores
the bare trend, the resolved yardstick rides the weight component, the
shared builder refuses the reference band that sits under an override,
the snapshot gates its mood pillar on the module map, an explicit target
reaches both the score and the dashboard bands, and weight/BMI record
direction follows the user's own goal.

F1 adds the golden the score has never had: the rollup read branch and
the live read branch scored against one series encoded both ways. On the
canonical one-weigh-in-a-day cadence they agree exactly. On an uneven
cadence they part company, and the test pins that the whole difference is
the per-day mean collapse - the rollup branch equals the live branch fed
those same daily means - with a companion assertion proving the fixture
is not a no-op.
This commit is contained in:
Marc-André Bombeck committed 2026-07-27 23:15:38 +02:00
1 parent b0862c0902
commit be348f8820
12 files changed
+886 -63

No files matched your search

@@ -359,3 +359,75 @@ describe("<HealthScoreCard>", () => {
expect(progressMatch?.[0]).toContain('aria-valuemax="100"');
});
});
/**
* v1.34 — the weight row names its yardstick. Before this the score graded
* weight against a band the user never set and the card said nothing at all,
* which is why the defect survived for months.
*/
describe("<HealthScoreCard> — weight yardstick disclosure", () => {
it("names the user's own target band", () => {
const html = ssr(
<HealthScoreCard
score={80}
band="green"
components={baseComponents}
delta={null}
weightYardstick={{ source: "user", targetLabel: "64-70 kg" }}
/>,
);
const line = html.match(
/<p[^>]*data-slot="health-score-card-weight-yardstick"[^>]*>([\s\S]*?)<\/p>/,
);
expect(line).not.toBeNull();
expect(line?.[0]).toContain('data-target-source="user"');
expect(line?.[1]).toContain("64-70 kg");
});
it("says plainly when no target graded the row", () => {
const html = ssr(
<HealthScoreCard
score={80}
band="green"
components={baseComponents}
delta={null}
weightYardstick={{ source: "none", targetLabel: null }}
/>,
);
const line = html.match(
/<p[^>]*data-slot="health-score-card-weight-yardstick"[^>]*>([\s\S]*?)<\/p>/,
);
expect(line).not.toBeNull();
expect(line?.[0]).toContain('data-target-source="none"');
expect(line?.[1]).toMatch(/trend/i);
});
it("discloses nothing when the payload carries no yardstick", () => {
// An older cached body has no `targetSource`; silence beats a guess.
const html = ssr(
<HealthScoreCard
score={80}
band="green"
components={baseComponents}
delta={null}
/>,
);
expect(html).not.toContain("health-score-card-weight-yardstick");
});
it("stays quiet when the weight pillar itself has no value", () => {
const html = ssr(
<HealthScoreCard
score={80}
band="green"
components={{
...baseComponents,
weight: { value: null, weight: 0 },
}}
delta={null}
weightYardstick={{ source: "none", targetLabel: null }}
/>,
);
expect(html).not.toContain("health-score-card-weight-yardstick");
});
});