@@ -10,7 +10,7 @@ import type {
1010} from '@cloudflare/workers-types' ;
1111import type { Event } from '@sentry/core' ;
1212import * as SentryCore from '@sentry/core' ;
13- import { beforeEach , describe , expect , onTestFinished , test , vi } from 'vitest' ;
13+ import { beforeEach , describe , expect , test , vi } from 'vitest' ;
1414import { CloudflareClient } from '../src/client' ;
1515import { withSentry } from '../src/handler' ;
1616import { markAsInstrumented } from '../src/instrument' ;
@@ -30,8 +30,29 @@ const MOCK_ENV = {
3030 SENTRY_RELEASE : '1.1.1' ,
3131} ;
3232
33- function addDelayedWaitUntil ( context : ExecutionContext ) {
34- context . waitUntil ( new Promise < void > ( resolve => setTimeout ( ( ) => resolve ( ) ) ) ) ;
33+ function makeWaitUntilAndTask <
34+ M extends ReturnType < typeof vi . fn > ,
35+ T extends M & {
36+ readonly ready : Promise < M > ;
37+ readonly task : { readonly promise : Promise < void > ; readonly resolve : M } ;
38+ } ,
39+ > ( ) : T {
40+ const waitUntil = vi . fn ( ) ;
41+ const { promise, resolve } = Promise . withResolvers ( ) ;
42+ const resolver = vi . fn ( ) . mockImplementation ( resolve ) . mockName ( 'waitUntil.ready' ) ;
43+ Object . defineProperties ( waitUntil , {
44+ ready : {
45+ get : ( ) => Promise . all ( waitUntil . mock . calls . map ( call => call [ 0 ] ) ) . then ( ( ) => resolver ) ,
46+ enumerable : true ,
47+ configurable : true ,
48+ } ,
49+ task : {
50+ value : { promise, resolve : resolver } ,
51+ enumerable : true ,
52+ configurable : true ,
53+ } ,
54+ } ) ;
55+ return waitUntil as T ;
3556}
3657
3758describe ( 'withSentry' , ( ) => {
@@ -135,27 +156,22 @@ describe('withSentry', () => {
135156
136157 test ( 'flush must be called when all waitUntil are done' , async ( ) => {
137158 const flush = vi . spyOn ( SentryCore . Client . prototype , 'flush' ) ;
138- vi . useFakeTimers ( ) ;
139- onTestFinished ( ( ) => {
140- vi . useRealTimers ( ) ;
141- } ) ;
159+ const waitUntil = makeWaitUntilAndTask ( ) ;
160+ process . nextTick ( waitUntil . task . resolve ) ;
142161 const handler = {
143- fetch ( _request , _env , _context ) {
144- addDelayedWaitUntil ( _context ) ;
162+ fetch ( ... args ) {
163+ args [ 2 ] . waitUntil ( waitUntil . task . promise ) ;
145164 return new Response ( 'test' ) ;
146165 } ,
147166 } satisfies ExportedHandler < typeof MOCK_ENV > ;
148167
149168 const wrappedHandler = withSentry ( vi . fn ( ) , handler ) ;
150- const waits : Promise < unknown > [ ] = [ ] ;
151- const waitUntil = vi . fn ( promise => waits . push ( promise ) ) ;
152169 await wrappedHandler . fetch ?.( new Request ( 'https://example.com' ) , MOCK_ENV , {
153170 waitUntil,
154171 } as unknown as ExecutionContext ) ;
155172 expect ( flush ) . not . toBeCalled ( ) ;
156- expect ( waitUntil ) . toBeCalled ( ) ;
157- vi . advanceTimersToNextTimer ( ) . runAllTimers ( ) ;
158- await Promise . all ( waits ) ;
173+ const ready = await waitUntil . ready ;
174+ expect ( flush ) . toHaveBeenCalledAfter ( ready ) ;
159175 expect ( flush ) . toHaveBeenCalledOnce ( ) ;
160176 } ) ;
161177 } ) ;
@@ -375,28 +391,23 @@ describe('withSentry', () => {
375391
376392 test ( 'flush must be called when all waitUntil are done' , async ( ) => {
377393 const flush = vi . spyOn ( SentryCore . Client . prototype , 'flush' ) ;
378- vi . useFakeTimers ( ) ;
379- onTestFinished ( ( ) => {
380- vi . useRealTimers ( ) ;
381- } ) ;
394+ const waitUntil = makeWaitUntilAndTask ( ) ;
395+ process . nextTick ( waitUntil . task . resolve ) ;
382396 const handler = {
383- scheduled ( _controller , _env , _context ) {
384- addDelayedWaitUntil ( _context ) ;
397+ scheduled ( ... args ) {
398+ args [ 2 ] . waitUntil ( waitUntil . task . promise ) ;
385399 return ;
386400 } ,
387401 } satisfies ExportedHandler < typeof MOCK_ENV > ;
388402
389403 const wrappedHandler = withSentry ( vi . fn ( ) , handler ) ;
390- const waits : Promise < unknown > [ ] = [ ] ;
391- const waitUntil = vi . fn ( promise => waits . push ( promise ) ) ;
392404 await wrappedHandler . scheduled ?.( createMockScheduledController ( ) , MOCK_ENV , {
393405 waitUntil,
394406 } as unknown as ExecutionContext ) ;
395407 expect ( flush ) . not . toBeCalled ( ) ;
396- expect ( waitUntil ) . toBeCalled ( ) ;
397- vi . advanceTimersToNextTimer ( ) . runAllTimers ( ) ;
398- await Promise . all ( waits ) ;
408+ await waitUntil . ready ;
399409 expect ( flush ) . toHaveBeenCalledOnce ( ) ;
410+ expect ( flush ) . toHaveBeenCalledAfter ( waitUntil ) ;
400411 } ) ;
401412 } ) ;
402413
@@ -614,28 +625,24 @@ describe('withSentry', () => {
614625
615626 test ( 'flush must be called when all waitUntil are done' , async ( ) => {
616627 const flush = vi . spyOn ( SentryCore . Client . prototype , 'flush' ) ;
617- vi . useFakeTimers ( ) ;
618- onTestFinished ( ( ) => {
619- vi . useRealTimers ( ) ;
620- } ) ;
628+ const waitUntil = makeWaitUntilAndTask ( ) ;
629+
630+ process . nextTick ( waitUntil . task . resolve ) ;
621631 const handler = {
622- email ( _controller , _env , _context ) {
623- addDelayedWaitUntil ( _context ) ;
632+ email ( ... args ) {
633+ args [ 2 ] . waitUntil ( waitUntil . task . promise ) ;
624634 return ;
625635 } ,
626636 } satisfies ExportedHandler < typeof MOCK_ENV > ;
627637
628638 const wrappedHandler = withSentry ( vi . fn ( ) , handler ) ;
629- const waits : Promise < unknown > [ ] = [ ] ;
630- const waitUntil = vi . fn ( promise => waits . push ( promise ) ) ;
631639 await wrappedHandler . email ?.( createMockEmailMessage ( ) , MOCK_ENV , {
632640 waitUntil,
633641 } as unknown as ExecutionContext ) ;
634642 expect ( flush ) . not . toBeCalled ( ) ;
635- expect ( waitUntil ) . toBeCalled ( ) ;
636- vi . advanceTimersToNextTimer ( ) . runAllTimers ( ) ;
637- await Promise . all ( waits ) ;
643+ const ready = await waitUntil . ready ;
638644 expect ( flush ) . toHaveBeenCalledOnce ( ) ;
645+ expect ( flush ) . toHaveBeenCalledAfter ( ready ) ;
639646 } ) ;
640647 } ) ;
641648
@@ -857,27 +864,22 @@ describe('withSentry', () => {
857864
858865 test ( 'flush must be called when all waitUntil are done' , async ( ) => {
859866 const flush = vi . spyOn ( SentryCore . Client . prototype , 'flush' ) ;
860- vi . useFakeTimers ( ) ;
861- onTestFinished ( ( ) => {
862- vi . useRealTimers ( ) ;
863- } ) ;
867+ const waitUntil = makeWaitUntilAndTask ( ) ;
868+ process . nextTick ( waitUntil . task . resolve ) ;
864869 const handler = {
865- queue ( _controller , _env , _context ) {
866- addDelayedWaitUntil ( _context ) ;
870+ queue ( ... args ) {
871+ args [ 2 ] . waitUntil ( waitUntil . task . promise ) ;
867872 return ;
868873 } ,
869874 } satisfies ExportedHandler < typeof MOCK_ENV > ;
870875
871876 const wrappedHandler = withSentry ( vi . fn ( ) , handler ) ;
872- const waits : Promise < unknown > [ ] = [ ] ;
873- const waitUntil = vi . fn ( promise => waits . push ( promise ) ) ;
874877 await wrappedHandler . queue ?.( createMockQueueBatch ( ) , MOCK_ENV , {
875878 waitUntil,
876879 } as unknown as ExecutionContext ) ;
877880 expect ( flush ) . not . toBeCalled ( ) ;
878- expect ( waitUntil ) . toBeCalled ( ) ;
879- vi . advanceTimersToNextTimer ( ) . runAllTimers ( ) ;
880- await Promise . all ( waits ) ;
881+
882+ expect ( flush ) . toHaveBeenCalledAfter ( await waitUntil . ready ) ;
881883 expect ( flush ) . toHaveBeenCalledOnce ( ) ;
882884 } ) ;
883885 } ) ;
@@ -1054,29 +1056,23 @@ describe('withSentry', () => {
10541056
10551057 test ( 'flush must be called when all waitUntil are done' , async ( ) => {
10561058 const flush = vi . spyOn ( SentryCore . Client . prototype , 'flush' ) ;
1057- vi . useFakeTimers ( ) ;
1058- onTestFinished ( ( ) => {
1059- vi . useRealTimers ( ) ;
1060- flush . mockRestore ( ) ;
1061- } ) ;
1059+ const waitUntil = makeWaitUntilAndTask ( ) ;
1060+ process . nextTick ( waitUntil . task . resolve ) ;
10621061 const handler = {
1063- tail ( _controller , _env , _context ) {
1064- addDelayedWaitUntil ( _context ) ;
1062+ tail ( ... args ) {
1063+ args [ 2 ] . waitUntil ( waitUntil . task . promise ) ;
10651064 return ;
10661065 } ,
10671066 } satisfies ExportedHandler < typeof MOCK_ENV > ;
10681067
10691068 const wrappedHandler = withSentry ( vi . fn ( ) , handler ) ;
1070- const waits : Promise < unknown > [ ] = [ ] ;
1071- const waitUntil = vi . fn ( promise => waits . push ( promise ) ) ;
10721069 await wrappedHandler . tail ?.( createMockTailEvent ( ) , MOCK_ENV , {
10731070 waitUntil,
10741071 } as unknown as ExecutionContext ) ;
10751072 expect ( flush ) . not . toBeCalled ( ) ;
1076- expect ( waitUntil ) . toBeCalled ( ) ;
1077- vi . advanceTimersToNextTimer ( ) . runAllTimers ( ) ;
1078- await Promise . all ( waits ) ;
1073+ const ready = await waitUntil . ready ;
10791074 expect ( flush ) . toHaveBeenCalledOnce ( ) ;
1075+ expect ( flush ) . toHaveBeenCalledAfter ( ready ) ;
10801076 } ) ;
10811077 } ) ;
10821078
0 commit comments