Skip to content

Commit bbf4d77

Browse files
author
devgioele
committed
add react-router tests
1 parent f2e5f4d commit bbf4d77

1 file changed

Lines changed: 257 additions & 0 deletions

File tree

Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
import { act, renderHook } from '@testing-library/react'
2+
import { z } from 'zod'
3+
import { BrowserRouter } from 'react-router-dom'
4+
import { NonNullableRecord } from '../../utils'
5+
import {
6+
useReactRouterQuery,
7+
useReactRouterPagination,
8+
useReactRouterQueryAndPagination,
9+
} from '../../zod'
10+
11+
const renderHookWithContext = <Result, Props>(
12+
render: (initialProps: Props) => Result
13+
) =>
14+
renderHook(render, {
15+
wrapper: ({ children }) => {
16+
return <BrowserRouter>{children}</BrowserRouter>
17+
},
18+
})
19+
20+
describe('ReactRouter', () => {
21+
beforeEach(() => {
22+
window.history.pushState({}, '', '/')
23+
})
24+
25+
const searchSchema = z.object({
26+
search: z.string().optional().catch(undefined),
27+
})
28+
29+
const useReactRouterQueryWithSearch = (
30+
defaultQuery: NonNullableRecord<z.infer<typeof searchSchema>>
31+
) => useReactRouterQuery(defaultQuery, searchSchema)
32+
33+
test('should set default page and size', () => {
34+
const page = 0
35+
const size = 15
36+
const { result } = renderHookWithContext(() =>
37+
useReactRouterPagination({ page, size })
38+
)
39+
40+
expect(result.current.page).toBe(page)
41+
expect(result.current.size).toBe(size)
42+
})
43+
44+
test('should change page', () => {
45+
const page = 2
46+
47+
const { result } = renderHookWithContext(() => useReactRouterPagination())
48+
49+
act(() => {
50+
result.current.setPage(page)
51+
})
52+
53+
expect(result.current.page).toBe(page)
54+
expect(window.location.search).toBe(`?page=${page}`)
55+
})
56+
57+
test('should change search', () => {
58+
const search = 'Max'
59+
60+
const { result } = renderHookWithContext(() =>
61+
useReactRouterQueryWithSearch({ search: '' })
62+
)
63+
64+
act(() => {
65+
result.current.setQuery({ search })
66+
})
67+
68+
expect(result.current.query?.search).toBe(search)
69+
expect(window.location.search).toBe(`?search=${search}`)
70+
})
71+
72+
test('changing pagination should not reset the remaining query', () => {
73+
const search = 'Max'
74+
const page = 2
75+
76+
const { result } = renderHookWithContext(() =>
77+
useReactRouterQueryAndPagination({ search: '' }, searchSchema)
78+
)
79+
80+
act(() => {
81+
result.current.setQuery({ search })
82+
})
83+
84+
act(() => {
85+
result.current.setPage(page)
86+
})
87+
88+
expect(window.location.search).toBe(`?search=${search}&page=${page}`)
89+
90+
act(() => {
91+
result.current.resetPagination()
92+
})
93+
94+
expect(result.current.query.search).toBe(search)
95+
expect(result.current.page).toBe(0)
96+
expect(window.location.search).toBe(`?search=${search}`)
97+
})
98+
99+
test('change default parameters', () => {
100+
const page = 1
101+
const size = 10
102+
const { result } = renderHookWithContext(() =>
103+
useReactRouterPagination({ page, size })
104+
)
105+
106+
expect(result.current.page).toBe(page)
107+
expect(result.current.size).toBe(size)
108+
})
109+
110+
test('changing the remaining query should reset the page', () => {
111+
const defaultSearch = ''
112+
const search1 = 'Max'
113+
const search2 = 'Peter'
114+
const page = 2
115+
116+
const { result } = renderHookWithContext(() =>
117+
useReactRouterQueryAndPagination({ search: defaultSearch }, searchSchema)
118+
)
119+
120+
act(() => {
121+
result.current.setQuery({ search: search1 })
122+
})
123+
124+
act(() => {
125+
result.current.setPage(page)
126+
})
127+
128+
expect(result.current.query.search).toBe(search1)
129+
expect(result.current.page).toBe(page)
130+
expect(window.location.search).toBe(`?search=${search1}&page=${page}`)
131+
132+
act(() => {
133+
result.current.setQuery({ search: search2 })
134+
})
135+
136+
expect(result.current.query.search).toBe(search2)
137+
expect(result.current.page).toBe(0)
138+
expect(window.location.search).toBe(`?search=${search2}`)
139+
140+
act(() => {
141+
result.current.resetQuery()
142+
})
143+
144+
expect(result.current.query.search).toBe(defaultSearch)
145+
expect(result.current.page).toBe(0)
146+
expect(window.location.search).toBe('')
147+
})
148+
149+
test('changing the remaining query with resetPage set to false should not reset the page', () => {
150+
const defaultSearch = ''
151+
const search = 'Max'
152+
const page = 2
153+
154+
const { result } = renderHookWithContext(() =>
155+
useReactRouterQueryAndPagination({ search: defaultSearch }, searchSchema)
156+
)
157+
158+
act(() => {
159+
result.current.setPage(page)
160+
})
161+
162+
expect(result.current.page).toBe(page)
163+
expect(window.location.search).toBe(`?page=${page}`)
164+
165+
act(() => {
166+
result.current.setQuery({ search }, { resetPage: false })
167+
})
168+
169+
expect(result.current.query.search).toBe(search)
170+
expect(result.current.page).toBe(page)
171+
expect(window.location.search).toBe(`?page=${page}&search=${search}`)
172+
173+
act(() => {
174+
result.current.resetQuery({ resetPage: false })
175+
})
176+
177+
expect(result.current.query.search).toBe(defaultSearch)
178+
expect(result.current.page).toBe(page)
179+
expect(window.location.search).toBe(`?page=${page}`)
180+
})
181+
182+
test('setting a query key should not overwrite other query keys', () => {
183+
const search = 'Max'
184+
const department = 'IT'
185+
186+
const schema = z.object({
187+
search: z.string().optional().catch(undefined),
188+
department: z.string().optional().catch(undefined),
189+
})
190+
191+
const { result } = renderHookWithContext(() =>
192+
useReactRouterQuery({ search: '', department: '' }, schema)
193+
)
194+
195+
act(() => {
196+
result.current.setQuery({ search })
197+
})
198+
199+
act(() => {
200+
result.current.setQuery({ department })
201+
})
202+
203+
expect(result.current.query.search).toBe(search)
204+
expect(result.current.query.department).toBe(department)
205+
})
206+
207+
test('unspecified query keys should be left untouched', () => {
208+
const greeting = 'hello'
209+
const search = 'Max'
210+
window.history.pushState({}, '', `/?greeting=${greeting}`)
211+
212+
const { result } = renderHookWithContext(() =>
213+
useReactRouterQuery({ search: '' }, searchSchema)
214+
)
215+
216+
act(() => {
217+
result.current.setQuery({ search })
218+
})
219+
220+
expect(result.current.query.search).toBe(search)
221+
expect(window.location.search).toBe(
222+
`?greeting=${greeting}&search=${search}`
223+
)
224+
})
225+
226+
test('query keys with default value should not be stored in the url', () => {
227+
const defaultSearch = ''
228+
229+
window.history.pushState({}, '', `/?search=Max`)
230+
231+
const { result } = renderHookWithContext(() =>
232+
useReactRouterQuery({ search: defaultSearch }, searchSchema)
233+
)
234+
235+
act(() => {
236+
result.current.resetQuery()
237+
})
238+
239+
expect(result.current.query.search).toBe(defaultSearch)
240+
expect(window.location.search).toBe('')
241+
})
242+
243+
test('default query value should not need to be an empty string', () => {
244+
const search = ''
245+
246+
const { result } = renderHookWithContext(() =>
247+
useReactRouterQuery({ search: 'Default search' }, searchSchema)
248+
)
249+
250+
act(() => {
251+
result.current.setQuery({ search })
252+
})
253+
254+
expect(result.current.query.search).toBe(search)
255+
expect(window.location.search).toBe(`?search=`)
256+
})
257+
})

0 commit comments

Comments
 (0)