Skip to content

Commit 0f312ce

Browse files
author
Luca Forstner
committed
Finalize tests
1 parent 5b9cfc6 commit 0f312ce

File tree

3 files changed

+554
-19
lines changed

3 files changed

+554
-19
lines changed

packages/node/test/transports/new/http.test.ts

Lines changed: 127 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,20 @@ jest.mock('@sentry/core', () => {
1313
};
1414
});
1515

16+
// eslint-disable-next-line @typescript-eslint/no-var-requires
17+
const httpProxyAgent = require('https-proxy-agent');
18+
jest.mock('https-proxy-agent', () => {
19+
return jest.fn().mockImplementation(() => new http.Agent({ keepAlive: false, maxSockets: 30, timeout: 2000 }));
20+
});
21+
1622
const SUCCESS = 200;
1723
const RATE_LIMIT = 429;
1824
const INVALID = 400;
1925
const FAILED = 500;
2026

2127
interface TestServerOptions {
2228
statusCode: number;
23-
responseHeaders: Record<string, string | string[] | undefined>;
29+
responseHeaders?: Record<string, string | string[] | undefined>;
2430
}
2531

2632
let testServer: http.Server | undefined;
@@ -44,14 +50,14 @@ function setupTestServer(
4450
res.end();
4551
});
4652

47-
testServer.listen(12345);
53+
testServer.listen(8099);
4854

4955
return new Promise(resolve => {
5056
testServer?.on('listening', resolve);
5157
});
5258
}
5359

54-
const testServerUrl = 'http://localhost:12345';
60+
const TEST_SERVER_URL = 'http://localhost:8099';
5561

5662
const EVENT_ENVELOPE = createEnvelope<EventEnvelope>({ event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2', sent_at: '123' }, [
5763
[{ type: 'event' }, { event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2' }] as EventItem,
@@ -70,26 +76,26 @@ describe('makeNewHttpTransport()', () => {
7076

7177
describe('.send()', () => {
7278
it('should correctly return successful server response', async () => {
73-
await setupTestServer({ statusCode: SUCCESS, responseHeaders: {} });
79+
await setupTestServer({ statusCode: SUCCESS });
7480

75-
const transport = makeNewHttpTransport({ url: testServerUrl });
81+
const transport = makeNewHttpTransport({ url: TEST_SERVER_URL });
7682
const transportResponse = await transport.send(EVENT_ENVELOPE);
7783

7884
expect(transportResponse).toEqual(expect.objectContaining({ status: 'success' }));
7985
});
8086

8187
it('should correctly send envelope to server', async () => {
82-
await setupTestServer({ statusCode: SUCCESS, responseHeaders: {} }, (req, body) => {
88+
await setupTestServer({ statusCode: SUCCESS }, (req, body) => {
8389
expect(req.method).toBe('POST');
8490
expect(body).toBe(SERIALIZED_EVENT_ENVELOPE);
8591
});
8692

87-
const transport = makeNewHttpTransport({ url: testServerUrl });
93+
const transport = makeNewHttpTransport({ url: TEST_SERVER_URL });
8894
await transport.send(EVENT_ENVELOPE);
8995
});
9096

9197
it('should correctly send user-provided headers to server', async () => {
92-
await setupTestServer({ statusCode: SUCCESS, responseHeaders: {} }, req => {
98+
await setupTestServer({ statusCode: SUCCESS }, req => {
9399
expect(req.headers).toEqual(
94100
expect.objectContaining({
95101
// node http module lower-cases incoming headers
@@ -100,7 +106,7 @@ describe('makeNewHttpTransport()', () => {
100106
});
101107

102108
const transport = makeNewHttpTransport({
103-
url: testServerUrl,
109+
url: TEST_SERVER_URL,
104110
headers: {
105111
'X-Some-Custom-Header-1': 'value1',
106112
'X-Some-Custom-Header-2': 'value2',
@@ -115,9 +121,9 @@ describe('makeNewHttpTransport()', () => {
115121
[INVALID, 'invalid'],
116122
[FAILED, 'failed'],
117123
])('should correctly reject bad server response (status %i)', async (serverStatusCode, expectedStatus) => {
118-
await setupTestServer({ statusCode: serverStatusCode, responseHeaders: {} });
124+
await setupTestServer({ statusCode: serverStatusCode });
119125

120-
const transport = makeNewHttpTransport({ url: testServerUrl });
126+
const transport = makeNewHttpTransport({ url: TEST_SERVER_URL });
121127
await expect(transport.send(EVENT_ENVELOPE)).rejects.toEqual(expect.objectContaining({ status: expectedStatus }));
122128
});
123129

@@ -130,7 +136,7 @@ describe('makeNewHttpTransport()', () => {
130136
},
131137
});
132138

133-
const transport = makeNewHttpTransport({ url: testServerUrl });
139+
const transport = makeNewHttpTransport({ url: TEST_SERVER_URL });
134140
const transportResponse = await transport.send(EVENT_ENVELOPE);
135141

136142
expect(transportResponse).toEqual(expect.objectContaining({ status: 'success' }));
@@ -145,13 +151,88 @@ describe('makeNewHttpTransport()', () => {
145151
},
146152
});
147153

148-
const transport = makeNewHttpTransport({ url: testServerUrl });
154+
const transport = makeNewHttpTransport({ url: TEST_SERVER_URL });
149155
const transportResponse = await transport.send(EVENT_ENVELOPE);
150156

151157
expect(transportResponse).toEqual(expect.objectContaining({ status: 'success' }));
152158
});
153159
});
154160

161+
describe('proxy', () => {
162+
it('can be configured through option', () => {
163+
makeNewHttpTransport({
164+
url: 'http://[email protected]:8989/mysubpath/50622',
165+
proxy: 'http://example.com',
166+
});
167+
168+
expect(httpProxyAgent).toHaveBeenCalledTimes(1);
169+
expect(httpProxyAgent).toHaveBeenCalledWith('http://example.com');
170+
});
171+
172+
it('can be configured through env variables option', () => {
173+
process.env.http_proxy = 'http://example.com';
174+
makeNewHttpTransport({
175+
url: 'http://[email protected]:8989/mysubpath/50622',
176+
});
177+
178+
expect(httpProxyAgent).toHaveBeenCalledTimes(1);
179+
expect(httpProxyAgent).toHaveBeenCalledWith('http://example.com');
180+
delete process.env.http_proxy;
181+
});
182+
183+
it('client options have priority over env variables', () => {
184+
process.env.http_proxy = 'http://foo.com';
185+
makeNewHttpTransport({
186+
url: 'http://[email protected]:8989/mysubpath/50622',
187+
proxy: 'http://bar.com',
188+
});
189+
190+
expect(httpProxyAgent).toHaveBeenCalledTimes(1);
191+
expect(httpProxyAgent).toHaveBeenCalledWith('http://bar.com');
192+
delete process.env.http_proxy;
193+
});
194+
195+
it('no_proxy allows for skipping specific hosts', () => {
196+
process.env.no_proxy = 'sentry.io';
197+
makeNewHttpTransport({
198+
url: 'http://[email protected]:8989/mysubpath/50622',
199+
proxy: 'http://example.com',
200+
});
201+
202+
expect(httpProxyAgent).not.toHaveBeenCalled();
203+
204+
delete process.env.no_proxy;
205+
});
206+
207+
it('no_proxy works with a port', () => {
208+
process.env.http_proxy = 'http://example.com:8080';
209+
process.env.no_proxy = 'sentry.io:8989';
210+
211+
makeNewHttpTransport({
212+
url: 'http://[email protected]:8989/mysubpath/50622',
213+
});
214+
215+
expect(httpProxyAgent).not.toHaveBeenCalled();
216+
217+
delete process.env.no_proxy;
218+
delete process.env.http_proxy;
219+
});
220+
221+
it('no_proxy works with multiple comma-separated hosts', () => {
222+
process.env.http_proxy = 'http://example.com:8080';
223+
process.env.no_proxy = 'example.com,sentry.io,wat.com:1337';
224+
225+
makeNewHttpTransport({
226+
url: 'http://[email protected]:8989/mysubpath/50622',
227+
});
228+
229+
expect(httpProxyAgent).not.toHaveBeenCalled();
230+
231+
delete process.env.no_proxy;
232+
delete process.env.http_proxy;
233+
});
234+
});
235+
155236
it('should register TransportRequestExecutor that returns the correct object from server response (rate limit)', async () => {
156237
await setupTestServer({
157238
statusCode: RATE_LIMIT,
@@ -161,7 +242,7 @@ describe('makeNewHttpTransport()', () => {
161242
},
162243
});
163244

164-
makeNewHttpTransport({ url: testServerUrl });
245+
makeNewHttpTransport({ url: TEST_SERVER_URL });
165246
const registeredRequestExecutor = (createTransport as jest.Mock).mock.calls[0][1];
166247

167248
const executorResult = registeredRequestExecutor({
@@ -180,13 +261,12 @@ describe('makeNewHttpTransport()', () => {
180261
);
181262
});
182263

183-
it('should register TransportRequestExecutor that returns the correct object from server response (success)', async () => {
264+
it('should register TransportRequestExecutor that returns the correct object from server response (OK)', async () => {
184265
await setupTestServer({
185266
statusCode: SUCCESS,
186-
responseHeaders: {},
187267
});
188268

189-
makeNewHttpTransport({ url: testServerUrl });
269+
makeNewHttpTransport({ url: TEST_SERVER_URL });
190270
const registeredRequestExecutor = (createTransport as jest.Mock).mock.calls[0][1];
191271

192272
const executorResult = registeredRequestExecutor({
@@ -205,7 +285,7 @@ describe('makeNewHttpTransport()', () => {
205285
);
206286
});
207287

208-
it('should register TransportRequestExecutor that returns the correct object from server response (success but rate-limit)', async () => {
288+
it('should register TransportRequestExecutor that returns the correct object from server response (OK with rate-limit headers)', async () => {
209289
await setupTestServer({
210290
statusCode: SUCCESS,
211291
responseHeaders: {
@@ -214,7 +294,7 @@ describe('makeNewHttpTransport()', () => {
214294
},
215295
});
216296

217-
makeNewHttpTransport({ url: testServerUrl });
297+
makeNewHttpTransport({ url: TEST_SERVER_URL });
218298
const registeredRequestExecutor = (createTransport as jest.Mock).mock.calls[0][1];
219299

220300
const executorResult = registeredRequestExecutor({
@@ -232,4 +312,32 @@ describe('makeNewHttpTransport()', () => {
232312
}),
233313
);
234314
});
315+
316+
it('should register TransportRequestExecutor that returns the correct object from server response (NOK with rate-limit headers)', async () => {
317+
await setupTestServer({
318+
statusCode: RATE_LIMIT,
319+
responseHeaders: {
320+
'Retry-After': '2700',
321+
'X-Sentry-Rate-Limits': '60::organization, 2700::organization',
322+
},
323+
});
324+
325+
makeNewHttpTransport({ url: TEST_SERVER_URL });
326+
const registeredRequestExecutor = (createTransport as jest.Mock).mock.calls[0][1];
327+
328+
const executorResult = registeredRequestExecutor({
329+
body: serializeEnvelope(EVENT_ENVELOPE),
330+
category: 'error',
331+
});
332+
333+
await expect(executorResult).resolves.toEqual(
334+
expect.objectContaining({
335+
headers: {
336+
'retry-after': '2700',
337+
'x-sentry-rate-limits': '60::organization, 2700::organization',
338+
},
339+
statusCode: RATE_LIMIT,
340+
}),
341+
);
342+
});
235343
});

0 commit comments

Comments
 (0)