Skip to content

test(settings): cover theme application effect and system media-query sync#471

Merged
Baskarayelu merged 1 commit into
CredenceOrg:mainfrom
samjay8:test/settings-theme-application
Jun 29, 2026
Merged

test(settings): cover theme application effect and system media-query sync#471
Baskarayelu merged 1 commit into
CredenceOrg:mainfrom
samjay8:test/settings-theme-application

Conversation

@samjay8

@samjay8 samjay8 commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Closes #448

Summary

Adds a focused Vitest + RTL suite in src/context/SettingsContext.theme.test.tsx that directly asserts the data-theme attribute and matchMedia listener lifecycle - locking down the dark-mode glue between settings state and CSS tokens.

What is tested

Explicit modes

  • themeMode="light" sets data-theme="light" on mount, no listener attached
  • themeMode="dark" sets data-theme="dark" on mount, no listener attached
  • Switching to light/dark via setters updates the attribute immediately

System mode

  • System + OS prefers light ? data-theme="light" on mount
  • System + OS prefers dark ? data-theme="dark" on mount
  • addEventListener called for the change event in system mode

OS theme-change flip

  • Dark OS flip while in system ? data-theme="dark"; light flip ? data-theme="light"; multi-flip tracking

Listener cleanup

  • Removed when switching away from system (same fn reference verified via mock)
  • Removed on unmount
  • OS changes ignored after leaving system mode
  • Re-attached when switching back to system

Persistence

  • setThemeMode() updates both data-theme attribute and the credence:settings localStorage payload simultaneously for all three modes
  • Mount initializes from localStorage and applies the stored theme

Strict Mode resilience

  • data-theme consistent across rerender cycles
  • Listener count does not grow unboundedly on rerenders

Mock approach

A custom createMatchMediaMock() helper tracks add/removeEventListener calls and exposes simulateChange() for deterministic OS theme transitions - no global jsdom patching required.

Test plan

  • npm run test passes (all new assertions green)
  • npm run lint passes
  • npm run build passes

… sync

Asserts data-theme for light/dark/system, OS-theme-change flips, and listener
cleanup, locking down the dark-mode glue.

New test file: src/context/SettingsContext.theme.test.tsx

- Explicit light mode: data-theme="light" set on mount, no listener attached
- Explicit dark mode: data-theme="dark" set on mount, no listener attached
- System mode (initial mount): resolves OS preference to light or dark
- System + OS change flip: dark→light, light→dark, and multi-flip tracking
- Listener cleanup: removed on mode change (same fn reference verified) and on
  unmount; no response to OS changes after leaving system mode; listener
  re-attached when switching back to system
- Persistence: setThemeMode() updates both data-theme attribute and the
  credence:settings localStorage payload simultaneously
- Double mount / Strict Mode: data-theme consistent across rerenders; listener
  count does not grow unboundedly

A custom createMatchMediaMock helper tracks add/removeEventListener calls and
exposes a simulateChange() method so OS theme transitions are deterministic.

Closes CredenceOrg#448
@drips-wave

drips-wave Bot commented Jun 29, 2026

Copy link
Copy Markdown

@samjay8 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unit-test the SettingsContext theme application: data-theme attribute and system media-query sync

2 participants