@@ -225,6 +225,157 @@ describe('React Router - Optional Path Parameters', () => {
225
225
)
226
226
} )
227
227
228
+ describe ( 'required and optional parameters on the same level' , ( ) => {
229
+ async function setupTestRouter ( ) {
230
+ const rootRoute = createRootRoute ( )
231
+
232
+ const indexRoute = createRoute ( {
233
+ getParentRoute : ( ) => rootRoute ,
234
+ path : '/' ,
235
+ component : ( ) => {
236
+ return (
237
+ < div data-testid = "index-route-component" >
238
+ < h1 > index</ h1 >
239
+ < Link
240
+ data-testid = "reports-optional-param-link"
241
+ params = { { adminLevelId : 'asdf' } }
242
+ to = "/admin-levels/{-$adminLevelId}/reports"
243
+ >
244
+ navigate to reports with optional param
245
+ </ Link >
246
+ </ div >
247
+ )
248
+ } ,
249
+ } )
250
+
251
+ const adminLevelsRoutes = createRoute ( {
252
+ getParentRoute : ( ) => rootRoute ,
253
+
254
+ path : 'admin-levels' ,
255
+ component : ( ) => (
256
+ < div data-testid = "admin-levels-route-component" >
257
+ < h1 > admin-levels</ h1 >
258
+ < Outlet />
259
+ </ div >
260
+ ) ,
261
+ } )
262
+
263
+ const requiredParamRoute = createRoute ( {
264
+ getParentRoute : ( ) => adminLevelsRoutes ,
265
+ path : '$adminLevelId' ,
266
+ component : ( ) => (
267
+ < div data-testid = "admin-levels-route-required-param-route-component" >
268
+ < h1 > Required Param Route</ h1 >
269
+ < Outlet />
270
+ </ div >
271
+ ) ,
272
+ } )
273
+
274
+ const requiredParamIndexRoute = createRoute ( {
275
+ getParentRoute : ( ) => requiredParamRoute ,
276
+ path : '/' ,
277
+ component : ( ) => (
278
+ < div data-testid = "admin-levels-route-required-param-index-route-component" >
279
+ < h1 > Required Param Route Index</ h1 >
280
+ </ div >
281
+ ) ,
282
+ } )
283
+
284
+ const optionalParamRoute = createRoute ( {
285
+ getParentRoute : ( ) => adminLevelsRoutes ,
286
+ path : '{-$adminLevelId}' ,
287
+ component : ( ) => (
288
+ < div data-testid = "admin-levels-route-optional-param-route-component" >
289
+ < h1 > Optional Param Route</ h1 >
290
+ < Outlet />
291
+ </ div >
292
+ ) ,
293
+ } )
294
+
295
+ const reportsRoute = createRoute ( {
296
+ getParentRoute : ( ) => optionalParamRoute ,
297
+ path : 'reports' ,
298
+ component : ( ) => (
299
+ < div data-testid = "reports-route-component" >
300
+ < h1 > Reports</ h1 >
301
+ < Link
302
+ data-testid = "navigate-to-required-param-link"
303
+ to = "/admin-levels/$adminLevelId"
304
+ params = { { adminLevelId : 'asdf' } }
305
+ >
306
+ navigate to required param route
307
+ </ Link >
308
+ < Outlet />
309
+ </ div >
310
+ ) ,
311
+ } )
312
+
313
+ const router = createRouter ( {
314
+ routeTree : rootRoute . addChildren ( [
315
+ indexRoute ,
316
+ adminLevelsRoutes . addChildren ( [
317
+ requiredParamRoute . addChildren ( [ requiredParamIndexRoute ] ) ,
318
+ optionalParamRoute . addChildren ( [ reportsRoute ] ) ,
319
+ ] ) ,
320
+ ] ) ,
321
+ } )
322
+
323
+ render ( < RouterProvider router = { router } /> )
324
+ await act ( ( ) => router . load ( ) )
325
+ return router
326
+ }
327
+
328
+ it ( 'direct visit' , async ( ) => {
329
+ window . history . replaceState ( { } , '' , 'admin-levels/asdf' )
330
+ await setupTestRouter ( )
331
+
332
+ expect (
333
+ await screen . findByTestId (
334
+ 'admin-levels-route-required-param-route-component' ,
335
+ ) ,
336
+ ) . toBeInTheDocument ( )
337
+ expect (
338
+ await screen . findByTestId (
339
+ 'admin-levels-route-required-param-index-route-component' ,
340
+ ) ,
341
+ ) . toBeInTheDocument ( )
342
+ } )
343
+
344
+ it ( 'client-side navigation' , async ( ) => {
345
+ window . history . replaceState ( { } , '' , '/' )
346
+
347
+ await setupTestRouter ( )
348
+
349
+ expect (
350
+ await screen . findByTestId ( 'index-route-component' ) ,
351
+ ) . toBeInTheDocument ( )
352
+ const reportsLink = await screen . findByTestId (
353
+ 'reports-optional-param-link' ,
354
+ )
355
+ fireEvent . click ( reportsLink )
356
+
357
+ expect (
358
+ await screen . findByTestId ( 'reports-route-component' ) ,
359
+ ) . toBeInTheDocument ( )
360
+ const requiredParamLink = await screen . findByTestId (
361
+ 'navigate-to-required-param-link' ,
362
+ )
363
+ fireEvent . click ( requiredParamLink )
364
+
365
+ expect (
366
+ await screen . findByTestId (
367
+ 'admin-levels-route-required-param-route-component' ,
368
+ ) ,
369
+ ) . toBeInTheDocument ( )
370
+
371
+ expect (
372
+ await screen . findByTestId (
373
+ 'admin-levels-route-required-param-index-route-component' ,
374
+ ) ,
375
+ ) . toBeInTheDocument ( )
376
+ } )
377
+ } )
378
+
228
379
describe ( 'Link component with optional parameters' , ( ) => {
229
380
it ( 'should generate correct href for optional parameters' , async ( ) => {
230
381
const rootRoute = createRootRoute ( )
0 commit comments