Skip to content

Commit 45ec8fa

Browse files
Copilotpethers
andcommitted
test: strengthen theme-transition toggle coverage and timer assertions
Co-authored-by: pethers <1726836+pethers@users.noreply.github.com>
1 parent ff4fa00 commit 45ec8fa

2 files changed

Lines changed: 32 additions & 27 deletions

File tree

public/js/theme-toggle.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
const STORAGE_KEY = 'riksdagsmonitor-theme';
2424
const DARK = 'dark';
2525
const LIGHT = 'light';
26-
var _transitionTimer = null;
26+
let _transitionTimer = null;
2727

2828
/* ── Helpers ──────────────────────────────────────────────────────────── */
2929

tests/theme-toggle.test.js

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -350,26 +350,39 @@ describe('Theme Toggle', () => {
350350
// ── theme-transition class (add/remove on toggle) ────────────────────────────
351351

352352
describe('theme-transition class', () => {
353+
function createToggleHandler() {
354+
let transitionTimer = null;
355+
return function toggle() {
356+
const current = document.documentElement.getAttribute('data-theme') || LIGHT;
357+
const next = current === DARK ? LIGHT : DARK;
358+
document.documentElement.classList.add('theme-transition');
359+
applyTheme(next, undefined, storage);
360+
updateButton(next);
361+
if (transitionTimer) { clearTimeout(transitionTimer); }
362+
transitionTimer = setTimeout(function () {
363+
document.documentElement.classList.remove('theme-transition');
364+
transitionTimer = null;
365+
}, 350);
366+
};
367+
}
368+
353369
it('adds theme-transition class on toggle', () => {
354370
buildButton();
355371
applyTheme('light', false, storage);
356-
const current = document.documentElement.getAttribute('data-theme') || LIGHT;
357-
const next = current === DARK ? LIGHT : DARK;
358-
document.documentElement.classList.add('theme-transition');
359-
applyTheme(next, undefined, storage);
360-
updateButton(next);
372+
const toggle = createToggleHandler();
373+
374+
expect(document.documentElement.classList.contains('theme-transition')).toBe(false);
375+
toggle();
361376
expect(document.documentElement.classList.contains('theme-transition')).toBe(true);
362377
});
363378

364379
it('removes theme-transition class after timeout', () => {
365380
vi.useFakeTimers();
366381
buildButton();
367382
applyTheme('light', false, storage);
368-
document.documentElement.classList.add('theme-transition');
369-
// Simulate the setTimeout cleanup from the toggle handler
370-
setTimeout(function () {
371-
document.documentElement.classList.remove('theme-transition');
372-
}, 350);
383+
const toggle = createToggleHandler();
384+
385+
toggle();
373386
expect(document.documentElement.classList.contains('theme-transition')).toBe(true);
374387
vi.advanceTimersByTime(350);
375388
expect(document.documentElement.classList.contains('theme-transition')).toBe(false);
@@ -380,30 +393,22 @@ describe('Theme Toggle', () => {
380393
vi.useFakeTimers();
381394
buildButton();
382395
applyTheme('light', false, storage);
383-
384-
// Simulate rapid toggle with clearTimeout guard
385-
let timer = null;
396+
const toggle = createToggleHandler();
386397

387398
// First toggle
388-
document.documentElement.classList.add('theme-transition');
389-
if (timer) { clearTimeout(timer); }
390-
timer = setTimeout(function () {
391-
document.documentElement.classList.remove('theme-transition');
392-
timer = null;
393-
}, 350);
394-
399+
toggle();
395400
vi.advanceTimersByTime(100);
396401
expect(document.documentElement.classList.contains('theme-transition')).toBe(true);
397402

398403
// Second rapid toggle — clears the first timer
399-
document.documentElement.classList.add('theme-transition');
400-
if (timer) { clearTimeout(timer); }
401-
setTimeout(function () {
402-
document.documentElement.classList.remove('theme-transition');
403-
}, 350);
404+
toggle();
405+
406+
// After 350ms from first toggle (250ms after second), class should still be present
407+
vi.advanceTimersByTime(250);
408+
expect(document.documentElement.classList.contains('theme-transition')).toBe(true);
404409

405410
// After 350ms from second toggle, class should be removed
406-
vi.advanceTimersByTime(350);
411+
vi.advanceTimersByTime(100);
407412
expect(document.documentElement.classList.contains('theme-transition')).toBe(false);
408413
vi.useRealTimers();
409414
});

0 commit comments

Comments
 (0)