forked from JhaSourav07/commitpulse
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathproxy.rate-limit.test.ts
More file actions
94 lines (86 loc) · 3.17 KB
/
Copy pathproxy.rate-limit.test.ts
File metadata and controls
94 lines (86 loc) · 3.17 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
import { describe, it, expect, vi } from 'vitest';
import { NextRequest } from 'next/server';
import { proxy } from './proxy';
import { rateLimit } from './lib/rate-limit';
vi.mock('./lib/rate-limit', () => ({
rateLimit: vi.fn(),
}));
describe('Proxy rate-limit consistency', () => {
it('returns consistent JSON error shape when rate limit is exceeded', async () => {
vi.mocked(rateLimit).mockResolvedValue({
success: false,
limit: 60,
remaining: 0,
reset: 123456789,
});
const generalResponse = await proxy(new NextRequest('http://localhost:3000/api/streak'));
expect(generalResponse.status).toBe(429);
expect(await generalResponse.json()).toEqual({ error: 'Too many requests' });
vi.mocked(rateLimit).mockResolvedValue({
success: false,
limit: 60,
remaining: 0,
reset: 123456789,
});
const refreshResponse = await proxy(
new NextRequest('http://localhost:3000/api/streak?refresh=true')
);
expect(refreshResponse.status).toBe(429);
expect(await refreshResponse.json()).toEqual({ error: 'Too many requests' });
});
it('includes rate limit headers on limited responses', async () => {
vi.mocked(rateLimit).mockResolvedValue({
success: false,
limit: 60,
remaining: 0,
reset: 123456789,
});
const limited = await proxy(new NextRequest('http://localhost:3000/api/streak'));
expect(limited.headers.has('X-RateLimit-Limit')).toBe(true);
expect(limited.headers.has('X-RateLimit-Remaining')).toBe(true);
expect(limited.headers.has('X-RateLimit-Reset')).toBe(true);
});
it('includes rate limit headers on successful responses', async () => {
vi.mocked(rateLimit).mockResolvedValue({
success: true,
limit: 60,
remaining: 59,
reset: 123456789,
});
const response = await proxy(new NextRequest('http://localhost:3000/api/streak'));
expect(response.status).toBe(200);
expect(response.headers.get('X-RateLimit-Limit')).toBe('60');
expect(response.headers.get('X-RateLimit-Remaining')).toBe('59');
expect(response.headers.get('X-RateLimit-Reset')).toBe('123456789');
});
it('returns 429 status on rate limited responses', async () => {
vi.mocked(rateLimit).mockResolvedValue({
success: false,
limit: 60,
remaining: 0,
reset: 123456789,
});
const response = await proxy(new NextRequest('http://localhost:3000/api/streak'));
expect(response.status).toBe(429);
});
it('proxy config matcher covers all expected API route patterns', async () => {
const { config: mwConfig } = await import('./proxy');
const expectedRoutes = [
'/api/streak/:path*',
'/api/github/:path*',
'/api/track-user/:path*',
'/api/stats/:path*',
'/api/og/:path*',
];
for (const route of expectedRoutes) {
expect(mwConfig.matcher).toContain(route);
}
});
it('exports proxy function and config from proxy.ts', async () => {
const mod = await import('./proxy');
expect(typeof mod.proxy).toBe('function');
expect(mod.config).toBeDefined();
expect(Array.isArray(mod.config.matcher)).toBe(true);
expect(mod.config.matcher.length).toBeGreaterThan(0);
});
});