diff --git a/CHANGELOG.md b/CHANGELOG.md index a4c57a4..1f84f74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and - Badges and search results use simple line icons instead of emoji. ### 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. - Finished goals no longer show as "late". - The chosen profile picture in Settings is now visibly selected. - Search results can be opened with the keyboard. diff --git a/assets/js/storage.js b/assets/js/storage.js index 7ec53be..c27073c 100644 --- a/assets/js/storage.js +++ b/assets/js/storage.js @@ -684,7 +684,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); diff --git a/tests/storage.test.js b/tests/storage.test.js index 7157511..d38d4dc 100644 --- a/tests/storage.test.js +++ b/tests/storage.test.js @@ -174,9 +174,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' } ] }) ); @@ -188,6 +192,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".