@@ -3,8 +3,15 @@ import { Hub, makeMain } from '@sentry/hub';
3
3
import * as utils from '@sentry/utils' ;
4
4
5
5
import { Span , SpanStatus , Transaction } from '../../src' ;
6
- import { fetchCallback , FetchData , registerRequestInstrumentation } from '../../src/browser/request' ;
6
+ import {
7
+ fetchCallback ,
8
+ FetchData ,
9
+ registerRequestInstrumentation ,
10
+ xhrCallback ,
11
+ XHRData ,
12
+ } from '../../src/browser/request' ;
7
13
import { addExtensionMethods } from '../../src/hubextensions' ;
14
+ import * as tracingUtils from '../../src/utils' ;
8
15
9
16
beforeAll ( ( ) => {
10
17
addExtensionMethods ( ) ;
@@ -14,6 +21,7 @@ beforeAll(() => {
14
21
} ) ;
15
22
16
23
const addInstrumentationHandler = jest . spyOn ( utils , 'addInstrumentationHandler' ) ;
24
+ const setRequestHeader = jest . fn ( ) ;
17
25
18
26
describe ( 'registerRequestInstrumentation' , ( ) => {
19
27
beforeEach ( ( ) => {
@@ -56,6 +64,21 @@ describe('callbacks', () => {
56
64
fetchData : { url : 'http://dogs.are.great/' , method : 'GET' } ,
57
65
startTimestamp : 1356996072000 ,
58
66
} ;
67
+ const xhrHandlerData : XHRData = {
68
+ xhr : {
69
+ __sentry_xhr__ : {
70
+ method : 'GET' ,
71
+ url : 'http://dogs.are.great/' ,
72
+ status_code : 200 ,
73
+ data : { } ,
74
+ } ,
75
+ __sentry_xhr_span_id__ : '1231201211212012' ,
76
+ // eslint-disable-next-line @typescript-eslint/unbound-method
77
+ // setRequestHeader: XMLHttpRequest.prototype.setRequestHeader,
78
+ setRequestHeader,
79
+ } ,
80
+ startTimestamp : 1353501072000 ,
81
+ } ;
59
82
const endTimestamp = 1356996072000 ;
60
83
61
84
beforeAll ( ( ) => {
@@ -142,4 +165,76 @@ describe('callbacks', () => {
142
165
// TODO
143
166
} ) ;
144
167
} ) ;
168
+
169
+ describe ( 'xhrCallback()' , ( ) => {
170
+ it ( 'does not create span if shouldCreateSpan returns false' , ( ) => {
171
+ const spans = { } ;
172
+
173
+ xhrCallback ( xhrHandlerData , neverCreateSpan , spans ) ;
174
+
175
+ expect ( spans ) . toEqual ( { } ) ;
176
+ } ) ;
177
+
178
+ it ( 'adds sentry-trace header to XHR requests' , ( ) => {
179
+ xhrCallback ( xhrHandlerData , alwaysCreateSpan , { } ) ;
180
+
181
+ expect ( setRequestHeader ) . toHaveBeenCalledWith (
182
+ 'sentry-trace' ,
183
+ expect . stringMatching ( tracingUtils . TRACEPARENT_REGEXP ) ,
184
+ ) ;
185
+ } ) ;
186
+
187
+ it ( 'creates and finishes XHR span on active transaction' , ( ) => {
188
+ const spans = { } ;
189
+
190
+ // triggered by request being sent
191
+ xhrCallback ( xhrHandlerData , alwaysCreateSpan , spans ) ;
192
+
193
+ const newSpan = transaction . spanRecorder ?. spans [ 1 ] ;
194
+
195
+ expect ( newSpan ) . toBeDefined ( ) ;
196
+ expect ( newSpan ) . toBeInstanceOf ( Span ) ;
197
+ expect ( newSpan ! . data ) . toEqual ( {
198
+ method : 'GET' ,
199
+ type : 'xhr' ,
200
+ url : 'http://dogs.are.great/' ,
201
+ } ) ;
202
+ expect ( newSpan ! . description ) . toBe ( 'GET http://dogs.are.great/' ) ;
203
+ expect ( newSpan ! . op ) . toBe ( 'http' ) ;
204
+ expect ( xhrHandlerData . xhr ! . __sentry_xhr_span_id__ ) . toBeDefined ( ) ;
205
+ expect ( xhrHandlerData . xhr ! . __sentry_xhr_span_id__ ) . toEqual ( newSpan ?. spanId ) ;
206
+
207
+ const postRequestXHRHandlerData = {
208
+ ...xhrHandlerData ,
209
+ endTimestamp,
210
+ } ;
211
+
212
+ // triggered by response coming back
213
+ xhrCallback ( postRequestXHRHandlerData , alwaysCreateSpan , spans ) ;
214
+
215
+ expect ( newSpan ! . endTimestamp ) . toBeDefined ( ) ;
216
+ } ) ;
217
+
218
+ it ( 'sets response status on finish' , ( ) => {
219
+ const spans = { } ;
220
+
221
+ // triggered by request being sent
222
+ xhrCallback ( xhrHandlerData , alwaysCreateSpan , spans ) ;
223
+
224
+ const newSpan = transaction . spanRecorder ?. spans [ 1 ] ;
225
+
226
+ expect ( newSpan ) . toBeDefined ( ) ;
227
+
228
+ const postRequestXHRHandlerData = {
229
+ ...xhrHandlerData ,
230
+ endTimestamp,
231
+ } ;
232
+ postRequestXHRHandlerData . xhr ! . __sentry_xhr__ ! . status_code = 404 ;
233
+
234
+ // triggered by response coming back
235
+ xhrCallback ( postRequestXHRHandlerData , alwaysCreateSpan , spans ) ;
236
+
237
+ expect ( newSpan ! . status ) . toBe ( SpanStatus . fromHttpCode ( 404 ) ) ;
238
+ } ) ;
239
+ } ) ;
145
240
} ) ;
0 commit comments