-
-
Notifications
You must be signed in to change notification settings - Fork 213
Expand file tree
/
Copy pathToggleDarkMode.test.tsx
More file actions
151 lines (130 loc) · 5.09 KB
/
ToggleDarkMode.test.tsx
File metadata and controls
151 lines (130 loc) · 5.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';
// ---------- Mutable store state ----------
let mockBackgroundColor = '#ffffff';
const mockToggleDarkMode = vi.fn();
vi.mock('../../store/store', () => {
// Return a function that, when called with no selector, returns the store object.
// When called with a selector, passes the store object through the selector.
const useAppStore = (...args: unknown[]) => {
const storeState = {
backgroundColor: mockBackgroundColor,
toggleDarkMode: mockToggleDarkMode,
};
if (typeof args[0] === 'function') {
return (args[0] as (s: typeof storeState) => unknown)(storeState);
}
return storeState;
};
return { default: useAppStore };
});
// ---------- Mock react-dark-mode-toggle ----------
vi.mock('react-dark-mode-toggle', () => ({
default: ({
checked,
onChange,
size,
className,
}: {
checked: boolean;
onChange: () => void;
size: number;
className: string;
}) => (
<button
data-testid="dark-mode-toggle"
data-checked={checked}
data-size={size}
className={className}
onClick={onChange}
>
Dark Mode Toggle
</button>
),
}));
// ---------- Mock styled-component ----------
vi.mock('../../styles/components/ToggleDarkMode', () => ({
ToggleDarkModeContainer: ({
children,
...props
}: React.PropsWithChildren<Record<string, unknown>>) => (
<div {...props}>{children}</div>
),
}));
// ---------- Import after mocks ----------
import ToggleDarkMode from '../../components/ToggleDarkMode';
// ---------- Tests ----------
describe('ToggleDarkMode', () => {
beforeEach(() => {
vi.clearAllMocks();
mockBackgroundColor = '#ffffff';
document.documentElement.removeAttribute('data-theme');
});
it('renders the toggle component', () => {
render(<ToggleDarkMode />);
expect(screen.getByTestId('toggle-dark-mode')).toBeInTheDocument();
});
it('initializes isDarkMode to false when backgroundColor is #ffffff', () => {
mockBackgroundColor = '#ffffff';
render(<ToggleDarkMode />);
const btn = screen.getByTestId('dark-mode-toggle');
expect(btn.getAttribute('data-checked')).toBe('false');
});
it('initializes isDarkMode to true when backgroundColor is #121212', () => {
mockBackgroundColor = '#121212';
render(<ToggleDarkMode />);
const btn = screen.getByTestId('dark-mode-toggle');
expect(btn.getAttribute('data-checked')).toBe('true');
});
it('calls toggleDarkMode when clicked', () => {
render(<ToggleDarkMode />);
fireEvent.click(screen.getByTestId('dark-mode-toggle'));
expect(mockToggleDarkMode).toHaveBeenCalledTimes(1);
});
it('sets data-theme to dark when toggled from light mode', () => {
mockBackgroundColor = '#ffffff';
render(<ToggleDarkMode />);
fireEvent.click(screen.getByTestId('dark-mode-toggle'));
expect(document.documentElement.getAttribute('data-theme')).toBe('dark');
});
it('sets data-theme to light when toggled from dark mode', () => {
mockBackgroundColor = '#121212';
render(<ToggleDarkMode />);
fireEvent.click(screen.getByTestId('dark-mode-toggle'));
expect(document.documentElement.getAttribute('data-theme')).toBe('light');
});
it('updates isDarkMode when backgroundColor prop changes', () => {
mockBackgroundColor = '#ffffff';
const { rerender } = render(<ToggleDarkMode />);
const btn = screen.getByTestId('dark-mode-toggle');
expect(btn.getAttribute('data-checked')).toBe('false');
// Simulate store change
mockBackgroundColor = '#121212';
rerender(<ToggleDarkMode />);
expect(btn.getAttribute('data-checked')).toBe('true');
});
it('passes size={60} to the toggle', () => {
render(<ToggleDarkMode />);
const btn = screen.getByTestId('dark-mode-toggle');
expect(btn.getAttribute('data-size')).toBe('60');
});
it('applies className dark-mode-toggle', () => {
render(<ToggleDarkMode />);
const btn = screen.getByTestId('dark-mode-toggle');
expect(btn.className).toBe('dark-mode-toggle');
});
it('handles multiple sequential toggles correctly', () => {
mockBackgroundColor = '#ffffff';
render(<ToggleDarkMode />);
const btn = screen.getByTestId('dark-mode-toggle');
// First click: light → dark
fireEvent.click(btn);
expect(document.documentElement.getAttribute('data-theme')).toBe('dark');
expect(mockToggleDarkMode).toHaveBeenCalledTimes(1);
// Second click: dark → light
fireEvent.click(btn);
expect(document.documentElement.getAttribute('data-theme')).toBe('light');
expect(mockToggleDarkMode).toHaveBeenCalledTimes(2);
});
});