1
1
/* eslint-disable react-hooks/rules-of-hooks */
2
2
import userEvent from "@testing-library/user-event" ;
3
+ import { useState } from "react" ;
4
+ import { createLoader } from "../../src/createLoader" ;
5
+ import { withLoader } from "../../src/withLoader" ;
6
+ import {
7
+ useGetPokemonByNameQuery ,
8
+ useGetPokemonsQuery ,
9
+ } from "./store" ;
3
10
import {
4
11
ExtendedLoaderComponent ,
5
12
FailTester ,
6
- FetchTestComponent ,
13
+ FetchTestRenderer ,
7
14
LoadPokemon ,
8
15
SimpleLoadedComponent ,
9
16
TestAggregateComponent ,
@@ -51,7 +58,7 @@ describe("withLoader", () => {
51
58
} ) ;
52
59
53
60
test ( "onFetching renders when applicable" , async ( ) => {
54
- render ( < FetchTestComponent /> ) ;
61
+ render ( < FetchTestRenderer /> ) ;
55
62
expect ( screen . getByText ( "Loading" ) ) . toBeVisible ( ) ;
56
63
await waitFor ( ( ) =>
57
64
expect ( screen . getByRole ( "textbox" ) ) . toBeVisible ( )
@@ -66,6 +73,24 @@ describe("withLoader", () => {
66
73
) ;
67
74
} ) ;
68
75
76
+ test ( "whileFetching renders when applicable" , async ( ) => {
77
+ render ( < FetchTestRenderer while /> ) ;
78
+ expect ( screen . getByText ( "Loading" ) ) . toBeVisible ( ) ;
79
+ await waitFor ( ( ) =>
80
+ expect ( screen . getByRole ( "textbox" ) ) . toBeVisible ( )
81
+ ) ;
82
+ const input = screen . getByRole ( "textbox" ) ;
83
+ userEvent . type ( input , "Abc{Enter}" ) ;
84
+ await waitFor (
85
+ ( ) =>
86
+ expect ( screen . getByText ( "FetchingWhile" ) ) . toBeVisible ( ) ,
87
+ { interval : 20 }
88
+ ) ;
89
+ await waitFor ( ( ) =>
90
+ expect ( screen . getByText ( "#3" ) ) . toBeVisible ( )
91
+ ) ;
92
+ } ) ;
93
+
69
94
test ( "Can transform the output of the loader" , async ( ) => {
70
95
render ( < TestTransformed /> ) ;
71
96
await waitFor ( ( ) =>
@@ -78,5 +103,158 @@ describe("withLoader", () => {
78
103
render ( < ExtendedLoaderComponent /> ) ;
79
104
expect ( screen . getByText ( "Extended loading" ) ) . toBeVisible ( ) ;
80
105
} ) ;
106
+
107
+ test ( "Can extend onError" , async ( ) => {
108
+ const Component = withLoader (
109
+ ( props , loaderData ) => {
110
+ return < div > Success</ div > ;
111
+ } ,
112
+ createLoader ( {
113
+ queries : ( ) =>
114
+ [ useGetPokemonByNameQuery ( "error" ) ] as const ,
115
+ onLoading : ( ) => < div > Loading</ div > ,
116
+ onError : ( ) => < div > Error</ div > ,
117
+ } ) . extend ( {
118
+ onError : ( ) => < div > Extended Error</ div > ,
119
+ } )
120
+ ) ;
121
+ render ( < Component /> ) ;
122
+ expect ( screen . getByText ( "Loading" ) ) . toBeVisible ( ) ;
123
+ await waitFor ( ( ) =>
124
+ expect ( screen . getByText ( "Extended Error" ) ) . toBeVisible ( )
125
+ ) ;
126
+ } ) ;
127
+
128
+ test ( "Can extend onFetching" , async ( ) => {
129
+ const loader = createLoader ( {
130
+ queries : ( arg : string ) =>
131
+ [ useGetPokemonByNameQuery ( arg ) ] as const ,
132
+ queriesArg : ( props : {
133
+ name : string ;
134
+ onChange : ( name : string ) => void ;
135
+ } ) => props . name ,
136
+ onLoading : ( ) => < div > Loading</ div > ,
137
+ onFetching : ( ) => < div > Fetching</ div > ,
138
+ } ) . extend ( {
139
+ onFetching : ( ) => < div > Extended Fetching</ div > ,
140
+ } ) ;
141
+
142
+ const Component = withLoader ( ( props , loaderData ) => {
143
+ return (
144
+ < div >
145
+ Success < span > { loaderData [ 0 ] . data . name } </ span >
146
+ < button
147
+ onClick = { ( ) => props . onChange ( props . name + "a" ) }
148
+ >
149
+ Refetch
150
+ </ button >
151
+ </ div >
152
+ ) ;
153
+ } , loader ) ;
154
+
155
+ const Controller = ( ) => {
156
+ const [ name , setName ] = useState ( "a" ) ;
157
+ return < Component name = { name } onChange = { setName } /> ;
158
+ } ;
159
+
160
+ render ( < Controller /> ) ;
161
+ expect ( screen . getByText ( "Loading" ) ) . toBeVisible ( ) ;
162
+ await waitFor ( ( ) =>
163
+ expect ( screen . getByRole ( "button" ) ) . toBeVisible ( )
164
+ ) ;
165
+ await userEvent . click ( screen . getByRole ( "button" ) ) ;
166
+ await waitFor ( ( ) =>
167
+ expect (
168
+ screen . getByText ( "Extended Fetching" )
169
+ ) . toBeVisible ( )
170
+ ) ;
171
+ } ) ;
172
+
173
+ test ( "Can extend whileFetching" , async ( ) => {
174
+ const loader = createLoader ( {
175
+ queries : ( arg : string ) =>
176
+ [ useGetPokemonByNameQuery ( arg ) ] as const ,
177
+ queriesArg : ( props : {
178
+ name : string ;
179
+ onChange : ( name : string ) => void ;
180
+ } ) => props . name ,
181
+ onLoading : ( ) => < div > Loading</ div > ,
182
+ whileFetching : {
183
+ prepend : ( ) => < div > Fetching</ div > ,
184
+ } ,
185
+ } ) . extend ( {
186
+ whileFetching : {
187
+ prepend : ( ) => < span > Extended Fetching</ span > ,
188
+ } ,
189
+ } ) ;
190
+ expect ( loader . whileFetching ?. prepend ) . not . toBeUndefined ( ) ;
191
+
192
+ const Component = withLoader ( ( props , loaderData ) => {
193
+ return (
194
+ < div >
195
+ Success < span > { loaderData [ 0 ] . data . name } </ span >
196
+ < button
197
+ onClick = { ( ) => props . onChange ( props . name + "a" ) }
198
+ >
199
+ Refetch
200
+ </ button >
201
+ </ div >
202
+ ) ;
203
+ } , loader ) ;
204
+
205
+ const Controller = ( ) => {
206
+ const [ name , setName ] = useState ( "a" ) ;
207
+ return < Component name = { name } onChange = { setName } /> ;
208
+ } ;
209
+
210
+ render ( < Controller /> ) ;
211
+ expect ( screen . getByText ( "Loading" ) ) . toBeVisible ( ) ;
212
+ await waitFor ( ( ) =>
213
+ expect ( screen . getByRole ( "button" ) ) . toBeVisible ( )
214
+ ) ;
215
+ await userEvent . click ( screen . getByRole ( "button" ) ) ;
216
+ await waitFor ( ( ) =>
217
+ expect (
218
+ screen . queryByText ( / e x t e n d e d f e t c h i n g / i)
219
+ ) . toBeVisible ( )
220
+ ) ;
221
+ } ) ;
222
+
223
+ test ( "Can extend queries" , async ( ) => {
224
+ const loader = createLoader ( {
225
+ queries : ( arg : string ) =>
226
+ [ useGetPokemonByNameQuery ( arg ) ] as const ,
227
+ queriesArg : ( props : { name : string } ) => props . name ,
228
+ onLoading : ( ) => < div > Loading</ div > ,
229
+ } ) . extend ( {
230
+ queries : ( arg : string ) =>
231
+ [
232
+ useGetPokemonByNameQuery ( arg ) ,
233
+ useGetPokemonsQuery ( undefined ) ,
234
+ ] as const ,
235
+ transform : ( q ) => q ,
236
+ } ) ;
237
+
238
+ const Component = withLoader ( ( props , loaderData ) => {
239
+ return (
240
+ < div >
241
+ < ul >
242
+ < li > { loaderData [ 0 ] . data . name } </ li >
243
+ { loaderData [ 1 ] . data . results . map ( ( pokemon ) => (
244
+ < li > { pokemon . name } </ li >
245
+ ) ) }
246
+ </ ul >
247
+ </ div >
248
+ ) ;
249
+ } , loader ) ;
250
+
251
+ render ( < Component name = "test" /> ) ;
252
+ expect ( screen . getByText ( "Loading" ) ) . toBeVisible ( ) ;
253
+ await waitFor ( ( ) =>
254
+ expect ( screen . getByText ( "test" ) ) . toBeVisible ( )
255
+ ) ;
256
+ expect ( screen . getByText ( / c h a r i z a r d / i) ) . toBeVisible ( ) ;
257
+ expect ( screen . getByText ( / p i k a c h u / i) ) . toBeVisible ( ) ;
258
+ } ) ;
81
259
} ) ;
82
260
} ) ;
0 commit comments