mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-13 22:32:04 +00:00
Prove the false drop cannot come back
The named failure now has a test that drives the whole chain a request takes: fixture rows through the real reader, the real score record write, the real dashboard snapshot, the real verdict rung, and the real digest that gives the morning push its sentence. Only the IO around that chain is faked. A version built on a hand-written snapshot literal would have stayed green through a release where the assembly between the two ends dropped the field, which has happened here before. Every case runs twice on the same data. Once with the recipe changed three days ago, once with it changed a month ago. The second run is what proves the fixture really does produce an eleven-point fall, so the first run's silence is the guard working rather than an account with nothing to say. The decline is gradual on purpose: a cliff would raise each pillar's own noise floor and the delta would be suppressed for a reason that has nothing to do with the recipe. Beside it, the boundary's edges, the notice key's two dimensions and the seam's shape, each with a case proving the guard stays quiet on innocent data. Against real Postgres, a row now has to come back carrying the recipe version and change date the account's stored configuration supplied.
This commit is contained in:
1 parent
087f3f496b
commit
5d13f0e69c
3 files changed
+982
-3
No files matched your search
@@ -207,12 +207,48 @@ describe("the score a surface shows is the score that gets written down", () =>
|
||||
expect(row.inputFingerprint).toMatch(/^[0-9a-f]{64}$/);
|
||||
expect(row.timezone).toBe("UTC");
|
||||
expect(row.dayKey).toBe(new Date(now).toISOString().slice(0, 10));
|
||||
// Nothing supplies these yet, and an invented default would be worse than
|
||||
// an honest null the day the delta guard starts reading them.
|
||||
expect(row.configVersion).toBeNull();
|
||||
// The recipe the day was scored under, resolved on the write path from
|
||||
// the account's own stored configuration. This account never opened the
|
||||
// settings surface, so the honest answer is version 0 with no change
|
||||
// date — the thing the first authored recipe will later be a move FROM.
|
||||
expect(row.configVersion).toBe(0);
|
||||
expect(row.configChangedAt).toBeNull();
|
||||
});
|
||||
|
||||
it("stamps the account's own recipe on the row, straight from the stored configuration", async () => {
|
||||
// The supply half of the delta guard, over real Postgres. Nothing in
|
||||
// the request carries the recipe: the write path resolves it from the
|
||||
// same column the composition came from, so a version that never
|
||||
// reached the writer shows up as a row that cannot say which recipe
|
||||
// produced it — and the seam becomes underivable a release later.
|
||||
const user = await seedSession("hsr-recipe");
|
||||
const now = Date.now();
|
||||
await seedBp(user.id, now, 20, 122);
|
||||
await seedSleep(user.id, now, 14);
|
||||
await seedWaist(user.id, now);
|
||||
const changedAt = new Date(now - 3 * DAY);
|
||||
await getPrismaClient().user.update({
|
||||
where: { id: user.id },
|
||||
data: {
|
||||
healthScoreConfigJson: {
|
||||
excludedPillars: ["FITNESS"],
|
||||
version: 6,
|
||||
changedAt: changedAt.toISOString(),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect((await readAnalytics()).data!.healthScore!.composite.status).toBe(
|
||||
"ok",
|
||||
);
|
||||
|
||||
const row = await getPrismaClient().healthScoreRecord.findFirstOrThrow({
|
||||
where: { userId: user.id },
|
||||
});
|
||||
expect(row.configVersion).toBe(6);
|
||||
expect(row.configChangedAt?.toISOString()).toBe(changedAt.toISOString());
|
||||
});
|
||||
|
||||
it("leaves the recorded day untouched when the same day is computed again under a changed standing", async () => {
|
||||
const user = await seedSession("hsr-never-restate");
|
||||
const now = Date.now();
|
||||
|
||||
Reference in new issue
Block a user