From 1214d2b2ed78cd7b0ddba7fd49ce106b475fe095 Mon Sep 17 00:00:00 2001 From: Lucas Winther Date: Wed, 2 Sep 2026 02:23:02 +0200 Subject: [PATCH] test(store): cover a v1 post missing standingRule entirely (v1 -> v2) Previously only an empty posts array was tested for the "no standingRule" path; a post that IS present but lacks the field was exercised only by an ad-hoc script, not a committed test. Asserts rules === [] (never a version wrapping undefined, which would later crash resolveRule/ruleAt) and that a sibling post's rule is unaffected. --- src/store/migrations.test.ts | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/store/migrations.test.ts b/src/store/migrations.test.ts index 84e5061..1bc6535 100644 --- a/src/store/migrations.test.ts +++ b/src/store/migrations.test.ts @@ -109,8 +109,29 @@ describe("v1 -> v2: rules become a dated series", () => { } }); - test("a v1 post with no posts at all migrates without throwing", () => { + test("an empty posts array migrates without throwing", () => { const empty = { ...v1Dataset(), posts: [] }; expect(migrate(empty).posts).toEqual([]); }); + + test("a v1 post with no standingRule at all migrates to an empty rules array, not a version wrapping undefined", () => { + const dataset = v1Dataset(); + dataset.posts.push({ + id: "unbudgeted", + name: "Unbudgeted", + order: 2, + archived: false, + currency: "DKK", + } as any); + + const migrated = migrate(dataset); + + const unbudgeted = migrated.posts.find((p) => p.id === "unbudgeted")!; + expect(unbudgeted.rules).toEqual([]); + + // The missing field on one post must not contaminate its siblings. + expect(migrated.posts[0]!.rules).toEqual([ + { from: "2026-01", rule: { kind: "percentOfIncome", percent: 20 } }, + ]); + }); });