11/* eslint-disable react-hooks/rules-of-hooks */
22import 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" ;
310import {
411 ExtendedLoaderComponent ,
512 FailTester ,
6- FetchTestComponent ,
13+ FetchTestRenderer ,
714 LoadPokemon ,
815 SimpleLoadedComponent ,
916 TestAggregateComponent ,
@@ -51,7 +58,7 @@ describe("withLoader", () => {
5158 } ) ;
5259
5360 test ( "onFetching renders when applicable" , async ( ) => {
54- render ( < FetchTestComponent /> ) ;
61+ render ( < FetchTestRenderer /> ) ;
5562 expect ( screen . getByText ( "Loading" ) ) . toBeVisible ( ) ;
5663 await waitFor ( ( ) =>
5764 expect ( screen . getByRole ( "textbox" ) ) . toBeVisible ( )
@@ -66,6 +73,24 @@ describe("withLoader", () => {
6673 ) ;
6774 } ) ;
6875
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+
6994 test ( "Can transform the output of the loader" , async ( ) => {
7095 render ( < TestTransformed /> ) ;
7196 await waitFor ( ( ) =>
@@ -78,5 +103,158 @@ describe("withLoader", () => {
78103 render ( < ExtendedLoaderComponent /> ) ;
79104 expect ( screen . getByText ( "Extended loading" ) ) . toBeVisible ( ) ;
80105 } ) ;
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+ } ) ;
81259 } ) ;
82260} ) ;
0 commit comments