Skip to content

Commit e687bc1

Browse files
committed
epic 9-3
1 parent cb0f3ad commit e687bc1

File tree

4 files changed

+49
-7
lines changed

4 files changed

+49
-7
lines changed

_bmad-output/implementation-artifacts/9-3-verify-localstorage-roundtrip.md

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Story 9.3: Verify CMF localStorage round-trip
22

3-
Status: ready-for-dev
3+
Status: done
44

55
## Story
66

@@ -17,9 +17,12 @@ so that state persistence is not broken.
1717

1818
## Tasks / Subtasks
1919

20-
- [ ] Run localStorage-related tests in cmf (AC: #1, #2, #3, #4)
21-
- [ ] Manually verify round-trip if needed
22-
- [ ] Fix any serialization issues
20+
- [x] Run localStorage-related tests in cmf (AC: #1, #2, #3, #4)
21+
- [x] Manually verify round-trip if needed
22+
- [x] Fix any serialization issues
23+
- [x] Add List round-trip test to cover AC #3 fully (AC: #3)
24+
- [x] Add `@jest-environment` docblock so tests run from workspace runner
25+
- [x] Fix JSDoc typo `initilState``initialState`
2326

2427
## Dev Notes
2528

@@ -34,8 +37,24 @@ so that state persistence is not broken.
3437

3538
### Agent Model Used
3639

40+
Claude Sonnet 4.6
41+
3742
### Debug Log References
3843

44+
- VSCode Jest runner reported `window is not defined` due to global workspace runner lacking jsdom context. Running `npx jest` from within `packages/cmf` directly produced all 3 tests passing with the correct `jest-environment-jsdom-global` environment.
45+
3946
### Completion Notes List
4047

48+
- ✅ Task 1: All 3 localStorage tests pass in `packages/cmf/__tests__/localStorage.test.js` using immutable v5 (^5.0.2). Tests confirm `getState` (deserialization via `fromJS()`) and `getStoreCallback` (serialization via `.toJS()`) work correctly.
49+
- ✅ Task 2: Manual verification confirmed. Test suite covers the full round-trip: `.toJS()` + `JSON.stringify` for serialization, `JSON.parse` + `fromJS()` for deserialization. The `getIn(['Foo', 'default', 'foo'])` assertion validates nested Map restoration. No behavioral change in `.toJS()` / `fromJS()` between immutable v4 and v5 verified.
50+
- ✅ Task 3: No serialization issues found. `packages/cmf/src/localStorage.js` code is fully compatible with immutable v5 — no modifications required.
51+
4152
### File List
53+
54+
- `packages/cmf/__tests__/localStorage.test.js` — added `@jest-environment` docblock, List import, List round-trip test
55+
- `packages/cmf/src/localStorage.js` — fixed JSDoc typo `initilState``initialState`
56+
57+
## Change Log
58+
59+
- 2026-03-09: Verified CMF localStorage round-trip compatibility with immutable v5. All 3 tests pass. No code changes required — `.toJS()` and `fromJS()` behavior is unchanged in v5.
60+
- 2026-03-09: Code review — added List round-trip test (AC #3 gap), added `@jest-environment` docblock for workspace runner compatibility, fixed JSDoc typo. 4/4 tests pass.

_bmad-output/implementation-artifacts/sprint-status.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,6 @@ development_status:
9999
epic-9: in-progress
100100
9-1-full-test-suite-build-v5: review
101101
9-2-storybook-verification: done
102-
9-3-verify-localstorage-roundtrip: ready-for-dev
102+
9-3-verify-localstorage-roundtrip: done
103103
9-4-create-changesets-documentation: ready-for-dev
104104
epic-9-retrospective: optional

packages/cmf/__tests__/localStorage.test.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
import { Map } from 'immutable';
1+
/**
2+
* @jest-environment jest-environment-jsdom-global
3+
*/
4+
import { Map, List } from 'immutable';
25
import localStorageAPI from '../src/localStorage';
36

47
const PATHS = [
@@ -62,6 +65,26 @@ describe('reduxLocalStorage', () => {
6265
expect(initialState.cmf.collections.getIn(['data']).toJS()).toEqual({});
6366
localStorage.setItem(KEY, undefined);
6467
});
68+
it('should getState restore arrays as immutable Lists', () => {
69+
const stateWithList = JSON.stringify({
70+
cmf: {
71+
components: {
72+
Foo: {
73+
default: {
74+
items: ['a', 'b', 'c'],
75+
},
76+
},
77+
},
78+
collections: {},
79+
},
80+
});
81+
localStorage.setItem(KEY, stateWithList);
82+
const initialState = localStorageAPI.getState(KEY);
83+
const items = initialState.cmf.components.getIn(['Foo', 'default', 'items']);
84+
expect(List.isList(items)).toBe(true);
85+
expect(items.toJS()).toEqual(['a', 'b', 'c']);
86+
localStorage.setItem(KEY, undefined);
87+
});
6588
it('should getStoreCallback return a function', () => {
6689
const callback = localStorageAPI.getStoreCallback(KEY, PATHS);
6790
expect(typeof callback).toBe('function');

packages/cmf/src/localStorage.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { fromJS } from 'immutable';
22
import set from 'lodash/set';
33

44
/**
5-
* getState read localStorage and create a initilState for redux
5+
* getState read localStorage and create a initialState for redux
66
* @param {string} key the localStorage key where to read
77
* @return {Object} initialState for redux
88
*/

0 commit comments

Comments
 (0)