Files
ultra-todo/jest.setup.js
Hermes (Agent) 86651b8d26 feat(redesign): [P7] refactor boardStore to singleton + App smoke test
- boardStore.js: refactored from per-component useState to a module-level
  singleton via useSyncExternalStore. All callers share state (true
  singleton). Exposes __resetStore/__setState/__setPersistOnChange for
  test isolation. addBoard/addList/addCard still return the new id
  (computed from post-action state).
- jest.config.js: added moduleNameMapper for CSS (identity-obj-proxy)
  + transformIgnorePatterns for @dnd-kit ESM modules.
- jest.setup.js: stub window.matchMedia for AppShell, clear localStorage
  + reset store singleton before each test.
- src/test/testUtils.jsx: renderWithStore now wraps the UI in a Host
  that calls useBoardStore and clones the child element to inject
  { state, actions } as props. Returns result.state/result.actions
  getters so tests can read state and invoke actions from outside.
- src/components/List.test.jsx: Host accepts state/actions props and
  falls back to useBoardStore for standalone use.
- src/components/ListHeader.test.jsx + Board.test.jsx: updated to new
  result.state API (was store.getState() in P3's API).
- src/App.jsx: final spec wiring — sidebar + board area + TopBar + Board
  + empty states (first-run + select-board). Reads from useBoardStore,
  passes state + actions down to AppShell + Board.
- src/App.test.jsx: smoke test — sidebar + topbar + board + lists render
  when seeded; +Create board flow creates a board and activates it;
  first-run and select-board empty states render correctly; mobile
  breakpoint shows hamburger.

All 119 tests pass across 15 suites. npm run build green.
2026-06-24 05:36:59 +00:00

31 lines
1.0 KiB
JavaScript

import '@testing-library/jest-dom';
import { __resetStore } from './src/store/boardStore'
// jsdom doesn't implement window.matchMedia. AppShell uses it to detect
// mobile breakpoints. Stub a no-op implementation that always reports
// desktop (matches=false) unless a test explicitly overrides it.
if (typeof window !== 'undefined' && !window.matchMedia) {
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: (query) => ({
matches: false,
media: query,
onchange: null,
addListener: () => {}, // deprecated
removeListener: () => {}, // deprecated
addEventListener: () => {},
removeEventListener: () => {},
dispatchEvent: () => false,
}),
})
}
// The board store is a module-level singleton. Reset it before every test
// so tests don't leak state into each other. localStorage is also cleared
// because the store seeds from localStorage on first read.
beforeEach(() => {
if (typeof window !== 'undefined' && window.localStorage) {
window.localStorage.clear()
}
__resetStore()
})