@@ -207,4 +207,112 @@ describe('Router', () => {
207207 const json = await response . json ( ) ;
208208 expect ( json ) . toEqual ( { foo : { bar : 'baz' } } ) ;
209209 } ) ;
210+
211+ describe ( 'use() - router merging' , ( ) => {
212+ it ( 'merges a sub-router without prefix' , async ( ) => {
213+ const usersRouter = createRouter < any , { } > ( ) . route ( {
214+ path : '/users' ,
215+ method : 'GET' ,
216+ handler : ( ) => Response . json ( { users : [ 'alice' , 'bob' ] } ) ,
217+ } ) ;
218+ const mainRouter = createRouter < any , { } > ( ) . use ( usersRouter ) ;
219+ const response = await mainRouter . fetch ( 'http://localhost:3000/users' ) ;
220+ expect ( response . status ) . toBe ( 200 ) ;
221+ const json = await response . json ( ) ;
222+ expect ( json . users ) . toEqual ( [ 'alice' , 'bob' ] ) ;
223+ } ) ;
224+
225+ it ( 'merges a sub-router with a prefix' , async ( ) => {
226+ const usersRouter = createRouter < any , { } > ( ) . route ( {
227+ path : '/users' ,
228+ method : 'GET' ,
229+ handler : ( ) => Response . json ( { users : [ 'alice' , 'bob' ] } ) ,
230+ } ) ;
231+ const mainRouter = createRouter < any , { } > ( ) . use ( '/api' , usersRouter ) ;
232+ const response = await mainRouter . fetch ( 'http://localhost:3000/api/users' ) ;
233+ expect ( response . status ) . toBe ( 200 ) ;
234+ const json = await response . json ( ) ;
235+ expect ( json . users ) . toEqual ( [ 'alice' , 'bob' ] ) ;
236+ } ) ;
237+
238+ it ( 'merges a sub-router that has its own base path' , async ( ) => {
239+ const usersRouter = createRouter < any , { } > ( { base : '/users' } ) . route ( {
240+ path : '/:id' ,
241+ method : 'GET' ,
242+ handler : request => Response . json ( { id : request . params . id } ) ,
243+ } ) ;
244+ const mainRouter = createRouter < any , { } > ( ) . use ( usersRouter ) ;
245+ const response = await mainRouter . fetch ( 'http://localhost:3000/users/42' ) ;
246+ expect ( response . status ) . toBe ( 200 ) ;
247+ const json = await response . json ( ) ;
248+ expect ( json . id ) . toBe ( '42' ) ;
249+ } ) ;
250+
251+ it ( 'merges multiple sub-routers' , async ( ) => {
252+ const usersRouter = createRouter < any , { } > ( ) . route ( {
253+ path : '/users' ,
254+ method : 'GET' ,
255+ handler : ( ) => Response . json ( { resource : 'users' } ) ,
256+ } ) ;
257+ const postsRouter = createRouter < any , { } > ( ) . route ( {
258+ path : '/posts' ,
259+ method : 'GET' ,
260+ handler : ( ) => Response . json ( { resource : 'posts' } ) ,
261+ } ) ;
262+ const mainRouter = createRouter < any , { } > ( ) . use ( usersRouter ) . use ( postsRouter ) ;
263+ const usersResponse = await mainRouter . fetch ( 'http://localhost:3000/users' ) ;
264+ expect ( usersResponse . status ) . toBe ( 200 ) ;
265+ expect ( await usersResponse . json ( ) ) . toEqual ( { resource : 'users' } ) ;
266+ const postsResponse = await mainRouter . fetch ( 'http://localhost:3000/posts' ) ;
267+ expect ( postsResponse . status ) . toBe ( 200 ) ;
268+ expect ( await postsResponse . json ( ) ) . toEqual ( { resource : 'posts' } ) ;
269+ } ) ;
270+
271+ it ( 'merges sub-router with prefix and route params' , async ( ) => {
272+ const itemsRouter = createRouter < any , { } > ( ) . route ( {
273+ path : '/:id' ,
274+ method : 'GET' ,
275+ handler : request => Response . json ( { id : request . params . id } ) ,
276+ } ) ;
277+ const mainRouter = createRouter < any , { } > ( ) . use ( '/items' , itemsRouter ) ;
278+ const response = await mainRouter . fetch ( 'http://localhost:3000/items/99' ) ;
279+ expect ( response . status ) . toBe ( 200 ) ;
280+ const json = await response . json ( ) ;
281+ expect ( json . id ) . toBe ( '99' ) ;
282+ } ) ;
283+
284+ it ( 'does not register sub-router internal routes in merged router' , async ( ) => {
285+ const subRouter = createRouter < any , { } > ( {
286+ openAPI : { endpoint : '/openapi.json' } ,
287+ } ) . route ( {
288+ path : '/hello' ,
289+ method : 'GET' ,
290+ handler : ( ) => Response . json ( { hello : 'world' } ) ,
291+ } ) ;
292+ const mainRouter = createRouter < any , { } > ( ) . use ( '/sub' , subRouter ) ;
293+ // The sub-router's internal /openapi.json should NOT be re-registered in the merged router
294+ const mergedPaths = mainRouter . __routes . map ( ( r : any ) => r . path ) ;
295+ expect ( mergedPaths ) . not . toContain ( '/sub/openapi.json' ) ;
296+ // The user-defined route should be in __routes with the prefix applied
297+ expect ( mergedPaths ) . toContain ( '/sub/hello' ) ;
298+ // The merged route should be accessible
299+ const helloResponse = await mainRouter . fetch ( 'http://localhost:3000/sub/hello' ) ;
300+ expect ( helloResponse . status ) . toBe ( 200 ) ;
301+ } ) ;
302+
303+ it ( 'handles transitive use() - router merged into another merged router' , async ( ) => {
304+ const deepRouter = createRouter < any , { } > ( { landingPage : false } ) . route ( {
305+ path : '/deep' ,
306+ method : 'GET' ,
307+ handler : ( ) => Response . json ( { level : 'deep' } ) ,
308+ } ) ;
309+ const midRouter = createRouter < any , { } > ( { landingPage : false } ) . use ( '/mid' , deepRouter ) ;
310+ const topRouter = createRouter < any , { } > ( { landingPage : false } ) . use ( '/top' , midRouter ) ;
311+
312+ const response = await topRouter . fetch ( 'http://localhost:3000/top/mid/deep' ) ;
313+ expect ( response . status ) . toBe ( 200 ) ;
314+ const json = await response . json ( ) ;
315+ expect ( json ) . toEqual ( { level : 'deep' } ) ;
316+ } ) ;
317+ } ) ;
210318} ) ;
0 commit comments