Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9c42621f74 | ||
| 1b98282202 |
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "flyer-crawler",
|
||||
"version": "0.9.32",
|
||||
"version": "0.9.33",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "flyer-crawler",
|
||||
"version": "0.9.32",
|
||||
"version": "0.9.33",
|
||||
"dependencies": {
|
||||
"@bull-board/api": "^6.14.2",
|
||||
"@bull-board/express": "^6.14.2",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "flyer-crawler",
|
||||
"private": true,
|
||||
"version": "0.9.32",
|
||||
"version": "0.9.33",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "concurrently \"npm:start:dev\" \"vite\"",
|
||||
|
||||
@@ -113,8 +113,8 @@ describe('Deals Routes (/api/users/deals)', () => {
|
||||
.set('X-Test-Rate-Limit-Enable', 'true');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.headers).toHaveProperty('x-ratelimit-limit');
|
||||
expect(parseInt(response.headers['x-ratelimit-limit'])).toBe(100);
|
||||
expect(response.headers).toHaveProperty('ratelimit-limit');
|
||||
expect(parseInt(response.headers['ratelimit-limit'])).toBe(100);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -319,8 +319,8 @@ describe('Flyer Routes (/api/flyers)', () => {
|
||||
.set('X-Test-Rate-Limit-Enable', 'true');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.headers).toHaveProperty('x-ratelimit-limit');
|
||||
expect(parseInt(response.headers['x-ratelimit-limit'])).toBe(100);
|
||||
expect(response.headers).toHaveProperty('ratelimit-limit');
|
||||
expect(parseInt(response.headers['ratelimit-limit'])).toBe(100);
|
||||
});
|
||||
|
||||
it('should apply batchLimiter to POST /items/batch-fetch', async () => {
|
||||
@@ -331,8 +331,8 @@ describe('Flyer Routes (/api/flyers)', () => {
|
||||
.send({ flyerIds: [1] });
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.headers).toHaveProperty('x-ratelimit-limit');
|
||||
expect(parseInt(response.headers['x-ratelimit-limit'])).toBe(50);
|
||||
expect(response.headers).toHaveProperty('ratelimit-limit');
|
||||
expect(parseInt(response.headers['ratelimit-limit'])).toBe(50);
|
||||
});
|
||||
|
||||
it('should apply batchLimiter to POST /items/batch-count', async () => {
|
||||
@@ -343,8 +343,8 @@ describe('Flyer Routes (/api/flyers)', () => {
|
||||
.send({ flyerIds: [1] });
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.headers).toHaveProperty('x-ratelimit-limit');
|
||||
expect(parseInt(response.headers['x-ratelimit-limit'])).toBe(50);
|
||||
expect(response.headers).toHaveProperty('ratelimit-limit');
|
||||
expect(parseInt(response.headers['ratelimit-limit'])).toBe(50);
|
||||
});
|
||||
|
||||
it('should apply trackingLimiter to POST /items/:itemId/track', async () => {
|
||||
@@ -357,8 +357,8 @@ describe('Flyer Routes (/api/flyers)', () => {
|
||||
.send({ type: 'view' });
|
||||
|
||||
expect(response.status).toBe(202);
|
||||
expect(response.headers).toHaveProperty('x-ratelimit-limit');
|
||||
expect(parseInt(response.headers['x-ratelimit-limit'])).toBe(200);
|
||||
expect(response.headers).toHaveProperty('ratelimit-limit');
|
||||
expect(parseInt(response.headers['ratelimit-limit'])).toBe(200);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -345,8 +345,8 @@ describe('Gamification Routes (/api/achievements)', () => {
|
||||
.set('X-Test-Rate-Limit-Enable', 'true');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.headers).toHaveProperty('x-ratelimit-limit');
|
||||
expect(parseInt(response.headers['x-ratelimit-limit'])).toBe(100);
|
||||
expect(response.headers).toHaveProperty('ratelimit-limit');
|
||||
expect(parseInt(response.headers['ratelimit-limit'])).toBe(100);
|
||||
});
|
||||
|
||||
it('should apply userReadLimiter to GET /me', async () => {
|
||||
@@ -360,8 +360,8 @@ describe('Gamification Routes (/api/achievements)', () => {
|
||||
.set('X-Test-Rate-Limit-Enable', 'true');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.headers).toHaveProperty('x-ratelimit-limit');
|
||||
expect(parseInt(response.headers['x-ratelimit-limit'])).toBe(100);
|
||||
expect(response.headers).toHaveProperty('ratelimit-limit');
|
||||
expect(parseInt(response.headers['ratelimit-limit'])).toBe(100);
|
||||
});
|
||||
|
||||
it('should apply adminTriggerLimiter to POST /award', async () => {
|
||||
@@ -378,8 +378,8 @@ describe('Gamification Routes (/api/achievements)', () => {
|
||||
.send({ userId: 'some-user', achievementName: 'some-achievement' });
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.headers).toHaveProperty('x-ratelimit-limit');
|
||||
expect(parseInt(response.headers['x-ratelimit-limit'])).toBe(30);
|
||||
expect(response.headers).toHaveProperty('ratelimit-limit');
|
||||
expect(parseInt(response.headers['ratelimit-limit'])).toBe(30);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -115,7 +115,7 @@ describe('Personalization Routes (/api/personalization)', () => {
|
||||
.set('X-Test-Rate-Limit-Enable', 'true');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.headers).toHaveProperty('x-ratelimit-limit');
|
||||
expect(response.headers).toHaveProperty('ratelimit-limit');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -159,8 +159,8 @@ describe('Price Routes (/api/price-history)', () => {
|
||||
.send({ masterItemIds: [1, 2] });
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.headers).toHaveProperty('x-ratelimit-limit');
|
||||
expect(parseInt(response.headers['x-ratelimit-limit'])).toBe(50);
|
||||
expect(response.headers).toHaveProperty('ratelimit-limit');
|
||||
expect(parseInt(response.headers['ratelimit-limit'])).toBe(50);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -218,7 +218,7 @@ describe('Reaction Routes (/api/reactions)', () => {
|
||||
.set('X-Test-Rate-Limit-Enable', 'true');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.headers).toHaveProperty('x-ratelimit-limit');
|
||||
expect(response.headers).toHaveProperty('ratelimit-limit');
|
||||
});
|
||||
|
||||
it('should apply userUpdateLimiter to POST /toggle', async () => {
|
||||
@@ -236,8 +236,8 @@ describe('Reaction Routes (/api/reactions)', () => {
|
||||
.send({ entity_type: 'recipe', entity_id: '1', reaction_type: 'like' });
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.headers).toHaveProperty('x-ratelimit-limit');
|
||||
expect(parseInt(response.headers['x-ratelimit-limit'])).toBe(150);
|
||||
expect(response.headers).toHaveProperty('ratelimit-limit');
|
||||
expect(parseInt(response.headers['ratelimit-limit'])).toBe(150);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -350,7 +350,7 @@ describe('Recipe Routes (/api/recipes)', () => {
|
||||
|
||||
// Assert
|
||||
expect(blockedResponse.status).toBe(429);
|
||||
expect(blockedResponse.text).toContain('Too many recipe suggestion requests');
|
||||
expect(blockedResponse.text).toContain('Too many AI generation requests');
|
||||
});
|
||||
|
||||
it('should NOT block requests when the opt-in header is not sent', async () => {
|
||||
@@ -375,8 +375,8 @@ describe('Recipe Routes (/api/recipes)', () => {
|
||||
.set('X-Test-Rate-Limit-Enable', 'true');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.headers).toHaveProperty('x-ratelimit-limit');
|
||||
expect(parseInt(response.headers['x-ratelimit-limit'])).toBe(100);
|
||||
expect(response.headers).toHaveProperty('ratelimit-limit');
|
||||
expect(parseInt(response.headers['ratelimit-limit'])).toBe(100);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -75,7 +75,7 @@ describe('Stats Routes (/api/stats)', () => {
|
||||
.set('X-Test-Rate-Limit-Enable', 'true');
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.headers).toHaveProperty('x-ratelimit-limit');
|
||||
expect(response.headers).toHaveProperty('ratelimit-limit');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -171,10 +171,10 @@ describe('System Routes (/api/system)', () => {
|
||||
.send({ address });
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.headers).toHaveProperty('x-ratelimit-limit');
|
||||
expect(response.headers).toHaveProperty('x-ratelimit-remaining');
|
||||
expect(parseInt(response.headers['x-ratelimit-limit'])).toBe(limit);
|
||||
expect(parseInt(response.headers['x-ratelimit-remaining'])).toBeLessThan(limit);
|
||||
expect(response.headers).toHaveProperty('ratelimit-limit');
|
||||
expect(response.headers).toHaveProperty('ratelimit-remaining');
|
||||
expect(parseInt(response.headers['ratelimit-limit'])).toBe(limit);
|
||||
expect(parseInt(response.headers['ratelimit-remaining'])).toBeLessThan(limit);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1237,6 +1237,19 @@ describe('User Routes (/api/users)', () => {
|
||||
}); // End of Recipe Routes
|
||||
|
||||
describe('Rate Limiting', () => {
|
||||
beforeAll(() => {
|
||||
vi.useFakeTimers();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// Advance time to ensure rate limits are reset between tests
|
||||
vi.advanceTimersByTime(60 * 60 * 1000 + 1000);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it('should apply userUpdateLimiter to PUT /profile', async () => {
|
||||
vi.mocked(db.userRepo.updateUserProfile).mockResolvedValue(mockUserProfile);
|
||||
|
||||
@@ -1246,8 +1259,8 @@ describe('User Routes (/api/users)', () => {
|
||||
.send({ full_name: 'Rate Limit Test' });
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.headers).toHaveProperty('x-ratelimit-limit');
|
||||
expect(parseInt(response.headers['x-ratelimit-limit'])).toBe(100);
|
||||
expect(response.headers).toHaveProperty('ratelimit-limit');
|
||||
expect(parseInt(response.headers['ratelimit-limit'])).toBe(100);
|
||||
});
|
||||
|
||||
it('should apply userSensitiveUpdateLimiter to PUT /profile/password and block after limit', async () => {
|
||||
@@ -1283,8 +1296,8 @@ describe('User Routes (/api/users)', () => {
|
||||
.attach('avatar', Buffer.from('dummy-image-content'), dummyImagePath);
|
||||
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.headers).toHaveProperty('x-ratelimit-limit');
|
||||
expect(parseInt(response.headers['x-ratelimit-limit'])).toBe(20);
|
||||
expect(response.headers).toHaveProperty('ratelimit-limit');
|
||||
expect(parseInt(response.headers['ratelimit-limit'])).toBe(20);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user