gabriel / musehub public
musehub.test.ts typescript
55 lines 2.0 KB
Raw
sha256:1705df128914797fd03b93ff582e57b748b25e0e17c57359b8f1a82e7f13970e fix: sync body class after htmx-boosted navigation (issue #168) Sonnet 5 patch 24 days ago
1 import { describe, it, expect, beforeAll, beforeEach, vi } from 'vitest';
2
3 // musehub.ts registers module-scope event listeners (click, DOMContentLoaded,
4 // htmx:*) that touch `document` at import time — this module must be
5 // dynamically imported after a minimal DOM stub is in place, not statically
6 // imported like a side-effect-free module.
7 const makeEl = (dataset: Record<string, string> = {}) => ({ dataset });
8
9 let body: { className: string };
10 let elements: Record<string, ReturnType<typeof makeEl> | undefined>;
11 let syncBodyClassFromContent: () => void;
12
13 beforeAll(async () => {
14 body = { className: '' };
15 elements = {};
16 vi.stubGlobal('document', {
17 body,
18 getElementById: (id: string) => elements[id] ?? null,
19 addEventListener: () => {},
20 documentElement: { classList: { add: () => {} } },
21 });
22 vi.stubGlobal('window', {});
23 ({ syncBodyClassFromContent } = await import('./musehub'));
24 });
25
26 beforeEach(() => {
27 body.className = '';
28 elements = {};
29 });
30
31 describe('syncBodyClassFromContent', () => {
32 it('applies #content data-body-class to body.className', () => {
33 body.className = 'app-shell'; // stale class from the previous (boosted-from) page
34 elements['content'] = makeEl({ bodyClass: 'app-shell' });
35 syncBodyClassFromContent();
36 expect(body.className).toBe('app-shell');
37 });
38
39 it('clears body.className when the new page has no body_class', () => {
40 // Reproduces issue #168: navigating from an app-shell page (e.g. issue
41 // detail) to a non-app-shell page (e.g. blob view) via an htmx-boosted
42 // link must not leave the stale "app-shell" class — and its
43 // overflow:hidden — stuck on <body>.
44 body.className = 'app-shell';
45 elements['content'] = makeEl({ bodyClass: '' });
46 syncBodyClassFromContent();
47 expect(body.className).toBe('');
48 });
49
50 it('defaults to empty string when #content is missing', () => {
51 body.className = 'app-shell';
52 syncBodyClassFromContent();
53 expect(body.className).toBe('');
54 });
55 });
File History 1 commit
sha256:1705df128914797fd03b93ff582e57b748b25e0e17c57359b8f1a82e7f13970e fix: sync body class after htmx-boosted navigation (issue #168) Sonnet 5 patch 24 days ago