11import { mount } from 'enzyme' ;
22import { createMemoryHistory } from 'history' ;
3- import React from 'react' ;
3+ import React , { Fragment } from 'react' ;
44import { defaultRegistry } from 'react-sweet-state' ;
55
66import { isServerEnvironment } from '../common/utils/is-server-environment' ;
77import { createResource , ResourceStore } from '../controllers/resource-store' ;
88import {
9+ Route ,
910 RouteComponent ,
1011 Router ,
11- RouterActions ,
12- RouterActionsType ,
12+ RouteResource ,
1313 StaticRouter ,
14+ useResource ,
1415} from '../index' ;
1516
1617jest . mock ( '../common/utils/is-server-environment' ) ;
@@ -22,55 +23,7 @@ describe('<Router /> client-side integration tests', () => {
2223
2324 afterEach ( ( ) => {
2425 defaultRegistry . stores . clear ( ) ;
25- } ) ;
26-
27- describe ( 'sends the expected path to history' , ( ) => {
28- function renderRouter ( basePath ?: string ) {
29- const history = createMemoryHistory ( ) ;
30- const push = jest . spyOn ( history , 'push' ) ;
31- const replace = jest . spyOn ( history , 'replace' ) ;
32-
33- let routerActions = { } as RouterActionsType ;
34- mount (
35- < Router basePath = { basePath } history = { history } routes = { [ ] } >
36- < RouterActions >
37- { actions => {
38- routerActions = actions ;
39-
40- return null ;
41- } }
42- </ RouterActions >
43- </ Router >
44- ) ;
45-
46- return {
47- history : {
48- push,
49- replace,
50- } ,
51- routerActions,
52- } ;
53- }
54-
55- it ( 'when basePath is set' , async ( ) => {
56- const { history, routerActions } = renderRouter ( '/basepath' ) ;
57-
58- routerActions . push ( '/push' ) ;
59- expect ( history . push ) . toHaveBeenCalledWith ( '/basepath/push' ) ;
60-
61- routerActions . replace ( '/replace' ) ;
62- expect ( history . replace ) . toHaveBeenCalledWith ( '/basepath/replace' ) ;
63- } ) ;
64-
65- it ( 'when basePath is not set' , async ( ) => {
66- const { history, routerActions } = renderRouter ( ) ;
67-
68- routerActions . push ( '/push' ) ;
69- expect ( history . push ) . toBeCalledWith ( '/push' ) ;
70-
71- routerActions . replace ( '/replace' ) ;
72- expect ( history . replace ) . toBeCalledWith ( '/replace' ) ;
73- } ) ;
26+ jest . useRealTimers ( ) ;
7427 } ) ;
7528
7629 it ( 're-triggers requests for timed out resources when mounted' , async ( ) => {
@@ -94,7 +47,7 @@ describe('<Router /> client-side integration tests', () => {
9447 const getTimeoutData = jest . spyOn ( timeoutResource , 'getData' ) ;
9548
9649 const route = {
97- component : ( ) => < div > foo </ div > ,
50+ component : ( ) => < div > test </ div > ,
9851 name : 'mock-route' ,
9952 path : location . substring ( 0 , location . indexOf ( '?' ) ) ,
10053 resources : [ completedResource , timeoutResource ] ,
@@ -110,6 +63,17 @@ describe('<Router /> client-side integration tests', () => {
11063 expect ( getTimeoutData ) . toHaveBeenCalledTimes ( 1 ) ;
11164
11265 expect ( serverData ) . toEqual ( {
66+ COMPLETED : {
67+ key : {
68+ data : 'completed' ,
69+ error : null ,
70+ expiresAt : null ,
71+ key : undefined ,
72+ loading : false ,
73+ promise : null ,
74+ accessedAt : null ,
75+ } ,
76+ } ,
11377 TIMEOUT : {
11478 key : {
11579 data : null ,
@@ -125,17 +89,6 @@ describe('<Router /> client-side integration tests', () => {
12589 accessedAt : null ,
12690 } ,
12791 } ,
128- COMPLETED : {
129- key : {
130- data : 'completed' ,
131- error : null ,
132- expiresAt : null ,
133- key : undefined ,
134- loading : false ,
135- promise : null ,
136- accessedAt : null ,
137- } ,
138- } ,
13992 } ) ;
14093
14194 defaultRegistry . stores . clear ( ) ;
@@ -165,9 +118,9 @@ describe('<Router /> client-side integration tests', () => {
165118 expect ( resourceStore . storeState . getState ( ) ) . toEqual ( {
166119 context : { } ,
167120 data : {
168- TIMEOUT : {
121+ COMPLETED : {
169122 key : {
170- data : 'timeout ' ,
123+ data : 'completed ' ,
171124 error : null ,
172125 expiresAt : expect . any ( Number ) ,
173126 key : undefined ,
@@ -176,9 +129,9 @@ describe('<Router /> client-side integration tests', () => {
176129 accessedAt : expect . any ( Number ) ,
177130 } ,
178131 } ,
179- COMPLETED : {
132+ TIMEOUT : {
180133 key : {
181- data : 'completed ' ,
134+ data : 'timeout ' ,
182135 error : null ,
183136 expiresAt : expect . any ( Number ) ,
184137 key : undefined ,
@@ -192,6 +145,148 @@ describe('<Router /> client-side integration tests', () => {
192145 prefetching : null ,
193146 } ) ;
194147 } ) ;
148+
149+ describe ( 'renders the next route with' , ( ) => {
150+ function renderRouter ( routes : Route [ ] ) {
151+ const history = createMemoryHistory ( { initialEntries : [ routes [ 0 ] . path ] } ) ;
152+ const push : any = jest . spyOn ( history , 'push' ) ;
153+ const waitForData = ( ) => new Promise ( resolve => setTimeout ( resolve ) ) ;
154+
155+ const router = mount (
156+ < Router history = { history } isGlobal routes = { routes } >
157+ < RouteComponent />
158+ </ Router >
159+ ) ;
160+
161+ return {
162+ history : {
163+ push,
164+ } ,
165+ router,
166+ waitForData,
167+ } ;
168+ }
169+
170+ function createResources ( ) {
171+ let cached = 0 ;
172+ let network = 0 ;
173+
174+ return {
175+ cacheResource : createResource ( {
176+ getData : ( ) => {
177+ cached += 1 ;
178+
179+ return Promise . resolve ( `cache-${ cached } ` ) ;
180+ } ,
181+ getKey : ( ) => 'cache' ,
182+ maxAge : Infinity ,
183+ type : 'CACHE' ,
184+ } ) ,
185+ networkResource : createResource ( {
186+ getData : ( ) => {
187+ network += 1 ;
188+
189+ return Promise . resolve ( `network-${ network } ` ) ;
190+ } ,
191+ getKey : ( ) => 'network' ,
192+ maxAge : 0 ,
193+ type : 'NETWORK' ,
194+ } ) ,
195+ } ;
196+ }
197+
198+ function createResourceComponent ( resource : RouteResource < string > ) {
199+ return ( ) => {
200+ const { data, error, loading } = useResource ( resource ) ;
201+ if ( error ) {
202+ return < > error:{ error } </ > ;
203+ }
204+
205+ if ( loading ) {
206+ return < > loading:{ resource . type . toLowerCase ( ) } </ > ;
207+ }
208+
209+ return < > data:{ data ?. toString ( ) } </ > ;
210+ } ;
211+ }
212+
213+ function createComponent ( resources : RouteResource < string > [ ] ) {
214+ const components = resources . map ( createResourceComponent ) ;
215+
216+ return ( ) => {
217+ return (
218+ < >
219+ { components . map ( ( Component , index ) => (
220+ < Fragment key = { index } >
221+ < Component />
222+ { index < components . length - 1 ? ' ' : '' }
223+ </ Fragment >
224+ ) ) }
225+ </ >
226+ ) ;
227+ } ;
228+ }
229+
230+ it ( 'previous data when transitioning to the same route and resource keys' , async ( ) => {
231+ const { cacheResource, networkResource } = createResources ( ) ;
232+ const route = {
233+ component : createComponent ( [ cacheResource , networkResource ] ) ,
234+ name : 'page-1' ,
235+ path : '/pages/1' ,
236+ resources : [ cacheResource , networkResource ] ,
237+ } ;
238+
239+ const { history, router, waitForData } = renderRouter ( [ route ] ) ;
240+
241+ expect ( router . html ( ) ) . toBe ( 'loading:cache loading:network' ) ;
242+ await waitForData ( ) ;
243+ router . update ( ) ;
244+ expect ( router . html ( ) ) . toBe ( 'data:cache-1 data:network-1' ) ;
245+
246+ history . push ( route . path + '?query#hash' ) ;
247+ router . update ( ) ;
248+
249+ expect ( router . html ( ) ) . toBe ( 'data:cache-1 data:network-1' ) ;
250+ await waitForData ( ) ;
251+ router . update ( ) ;
252+ expect ( router . html ( ) ) . toBe ( 'data:cache-1 data:network-1' ) ;
253+ } ) ;
254+
255+ it ( 'fresh data when transitioning to a new route' , async ( ) => {
256+ const { cacheResource, networkResource } = createResources ( ) ;
257+ const component = createComponent ( [ cacheResource , networkResource ] ) ;
258+
259+ const routes = [
260+ {
261+ component,
262+ name : 'page-1' ,
263+ path : '/pages/1' ,
264+ resources : [ cacheResource , networkResource ] ,
265+ } ,
266+ {
267+ component,
268+ name : 'page-2' ,
269+ path : '/pages/2' ,
270+ resources : [ cacheResource , networkResource ] ,
271+ } ,
272+ ] ;
273+
274+ const { history, router, waitForData } = renderRouter ( routes ) ;
275+
276+ expect ( router . html ( ) ) . toBe ( 'loading:cache loading:network' ) ;
277+ await waitForData ( ) ;
278+ router . update ( ) ;
279+ expect ( router . html ( ) ) . toBe ( 'data:cache-1 data:network-1' ) ;
280+
281+ history . push ( routes [ 1 ] . path ) ;
282+ router . update ( ) ;
283+
284+ expect ( router . html ( ) ) . toBe ( 'data:cache-1 loading:network' ) ;
285+ await waitForData ( ) ;
286+ router . update ( ) ;
287+ expect ( router . html ( ) ) . toBe ( 'data:cache-1 data:network-2' ) ;
288+ } ) ;
289+ } ) ;
195290} ) ;
196291
197292describe ( '<StaticRouter /> server-side integration tests' , ( ) => {
@@ -205,11 +300,11 @@ describe('<StaticRouter /> server-side integration tests', () => {
205300 ( isServerEnvironment as any ) . mockReturnValue ( true ) ;
206301 } ) ;
207302
208- it ( 'should match the right route when basePath is set' , async ( ) => {
303+ it ( 'renders the expected route when basePath is set' , async ( ) => {
209304 const wrapper = mount (
210305 < StaticRouter
211- basePath = "/basepath "
212- location = { `/basepath ${ route . path } ` }
306+ basePath = "/base-path "
307+ location = { `/base-path ${ route . path } ` }
213308 routes = { [ route ] }
214309 >
215310 < RouteComponent />
@@ -219,7 +314,7 @@ describe('<StaticRouter /> server-side integration tests', () => {
219314 expect ( wrapper . text ( ) ) . toBe ( 'route component' ) ;
220315 } ) ;
221316
222- it ( 'should match the right route when basePath is not set' , async ( ) => {
317+ it ( 'renders the expected route when basePath is not set' , async ( ) => {
223318 const wrapper = mount (
224319 < StaticRouter location = { route . path } routes = { [ route ] } >
225320 < RouteComponent />
0 commit comments