Skip to content

Commit 652af5c

Browse files
authored
test(navbar): add mobile menu toggle unit tests (JhaSourav07#590)
## Description Added unit tests for the Navbar mobile menu toggle behavior. ### Changes made - Added `app/components/navbar.test.tsx` - Mocked `framer-motion` - Mocked `lucide-react` - Added `window.matchMedia` mock for test environment - Added tests for: - menu hidden by default - menu opens on button click - menu closes on second click - menu closes on desktop resize Fixes JhaSourav07#346 ## Pillar - [ ] 🎨 Pillar 1 — New Theme Design - [ ] 📐 Pillar 2 — Geometric SVG Improvement - [ ] 🕐 Pillar 3 — Timezone Logic Optimization - [x] 🛠️ Other (Bug fix, refactoring, docs) ## Visual Preview <img width="510" height="896" alt="Screenshot 2026-05-27 202550" src="https://github.com/user-attachments/assets/67b4625f-8990-4b35-a7d8-e8e3aaee634c" /> <img width="510" height="896" alt="Screenshot 2026-05-27 202754" src="https://github.com/user-attachments/assets/502c8b70-a8a1-4b77-94f1-10a1c2156a77" /> ## Checklist before requesting a review: - [x] I have read the `CONTRIBUTING.md` file. - [x] I have tested these changes locally (`localhost:3000/api/streak?user=YOUR_USERNAME`). - [x] I have run `npm run format` and `npm run lint` locally and resolved all errors (CI will fail otherwise). - [x] My commits follow the Conventional Commits format (e.g., `feat(themes): ...`, `fix(calculate): ...`). - [ ] I have updated `README.md` if I added a new theme or URL parameter. - [ ] I have started the repo. - [x] I have made sure that i have only one commit to merge in this PR. - [ ] The SVG output matches the CommitPulse "premium quality" aesthetic standard (no raw elements, smooth animations, correct fonts). - [x] (Recommended) I joined the CommitPulse Discord community for contributor discussions, mentorship, and faster PR support.
2 parents 6508748 + 62caee1 commit 652af5c

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)