Skip to content

Commit f3d60f4

Browse files
authored
test(scroll-restoration): add ScrollRestoration component test suite (JhaSourav07#3100)
## Description Adds a complete test suite for ScrollRestoration. - Verifies component mounts successfully - Restores saved scroll position from sessionStorage - Persists scroll position during scroll events - Handles missing saved positions correctly - Cleans up scroll listeners on unmount Fixes JhaSourav07#2286 ## Pillar - [x] 📐 Pillar 2 — Geometric SVG Improvement - [x] 🛠️ Other (Bug fix, refactoring, docs) ## 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): ...`). - [x] I have updated `README.md` if I added a new theme or URL parameter. - [x] I have started the repo. - [x] I have made sure that i have only one commit to merge in this PR. - [x] 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 f2603b3 + 178693e commit f3d60f4

1 file changed

Lines changed: 83 additions & 0 deletions

File tree

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { render, cleanup } from '@testing-library/react';
2+
import '@testing-library/jest-dom/vitest';
3+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
4+
import ScrollRestoration from './ScrollRestoration';
5+
6+
const mockUsePathname = vi.fn();
7+
8+
vi.mock('next/navigation', () => ({
9+
usePathname: () => mockUsePathname(),
10+
}));
11+
12+
describe('ScrollRestoration', () => {
13+
const scrollToMock = vi.fn();
14+
const addEventListenerSpy = vi.spyOn(window, 'addEventListener');
15+
const removeEventListenerSpy = vi.spyOn(window, 'removeEventListener');
16+
17+
beforeEach(() => {
18+
vi.clearAllMocks();
19+
20+
mockUsePathname.mockReturnValue('/dashboard');
21+
22+
Object.defineProperty(window, 'scrollTo', {
23+
writable: true,
24+
value: scrollToMock,
25+
});
26+
27+
sessionStorage.clear();
28+
});
29+
30+
afterEach(() => {
31+
cleanup();
32+
});
33+
34+
it('mounts cleanly without crashing', () => {
35+
const { container } = render(<ScrollRestoration />);
36+
37+
expect(container).toBeDefined();
38+
});
39+
40+
it('restores saved scroll position on mount', () => {
41+
sessionStorage.setItem('scroll-position-/dashboard', '250');
42+
43+
render(<ScrollRestoration />);
44+
45+
expect(scrollToMock).toHaveBeenCalledWith(0, 250);
46+
});
47+
48+
it('registers scroll listener and saves scroll position', () => {
49+
render(<ScrollRestoration />);
50+
51+
expect(addEventListenerSpy).toHaveBeenCalledWith('scroll', expect.any(Function));
52+
53+
Object.defineProperty(window, 'scrollY', {
54+
writable: true,
55+
configurable: true,
56+
value: 500,
57+
});
58+
59+
const handler = addEventListenerSpy.mock.calls.find(
60+
([event]) => event === 'scroll'
61+
)?.[1] as EventListener;
62+
63+
handler(new Event('scroll'));
64+
65+
expect(sessionStorage.getItem('scroll-position-/dashboard')).toBe('500');
66+
});
67+
68+
it('does not scroll when no saved position exists', () => {
69+
render(<ScrollRestoration />);
70+
71+
expect(scrollToMock).not.toHaveBeenCalled();
72+
});
73+
74+
it('removes scroll listener on unmount', () => {
75+
const { unmount } = render(<ScrollRestoration />);
76+
77+
const handler = addEventListenerSpy.mock.calls.find(([event]) => event === 'scroll')?.[1];
78+
79+
unmount();
80+
81+
expect(removeEventListenerSpy).toHaveBeenCalledWith('scroll', handler);
82+
});
83+
});

0 commit comments

Comments
 (0)