1
1
import * as domain from 'domain' ;
2
- import * as SentryNode from '@sentry/node' ;
3
2
import type { Event , Integration } from '@sentry/types' ;
4
3
5
4
import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core' ;
6
- import * as Sentry from '../src' ;
7
5
import { wrapCloudEventFunction , wrapEventFunction , wrapHttpFunction } from '../src/gcpfunction' ;
8
6
import type {
9
7
CloudEventFunction ,
@@ -15,10 +13,65 @@ import type {
15
13
Response ,
16
14
} from '../src/gcpfunction/general' ;
17
15
16
+ import { init } from '../src/gcpfunction' ;
17
+
18
+ const mockStartInactiveSpan = jest . fn ( ( ...spanArgs ) => ( { ...spanArgs } ) ) ;
19
+ const mockStartSpanManual = jest . fn ( ( ...spanArgs ) => ( { ...spanArgs } ) ) ;
20
+ const mockFlush = jest . fn ( ( ...args ) => Promise . resolve ( args ) ) ;
21
+ const mockWithScope = jest . fn ( ) ;
22
+ const mockCaptureMessage = jest . fn ( ) ;
23
+ const mockCaptureException = jest . fn ( ) ;
24
+ const mockInit = jest . fn ( ) ;
25
+
26
+ const mockScope = {
27
+ setTag : jest . fn ( ) ,
28
+ setContext : jest . fn ( ) ,
29
+ addEventProcessor : jest . fn ( ) ,
30
+ setSDKProcessingMetadata : jest . fn ( ) ,
31
+ } ;
32
+
33
+ const mockSpan = {
34
+ end : jest . fn ( ) ,
35
+ } ;
36
+
37
+ jest . mock ( '@sentry/node' , ( ) => {
38
+ const original = jest . requireActual ( '@sentry/node' ) ;
39
+ return {
40
+ ...original ,
41
+ init : ( options : unknown ) => {
42
+ mockInit ( options ) ;
43
+ } ,
44
+ startInactiveSpan : ( ...args : unknown [ ] ) => {
45
+ mockStartInactiveSpan ( ...args ) ;
46
+ return mockSpan ;
47
+ } ,
48
+ startSpanManual : ( ...args : unknown [ ] ) => {
49
+ mockStartSpanManual ( ...args ) ;
50
+ mockSpan . end ( ) ;
51
+ return original . startSpanManual ( ...args ) ;
52
+ } ,
53
+ getCurrentScope : ( ) => {
54
+ return mockScope ;
55
+ } ,
56
+ flush : ( ...args : unknown [ ] ) => {
57
+ return mockFlush ( ...args ) ;
58
+ } ,
59
+ withScope : ( fn : ( scope : unknown ) => void ) => {
60
+ mockWithScope ( fn ) ;
61
+ fn ( mockScope ) ;
62
+ } ,
63
+ captureMessage : ( ...args : unknown [ ] ) => {
64
+ mockCaptureMessage ( ...args ) ;
65
+ } ,
66
+ captureException : ( ...args : unknown [ ] ) => {
67
+ mockCaptureException ( ...args ) ;
68
+ } ,
69
+ } ;
70
+ } ) ;
71
+
18
72
describe ( 'GCPFunction' , ( ) => {
19
- afterEach ( ( ) => {
20
- // @ts -expect-error see "Why @ts-expect-error" note
21
- SentryNode . resetMocks ( ) ;
73
+ beforeEach ( ( ) => {
74
+ jest . clearAllMocks ( ) ;
22
75
} ) ;
23
76
24
77
async function handleHttp ( fn : HttpFunction , trace_headers : { [ key : string ] : string } | null = null ) : Promise < void > {
@@ -89,7 +142,7 @@ describe('GCPFunction', () => {
89
142
const wrappedHandler = wrapHttpFunction ( handler , { flushTimeout : 1337 } ) ;
90
143
91
144
await handleHttp ( wrappedHandler ) ;
92
- expect ( SentryNode . flush ) . toBeCalledWith ( 1337 ) ;
145
+ expect ( mockFlush ) . toBeCalledWith ( 1337 ) ;
93
146
} ) ;
94
147
} ) ;
95
148
@@ -112,12 +165,9 @@ describe('GCPFunction', () => {
112
165
metadata : { } ,
113
166
} ;
114
167
115
- expect ( SentryNode . startSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
116
- // @ts -expect-error see "Why @ts-expect-error" note
117
- expect ( SentryNode . fakeSpan . setHttpStatus ) . toBeCalledWith ( 200 ) ;
118
- // @ts -expect-error see "Why @ts-expect-error" note
119
- expect ( SentryNode . fakeSpan . end ) . toBeCalled ( ) ;
120
- expect ( SentryNode . flush ) . toBeCalledWith ( 2000 ) ;
168
+ expect ( mockStartSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
169
+ expect ( mockSpan . end ) . toBeCalled ( ) ;
170
+ expect ( mockFlush ) . toBeCalledWith ( 2000 ) ;
121
171
} ) ;
122
172
123
173
test ( 'incoming trace headers are correctly parsed and used' , async ( ) => {
@@ -149,7 +199,7 @@ describe('GCPFunction', () => {
149
199
} ,
150
200
} ;
151
201
152
- expect ( SentryNode . startSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
202
+ expect ( mockStartSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
153
203
} ) ;
154
204
155
205
test ( 'capture error' , async ( ) => {
@@ -178,11 +228,10 @@ describe('GCPFunction', () => {
178
228
metadata : { dynamicSamplingContext : { } } ,
179
229
} ;
180
230
181
- expect ( SentryNode . startSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
182
- expect ( SentryNode . captureException ) . toBeCalledWith ( error , expect . any ( Function ) ) ;
183
- // @ts -expect-error see "Why @ts-expect-error" note
184
- expect ( SentryNode . fakeSpan . end ) . toBeCalled ( ) ;
185
- expect ( SentryNode . flush ) . toBeCalled ( ) ;
231
+ expect ( mockStartSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
232
+ expect ( mockCaptureException ) . toBeCalledWith ( error , expect . any ( Function ) ) ;
233
+ expect ( mockSpan . end ) . toBeCalled ( ) ;
234
+ expect ( mockFlush ) . toBeCalled ( ) ;
186
235
} ) ;
187
236
188
237
test ( 'should not throw when flush rejects' , async ( ) => {
@@ -203,7 +252,7 @@ describe('GCPFunction', () => {
203
252
const mockEnd = jest . fn ( ) ;
204
253
const response = { end : mockEnd } as unknown as Response ;
205
254
206
- jest . spyOn ( Sentry , 'flush' ) . mockImplementationOnce ( async ( ) => {
255
+ mockFlush . mockImplementationOnce ( async ( ) => {
207
256
throw new Error ( ) ;
208
257
} ) ;
209
258
@@ -216,7 +265,7 @@ describe('GCPFunction', () => {
216
265
// integration is included in the defaults and the necessary data is stored in `sdkProcessingMetadata`. The
217
266
// integration's tests cover testing that it uses that data correctly.
218
267
test ( 'wrapHttpFunction request data prereqs' , async ( ) => {
219
- Sentry . GCPFunction . init ( { } ) ;
268
+ init ( { } ) ;
220
269
221
270
const handler : HttpFunction = ( _req , res ) => {
222
271
res . end ( ) ;
@@ -225,13 +274,12 @@ describe('GCPFunction', () => {
225
274
226
275
await handleHttp ( wrappedHandler ) ;
227
276
228
- const initOptions = ( SentryNode . init as unknown as jest . SpyInstance ) . mock . calls [ 0 ] ;
277
+ const initOptions = ( mockInit as unknown as jest . SpyInstance ) . mock . calls [ 0 ] ;
229
278
const defaultIntegrations = initOptions [ 0 ] . defaultIntegrations . map ( ( i : Integration ) => i . name ) ;
230
279
231
280
expect ( defaultIntegrations ) . toContain ( 'RequestData' ) ;
232
281
233
- // @ts -expect-error see "Why @ts-expect-error" note
234
- expect ( SentryNode . fakeScope . setSDKProcessingMetadata ) . toHaveBeenCalledWith ( {
282
+ expect ( mockScope . setSDKProcessingMetadata ) . toHaveBeenCalledWith ( {
235
283
request : {
236
284
method : 'POST' ,
237
285
url : '/path?q=query' ,
@@ -259,10 +307,9 @@ describe('GCPFunction', () => {
259
307
} ,
260
308
} ;
261
309
262
- expect ( SentryNode . startSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
263
- // @ts -expect-error see "Why @ts-expect-error" note
264
- expect ( SentryNode . fakeSpan . end ) . toBeCalled ( ) ;
265
- expect ( SentryNode . flush ) . toBeCalledWith ( 2000 ) ;
310
+ expect ( mockStartSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
311
+ expect ( mockSpan . end ) . toBeCalled ( ) ;
312
+ expect ( mockFlush ) . toBeCalledWith ( 2000 ) ;
266
313
} ) ;
267
314
268
315
test ( 'capture error' , async ( ) => {
@@ -282,11 +329,10 @@ describe('GCPFunction', () => {
282
329
} ,
283
330
} ;
284
331
285
- expect ( SentryNode . startSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
286
- expect ( SentryNode . captureException ) . toBeCalledWith ( error , expect . any ( Function ) ) ;
287
- // @ts -expect-error see "Why @ts-expect-error" note
288
- expect ( SentryNode . fakeSpan . end ) . toBeCalled ( ) ;
289
- expect ( SentryNode . flush ) . toBeCalled ( ) ;
332
+ expect ( mockStartSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
333
+ expect ( mockCaptureException ) . toBeCalledWith ( error , expect . any ( Function ) ) ;
334
+ expect ( mockSpan . end ) . toBeCalled ( ) ;
335
+ expect ( mockFlush ) . toBeCalled ( ) ;
290
336
} ) ;
291
337
} ) ;
292
338
@@ -310,10 +356,9 @@ describe('GCPFunction', () => {
310
356
} ,
311
357
} ;
312
358
313
- expect ( SentryNode . startSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
314
- // @ts -expect-error see "Why @ts-expect-error" note
315
- expect ( SentryNode . fakeSpan . end ) . toBeCalled ( ) ;
316
- expect ( SentryNode . flush ) . toBeCalledWith ( 2000 ) ;
359
+ expect ( mockStartSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
360
+ expect ( mockSpan . end ) . toBeCalled ( ) ;
361
+ expect ( mockFlush ) . toBeCalledWith ( 2000 ) ;
317
362
} ) ;
318
363
319
364
test ( 'capture error' , async ( ) => {
@@ -337,11 +382,10 @@ describe('GCPFunction', () => {
337
382
} ,
338
383
} ;
339
384
340
- expect ( SentryNode . startSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
341
- expect ( SentryNode . captureException ) . toBeCalledWith ( error , expect . any ( Function ) ) ;
342
- // @ts -expect-error see "Why @ts-expect-error" note
343
- expect ( SentryNode . fakeSpan . end ) . toBeCalled ( ) ;
344
- expect ( SentryNode . flush ) . toBeCalled ( ) ;
385
+ expect ( mockStartSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
386
+ expect ( mockCaptureException ) . toBeCalledWith ( error , expect . any ( Function ) ) ;
387
+ expect ( mockSpan . end ) . toBeCalled ( ) ;
388
+ expect ( mockFlush ) . toBeCalled ( ) ;
345
389
} ) ;
346
390
} ) ;
347
391
@@ -362,10 +406,9 @@ describe('GCPFunction', () => {
362
406
} ,
363
407
} ;
364
408
365
- expect ( SentryNode . startSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
366
- // @ts -expect-error see "Why @ts-expect-error" note
367
- expect ( SentryNode . fakeSpan . end ) . toBeCalled ( ) ;
368
- expect ( SentryNode . flush ) . toBeCalledWith ( 2000 ) ;
409
+ expect ( mockStartSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
410
+ expect ( mockSpan . end ) . toBeCalled ( ) ;
411
+ expect ( mockFlush ) . toBeCalledWith ( 2000 ) ;
369
412
} ) ;
370
413
371
414
test ( 'capture error' , async ( ) => {
@@ -385,11 +428,10 @@ describe('GCPFunction', () => {
385
428
} ,
386
429
} ;
387
430
388
- expect ( SentryNode . startSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
389
- expect ( SentryNode . captureException ) . toBeCalledWith ( error , expect . any ( Function ) ) ;
390
- // @ts -expect-error see "Why @ts-expect-error" note
391
- expect ( SentryNode . fakeSpan . end ) . toBeCalled ( ) ;
392
- expect ( SentryNode . flush ) . toBeCalled ( ) ;
431
+ expect ( mockStartSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
432
+ expect ( mockCaptureException ) . toBeCalledWith ( error , expect . any ( Function ) ) ;
433
+ expect ( mockSpan . end ) . toBeCalled ( ) ;
434
+ expect ( mockFlush ) . toBeCalled ( ) ;
393
435
} ) ;
394
436
395
437
test ( 'capture exception' , async ( ) => {
@@ -409,8 +451,8 @@ describe('GCPFunction', () => {
409
451
} ,
410
452
} ;
411
453
412
- expect ( SentryNode . startSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
413
- expect ( SentryNode . captureException ) . toBeCalledWith ( error , expect . any ( Function ) ) ;
454
+ expect ( mockStartSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
455
+ expect ( mockCaptureException ) . toBeCalledWith ( error , expect . any ( Function ) ) ;
414
456
} ) ;
415
457
} ) ;
416
458
@@ -422,10 +464,9 @@ describe('GCPFunction', () => {
422
464
const wrappedHandler = wrapEventFunction ( handler ) ;
423
465
await expect ( handleEvent ( wrappedHandler ) ) . rejects . toThrowError ( error ) ;
424
466
425
- expect ( SentryNode . captureException ) . toBeCalledWith ( error , expect . any ( Function ) ) ;
467
+ expect ( mockCaptureException ) . toBeCalledWith ( error , expect . any ( Function ) ) ;
426
468
427
- // @ts -expect-error just mocking around...
428
- const scopeFunction = SentryNode . captureException . mock . calls [ 0 ] [ 1 ] ;
469
+ const scopeFunction = mockCaptureException . mock . calls [ 0 ] [ 1 ] ;
429
470
const event : Event = { exception : { values : [ { } ] } } ;
430
471
let evtProcessor : ( ( e : Event ) => Event ) | undefined = undefined ;
431
472
scopeFunction ( { addEventProcessor : jest . fn ( ) . mockImplementation ( proc => ( evtProcessor = proc ) ) } ) ;
@@ -442,8 +483,7 @@ describe('GCPFunction', () => {
442
483
const handler : EventFunction = ( _data , _context ) => 42 ;
443
484
const wrappedHandler = wrapEventFunction ( handler ) ;
444
485
await handleEvent ( wrappedHandler ) ;
445
- // @ts -expect-error see "Why @ts-expect-error" note
446
- expect ( SentryNode . fakeScope . setContext ) . toBeCalledWith ( 'gcp.function.context' , {
486
+ expect ( mockScope . setContext ) . toBeCalledWith ( 'gcp.function.context' , {
447
487
eventType : 'event.type' ,
448
488
resource : 'some.resource' ,
449
489
} ) ;
@@ -466,10 +506,9 @@ describe('GCPFunction', () => {
466
506
} ,
467
507
} ;
468
508
469
- expect ( SentryNode . startSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
470
- // @ts -expect-error see "Why @ts-expect-error" note
471
- expect ( SentryNode . fakeSpan . end ) . toBeCalled ( ) ;
472
- expect ( SentryNode . flush ) . toBeCalledWith ( 2000 ) ;
509
+ expect ( mockStartSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
510
+ expect ( mockSpan . end ) . toBeCalled ( ) ;
511
+ expect ( mockFlush ) . toBeCalledWith ( 2000 ) ;
473
512
} ) ;
474
513
475
514
test ( 'capture error' , async ( ) => {
@@ -489,11 +528,10 @@ describe('GCPFunction', () => {
489
528
} ,
490
529
} ;
491
530
492
- expect ( SentryNode . startSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
493
- expect ( SentryNode . captureException ) . toBeCalledWith ( error , expect . any ( Function ) ) ;
494
- // @ts -expect-error see "Why @ts-expect-error" note
495
- expect ( SentryNode . fakeSpan . end ) . toBeCalled ( ) ;
496
- expect ( SentryNode . flush ) . toBeCalled ( ) ;
531
+ expect ( mockStartSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
532
+ expect ( mockCaptureException ) . toBeCalledWith ( error , expect . any ( Function ) ) ;
533
+ expect ( mockSpan . end ) . toBeCalled ( ) ;
534
+ expect ( mockFlush ) . toBeCalled ( ) ;
497
535
} ) ;
498
536
} ) ;
499
537
@@ -514,10 +552,9 @@ describe('GCPFunction', () => {
514
552
} ,
515
553
} ;
516
554
517
- expect ( SentryNode . startSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
518
- // @ts -expect-error see "Why @ts-expect-error" note
519
- expect ( SentryNode . fakeSpan . end ) . toBeCalled ( ) ;
520
- expect ( SentryNode . flush ) . toBeCalledWith ( 2000 ) ;
555
+ expect ( mockStartSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
556
+ expect ( mockSpan . end ) . toBeCalled ( ) ;
557
+ expect ( mockFlush ) . toBeCalledWith ( 2000 ) ;
521
558
} ) ;
522
559
523
560
test ( 'capture error' , async ( ) => {
@@ -537,11 +574,10 @@ describe('GCPFunction', () => {
537
574
} ,
538
575
} ;
539
576
540
- expect ( SentryNode . startSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
541
- expect ( SentryNode . captureException ) . toBeCalledWith ( error , expect . any ( Function ) ) ;
542
- // @ts -expect-error see "Why @ts-expect-error" note
543
- expect ( SentryNode . fakeSpan . end ) . toBeCalled ( ) ;
544
- expect ( SentryNode . flush ) . toBeCalled ( ) ;
577
+ expect ( mockStartSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
578
+ expect ( mockCaptureException ) . toBeCalledWith ( error , expect . any ( Function ) ) ;
579
+ expect ( mockSpan . end ) . toBeCalled ( ) ;
580
+ expect ( mockFlush ) . toBeCalled ( ) ;
545
581
} ) ;
546
582
547
583
test ( 'capture exception' , async ( ) => {
@@ -561,24 +597,23 @@ describe('GCPFunction', () => {
561
597
} ,
562
598
} ;
563
599
564
- expect ( SentryNode . startSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
565
- expect ( SentryNode . captureException ) . toBeCalledWith ( error , expect . any ( Function ) ) ;
600
+ expect ( mockStartSpanManual ) . toBeCalledWith ( fakeTransactionContext , expect . any ( Function ) ) ;
601
+ expect ( mockCaptureException ) . toBeCalledWith ( error , expect . any ( Function ) ) ;
566
602
} ) ;
567
603
} ) ;
568
604
569
605
test ( 'wrapCloudEventFunction scope data' , async ( ) => {
570
606
const handler : CloudEventFunction = _context => 42 ;
571
607
const wrappedHandler = wrapCloudEventFunction ( handler ) ;
572
608
await handleCloudEvent ( wrappedHandler ) ;
573
- // @ts -expect-error see "Why @ts-expect-error" note
574
- expect ( SentryNode . fakeScope . setContext ) . toBeCalledWith ( 'gcp.function.context' , { type : 'event.type' } ) ;
609
+ expect ( mockScope . setContext ) . toBeCalledWith ( 'gcp.function.context' , { type : 'event.type' } ) ;
575
610
} ) ;
576
611
577
612
describe ( 'init()' , ( ) => {
578
613
test ( 'calls Sentry.init with correct sdk info metadata' , ( ) => {
579
- Sentry . GCPFunction . init ( { } ) ;
614
+ init ( { } ) ;
580
615
581
- expect ( Sentry . init ) . toBeCalledWith (
616
+ expect ( mockInit ) . toBeCalledWith (
582
617
expect . objectContaining ( {
583
618
_metadata : {
584
619
sdk : {
@@ -587,10 +622,10 @@ describe('GCPFunction', () => {
587
622
packages : [
588
623
{
589
624
name : 'npm:@sentry/serverless' ,
590
- version : '6.6.6' ,
625
+ version : expect . any ( String ) ,
591
626
} ,
592
627
] ,
593
- version : '6.6.6' ,
628
+ version : expect . any ( String ) ,
594
629
} ,
595
630
} ,
596
631
} ) ,
0 commit comments