@@ -69,6 +69,43 @@ describe('sentryMiddleware', () => {
69
69
expect ( resultFromNext ) . toStrictEqual ( nextResult ) ;
70
70
} ) ;
71
71
72
+ it ( "sets source route if the url couldn't be decoded correctly" , async ( ) => {
73
+ const middleware = handleRequest ( ) ;
74
+ const ctx = {
75
+ request : {
76
+ method : 'GET' ,
77
+ url : '/a%xx' ,
78
+ headers : new Headers ( ) ,
79
+ } ,
80
+ url : { pathname : 'a%xx' , href : 'http://localhost:1234/a%xx' } ,
81
+ params : { } ,
82
+ } ;
83
+ const next = vi . fn ( ( ) => nextResult ) ;
84
+
85
+ // @ts -expect-error, a partial ctx object is fine here
86
+ const resultFromNext = middleware ( ctx , next ) ;
87
+
88
+ expect ( startSpanSpy ) . toHaveBeenCalledWith (
89
+ {
90
+ data : {
91
+ method : 'GET' ,
92
+ url : 'http://localhost:1234/a%xx' ,
93
+ } ,
94
+ metadata : {
95
+ source : 'url' ,
96
+ } ,
97
+ name : 'GET a%xx' ,
98
+ op : 'http.server' ,
99
+ origin : 'auto.http.astro' ,
100
+ status : 'ok' ,
101
+ } ,
102
+ expect . any ( Function ) , // the `next` function
103
+ ) ;
104
+
105
+ expect ( next ) . toHaveBeenCalled ( ) ;
106
+ expect ( resultFromNext ) . toStrictEqual ( nextResult ) ;
107
+ } ) ;
108
+
72
109
it ( 'throws and sends an error to sentry if `next()` throws' , async ( ) => {
73
110
const captureExceptionSpy = vi . spyOn ( SentryNode , 'captureException' ) ;
74
111
@@ -299,15 +336,31 @@ describe('sentryMiddleware', () => {
299
336
300
337
describe ( 'interpolateRouteFromUrlAndParams' , ( ) => {
301
338
it . each ( [
339
+ [ '/' , { } , '/' ] ,
302
340
[ '/foo/bar' , { } , '/foo/bar' ] ,
303
341
[ '/users/123' , { id : '123' } , '/users/[id]' ] ,
304
342
[ '/users/123' , { id : '123' , foo : 'bar' } , '/users/[id]' ] ,
305
343
[ '/lang/en-US' , { lang : 'en' , region : 'US' } , '/lang/[lang]-[region]' ] ,
306
344
[ '/lang/en-US/posts' , { lang : 'en' , region : 'US' } , '/lang/[lang]-[region]/posts' ] ,
345
+ // edge cases that astro doesn't support
346
+ [ '/lang/-US' , { region : 'US' } , '/lang/-[region]' ] ,
347
+ [ '/lang/en-' , { lang : 'en' } , '/lang/[lang]-' ] ,
307
348
] ) ( 'interpolates route from URL and params %s' , ( rawUrl , params , expectedRoute ) => {
308
349
expect ( interpolateRouteFromUrlAndParams ( rawUrl , params ) ) . toEqual ( expectedRoute ) ;
309
350
} ) ;
310
351
352
+ it . each ( [
353
+ [ '/(a+)+/aaaaaaaaa!' , { id : '(a+)+' , slug : 'aaaaaaaaa!' } , '/[id]/[slug]' ] ,
354
+ [ '/([a-zA-Z]+)*/aaaaaaaaa!' , { id : '([a-zA-Z]+)*' , slug : 'aaaaaaaaa!' } , '/[id]/[slug]' ] ,
355
+ [ '/(a|aa)+/aaaaaaaaa!' , { id : '(a|aa)+' , slug : 'aaaaaaaaa!' } , '/[id]/[slug]' ] ,
356
+ [ '/(a|a?)+/aaaaaaaaa!' , { id : '(a|a?)+' , slug : 'aaaaaaaaa!' } , '/[id]/[slug]' ] ,
357
+ // with URL encoding
358
+ [ '/(a%7Caa)+/aaaaaaaaa!' , { id : '(a|aa)+' , slug : 'aaaaaaaaa!' } , '/[id]/[slug]' ] ,
359
+ [ '/(a%7Ca?)+/aaaaaaaaa!' , { id : '(a|a?)+' , slug : 'aaaaaaaaa!' } , '/[id]/[slug]' ] ,
360
+ ] ) ( 'handles regex characters in param values correctly %s' , ( rawUrl , params , expectedRoute ) => {
361
+ expect ( interpolateRouteFromUrlAndParams ( rawUrl , params ) ) . toEqual ( expectedRoute ) ;
362
+ } ) ;
363
+
311
364
it ( 'handles params across multiple URL segments in catchall routes' , ( ) => {
312
365
// Ideally, Astro would let us know that this is a catchall route so we can make the param [...catchall] but it doesn't
313
366
expect (
@@ -324,4 +377,11 @@ describe('interpolateRouteFromUrlAndParams', () => {
324
377
const expectedRoute = '/usernames/[name]' ;
325
378
expect ( interpolateRouteFromUrlAndParams ( rawUrl , params ) ) . toEqual ( expectedRoute ) ;
326
379
} ) ;
380
+
381
+ it ( 'handles set but undefined params' , ( ) => {
382
+ const rawUrl = '/usernames/user' ;
383
+ const params = { name : undefined , name2 : '' } ;
384
+ const expectedRoute = '/usernames/user' ;
385
+ expect ( interpolateRouteFromUrlAndParams ( rawUrl , params ) ) . toEqual ( expectedRoute ) ;
386
+ } ) ;
327
387
} ) ;
0 commit comments