Skip to content

Commit b28aae1

Browse files
committed
add first test
1 parent 9f20419 commit b28aae1

File tree

3 files changed

+73
-5
lines changed

3 files changed

+73
-5
lines changed

packages/browser/src/transports/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ export { FetchTransport } from './fetch';
33
export { XHRTransport } from './xhr';
44

55
export { makeNewFetchTransport } from './new-fetch';
6+
export { makeNewXHRTransport } from './new-xhr';

packages/browser/src/transports/new-xhr.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import {
88
import { SyncPromise } from '@sentry/utils';
99

1010
export interface XHRTransportOptions extends BaseTransportOptions {
11+
// TODO choose whatever is preferred here (I like record more for easier readability)
1112
headers?: { [key: string]: string };
13+
// headers?: Record<string, string>;
1214
}
1315

1416
/**
@@ -21,17 +23,17 @@ export function makeNewXHRTransport(options: XHRTransportOptions): NewTransport
2123

2224
xhr.onreadystatechange = (): void => {
2325
if (xhr.readyState === 4) {
24-
const headers = {
25-
'x-sentry-rate-limits': xhr.getResponseHeader('X-Sentry-Rate-Limits'),
26-
'retry-after': xhr.getResponseHeader('Retry-After'),
27-
};
2826
const response = {
2927
body: xhr.response,
30-
headers,
28+
headers: {
29+
'x-sentry-rate-limits': xhr.getResponseHeader('X-Sentry-Rate-Limits'),
30+
'retry-after': xhr.getResponseHeader('Retry-After'),
31+
},
3132
reason: xhr.statusText,
3233
statusCode: xhr.status,
3334
};
3435

36+
// TODO when to reject? is it necessary at all, given that createTransport handles rejections?
3537
resolve(response);
3638
}
3739
};
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { EventEnvelope, EventItem } from '@sentry/types';
2+
import { createEnvelope, serializeEnvelope } from '@sentry/utils';
3+
import { makeNewXHRTransport, XHRTransportOptions } from '../../../src/transports/new-xhr';
4+
5+
const DEFAULT_XHR_TRANSPORT_OPTIONS: XHRTransportOptions = {
6+
url: 'https://sentry.io/api/42/store/?sentry_key=123&sentry_version=7',
7+
};
8+
9+
const ERROR_ENVELOPE = createEnvelope<EventEnvelope>({ event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2', sent_at: '123' }, [
10+
[{ type: 'event' }, { event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2' }] as EventItem,
11+
]);
12+
13+
function createXHRMock() {
14+
const retryAfterSeconds = 10;
15+
16+
const xhrMock: Partial<XMLHttpRequest> = {
17+
open: jest.fn(),
18+
send: jest.fn(),
19+
setRequestHeader: jest.fn(),
20+
readyState: 4,
21+
status: 200,
22+
response: 'Hello World!',
23+
onreadystatechange: () => {},
24+
getResponseHeader: (header: string) => {
25+
switch (header) {
26+
case 'Retry-After':
27+
return '10';
28+
case `${retryAfterSeconds}`:
29+
return;
30+
default:
31+
return `${retryAfterSeconds}:error:scope`;
32+
}
33+
},
34+
};
35+
36+
//@ts-ignore
37+
jest.spyOn(window, 'XMLHttpRequest').mockImplementation(() => xhrMock as XMLHttpRequest);
38+
39+
return xhrMock;
40+
}
41+
42+
describe('NewXHRTransport', () => {
43+
it('makes an XHR request to the given URL', done => {
44+
const xhrMock: Partial<XMLHttpRequest> = createXHRMock();
45+
46+
const transport = makeNewXHRTransport(DEFAULT_XHR_TRANSPORT_OPTIONS);
47+
expect(xhrMock.open).toHaveBeenCalledTimes(0);
48+
expect(xhrMock.setRequestHeader).toHaveBeenCalledTimes(0);
49+
expect(xhrMock.send).toHaveBeenCalledTimes(0);
50+
51+
transport.send(ERROR_ENVELOPE).then(res => {
52+
expect(xhrMock.open).toHaveBeenCalledTimes(1);
53+
expect(xhrMock.open).toHaveBeenCalledWith('POST', DEFAULT_XHR_TRANSPORT_OPTIONS.url);
54+
expect(xhrMock.send).toBeCalledWith(serializeEnvelope(ERROR_ENVELOPE));
55+
56+
expect(res).toBeTruthy;
57+
expect(res.status).toEqual('success');
58+
59+
done();
60+
});
61+
62+
//@ts-ignore
63+
xhrMock.onreadystatechange();
64+
});
65+
});

0 commit comments

Comments
 (0)