Skip to content

Commit 62caee1

Browse files
test(navbar): add mobile menu toggle unit tests
1 parent e15a46a commit 62caee1

1 file changed

Lines changed: 85 additions & 0 deletions

File tree

app/components/navbar.test.tsx

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { describe, it, expect, vi, beforeEach } from 'vitest';
2+
import { render, screen, fireEvent } from '@testing-library/react';
3+
import Navbar from './navbar';
4+
import type { ReactNode } from 'react';
5+
6+
Object.defineProperty(window, 'matchMedia', {
7+
writable: true,
8+
value: vi.fn().mockImplementation((query) => ({
9+
matches: false,
10+
media: query,
11+
onchange: null,
12+
addListener: vi.fn(),
13+
removeListener: vi.fn(),
14+
addEventListener: vi.fn(),
15+
removeEventListener: vi.fn(),
16+
dispatchEvent: vi.fn(),
17+
})),
18+
});
19+
20+
vi.mock('framer-motion', () => ({
21+
motion: {
22+
div: ({ children }: { children: ReactNode }) => <div>{children}</div>,
23+
},
24+
}));
25+
26+
vi.mock('lucide-react', () => ({
27+
Menu: () => <div>MenuIcon</div>,
28+
X: () => <div>CloseIcon</div>,
29+
Activity: () => <div>ActivityIcon</div>,
30+
Sun: () => <div>SunIcon</div>,
31+
Moon: () => <div>MoonIcon</div>,
32+
}));
33+
34+
describe('Navbar mobile menu', () => {
35+
beforeEach(() => {
36+
window.innerWidth = 500;
37+
});
38+
39+
it('menu is hidden by default', () => {
40+
render(<Navbar />);
41+
42+
expect(screen.queryByText(/closeicon/i)).toBeNull();
43+
});
44+
45+
it('opens menu on button click', () => {
46+
render(<Navbar />);
47+
48+
const button = screen.getByLabelText(/open menu/i);
49+
50+
fireEvent.click(button);
51+
52+
expect(screen.getByText(/closeicon/i)).toBeTruthy();
53+
});
54+
55+
it('closes menu on second click', () => {
56+
render(<Navbar />);
57+
58+
const button = screen.getByLabelText(/open menu/i);
59+
60+
fireEvent.click(button);
61+
fireEvent.click(button);
62+
63+
expect(screen.queryByText(/closeicon/i)).toBeNull();
64+
});
65+
66+
it('closes menu on resize to desktop', () => {
67+
render(<Navbar />);
68+
69+
const button = screen.getByLabelText(/open menu/i);
70+
71+
fireEvent.click(button);
72+
73+
window.innerWidth = 1200;
74+
75+
window.matchMedia = vi.fn().mockImplementation(() => ({
76+
matches: true,
77+
addEventListener: vi.fn(),
78+
removeEventListener: vi.fn(),
79+
}));
80+
81+
window.dispatchEvent(new Event('resize'));
82+
83+
expect(button.getAttribute('aria-expanded')).toBe('true');
84+
});
85+
});

0 commit comments

Comments
 (0)