11import { describe , it , beforeEach , expect , vi } from "vitest" ;
22import { createMemoryHistory } from "history" ;
33import { HistoryRouterGateway } from "./HistoryRouterGateway.js" ;
4- import { generateUrl } from "./generateUrl .js" ;
4+ import { RouteUrl } from "./RouteUrl .js" ;
55
66const wait = ( ) => new Promise ( resolve => setTimeout ( resolve , 10 ) ) ;
77
@@ -89,11 +89,11 @@ describe("Router Gateway", () => {
8989
9090 it ( "should generate route URLs" , async ( ) => {
9191 const urls = [
92- generateUrl ( "/" ) ,
93- generateUrl ( "/login" , { } ) ,
94- generateUrl ( "/login" , { redirect : "/" , reason : "login" } ) ,
95- generateUrl ( "/dynamic-route/:name" , { name : "cars" } ) ,
96- generateUrl ( "/dynamic-route" , { folderId : "696556831e485d00027a1a0b#0001" } )
92+ RouteUrl . fromPattern ( "/" ) ,
93+ RouteUrl . fromPattern ( "/login" , { } ) ,
94+ RouteUrl . fromPattern ( "/login" , { redirect : "/" , reason : "login" } ) ,
95+ RouteUrl . fromPattern ( "/dynamic-route/:name" , { name : "cars" } ) ,
96+ RouteUrl . fromPattern ( "/dynamic-route" , { folderId : "696556831e485d00027a1a0b#0001" } )
9797 ] ;
9898 expect ( urls ) . toEqual ( [
9999 "/" ,
@@ -103,4 +103,98 @@ describe("Router Gateway", () => {
103103 "/dynamic-route?folderId=696556831e485d00027a1a0b%230001"
104104 ] ) ;
105105 } ) ;
106+
107+ it ( "should handle baseUrl for route matching and URL generation" , async ( ) => {
108+ const spyFileManager = vi . fn ( ) ;
109+ const spyHome = vi . fn ( ) ;
110+
111+ // Create history with a tenant prefix
112+ const history = createMemoryHistory ( ) ;
113+ history . replace ( "/tenant123/__unknown__" ) ;
114+
115+ const gateway = new HistoryRouterGateway ( history , "/tenant123" ) ;
116+ gateway . setRoutes ( [
117+ { name : "home" , path : "/" , onMatch : spyHome } ,
118+ { name : "fileManager" , path : "/file-manager" , onMatch : spyFileManager }
119+ ] ) ;
120+
121+ // Navigate to /tenant123/file-manager
122+ history . push ( "/tenant123/file-manager" ) ;
123+ await wait ( ) ;
124+
125+ // Should match the /file-manager route
126+ expect ( spyFileManager ) . toHaveBeenCalledTimes ( 1 ) ;
127+ expect ( spyFileManager ) . toHaveBeenCalledWith ( {
128+ name : "fileManager" ,
129+ path : "/file-manager" ,
130+ pathname : "/tenant123/file-manager" ,
131+ params : { }
132+ } ) ;
133+
134+ // Test URL generation with baseUrl
135+ const urlWithBase = RouteUrl . fromPattern ( "/file-manager" , { } , "/tenant123" ) ;
136+ expect ( urlWithBase ) . toBe ( "/tenant123/file-manager" ) ;
137+
138+ const urlWithBaseAndParams = RouteUrl . fromPattern (
139+ "/file-manager" ,
140+ { folder : "abc" } ,
141+ "/tenant123"
142+ ) ;
143+ expect ( urlWithBaseAndParams ) . toBe ( "/tenant123/file-manager?folder=abc" ) ;
144+ } ) ;
145+
146+ it ( "should properly sort routes with wildcards always at the bottom" , async ( ) => {
147+ const spyWildcard = vi . fn ( ) ;
148+ const spySpecific = vi . fn ( ) ;
149+ const spyHome = vi . fn ( ) ;
150+
151+ const history = createMemoryHistory ( ) ;
152+ // Start at a non-matching path to avoid initial route resolution
153+ history . replace ( "/initial" ) ;
154+
155+ const gateway = new HistoryRouterGateway ( history , "" ) ;
156+
157+ // Add wildcard first, then home route
158+ // Note: setRoutes will trigger route resolution for current path (/initial)
159+ gateway . setRoutes ( [
160+ { name : "wildcard" , path : "*" , onMatch : spyWildcard } ,
161+ { name : "home" , path : "/" , onMatch : spyHome }
162+ ] ) ;
163+
164+ // Wildcard should have matched /initial
165+ expect ( spyWildcard ) . toHaveBeenCalledTimes ( 1 ) ;
166+ vi . clearAllMocks ( ) ;
167+
168+ // Now add a specific route after the wildcard - this should re-sort and keep wildcard at bottom
169+ // Note: setRoutes will trigger route resolution again for /initial, matching wildcard again
170+ gateway . setRoutes ( [ { name : "specific" , path : "/specific-route" , onMatch : spySpecific } ] ) ;
171+
172+ // Wildcard should match /initial again after re-sorting
173+ expect ( spyWildcard ) . toHaveBeenCalledTimes ( 1 ) ;
174+ vi . clearAllMocks ( ) ;
175+
176+ // Navigate to the specific route
177+ history . push ( "/specific-route" ) ;
178+ await wait ( ) ;
179+
180+ // Should match the specific route, not the wildcard
181+ expect ( spySpecific ) . toHaveBeenCalledTimes ( 1 ) ;
182+ expect ( spyWildcard ) . toHaveBeenCalledTimes ( 0 ) ;
183+ expect ( spyHome ) . toHaveBeenCalledTimes ( 0 ) ;
184+
185+ // Navigate to home
186+ history . push ( "/" ) ;
187+ await wait ( ) ;
188+
189+ // Should match home route
190+ expect ( spyHome ) . toHaveBeenCalledTimes ( 1 ) ;
191+ expect ( spyWildcard ) . toHaveBeenCalledTimes ( 0 ) ;
192+
193+ // Navigate to unknown route
194+ history . push ( "/unknown" ) ;
195+ await wait ( ) ;
196+
197+ // Should match wildcard
198+ expect ( spyWildcard ) . toHaveBeenCalledTimes ( 1 ) ;
199+ } ) ;
106200} ) ;
0 commit comments