Skip to content

Commit 239ee22

Browse files
committed
fix tests
1 parent efc6624 commit 239ee22

File tree

3 files changed

+494
-338
lines changed

3 files changed

+494
-338
lines changed

packages/node/test/handlers.test.ts

+6-338
Original file line numberDiff line numberDiff line change
@@ -2,174 +2,15 @@ import * as sentryCore from '@sentry/core';
22
import * as sentryHub from '@sentry/hub';
33
import { Hub } from '@sentry/hub';
44
import { Transaction } from '@sentry/tracing';
5-
import { Baggage } from '@sentry/types';
5+
import { Baggage, Event } from '@sentry/types';
66
import { SentryError } from '@sentry/utils';
77
import * as http from 'http';
8-
import * as net from 'net';
98

10-
import { Event, Request, User } from '../src';
119
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';
2011
import * as SDK from '../src/sdk';
2112
import { getDefaultNodeClientOptions } from './helper/node-client-options';
2213

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-
17314
describe('requestHandler', () => {
17415
const headers = { ears: 'furry', nose: 'wet', tongue: 'spotted', cookie: 'favorite=zukes' };
17516
const method = 'wagging';
@@ -270,7 +111,7 @@ describe('requestHandler', () => {
270111
});
271112
});
272113

273-
it('patches `res.end` when `flushTimeout` is specified', () => {
114+
it('patches `res.end` when `flushTimeout` is specified', done => {
274115
const flush = jest.spyOn(SDK, 'flush').mockResolvedValue(true);
275116

276117
const sentryRequestMiddleware = requestHandler({ flushTimeout: 1337 });
@@ -280,10 +121,11 @@ describe('requestHandler', () => {
280121
setImmediate(() => {
281122
expect(flush).toHaveBeenCalledWith(1337);
282123
expect(res.finished).toBe(true);
124+
done();
283125
});
284126
});
285127

286-
it('prevents errors thrown during `flush` from breaking the response', async () => {
128+
it('prevents errors thrown during `flush` from breaking the response', done => {
287129
jest.spyOn(SDK, 'flush').mockRejectedValue(new SentryError('HTTP Error (429)'));
288130

289131
const sentryRequestMiddleware = requestHandler({ flushTimeout: 1337 });
@@ -292,6 +134,7 @@ describe('requestHandler', () => {
292134

293135
setImmediate(() => {
294136
expect(res.finished).toBe(true);
137+
done();
295138
});
296139
});
297140
});
@@ -530,181 +373,6 @@ describe('tracingHandler', () => {
530373
});
531374
});
532375

533-
describe('extractRequestData()', () => {
534-
describe('default behaviour', () => {
535-
test('node', () => {
536-
expect(
537-
extractRequestData({
538-
headers: { host: 'example.com' },
539-
method: 'GET',
540-
secure: true,
541-
originalUrl: '/',
542-
}),
543-
).toEqual({
544-
cookies: {},
545-
headers: {
546-
host: 'example.com',
547-
},
548-
method: 'GET',
549-
query_string: null,
550-
url: 'https://example.com/',
551-
});
552-
});
553-
554-
test('degrades gracefully without request data', () => {
555-
expect(extractRequestData({})).toEqual({
556-
cookies: {},
557-
headers: {},
558-
method: undefined,
559-
query_string: null,
560-
url: 'http://<no host>',
561-
});
562-
});
563-
});
564-
565-
describe('cookies', () => {
566-
it('uses `req.cookies` if available', () => {
567-
expect(
568-
extractRequestData(
569-
{
570-
cookies: { foo: 'bar' },
571-
},
572-
['cookies'],
573-
),
574-
).toEqual({
575-
cookies: { foo: 'bar' },
576-
});
577-
});
578-
579-
it('parses the cookie header', () => {
580-
expect(
581-
extractRequestData(
582-
{
583-
headers: {
584-
cookie: 'foo=bar;',
585-
},
586-
},
587-
['cookies'],
588-
),
589-
).toEqual({
590-
cookies: { foo: 'bar' },
591-
});
592-
});
593-
594-
it('falls back if no cookies are defined', () => {
595-
expect(extractRequestData({}, ['cookies'])).toEqual({
596-
cookies: {},
597-
});
598-
});
599-
});
600-
601-
describe('data', () => {
602-
it('includes data from `req.body` if available', () => {
603-
expect(
604-
extractRequestData(
605-
{
606-
method: 'POST',
607-
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
608-
body: 'foo=bar',
609-
},
610-
['data'],
611-
),
612-
).toEqual({
613-
data: 'foo=bar',
614-
});
615-
});
616-
617-
it('encodes JSON body contents back to a string', () => {
618-
expect(
619-
extractRequestData(
620-
{
621-
method: 'POST',
622-
headers: { 'Content-Type': 'application/json' },
623-
body: { foo: 'bar' },
624-
},
625-
['data'],
626-
),
627-
).toEqual({
628-
data: '{"foo":"bar"}',
629-
});
630-
});
631-
});
632-
633-
describe('query_string', () => {
634-
it('parses the query parms from the url', () => {
635-
expect(
636-
extractRequestData(
637-
{
638-
headers: { host: 'example.com' },
639-
secure: true,
640-
originalUrl: '/?foo=bar',
641-
},
642-
['query_string'],
643-
),
644-
).toEqual({
645-
query_string: 'foo=bar',
646-
});
647-
});
648-
649-
it('gracefully degrades if url cannot be determined', () => {
650-
expect(extractRequestData({}, ['query_string'])).toEqual({
651-
query_string: null,
652-
});
653-
});
654-
});
655-
656-
describe('url', () => {
657-
test('express/koa', () => {
658-
expect(
659-
extractRequestData(
660-
{
661-
host: 'example.com',
662-
protocol: 'https',
663-
url: '/',
664-
},
665-
['url'],
666-
),
667-
).toEqual({
668-
url: 'https://example.com/',
669-
});
670-
});
671-
672-
test('node', () => {
673-
expect(
674-
extractRequestData(
675-
{
676-
headers: { host: 'example.com' },
677-
secure: true,
678-
originalUrl: '/',
679-
},
680-
['url'],
681-
),
682-
).toEqual({
683-
url: 'https://example.com/',
684-
});
685-
});
686-
});
687-
688-
describe('custom key', () => {
689-
it('includes the custom key if present', () => {
690-
expect(
691-
extractRequestData(
692-
{
693-
httpVersion: '1.1',
694-
},
695-
['httpVersion'],
696-
),
697-
).toEqual({
698-
httpVersion: '1.1',
699-
});
700-
});
701-
702-
it('gracefully degrades if the custom key is missing', () => {
703-
expect(extractRequestData({}, ['httpVersion'])).toEqual({});
704-
});
705-
});
706-
});
707-
708376
describe('errorHandler()', () => {
709377
const headers = { ears: 'furry', nose: 'wet', tongue: 'spotted', cookie: 'favorite=zukes' };
710378
const method = 'wagging';

0 commit comments

Comments
 (0)