Skip to content

Commit c8524ff

Browse files
committed
test: Core and browser transport tests
1 parent 1ae28f2 commit c8524ff

File tree

7 files changed

+133
-69
lines changed

7 files changed

+133
-69
lines changed

packages/browser/src/transports/fetch.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ export class FetchTransport extends BaseTransport {
2727
: '') as ReferrerPolicy,
2828
};
2929

30-
return global.fetch(this.url, defaultOptions);
30+
return (global as Window).fetch(this.url, defaultOptions);
3131
}
3232
}

packages/browser/test/backend.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { expect } from 'chai';
2+
import { SentryEvent } from '../src';
3+
import { BrowserBackend } from '../src/backend';
4+
import { BaseTransport } from '../src/transports';
5+
6+
class SimpleTransport extends BaseTransport {
7+
public async send(event: SentryEvent): Promise<Response> {
8+
return new Response(event.event_id, {
9+
status: 200,
10+
});
11+
}
12+
}
13+
14+
const dsn = 'https://[email protected]/42';
15+
const testEvent = {
16+
event_id: '1337',
17+
message: 'Pickle Rick',
18+
user: {
19+
username: 'Morty',
20+
},
21+
};
22+
23+
let backend: BrowserBackend;
24+
25+
describe('BrowserBackend', () => {
26+
describe('sendEvent()', () => {
27+
it('should throw when no DSN is provided', async () => {
28+
backend = new BrowserBackend({ dsn });
29+
30+
try {
31+
await backend.sendEvent(testEvent);
32+
} catch (e) {
33+
expect(e.message).equal('Cannot sendEvent without a valid DSN');
34+
}
35+
});
36+
37+
it('should call send() on provided transport', async () => {
38+
backend = new BrowserBackend({ dsn, transport: SimpleTransport });
39+
const status = await backend.sendEvent(testEvent);
40+
expect(status).equal(200);
41+
});
42+
});
43+
});

packages/core/src/base.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -249,11 +249,13 @@ export abstract class BaseClient<B extends Backend, O extends Options>
249249
if (prepared.message) {
250250
prepared.message = truncate(prepared.message, MAX_URL_LENGTH);
251251
}
252-
if (prepared.exception) {
253-
const exception = prepared.exception.values[0];
254-
if (exception.value) {
255-
exception.value = truncate(exception.value, MAX_URL_LENGTH);
256-
}
252+
253+
const exception =
254+
prepared.exception &&
255+
prepared.exception.values &&
256+
prepared.exception.values[0];
257+
if (exception && exception.value) {
258+
exception.value = truncate(exception.value, MAX_URL_LENGTH);
257259
}
258260

259261
const request = prepared.request;

packages/core/test/lib/base.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ import { TEST_SDK, TestClient } from '../mocks/client';
66

77
const PUBLIC_DSN = 'https://username@domain/path';
88

9+
jest.mock('@sentry/utils', () => ({
10+
uuid4(): string {
11+
return '42';
12+
},
13+
truncate(str: string): string {
14+
return str;
15+
},
16+
}));
17+
918
describe('BaseClient', () => {
1019
describe('constructor() / getDSN()', () => {
1120
test('returns the DSN', () => {
@@ -151,6 +160,7 @@ describe('BaseClient', () => {
151160
const scope = new Scope();
152161
await client.captureException(new Error('test exception'), scope);
153162
expect(TestBackend.instance!.event).toEqual({
163+
event_id: '42',
154164
exception: [
155165
{
156166
type: 'Error',
@@ -167,6 +177,7 @@ describe('BaseClient', () => {
167177
const scope = new Scope();
168178
await client.captureMessage('test message', scope);
169179
expect(TestBackend.instance!.event).toEqual({
180+
event_id: '42',
170181
message: 'test message',
171182
sdk: TEST_SDK,
172183
});
@@ -194,6 +205,7 @@ describe('BaseClient', () => {
194205
await client.captureEvent({ message: 'message' }, scope);
195206
expect(TestBackend.instance!.event!.message).toBe('message');
196207
expect(TestBackend.instance!.event).toEqual({
208+
event_id: '42',
197209
message: 'message',
198210
sdk: TEST_SDK,
199211
});
@@ -208,6 +220,7 @@ describe('BaseClient', () => {
208220
await client.captureEvent({ message: 'message' }, scope);
209221
expect(TestBackend.instance!.event!).toEqual({
210222
environment: 'env',
223+
event_id: '42',
211224
message: 'message',
212225
sdk: TEST_SDK,
213226
});
@@ -221,6 +234,7 @@ describe('BaseClient', () => {
221234
const scope = new Scope();
222235
await client.captureEvent({ message: 'message' }, scope);
223236
expect(TestBackend.instance!.event!).toEqual({
237+
event_id: '42',
224238
message: 'message',
225239
release: 'v1.0.0',
226240
sdk: TEST_SDK,
@@ -234,6 +248,7 @@ describe('BaseClient', () => {
234248
await client.captureEvent({ message: 'message' }, scope);
235249
expect(TestBackend.instance!.event!).toEqual({
236250
breadcrumbs: [{ message: 'breadcrumb' }],
251+
event_id: '42',
237252
message: 'message',
238253
sdk: TEST_SDK,
239254
});
@@ -247,6 +262,7 @@ describe('BaseClient', () => {
247262
await client.captureEvent({ message: 'message' }, scope);
248263
expect(TestBackend.instance!.event!).toEqual({
249264
breadcrumbs: [{ message: '2' }],
265+
event_id: '42',
250266
message: 'message',
251267
sdk: TEST_SDK,
252268
});
@@ -260,6 +276,7 @@ describe('BaseClient', () => {
260276
scope.setUser({ id: 'user' });
261277
await client.captureEvent({ message: 'message' }, scope);
262278
expect(TestBackend.instance!.event!).toEqual({
279+
event_id: '42',
263280
extra: { b: 'b' },
264281
message: 'message',
265282
sdk: TEST_SDK,
@@ -274,6 +291,7 @@ describe('BaseClient', () => {
274291
scope.setFingerprint(['abcd']);
275292
await client.captureEvent({ message: 'message' }, scope);
276293
expect(TestBackend.instance!.event!).toEqual({
294+
event_id: '42',
277295
fingerprint: ['abcd'],
278296
message: 'message',
279297
sdk: TEST_SDK,
@@ -286,6 +304,7 @@ describe('BaseClient', () => {
286304
const scope = new Scope();
287305
await client.captureEvent({ message: 'hello' }, scope);
288306
expect(TestBackend.instance!.event).toEqual({
307+
event_id: '42',
289308
message: 'hello',
290309
sdk: TEST_SDK,
291310
});

packages/utils/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ export { mkdirp, mkdirpSync } from './fs';
33
export { clone, deserialize, fill, serialize, urlEncode } from './object';
44
export { Store } from './store';
55
export { isError, isErrorEvent, isDOMError, isDOMException } from './is';
6-
export { truncate, uuid4 } from './string';
6+
export { truncate } from './string';
77
export {
88
supportsDOMError,
99
supportsDOMException,
1010
supportsErrorEvent,
1111
supportsFetch,
1212
supportsReferrerPolicy,
1313
} from './supports';
14-
export { getGlobalObject } from './misc';
14+
export { getGlobalObject, uuid4 } from './misc';

packages/utils/src/misc.ts

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,66 @@ export function getGlobalObject(): Window | NodeJS.Global | {} {
99
? window
1010
: typeof global !== 'undefined'
1111
? global
12-
: typeof self !== 'undefined' ? self : {};
12+
: typeof self !== 'undefined'
13+
? self
14+
: {};
1315
}
1416
// tslint:enable:strict-type-predicates
17+
18+
/**
19+
* Extended Window interface that allows for Crypto API usage in IE browsers
20+
*/
21+
interface MsCryptoWindow extends Window {
22+
msCrypto?: Crypto;
23+
}
24+
25+
/**
26+
* UUID4 generator
27+
*
28+
* @returns string Generated UUID4.
29+
*/
30+
export function uuid4(): string {
31+
const global = getGlobalObject() as MsCryptoWindow;
32+
const crypto = global.crypto || global.msCrypto;
33+
34+
if (!(crypto === void 0) && crypto.getRandomValues) {
35+
// Use window.crypto API if available
36+
const arr = new Uint16Array(8);
37+
crypto.getRandomValues(arr);
38+
39+
// set 4 in byte 7
40+
// tslint:disable-next-line:no-bitwise
41+
arr[3] = (arr[3] & 0xfff) | 0x4000;
42+
// set 2 most significant bits of byte 9 to '10'
43+
// tslint:disable-next-line:no-bitwise
44+
arr[4] = (arr[4] & 0x3fff) | 0x8000;
45+
46+
const pad = (num: number): string => {
47+
let v = num.toString(16);
48+
while (v.length < 4) {
49+
v = `0${v}`;
50+
}
51+
return v;
52+
};
53+
54+
return (
55+
pad(arr[0]) +
56+
pad(arr[1]) +
57+
pad(arr[2]) +
58+
pad(arr[3]) +
59+
pad(arr[4]) +
60+
pad(arr[5]) +
61+
pad(arr[6]) +
62+
pad(arr[7])
63+
);
64+
} else {
65+
// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523
66+
return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, c => {
67+
// tslint:disable-next-line:no-bitwise
68+
const r = (Math.random() * 16) | 0;
69+
// tslint:disable-next-line:no-bitwise
70+
const v = c === 'x' ? r : (r & 0x3) | 0x8;
71+
return v.toString(16);
72+
});
73+
}
74+
}

packages/utils/src/string.ts

Lines changed: 0 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import { getGlobalObject } from './misc';
2-
31
/**
42
* Encodes given object into url-friendly format
53
*
@@ -14,61 +12,3 @@ export function truncate(str: string, max: number): string {
1412
}
1513
return str.length <= max ? str : `${str.substr(0, max)}\u2026`;
1614
}
17-
18-
/**
19-
* Extended Window interface that allows for Crypto API usage in IE browsers
20-
*/
21-
interface MsCryptoWindow extends Window {
22-
msCrypto?: Crypto;
23-
}
24-
25-
/**
26-
* UUID4 generator
27-
*
28-
* @returns string Generated UUID4.
29-
*/
30-
export function uuid4(): string {
31-
const global = getGlobalObject() as MsCryptoWindow;
32-
const crypto = global.crypto || global.msCrypto;
33-
34-
if (!(crypto === void 0) && crypto.getRandomValues) {
35-
// Use window.crypto API if available
36-
const arr = new Uint16Array(8);
37-
crypto.getRandomValues(arr);
38-
39-
// set 4 in byte 7
40-
// tslint:disable-next-line:no-bitwise
41-
arr[3] = (arr[3] & 0xfff) | 0x4000;
42-
// set 2 most significant bits of byte 9 to '10'
43-
// tslint:disable-next-line:no-bitwise
44-
arr[4] = (arr[4] & 0x3fff) | 0x8000;
45-
46-
const pad = (num: number): string => {
47-
let v = num.toString(16);
48-
while (v.length < 4) {
49-
v = `0${v}`;
50-
}
51-
return v;
52-
};
53-
54-
return (
55-
pad(arr[0]) +
56-
pad(arr[1]) +
57-
pad(arr[2]) +
58-
pad(arr[3]) +
59-
pad(arr[4]) +
60-
pad(arr[5]) +
61-
pad(arr[6]) +
62-
pad(arr[7])
63-
);
64-
} else {
65-
// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523
66-
return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, c => {
67-
// tslint:disable-next-line:no-bitwise
68-
const r = (Math.random() * 16) | 0;
69-
// tslint:disable-next-line:no-bitwise
70-
const v = c === 'x' ? r : (r & 0x3) | 0x8;
71-
return v.toString(16);
72-
});
73-
}
74-
}

0 commit comments

Comments
 (0)