diff --git a/CHANGELOG.md b/CHANGELOG.md index bbd284f..f03c1e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ A calmer, simpler CodeOrbit that works offline and reminds you to back up. - New projects start with an empty "Tools used" list instead of "TypeScript, Node.js". ### Fixed +- Importing a backup with a 0-minute session no longer turns it into 30 minutes; zero and negative durations are clamped to 1, the same as any other out-of-range value. - The getting-started screen (and its *Try it with sample data first* button) appeared when you had only projects or goals, and loading sample data would have replaced them. It now only appears when nothing at all is saved. - Skill cards were hard on the eyes: too many bright, heavy elements. They are calmer now: softer numbers, grey planets and bars (crimson only when finished), plain-text categories, and regular digits on the ±10% buttons. Main text is now a soft off-white instead of near-pure white. - Loading sample data, restoring a backup or deleting all data no longer shows "You earned a badge" pop-ups. Badges you really earn still get one. diff --git a/assets/js/storage.js b/assets/js/storage.js index 01b5eab..74f87fd 100644 --- a/assets/js/storage.js +++ b/assets/js/storage.js @@ -718,7 +718,8 @@ class StorageManager { g.progress = Math.min(100, Math.max(0, parseInt(g.progress, 10) || 0)); }); parsed.activities.forEach(a => { - a.duration = Math.max(1, parseInt(a.duration, 10) || 30); + const duration = parseInt(a.duration, 10); + a.duration = Math.max(1, Number.isNaN(duration) ? 30 : duration); }); this.saveUniverse(parsed, 'replace'); diff --git a/tests/storage.test.js b/tests/storage.test.js index fed031b..9402737 100644 --- a/tests/storage.test.js +++ b/tests/storage.test.js @@ -179,9 +179,13 @@ describe('import and export', () => { { id: 's2', progress: -5 } ], projects: [{ id: 'p1', progress: '42' }], + // Every activity needs a valid date: imports drop dateless entries + // (see the malformed-dates security test below). activities: [ - { id: 'a1', duration: -10 }, - { id: 'a2', duration: 'x' } + { id: 'a1', date: '2026-11-01', duration: -10 }, + { id: 'a2', date: '2026-11-02', duration: 'x' }, + { id: 'a3', date: '2026-11-03', duration: 0 }, + { id: 'a4', date: '2026-11-04' } ] }) ); @@ -193,6 +197,11 @@ describe('import and export', () => { assert.equal(u.projects[0].progress, 42); assert.deepEqual(u.projects[0].technologies, []); for (const a of u.activities) assert.ok(a.duration >= 1, `duration ${a.duration}`); + // -10 -> 1 (minimum), 0 -> 1, non-numeric/missing -> 30 (default) + assert.deepEqual( + u.activities.map(a => a.duration), + [1, 30, 1, 30] + ); }); // Regression for D-009: a backup without a profile used to become "Alex Rivera".