Skip to content

Commit cb3980d

Browse files
committed
fix: resolve rebase conflict in responsive breakpoint tests
1 parent ec03eda commit cb3980d

1 file changed

Lines changed: 45 additions & 72 deletions

File tree

Lines changed: 45 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,102 +1,75 @@
1-
import { beforeEach, describe, expect, it, vi } from 'vitest';
1+
import { beforeEach, describe, expect, it } from 'vitest';
22
import refreshRateLimiter from './refresh-rate-limiter';
33

4-
function setViewportWidth(width: number) {
5-
Object.defineProperty(window, 'innerWidth', {
6-
configurable: true,
7-
writable: true,
8-
value: width,
9-
});
10-
window.dispatchEvent(new Event('resize'));
11-
}
12-
13-
function mockMatchMedia(matches: boolean) {
14-
Object.defineProperty(window, 'matchMedia', {
15-
configurable: true,
16-
writable: true,
17-
value: vi.fn().mockImplementation((query: string) => ({
18-
matches,
19-
media: query,
20-
onchange: null,
21-
addListener: vi.fn(),
22-
removeListener: vi.fn(),
23-
addEventListener: vi.fn(),
24-
removeEventListener: vi.fn(),
25-
dispatchEvent: vi.fn(),
26-
})),
27-
});
28-
}
29-
304
describe('RefreshRateLimiter responsive breakpoints', () => {
315
beforeEach(() => {
326
refreshRateLimiter.reset();
33-
setViewportWidth(1280);
34-
mockMatchMedia(false);
7+
delete process.env.MAX_REFRESHES_PER_HOUR;
8+
window.innerWidth = 375;
9+
window.dispatchEvent(new Event('resize'));
3510
});
3611

37-
it('allows refreshes normally on a mobile-width viewport (375px)', () => {
38-
setViewportWidth(375);
39-
mockMatchMedia(true);
12+
it('maintains default limit behavior under a narrow mobile viewport', () => {
13+
expect(window.innerWidth).toBe(375);
4014

41-
const response = refreshRateLimiter.checkLimit('203.0.113.5');
15+
const response1 = refreshRateLimiter.checkLimit('203.0.113.5');
16+
expect(response1.success).toBe(true);
17+
expect(response1.limit).toBe(3);
18+
expect(response1.remaining).toBe(2);
4219

43-
expect(window.innerWidth).toBe(375);
44-
expect(response.success).toBe(true);
45-
expect(response.limit).toBe(3);
46-
expect(response.remaining).toBe(2);
20+
const response2 = refreshRateLimiter.checkLimit('203.0.113.5');
21+
expect(response2.success).toBe(true);
22+
expect(response2.remaining).toBe(1);
4723
});
4824

49-
it('maintains the same rate-limit behavior when switching from desktop to mobile widths', () => {
50-
setViewportWidth(1280);
51-
const desktopResponse = refreshRateLimiter.checkLimit('198.51.100.10');
25+
it('reflows client tracking correctly when the same IP is reused on mobile breakpoints', () => {
26+
window.innerWidth = 375;
27+
window.dispatchEvent(new Event('resize'));
5228

53-
setViewportWidth(375);
54-
mockMatchMedia(true);
55-
const mobileResponse = refreshRateLimiter.checkLimit('198.51.100.10');
29+
const first = refreshRateLimiter.checkLimit(' 203.0.113.5 ');
30+
expect(first.success).toBe(true);
31+
expect(first.remaining).toBe(2);
5632

57-
expect(window.innerWidth).toBe(375);
58-
expect(desktopResponse.success).toBe(true);
59-
expect(mobileResponse.success).toBe(true);
60-
expect(mobileResponse.remaining).toBe(desktopResponse.remaining - 1);
33+
const second = refreshRateLimiter.checkLimit('203.0.113.5');
34+
expect(second.success).toBe(true);
35+
expect(second.remaining).toBe(1);
36+
expect(second.limit).toBe(first.limit);
6137
});
6238

63-
it('reports cleanly when a mobile breakpoint is active and the same IP checks again', () => {
64-
setViewportWidth(375);
65-
mockMatchMedia(true);
39+
it('adapts to environment-driven limits while preserving mobile-friendly fallback state', () => {
40+
process.env.MAX_REFRESHES_PER_HOUR = '2';
41+
refreshRateLimiter.reset();
6642

67-
const first = refreshRateLimiter.checkLimit('127.0.0.1');
68-
const second = refreshRateLimiter.checkLimit('127.0.0.1');
43+
expect(window.innerWidth).toBe(375);
6944

45+
const first = refreshRateLimiter.checkLimit('198.51.100.1');
7046
expect(first.success).toBe(true);
47+
expect(first.limit).toBe(2);
48+
expect(first.remaining).toBe(1);
49+
50+
const second = refreshRateLimiter.checkLimit('198.51.100.1');
7151
expect(second.success).toBe(true);
72-
expect(second.remaining).toBe(1);
73-
expect(first.limit).toBe(3);
52+
expect(second.remaining).toBe(0);
7453
});
7554

76-
it('enforces a custom mobile friendly limit without breaking on narrow viewports', () => {
77-
setViewportWidth(375);
78-
mockMatchMedia(true);
79-
refreshRateLimiter.setLimit(1, 60 * 60 * 1000);
55+
it('returns a reset timestamp without relying on absolute screen dimensions', () => {
56+
const response = refreshRateLimiter.checkLimit('198.51.100.2');
57+
expect(response.reset).toBeGreaterThan(Date.now());
58+
expect(typeof response.reset).toBe('number');
59+
expect(response.limit).toBe(3);
60+
});
8061

81-
const allowed = refreshRateLimiter.checkLimit('203.0.113.15');
82-
const blocked = refreshRateLimiter.checkLimit('203.0.113.15');
62+
it('enforces the limit and reports blocked refreshes cleanly on simulated mobile width', () => {
63+
refreshRateLimiter.setLimit(1, 1000 * 60 * 60);
64+
expect(window.innerWidth).toBe(375);
8365

66+
const allowed = refreshRateLimiter.checkLimit('203.0.113.10');
8467
expect(allowed.success).toBe(true);
8568
expect(allowed.remaining).toBe(0);
69+
70+
const blocked = refreshRateLimiter.checkLimit('203.0.113.10');
8671
expect(blocked.success).toBe(false);
8772
expect(blocked.remaining).toBe(0);
8873
expect(blocked.limit).toBe(1);
8974
});
90-
91-
it('keeps responsive viewport simulation clean and does not depend on absolute width assumptions', () => {
92-
setViewportWidth(375);
93-
mockMatchMedia(true);
94-
95-
const response = refreshRateLimiter.checkLimit('192.0.2.1');
96-
97-
expect(window.innerWidth).toBeLessThanOrEqual(375);
98-
expect(response.success).toBe(true);
99-
expect(response.reset).toBeGreaterThan(Date.now() - 1000);
100-
expect(response.limit).toBe(3);
101-
});
10275
});

0 commit comments

Comments
 (0)