-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Expand file tree
/
Copy pathrateLimiting.test.ts
More file actions
116 lines (98 loc) · 3.15 KB
/
rateLimiting.test.ts
File metadata and controls
116 lines (98 loc) · 3.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/**
* @vitest-environment jsdom
*/
import '../utils/mock-internal-setTimeout';
import type { Transport, TransportMakeRequestResponse } from '@sentry/core';
import { getClient } from '@sentry/core';
import type { MockedFunction } from 'vitest';
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
import { DEFAULT_FLUSH_MIN_DELAY } from '../../src/constants';
import type { ReplayContainer } from '../../src/replay';
import { clearSession } from '../../src/session/clearSession';
import { BASE_TIMESTAMP, mockSdk } from '../index';
async function advanceTimers(time: number) {
vi.advanceTimersByTime(time);
await new Promise(process.nextTick);
}
type MockTransportSend = MockedFunction<Transport['send']>;
describe('Integration | rate-limiting behaviour', () => {
let replay: ReplayContainer;
let mockTransportSend: MockTransportSend;
beforeAll(() => {
vi.useFakeTimers();
});
beforeEach(async () => {
vi.setSystemTime(new Date(BASE_TIMESTAMP));
({ replay } = await mockSdk({
autoStart: false,
replayOptions: {
stickySession: false,
},
}));
mockTransportSend = getClient()?.getTransport()?.send as MockTransportSend;
});
afterEach(async () => {
clearSession(replay);
vi.clearAllMocks();
replay?.stop();
});
it.each([
['429 status code', { statusCode: 429, headers: {} } as TransportMakeRequestResponse],
[
'200 status code with x-sentry-rate-limits header',
{
statusCode: 200,
headers: {
'x-sentry-rate-limits': '30',
},
} as TransportMakeRequestResponse,
],
[
'200 status code with x-sentry-rate-limits replay header',
{
statusCode: 200,
headers: {
'x-sentry-rate-limits': '30:replay',
},
} as TransportMakeRequestResponse,
],
])('handles %s responses by stopping the replay', async (_name, { statusCode, headers }) => {
const mockStop = vi.spyOn(replay, 'stop');
mockTransportSend.mockImplementationOnce(() => {
return Promise.resolve({ statusCode, headers });
});
replay.start();
await advanceTimers(DEFAULT_FLUSH_MIN_DELAY);
expect(mockStop).toHaveBeenCalledTimes(1);
expect(replay.session).toBeUndefined();
expect(replay.isEnabled()).toBe(false);
});
it.each([
[
'200 status code without x-sentry-rate-limits header',
{
statusCode: 200,
headers: {},
} as TransportMakeRequestResponse,
],
[
'200 status code with x-sentry-rate-limits profile header',
{
statusCode: 200,
headers: {
'x-sentry-rate-limits': '30:profile',
},
} as TransportMakeRequestResponse,
],
])('handles %s responses by not stopping', async (_name, { statusCode, headers }) => {
const mockStop = vi.spyOn(replay, 'stop');
mockTransportSend.mockImplementationOnce(() => {
return Promise.resolve({ statusCode, headers });
});
replay.start();
await advanceTimers(DEFAULT_FLUSH_MIN_DELAY);
expect(mockStop).not.toHaveBeenCalled();
expect(replay.session).toBeDefined();
expect(replay.isEnabled()).toBe(true);
});
});