1- import { describe , expect , it , vi } from 'vitest' ;
1+ import { beforeEach , describe , expect , it , vi } from 'vitest' ;
2+ import type { HandlerDataFetch } from '../../src' ;
23import { _addTracingHeadersToFetchRequest , instrumentFetchRequest } from '../../src/fetch' ;
34import type { Span } from '../../src/types-hoist/span' ;
45
5- const { DEFAULT_SENTRY_TRACE , DEFAULT_BAGGAGE } = vi . hoisted ( ( ) => ( {
6+ const { DEFAULT_SENTRY_TRACE , DEFAULT_BAGGAGE , hasSpansEnabled } = vi . hoisted ( ( ) => ( {
67 DEFAULT_SENTRY_TRACE : 'defaultTraceId-defaultSpanId-1' ,
78 DEFAULT_BAGGAGE : 'sentry-trace_id=defaultTraceId,sentry-sampled=true,sentry-sample_rate=0.5,sentry-sample_rand=0.232' ,
9+ hasSpansEnabled : vi . fn ( ) ,
810} ) ) ;
911
1012const CUSTOM_SENTRY_TRACE = '123-abc-1' ;
@@ -23,7 +25,18 @@ vi.mock('../../src/utils/traceData', () => {
2325 } ;
2426} ) ;
2527
28+ vi . mock ( '../../src/utils/hasSpansEnabled' , ( ) => {
29+ return {
30+ hasSpansEnabled,
31+ } ;
32+ } ) ;
33+
2634describe ( '_addTracingHeadersToFetchRequest' , ( ) => {
35+ beforeEach ( ( ) => {
36+ vi . clearAllMocks ( ) ;
37+ hasSpansEnabled . mockReturnValue ( false ) ;
38+ } ) ;
39+
2740 describe ( 'when request is a string' , ( ) => {
2841 describe ( 'and no request headers are set' , ( ) => {
2942 it . each ( [
@@ -412,6 +425,53 @@ describe('_addTracingHeadersToFetchRequest', () => {
412425} ) ;
413426
414427describe ( 'instrumentFetchRequest' , ( ) => {
428+ describe ( 'span cleanup' , ( ) => {
429+ it . each ( [
430+ { name : 'non-recording' , hasTracingEnabled : false } ,
431+ { name : 'recording' , hasTracingEnabled : true } ,
432+ ] ) ( 'cleans up $name spans from the spans record when fetch completes' , ( { hasTracingEnabled } ) => {
433+ hasSpansEnabled . mockReturnValue ( hasTracingEnabled ) ;
434+
435+ const spans : Record < string , Span > = { } ;
436+
437+ const handlerData = {
438+ fetchData : { url : '/api/test' , method : 'GET' } ,
439+ args : [ '/api/test' ] as unknown [ ] ,
440+ startTimestamp : Date . now ( ) ,
441+ } ;
442+
443+ instrumentFetchRequest (
444+ handlerData ,
445+ ( ) => true ,
446+ ( ) => false ,
447+ spans ,
448+ { spanOrigin : 'auto.http.fetch' } ,
449+ ) ;
450+
451+ // @ts -expect-error -- we know it exists
452+ const spanId = handlerData . fetchData . __span ;
453+
454+ expect ( spanId ) . toBeDefined ( ) ;
455+ expect ( spans [ spanId ] ) . toBeDefined ( ) ;
456+
457+ const completedHandlerData : HandlerDataFetch = {
458+ ...handlerData ,
459+ endTimestamp : Date . now ( ) + 100 ,
460+ response : { status : 200 , headers : new Headers ( ) } as Response ,
461+ } ;
462+
463+ instrumentFetchRequest (
464+ completedHandlerData ,
465+ ( ) => true ,
466+ ( ) => false ,
467+ spans ,
468+ { spanOrigin : 'auto.http.fetch' } ,
469+ ) ;
470+
471+ expect ( spans [ spanId ] ) . toBeUndefined ( ) ;
472+ } ) ;
473+ } ) ;
474+
415475 describe ( 'options object mutation' , ( ) => {
416476 it ( 'does not mutate the original options object' , ( ) => {
417477 const originalOptions = { method : 'POST' , body : JSON . stringify ( { data : 'test' } ) } ;
0 commit comments