@@ -2,174 +2,15 @@ import * as sentryCore from '@sentry/core';
2
2
import * as sentryHub from '@sentry/hub' ;
3
3
import { Hub } from '@sentry/hub' ;
4
4
import { Transaction } from '@sentry/tracing' ;
5
- import { Baggage } from '@sentry/types' ;
5
+ import { Baggage , Event } from '@sentry/types' ;
6
6
import { isBaggageEmpty , isBaggageMutable , SentryError } from '@sentry/utils' ;
7
7
import * as http from 'http' ;
8
- import * as net from 'net' ;
9
8
10
- import { Event , Request , User } from '../src' ;
11
9
import { NodeClient } from '../src/client' ;
12
- import {
13
- errorHandler ,
14
- ExpressRequest ,
15
- extractRequestData ,
16
- parseRequest ,
17
- requestHandler ,
18
- tracingHandler ,
19
- } from '../src/handlers' ;
10
+ import { errorHandler , requestHandler , tracingHandler } from '../src/handlers' ;
20
11
import * as SDK from '../src/sdk' ;
21
12
import { getDefaultNodeClientOptions } from './helper/node-client-options' ;
22
13
23
- describe ( 'parseRequest' , ( ) => {
24
- let mockReq : { [ key : string ] : any } ;
25
-
26
- beforeEach ( ( ) => {
27
- mockReq = {
28
- baseUrl : '/routerMountPath' ,
29
- body : 'foo' ,
30
- cookies : { test : 'test' } ,
31
- headers : {
32
- host : 'mattrobenolt.com' ,
33
- } ,
34
- method : 'POST' ,
35
- originalUrl : '/routerMountPath/subpath/specificValue?querystringKey=querystringValue' ,
36
- path : '/subpath/specificValue' ,
37
- query : {
38
- querystringKey : 'querystringValue' ,
39
- } ,
40
- route : {
41
- path : '/subpath/:parameterName' ,
42
- stack : [
43
- {
44
- name : 'parameterNameRouteHandler' ,
45
- } ,
46
- ] ,
47
- } ,
48
- url : '/subpath/specificValue?querystringKey=querystringValue' ,
49
- user : {
50
- custom_property : 'foo' ,
51
-
52
- id : 123 ,
53
- username : 'tobias' ,
54
- } ,
55
- } ;
56
- } ) ;
57
-
58
- describe ( 'parseRequest.user properties' , ( ) => {
59
- const DEFAULT_USER_KEYS = [ 'id' , 'username' , 'email' ] ;
60
- const CUSTOM_USER_KEYS = [ 'custom_property' ] ;
61
-
62
- test ( 'parseRequest.user only contains the default properties from the user' , ( ) => {
63
- const parsedRequest : Event = parseRequest ( { } , mockReq as ExpressRequest ) ;
64
- expect ( Object . keys ( parsedRequest . user as User ) ) . toEqual ( DEFAULT_USER_KEYS ) ;
65
- } ) ;
66
-
67
- test ( 'parseRequest.user only contains the custom properties specified in the options.user array' , ( ) => {
68
- const parsedRequest : Event = parseRequest ( { } , mockReq as ExpressRequest , {
69
- user : CUSTOM_USER_KEYS ,
70
- } ) ;
71
- expect ( Object . keys ( parsedRequest . user as User ) ) . toEqual ( CUSTOM_USER_KEYS ) ;
72
- } ) ;
73
-
74
- test ( 'parseRequest.user doesnt blow up when someone passes non-object value' , ( ) => {
75
- const parsedRequest : Event = parseRequest (
76
- { } ,
77
- {
78
- ...mockReq ,
79
- // @ts -ignore user is not assignable to object
80
- user : 'wat' ,
81
- } ,
82
- ) ;
83
- expect ( Object . keys ( parsedRequest . user as User ) ) . toEqual ( [ ] ) ;
84
- } ) ;
85
- } ) ;
86
-
87
- describe ( 'parseRequest.ip property' , ( ) => {
88
- test ( 'can be extracted from req.ip' , ( ) => {
89
- const parsedRequest : Event = parseRequest (
90
- { } ,
91
- {
92
- ...mockReq ,
93
- ip : '123' ,
94
- } as ExpressRequest ,
95
- {
96
- ip : true ,
97
- } ,
98
- ) ;
99
- expect ( parsedRequest . user ! . ip_address ) . toEqual ( '123' ) ;
100
- } ) ;
101
-
102
- test ( 'can extract from req.connection.remoteAddress' , ( ) => {
103
- const parsedRequest : Event = parseRequest (
104
- { } ,
105
- {
106
- ...mockReq ,
107
- connection : {
108
- remoteAddress : '321' ,
109
- } as net . Socket ,
110
- } as ExpressRequest ,
111
- {
112
- ip : true ,
113
- } ,
114
- ) ;
115
- expect ( parsedRequest . user ! . ip_address ) . toEqual ( '321' ) ;
116
- } ) ;
117
- } ) ;
118
-
119
- describe ( 'parseRequest.request properties' , ( ) => {
120
- test ( 'parseRequest.request only contains the default set of properties from the request' , ( ) => {
121
- const DEFAULT_REQUEST_PROPERTIES = [ 'cookies' , 'data' , 'headers' , 'method' , 'query_string' , 'url' ] ;
122
- const parsedRequest : Event = parseRequest ( { } , mockReq as ExpressRequest ) ;
123
- expect ( Object . keys ( parsedRequest . request as Request ) ) . toEqual ( DEFAULT_REQUEST_PROPERTIES ) ;
124
- } ) ;
125
-
126
- test ( 'parseRequest.request only contains the specified properties in the options.request array' , ( ) => {
127
- const INCLUDED_PROPERTIES = [ 'data' , 'headers' , 'query_string' , 'url' ] ;
128
- const parsedRequest : Event = parseRequest ( { } , mockReq as ExpressRequest , {
129
- request : INCLUDED_PROPERTIES ,
130
- } ) ;
131
- expect ( Object . keys ( parsedRequest . request as Request ) ) . toEqual ( INCLUDED_PROPERTIES ) ;
132
- } ) ;
133
-
134
- test ( 'parseRequest.request skips `body` property for GET and HEAD requests' , ( ) => {
135
- expect ( parseRequest ( { } , mockReq as ExpressRequest , { } ) . request ) . toHaveProperty ( 'data' ) ;
136
- expect ( parseRequest ( { } , { ...mockReq , method : 'GET' } as ExpressRequest , { } ) . request ) . not . toHaveProperty ( 'data' ) ;
137
- expect ( parseRequest ( { } , { ...mockReq , method : 'HEAD' } as ExpressRequest , { } ) . request ) . not . toHaveProperty ( 'data' ) ;
138
- } ) ;
139
- } ) ;
140
-
141
- describe ( 'parseRequest.transaction property' , ( ) => {
142
- test ( 'extracts method and full route path by default`' , ( ) => {
143
- const parsedRequest : Event = parseRequest ( { } , mockReq as ExpressRequest ) ;
144
- expect ( parsedRequest . transaction ) . toEqual ( 'POST /routerMountPath/subpath/:parameterName' ) ;
145
- } ) ;
146
-
147
- test ( 'extracts method and full path by default when mountpoint is `/`' , ( ) => {
148
- mockReq . originalUrl = mockReq . originalUrl . replace ( '/routerMountpath' , '' ) ;
149
- mockReq . baseUrl = '' ;
150
- const parsedRequest : Event = parseRequest ( { } , mockReq as ExpressRequest ) ;
151
- // "sub"path is the full path here, because there's no router mount path
152
- expect ( parsedRequest . transaction ) . toEqual ( 'POST /subpath/:parameterName' ) ;
153
- } ) ;
154
-
155
- test ( 'fallback to method and `originalUrl` if route is missing' , ( ) => {
156
- delete mockReq . route ;
157
- const parsedRequest : Event = parseRequest ( { } , mockReq as ExpressRequest ) ;
158
- expect ( parsedRequest . transaction ) . toEqual ( 'POST /routerMountPath/subpath/specificValue' ) ;
159
- } ) ;
160
-
161
- test ( 'can extract path only instead if configured' , ( ) => {
162
- const parsedRequest : Event = parseRequest ( { } , mockReq as ExpressRequest , { transaction : 'path' } ) ;
163
- expect ( parsedRequest . transaction ) . toEqual ( '/routerMountPath/subpath/:parameterName' ) ;
164
- } ) ;
165
-
166
- test ( 'can extract handler name instead if configured' , ( ) => {
167
- const parsedRequest : Event = parseRequest ( { } , mockReq as ExpressRequest , { transaction : 'handler' } ) ;
168
- expect ( parsedRequest . transaction ) . toEqual ( 'parameterNameRouteHandler' ) ;
169
- } ) ;
170
- } ) ;
171
- } ) ;
172
-
173
14
describe ( 'requestHandler' , ( ) => {
174
15
const headers = { ears : 'furry' , nose : 'wet' , tongue : 'spotted' , cookie : 'favorite=zukes' } ;
175
16
const method = 'wagging' ;
@@ -270,7 +111,7 @@ describe('requestHandler', () => {
270
111
} ) ;
271
112
} ) ;
272
113
273
- it ( 'patches `res.end` when `flushTimeout` is specified' , ( ) => {
114
+ it ( 'patches `res.end` when `flushTimeout` is specified' , done => {
274
115
const flush = jest . spyOn ( SDK , 'flush' ) . mockResolvedValue ( true ) ;
275
116
276
117
const sentryRequestMiddleware = requestHandler ( { flushTimeout : 1337 } ) ;
@@ -280,10 +121,11 @@ describe('requestHandler', () => {
280
121
setImmediate ( ( ) => {
281
122
expect ( flush ) . toHaveBeenCalledWith ( 1337 ) ;
282
123
expect ( res . finished ) . toBe ( true ) ;
124
+ done ( ) ;
283
125
} ) ;
284
126
} ) ;
285
127
286
- it ( 'prevents errors thrown during `flush` from breaking the response' , async ( ) => {
128
+ it ( 'prevents errors thrown during `flush` from breaking the response' , done => {
287
129
jest . spyOn ( SDK , 'flush' ) . mockRejectedValue ( new SentryError ( 'HTTP Error (429)' ) ) ;
288
130
289
131
const sentryRequestMiddleware = requestHandler ( { flushTimeout : 1337 } ) ;
@@ -292,6 +134,7 @@ describe('requestHandler', () => {
292
134
293
135
setImmediate ( ( ) => {
294
136
expect ( res . finished ) . toBe ( true ) ;
137
+ done ( ) ;
295
138
} ) ;
296
139
} ) ;
297
140
} ) ;
@@ -537,181 +380,6 @@ describe('tracingHandler', () => {
537
380
} ) ;
538
381
} ) ;
539
382
540
- describe ( 'extractRequestData()' , ( ) => {
541
- describe ( 'default behaviour' , ( ) => {
542
- test ( 'node' , ( ) => {
543
- expect (
544
- extractRequestData ( {
545
- headers : { host : 'example.com' } ,
546
- method : 'GET' ,
547
- secure : true ,
548
- originalUrl : '/' ,
549
- } ) ,
550
- ) . toEqual ( {
551
- cookies : { } ,
552
- headers : {
553
- host : 'example.com' ,
554
- } ,
555
- method : 'GET' ,
556
- query_string : null ,
557
- url : 'https://example.com/' ,
558
- } ) ;
559
- } ) ;
560
-
561
- test ( 'degrades gracefully without request data' , ( ) => {
562
- expect ( extractRequestData ( { } ) ) . toEqual ( {
563
- cookies : { } ,
564
- headers : { } ,
565
- method : undefined ,
566
- query_string : null ,
567
- url : 'http://<no host>' ,
568
- } ) ;
569
- } ) ;
570
- } ) ;
571
-
572
- describe ( 'cookies' , ( ) => {
573
- it ( 'uses `req.cookies` if available' , ( ) => {
574
- expect (
575
- extractRequestData (
576
- {
577
- cookies : { foo : 'bar' } ,
578
- } ,
579
- [ 'cookies' ] ,
580
- ) ,
581
- ) . toEqual ( {
582
- cookies : { foo : 'bar' } ,
583
- } ) ;
584
- } ) ;
585
-
586
- it ( 'parses the cookie header' , ( ) => {
587
- expect (
588
- extractRequestData (
589
- {
590
- headers : {
591
- cookie : 'foo=bar;' ,
592
- } ,
593
- } ,
594
- [ 'cookies' ] ,
595
- ) ,
596
- ) . toEqual ( {
597
- cookies : { foo : 'bar' } ,
598
- } ) ;
599
- } ) ;
600
-
601
- it ( 'falls back if no cookies are defined' , ( ) => {
602
- expect ( extractRequestData ( { } , [ 'cookies' ] ) ) . toEqual ( {
603
- cookies : { } ,
604
- } ) ;
605
- } ) ;
606
- } ) ;
607
-
608
- describe ( 'data' , ( ) => {
609
- it ( 'includes data from `req.body` if available' , ( ) => {
610
- expect (
611
- extractRequestData (
612
- {
613
- method : 'POST' ,
614
- headers : { 'Content-Type' : 'application/x-www-form-urlencoded' } ,
615
- body : 'foo=bar' ,
616
- } ,
617
- [ 'data' ] ,
618
- ) ,
619
- ) . toEqual ( {
620
- data : 'foo=bar' ,
621
- } ) ;
622
- } ) ;
623
-
624
- it ( 'encodes JSON body contents back to a string' , ( ) => {
625
- expect (
626
- extractRequestData (
627
- {
628
- method : 'POST' ,
629
- headers : { 'Content-Type' : 'application/json' } ,
630
- body : { foo : 'bar' } ,
631
- } ,
632
- [ 'data' ] ,
633
- ) ,
634
- ) . toEqual ( {
635
- data : '{"foo":"bar"}' ,
636
- } ) ;
637
- } ) ;
638
- } ) ;
639
-
640
- describe ( 'query_string' , ( ) => {
641
- it ( 'parses the query parms from the url' , ( ) => {
642
- expect (
643
- extractRequestData (
644
- {
645
- headers : { host : 'example.com' } ,
646
- secure : true ,
647
- originalUrl : '/?foo=bar' ,
648
- } ,
649
- [ 'query_string' ] ,
650
- ) ,
651
- ) . toEqual ( {
652
- query_string : 'foo=bar' ,
653
- } ) ;
654
- } ) ;
655
-
656
- it ( 'gracefully degrades if url cannot be determined' , ( ) => {
657
- expect ( extractRequestData ( { } , [ 'query_string' ] ) ) . toEqual ( {
658
- query_string : null ,
659
- } ) ;
660
- } ) ;
661
- } ) ;
662
-
663
- describe ( 'url' , ( ) => {
664
- test ( 'express/koa' , ( ) => {
665
- expect (
666
- extractRequestData (
667
- {
668
- host : 'example.com' ,
669
- protocol : 'https' ,
670
- url : '/' ,
671
- } ,
672
- [ 'url' ] ,
673
- ) ,
674
- ) . toEqual ( {
675
- url : 'https://example.com/' ,
676
- } ) ;
677
- } ) ;
678
-
679
- test ( 'node' , ( ) => {
680
- expect (
681
- extractRequestData (
682
- {
683
- headers : { host : 'example.com' } ,
684
- secure : true ,
685
- originalUrl : '/' ,
686
- } ,
687
- [ 'url' ] ,
688
- ) ,
689
- ) . toEqual ( {
690
- url : 'https://example.com/' ,
691
- } ) ;
692
- } ) ;
693
- } ) ;
694
-
695
- describe ( 'custom key' , ( ) => {
696
- it ( 'includes the custom key if present' , ( ) => {
697
- expect (
698
- extractRequestData (
699
- {
700
- httpVersion : '1.1' ,
701
- } ,
702
- [ 'httpVersion' ] ,
703
- ) ,
704
- ) . toEqual ( {
705
- httpVersion : '1.1' ,
706
- } ) ;
707
- } ) ;
708
-
709
- it ( 'gracefully degrades if the custom key is missing' , ( ) => {
710
- expect ( extractRequestData ( { } , [ 'httpVersion' ] ) ) . toEqual ( { } ) ;
711
- } ) ;
712
- } ) ;
713
- } ) ;
714
-
715
383
describe ( 'errorHandler()' , ( ) => {
716
384
const headers = { ears : 'furry' , nose : 'wet' , tongue : 'spotted' , cookie : 'favorite=zukes' } ;
717
385
const method = 'wagging' ;
0 commit comments