Skip to content

Commit e81b549

Browse files
committed
test: add useParagonTheme test
1 parent 4c50878 commit e81b549

File tree

2 files changed

+91
-40
lines changed

2 files changed

+91
-40
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import { act, renderHook } from '@testing-library/react-hooks';
2+
import useParagonTheme from './useParagonTheme';
3+
import { getConfig } from '../../../config';
4+
5+
jest.mock('../../../config', () => ({
6+
...jest.requireActual('.../../../config'),
7+
getConfig: jest.fn().mockReturnValue({
8+
PARAGON_THEME_URLS: {
9+
core: {
10+
urls: {
11+
default: 'core.css',
12+
},
13+
},
14+
defaults: {
15+
light: 'light',
16+
dark: 'dark',
17+
},
18+
variants: {
19+
light: {
20+
urls: {
21+
default: 'https://cdn.jsdelivr.net/npm/@edx/paragon@$21.0.0/dist/light.min.css',
22+
},
23+
},
24+
dark: {
25+
urls: {
26+
default: 'https://cdn.jsdelivr.net/npm/@edx/paragon@$21.0.0/dist/dark.min.css',
27+
},
28+
},
29+
},
30+
},
31+
}),
32+
}));
33+
34+
let mockMediaQueryListEvent;
35+
const mockAddEventListener = jest.fn((dispatch, fn) => fn(mockMediaQueryListEvent));
36+
const mockRemoveEventListener = jest.fn();
37+
38+
Object.defineProperty(window, 'matchMedia', {
39+
value: jest.fn(() => ({
40+
addEventListener: mockAddEventListener,
41+
removeEventListener: mockRemoveEventListener,
42+
})),
43+
});
44+
45+
Object.defineProperty(window, 'localStorage', {
46+
value: {
47+
getItem: jest.fn(),
48+
},
49+
});
50+
51+
describe('useParagonTheme', () => {
52+
beforeEach(() => {
53+
document.head.innerHTML = '';
54+
mockMediaQueryListEvent = { matches: true };
55+
mockAddEventListener.mockClear();
56+
mockRemoveEventListener.mockClear();
57+
window.localStorage.getItem.mockClear();
58+
});
59+
60+
it('should configure theme variants according with system preference and add the change event listener', () => {
61+
const { unmount } = renderHook(() => useParagonTheme(getConfig()));
62+
const themeLinks = document.head.querySelectorAll('link');
63+
const darkLink = document.head.querySelector('link[data-paragon-theme-variant="dark"]');
64+
const lightLink = document.head.querySelector('link[data-paragon-theme-variant="light"]');
65+
act(() => { themeLinks.forEach((link) => link.onload()); });
66+
67+
expect(window.matchMedia).toHaveBeenCalledWith('(prefers-color-scheme: dark)');
68+
expect(mockAddEventListener).toHaveBeenCalled();
69+
expect(darkLink.rel).toBe('stylesheet');
70+
expect(lightLink.rel).toBe('alternate stylesheet');
71+
unmount();
72+
expect(mockRemoveEventListener).toHaveBeenCalled();
73+
});
74+
75+
it('should configure theme variants according with user preference if is defined (localStorage)', () => {
76+
window.localStorage.getItem.mockReturnValue('light');
77+
const { unmount } = renderHook(() => useParagonTheme(getConfig()));
78+
const themeLinks = document.head.querySelectorAll('link');
79+
const darkLink = document.head.querySelector('link[data-paragon-theme-variant="dark"]');
80+
const lightLink = document.head.querySelector('link[data-paragon-theme-variant="light"]');
81+
act(() => { themeLinks.forEach((link) => link.onload()); });
82+
83+
expect(window.matchMedia).toHaveBeenCalledWith('(prefers-color-scheme: dark)');
84+
expect(mockAddEventListener).toHaveBeenCalled();
85+
86+
expect(darkLink.rel).toBe('alternate stylesheet');
87+
expect(lightLink.rel).toBe('stylesheet');
88+
unmount();
89+
expect(mockRemoveEventListener).toHaveBeenCalled();
90+
});
91+
});

src/react/hooks/paragon/useParagonThemeVariants.test.js

-40
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,6 @@ import useParagonThemeVariants from './useParagonThemeVariants';
55

66
jest.mock('../../../logging');
77

8-
const mockAddEventListener = jest.fn();
9-
const mockRemoveEventListener = jest.fn();
10-
const mockOnChange = jest.fn();
11-
12-
Object.defineProperty(window, 'matchMedia', {
13-
value: jest.fn(() => ({
14-
addEventListener: mockAddEventListener,
15-
removeEventListener: mockRemoveEventListener,
16-
onchange: mockOnChange,
17-
})),
18-
});
19-
208
describe('useParagonThemeVariants', () => {
219
const themeOnLoad = jest.fn();
2210

@@ -85,34 +73,6 @@ describe('useParagonThemeVariants', () => {
8573
expect(document.querySelector('link').href).toBe(`${getConfig().BASE_URL}/${PARAGON_THEME.paragon.themeUrls.variants.light.fileName}`);
8674
});
8775

88-
it('should configure theme variants according with system preference and add the change event listener', () => {
89-
window.matchMedia['prefers-color-scheme'] = 'dark';
90-
91-
const themeVariants = {
92-
light: {
93-
urls: {
94-
default: 'https://cdn.jsdelivr.net/npm/@edx/paragon@$21.0.0/dist/light.min.css',
95-
brandOverride: 'https://cdn.jsdelivr.net/npm/@edx/brand@$2.0.0/dist/light.min.css',
96-
},
97-
},
98-
dark: {
99-
urls: {
100-
default: 'https://cdn.jsdelivr.net/npm/@edx/paragon@$21.0.0/dist/dark.min.css',
101-
brandOverride: 'https://cdn.jsdelivr.net/npm/@edx/brand@$2.0.0/dist/dark.min.css',
102-
},
103-
},
104-
};
105-
106-
const currentThemeVariant = 'light';
107-
108-
renderHook(() => useParagonThemeVariants({ themeVariants, currentThemeVariant, onLoad: themeOnLoad }));
109-
110-
const themeLinks = document.head.querySelectorAll('link');
111-
act(() => { themeLinks.forEach((link) => link.onload()); });
112-
113-
expect(mockAddEventListener).toHaveBeenCalledTimes(1);
114-
});
115-
11676
it('should do nothing if themeVariants is not configured', () => {
11777
const themeVariants = null;
11878
const currentTheme = 'light';

0 commit comments

Comments
 (0)