forked from int-money/landing-page
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuse-mobile.test.ts
More file actions
104 lines (87 loc) · 3.17 KB
/
Copy pathuse-mobile.test.ts
File metadata and controls
104 lines (87 loc) · 3.17 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
import { renderHook, act } from "@testing-library/react";
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import { useIsMobile } from "@/hooks/use-mobile";
describe("useIsMobile", () => {
beforeEach(() => {
// Mock window.innerWidth
Object.defineProperty(window, "innerWidth", {
writable: true,
configurable: true,
value: 1024,
});
// Mock window.matchMedia
Object.defineProperty(window, "matchMedia", {
writable: true,
configurable: true,
value: vi.fn().mockImplementation((query) => ({
matches: false,
media: query,
onchange: null,
addListener: vi.fn(), // deprecated
removeListener: vi.fn(), // deprecated
addEventListener: vi.fn(),
removeEventListener: vi.fn(),
dispatchEvent: vi.fn(),
})),
});
});
afterEach(() => {
vi.clearAllMocks();
});
it("should return false when viewport width is >= 768px", () => {
Object.defineProperty(window, "innerWidth", { value: 1024 });
const { result } = renderHook(() => useIsMobile());
expect(result.current).toBe(false);
});
it("should return true when viewport width is < 768px", () => {
Object.defineProperty(window, "innerWidth", { value: 500 });
const { result } = renderHook(() => useIsMobile());
expect(result.current).toBe(true);
});
it("should return false when viewport width is exactly 768px (boundary condition)", () => {
Object.defineProperty(window, "innerWidth", { value: 768 });
const { result } = renderHook(() => useIsMobile());
expect(result.current).toBe(false);
});
it("should update when window is resized", () => {
Object.defineProperty(window, "innerWidth", { value: 1024, writable: true });
let changeCallback: () => void = () => {};
// Mock matchMedia to capture the change callback
(window.matchMedia as ReturnType<typeof vi.fn>).mockImplementation((query: string) => ({
matches: false,
media: query,
onchange: null,
addEventListener: vi.fn((event: string, cb: () => void) => {
if (event === "change") changeCallback = cb;
}),
removeEventListener: vi.fn(),
}));
const { result } = renderHook(() => useIsMobile());
expect(result.current).toBe(false);
// Simulate resize to mobile width
act(() => {
(window as Window & { innerWidth: number }).innerWidth = 500;
changeCallback();
});
expect(result.current).toBe(true);
// Simulate resize back to desktop width
act(() => {
(window as Window & { innerWidth: number }).innerWidth = 1024;
changeCallback();
});
expect(result.current).toBe(false);
});
it("should clean up event listener on unmount", () => {
const removeEventListenerMock = vi.fn();
(window.matchMedia as ReturnType<typeof vi.fn>).mockImplementation((query: string) => ({
matches: false,
media: query,
onchange: null,
addEventListener: vi.fn(),
removeEventListener: removeEventListenerMock,
}));
const { unmount } = renderHook(() => useIsMobile());
unmount();
expect(removeEventListenerMock).toHaveBeenCalledWith("change", expect.any(Function));
});
});