@@ -38,6 +38,7 @@ function createMockSpan() {
3838 return {
3939 setAttribute : vi . fn ( ) ,
4040 setAttributes : vi . fn ( ) ,
41+ addLinks : vi . fn ( ) ,
4142 spanContext : vi . fn ( ) . mockReturnValue ( {
4243 traceId : 'test-trace-id-12345678901234567890' ,
4344 spanId : 'test-span-id' ,
@@ -84,7 +85,7 @@ describe('wrapMethodWithSentry', () => {
8485 expect ( result ) . toBe ( 'sync-result' ) ;
8586 } ) ;
8687
87- it ( 'wraps a sync method with spanName and returns synchronously (not a Promise) ' , ( ) => {
88+ it ( 'wraps a sync method with spanName and preserves sync behavior ' , ( ) => {
8889 const handler = vi . fn ( ) . mockReturnValue ( 'sync-result' ) ;
8990 const options = {
9091 options : { } ,
@@ -100,7 +101,7 @@ describe('wrapMethodWithSentry', () => {
100101 expect ( result ) . toBe ( 'sync-result' ) ;
101102 } ) ;
102103
103- it ( 'wraps a sync method with startNewTrace and returns synchronously (not a Promise) ' , ( ) => {
104+ it ( 'wraps a sync method with startNewTrace and preserves sync behavior ' , ( ) => {
104105 const handler = vi . fn ( ) . mockReturnValue ( 'sync-result' ) ;
105106 const options = {
106107 options : { } ,
@@ -132,14 +133,15 @@ describe('wrapMethodWithSentry', () => {
132133 expect ( handler ) . toHaveBeenCalled ( ) ;
133134 } ) ;
134135
135- it ( 'returns a Promise when linkPreviousTrace is true (even for sync handlers )' , async ( ) => {
136+ it ( 'does not change sync/async behavior when linkPreviousTrace is true (links are set via waitUntil )' , ( ) => {
136137 const handler = vi . fn ( ) . mockReturnValue ( 'sync-result' ) ;
137138 const mockStorage = {
138139 get : vi . fn ( ) . mockResolvedValue ( undefined ) ,
139140 put : vi . fn ( ) . mockResolvedValue ( undefined ) ,
140141 } ;
142+ const waitUntilPromises : Promise < void > [ ] = [ ] ;
141143 const context = {
142- waitUntil : vi . fn ( ) ,
144+ waitUntil : vi . fn ( ( p : Promise < void > ) => waitUntilPromises . push ( p ) ) ,
143145 originalStorage : mockStorage ,
144146 } as any ;
145147
@@ -154,8 +156,12 @@ describe('wrapMethodWithSentry', () => {
154156 const wrapped = wrapMethodWithSentry ( options , handler ) ;
155157 const result = wrapped ( ) ;
156158
157- expect ( result ) . toBeInstanceOf ( Promise ) ;
158- await expect ( result ) . resolves . toBe ( 'sync-result' ) ;
159+ // linkPreviousTrace does not make the result async - links are set via waitUntil
160+ expect ( result ) . not . toBeInstanceOf ( Promise ) ;
161+ expect ( result ) . toBe ( 'sync-result' ) ;
162+
163+ // The link fetching happens via waitUntil, not blocking the response
164+ expect ( context . waitUntil ) . toHaveBeenCalled ( ) ;
159165 } ) ;
160166
161167 it ( 'marks handler as instrumented' , ( ) => {
@@ -363,8 +369,13 @@ describe('wrapMethodWithSentry', () => {
363369 get : vi . fn ( ) . mockResolvedValue ( storedContext ) ,
364370 put : vi . fn ( ) . mockResolvedValue ( undefined ) ,
365371 } ;
372+
373+ const mockSpan = createMockSpan ( ) ;
374+ vi . mocked ( sentryCore . startSpan ) . mockImplementation ( ( opts , callback ) => callback ( mockSpan as any ) ) ;
375+
376+ const waitUntilPromises : Promise < void > [ ] = [ ] ;
366377 const context = {
367- waitUntil : vi . fn ( ) ,
378+ waitUntil : vi . fn ( ( p : Promise < void > ) => waitUntilPromises . push ( p ) ) ,
368379 originalStorage : mockStorage ,
369380 } as any ;
370381
@@ -380,20 +391,20 @@ describe('wrapMethodWithSentry', () => {
380391 const wrapped = wrapMethodWithSentry ( options , handler ) ;
381392 await wrapped ( ) ;
382393
383- // startSpan should be called with links
384- expect ( sentryCore . startSpan ) . toHaveBeenCalledWith (
385- expect . objectContaining ( {
386- links : expect . arrayContaining ( [
387- expect . objectContaining ( {
388- context : expect . objectContaining ( {
389- traceId : 'previous-trace-id-1234567890123456' ,
390- spanId : 'previous-span-id' ,
391- } ) ,
392- attributes : { 'sentry.link.type' : 'previous_trace' } ,
394+ // Wait for waitUntil promises to resolve (setSpanLinks is called via waitUntil)
395+ await Promise . all ( waitUntilPromises ) ;
396+
397+ // addLinks should be called on the span with the stored context
398+ expect ( mockSpan . addLinks ) . toHaveBeenCalledWith (
399+ expect . arrayContaining ( [
400+ expect . objectContaining ( {
401+ context : expect . objectContaining ( {
402+ traceId : 'previous-trace-id-1234567890123456' ,
403+ spanId : 'previous-span-id' ,
393404 } ) ,
394- ] ) ,
395- } ) ,
396- expect . any ( Function ) ,
405+ attributes : { 'sentry.link.type' : 'previous_trace' } ,
406+ } ) ,
407+ ] ) ,
397408 ) ;
398409 } ) ;
399410
@@ -430,13 +441,22 @@ describe('wrapMethodWithSentry', () => {
430441 expect ( mockStorage . put ) . toHaveBeenCalledWith ( '__SENTRY_TRACE_LINK__alarm' , expect . any ( Object ) ) ;
431442 } ) ;
432443
433- it ( 'does not retrieve stored context when linkPreviousTrace is false' , async ( ) => {
444+ it ( 'does not store span context when linkPreviousTrace is false' , async ( ) => {
445+ vi . mocked ( sentryCore . getActiveSpan ) . mockReturnValue ( {
446+ spanContext : vi . fn ( ) . mockReturnValue ( {
447+ traceId : 'current-trace-id-123456789012345678' ,
448+ spanId : 'current-span-id' ,
449+ } ) ,
450+ } as any ) ;
451+
434452 const mockStorage = {
435453 get : vi . fn ( ) . mockResolvedValue ( undefined ) ,
436454 put : vi . fn ( ) . mockResolvedValue ( undefined ) ,
437455 } ;
456+
457+ const waitUntilPromises : Promise < void > [ ] = [ ] ;
438458 const context = {
439- waitUntil : vi . fn ( ) ,
459+ waitUntil : vi . fn ( ( p : Promise < void > ) => waitUntilPromises . push ( p ) ) ,
440460 originalStorage : mockStorage ,
441461 } as any ;
442462
@@ -452,7 +472,11 @@ describe('wrapMethodWithSentry', () => {
452472 const wrapped = wrapMethodWithSentry ( options , handler ) ;
453473 await wrapped ( ) ;
454474
455- expect ( mockStorage . get ) . not . toHaveBeenCalled ( ) ;
475+ // Wait for all waitUntil promises to resolve
476+ await Promise . all ( waitUntilPromises ) ;
477+
478+ // Should NOT store span context when linkPreviousTrace is false
479+ expect ( mockStorage . put ) . not . toHaveBeenCalledWith ( '__SENTRY_TRACE_LINK__alarm' , expect . any ( Object ) ) ;
456480 } ) ;
457481 } ) ;
458482
0 commit comments