2
2
* @jest -environment node
3
3
*/
4
4
5
- import type { StaticHandlerContext } from "react-router" ;
5
+ import {
6
+ unstable_createContext ,
7
+ type StaticHandlerContext ,
8
+ } from "react-router" ;
6
9
7
10
import { createRequestHandler } from "../../lib/server-runtime/server" ;
8
11
import { ServerMode } from "../../lib/server-runtime/mode" ;
@@ -24,7 +27,7 @@ function spyConsole() {
24
27
return spy ;
25
28
}
26
29
27
- describe . skip ( "server" , ( ) => {
30
+ describe ( "server" , ( ) => {
28
31
let routeId = "root" ;
29
32
let build : ServerBuild = {
30
33
ssr : true ,
@@ -72,20 +75,20 @@ describe.skip("server", () => {
72
75
} ) ;
73
76
74
77
let allowThrough = [
75
- [ "GET" , "/" ] ,
76
- [ "GET" , "/?_data=root " ] ,
77
- [ "POST" , "/" ] ,
78
- [ "POST" , "/?_data=root " ] ,
79
- [ "PUT" , "/" ] ,
80
- [ "PUT" , "/?_data=root " ] ,
81
- [ "DELETE" , "/" ] ,
82
- [ "DELETE" , "/?_data=root " ] ,
83
- [ "PATCH" , "/" ] ,
84
- [ "PATCH" , "/?_data=root " ] ,
78
+ [ "GET" , "/" , "COMPONENT" ] ,
79
+ [ "GET" , "/_root.data" , "LOADER "] ,
80
+ [ "POST" , "/" , "COMPONENT" ] ,
81
+ [ "POST" , "/_root.data" , "ACTION "] ,
82
+ [ "PUT" , "/" , "COMPONENT" ] ,
83
+ [ "PUT" , "/_root.data" , "ACTION "] ,
84
+ [ "DELETE" , "/" , "COMPONENT" ] ,
85
+ [ "DELETE" , "/_root.data" , "ACTION "] ,
86
+ [ "PATCH" , "/" , "COMPONENT" ] ,
87
+ [ "PATCH" , "/_root.data" , "ACTION "] ,
85
88
] ;
86
89
it . each ( allowThrough ) (
87
90
`allows through %s request to %s` ,
88
- async ( method , to ) => {
91
+ async ( method , to , expected ) => {
89
92
let handler = createRequestHandler ( build ) ;
90
93
let response = await handler (
91
94
new Request ( `http://localhost:3000${ to } ` , {
@@ -96,11 +99,6 @@ describe.skip("server", () => {
96
99
expect ( response . status ) . toBe ( 200 ) ;
97
100
let text = await response . text ( ) ;
98
101
expect ( text ) . toContain ( method ) ;
99
- let expected = ! to . includes ( "?_data=root" )
100
- ? "COMPONENT"
101
- : method === "GET"
102
- ? "LOADER"
103
- : "ACTION" ;
104
102
expect ( text ) . toContain ( expected ) ;
105
103
expect ( spy . console ) . not . toHaveBeenCalled ( ) ;
106
104
}
@@ -116,6 +114,203 @@ describe.skip("server", () => {
116
114
117
115
expect ( await response . text ( ) ) . toBe ( "" ) ;
118
116
} ) ;
117
+
118
+ it ( "accepts proper values from getLoadContext (without middleware)" , async ( ) => {
119
+ let handler = createRequestHandler ( {
120
+ ssr : true ,
121
+ entry : {
122
+ module : {
123
+ default : async ( request ) => {
124
+ return new Response (
125
+ `${ request . method } , ${ request . url } COMPONENT`
126
+ ) ;
127
+ } ,
128
+ } ,
129
+ } ,
130
+ routes : {
131
+ root : {
132
+ id : "root" ,
133
+ path : "" ,
134
+ module : {
135
+ loader : ( { context } ) => context . foo ,
136
+ default : ( ) => "COMPONENT" ,
137
+ } ,
138
+ } ,
139
+ } ,
140
+ assets : {
141
+ routes : {
142
+ root : {
143
+ clientActionModule : undefined ,
144
+ clientLoaderModule : undefined ,
145
+ clientMiddlewareModule : undefined ,
146
+ hasAction : true ,
147
+ hasClientAction : false ,
148
+ hasClientLoader : false ,
149
+ hasClientMiddleware : false ,
150
+ hasErrorBoundary : false ,
151
+ hasLoader : true ,
152
+ hydrateFallbackModule : undefined ,
153
+ id : routeId ,
154
+ module : routeId ,
155
+ path : "" ,
156
+ } ,
157
+ } ,
158
+ entry : { imports : [ ] , module : "" } ,
159
+ url : "" ,
160
+ version : "" ,
161
+ } ,
162
+ future : {
163
+ unstable_middleware : false ,
164
+ } ,
165
+ prerender : [ ] ,
166
+ publicPath : "/" ,
167
+ assetsBuildDirectory : "/" ,
168
+ isSpaMode : false ,
169
+ } ) ;
170
+ let response = await handler (
171
+ new Request ( "http://localhost:3000/_root.data" ) ,
172
+ {
173
+ foo : "FOO" ,
174
+ }
175
+ ) ;
176
+
177
+ expect ( await response . text ( ) ) . toContain ( "FOO" ) ;
178
+ } ) ;
179
+
180
+ it ( "accepts proper values from getLoadContext (with middleware)" , async ( ) => {
181
+ let fooContext = unstable_createContext < string > ( ) ;
182
+ let handler = createRequestHandler ( {
183
+ ssr : true ,
184
+ entry : {
185
+ module : {
186
+ default : async ( request ) => {
187
+ return new Response (
188
+ `${ request . method } , ${ request . url } COMPONENT`
189
+ ) ;
190
+ } ,
191
+ } ,
192
+ } ,
193
+ routes : {
194
+ root : {
195
+ id : "root" ,
196
+ path : "" ,
197
+ module : {
198
+ loader : ( { context } ) => context . get ( fooContext ) ,
199
+ default : ( ) => "COMPONENT" ,
200
+ } ,
201
+ } ,
202
+ } ,
203
+ assets : {
204
+ routes : {
205
+ root : {
206
+ clientActionModule : undefined ,
207
+ clientLoaderModule : undefined ,
208
+ clientMiddlewareModule : undefined ,
209
+ hasAction : true ,
210
+ hasClientAction : false ,
211
+ hasClientLoader : false ,
212
+ hasClientMiddleware : false ,
213
+ hasErrorBoundary : false ,
214
+ hasLoader : true ,
215
+ hydrateFallbackModule : undefined ,
216
+ id : routeId ,
217
+ module : routeId ,
218
+ path : "" ,
219
+ } ,
220
+ } ,
221
+ entry : { imports : [ ] , module : "" } ,
222
+ url : "" ,
223
+ version : "" ,
224
+ } ,
225
+ future : {
226
+ unstable_middleware : true ,
227
+ } ,
228
+ prerender : [ ] ,
229
+ publicPath : "/" ,
230
+ assetsBuildDirectory : "/" ,
231
+ isSpaMode : false ,
232
+ } ) ;
233
+ let response = await handler (
234
+ new Request ( "http://localhost:3000/_root.data" ) ,
235
+ // @ts -expect-error In apps the expected type is handled via the Future interface
236
+ new Map ( [ [ fooContext , "FOO" ] ] )
237
+ ) ;
238
+
239
+ expect ( await response . text ( ) ) . toContain ( "FOO" ) ;
240
+ } ) ;
241
+
242
+ it ( "errors if an invalid value is returned from getLoadContext (with middleware)" , async ( ) => {
243
+ let handleErrorSpy = jest . fn ( ) ;
244
+ let handler = createRequestHandler ( {
245
+ ssr : true ,
246
+ entry : {
247
+ module : {
248
+ handleError : handleErrorSpy ,
249
+ default : async ( request ) => {
250
+ return new Response (
251
+ `${ request . method } , ${ request . url } COMPONENT`
252
+ ) ;
253
+ } ,
254
+ } ,
255
+ } ,
256
+ routes : {
257
+ root : {
258
+ id : "root" ,
259
+ path : "" ,
260
+ module : {
261
+ loader : ( { context } ) => context . foo ,
262
+ default : ( ) => "COMPONENT" ,
263
+ } ,
264
+ } ,
265
+ } ,
266
+ assets : {
267
+ routes : {
268
+ root : {
269
+ clientActionModule : undefined ,
270
+ clientLoaderModule : undefined ,
271
+ clientMiddlewareModule : undefined ,
272
+ hasAction : true ,
273
+ hasClientAction : false ,
274
+ hasClientLoader : false ,
275
+ hasClientMiddleware : false ,
276
+ hasErrorBoundary : false ,
277
+ hasLoader : true ,
278
+ hydrateFallbackModule : undefined ,
279
+ id : routeId ,
280
+ module : routeId ,
281
+ path : "" ,
282
+ } ,
283
+ } ,
284
+ entry : { imports : [ ] , module : "" } ,
285
+ url : "" ,
286
+ version : "" ,
287
+ } ,
288
+ future : {
289
+ unstable_middleware : true ,
290
+ } ,
291
+ prerender : [ ] ,
292
+ publicPath : "/" ,
293
+ assetsBuildDirectory : "/" ,
294
+ isSpaMode : false ,
295
+ } ) ;
296
+
297
+ let response = await handler (
298
+ new Request ( "http://localhost:3000/_root.data" ) ,
299
+ {
300
+ foo : "FOO" ,
301
+ }
302
+ ) ;
303
+
304
+ expect ( response . status ) . toBe ( 500 ) ;
305
+ expect ( await response . text ( ) ) . toContain ( "Unexpected Server Error" ) ;
306
+ expect ( handleErrorSpy ) . toHaveBeenCalledTimes ( 1 ) ;
307
+ expect ( handleErrorSpy . mock . calls [ 0 ] [ 0 ] ) . toMatchInlineSnapshot ( `
308
+ [Error: Unable to create initial \`unstable_RouterContextProvider\` instance. Please confirm you are returning an instance of \`Map<unstable_routerContext, unknown>\` from your \`getLoadContext\` function.
309
+
310
+ Error: TypeError: init is not iterable]
311
+ ` ) ;
312
+ handleErrorSpy . mockRestore ( ) ;
313
+ } ) ;
119
314
} ) ;
120
315
} ) ;
121
316
0 commit comments