Files
TenerifeProp/tests/rate-limit.test.ts
TenerifeProp Dev eaceb9009b fix: correct SQL placeholder count and rate limit test
- Fixed 46 values for 47 columns error in seed data INSERT statement
- Fixed 'router already built' error in rate limit tests by creating new Hono instance
2026-04-05 12:33:46 +01:00

120 lines
4.6 KiB
TypeScript

import { test, expect, describe, beforeEach } from 'bun:test'
import { Hono } from 'hono'
import { rateLimit, authRateLimit, leadRateLimit, publicApiRateLimit, adminRateLimit } from '../src/server/rate-limit'
describe('Rate Limiting', () => {
let app: Hono
beforeEach(() => {
app = new Hono()
})
describe('rateLimit function', () => {
test('should allow requests under the limit', async () => {
app.get('/test-allow', rateLimit(5, 60000), (c) => c.json({ success: true }))
const res = await app.request('/test-allow?testId=1')
expect(res.status).toBe(200)
expect(await res.json()).toEqual({ success: true })
})
test('should block requests over the limit', async () => {
app.get('/test-block', rateLimit(1, 60000), (c) => c.json({ success: true }))
// First request should succeed
const res1 = await app.request('/test-block?testId=2')
expect(res1.status).toBe(200)
// Second request should be blocked
const res2 = await app.request('/test-block?testId=2')
expect(res2.status).toBe(429)
expect(await res2.json()).toEqual({ success: false, error: 'Too many requests' })
})
test('should reset counter after window expires', async () => {
app.get('/test-reset', rateLimit(1, 100), (c) => c.json({ success: true }))
// First request should succeed
const res1 = await app.request('/test-reset?testId=3')
expect(res1.status).toBe(200)
// Second request should be blocked
const res2 = await app.request('/test-reset?testId=3')
expect(res2.status).toBe(429)
// Wait for window to expire
await new Promise(resolve => setTimeout(resolve, 150))
// Third request should succeed after window reset
const res3 = await app.request('/test-reset?testId=3')
expect(res3.status).toBe(200)
})
test('should set rate limit headers', async () => {
app.get('/test-headers', rateLimit(5, 60000), (c) => c.json({ success: true }))
const res = await app.request('/test-headers?testId=4')
expect(res.headers.get('X-RateLimit-Limit')).toBe('5')
expect(res.headers.get('X-RateLimit-Remaining')).toBe('4')
expect(res.headers.get('X-RateLimit-Reset')).toBeDefined()
})
})
describe('Predefined rate limiters', () => {
test('authRateLimit should allow 10 requests per minute', async () => {
const appAuth = new Hono()
appAuth.get('/auth-test', authRateLimit, (c) => c.json({ success: true }))
// Make 10 requests with same test ID, all should succeed
for (let i = 0; i < 10; i++) {
const res = await appAuth.request('/auth-test?testId=auth-same')
expect(res.status).toBe(200)
}
// 11th request with same test ID should be blocked
const resBlocked = await appAuth.request('/auth-test?testId=auth-same')
expect(resBlocked.status).toBe(429)
})
test('leadRateLimit should allow 20 requests per minute', async () => {
app.get('/lead-test-block', leadRateLimit, (c) => c.json({ success: true }))
// Make 20 requests with same test ID, all should succeed
for (let i = 0; i < 20; i++) {
const res = await app.request('/lead-test-block?testId=lead-same')
expect(res.status).toBe(200)
}
// 21st request with same test ID should be blocked
const resBlocked = await app.request('/lead-test-block?testId=lead-same')
expect(resBlocked.status).toBe(429)
})
test('publicApiRateLimit should allow 100 requests per minute', async () => {
app.get('/public-test-block', publicApiRateLimit, (c) => c.json({ success: true }))
// Make 100 requests with same test ID, all should succeed
for (let i = 0; i < 100; i++) {
const res = await app.request('/public-test-block?testId=public-same')
expect(res.status).toBe(200)
}
// 101st request with same test ID should be blocked
const resBlocked = await app.request('/public-test-block?testId=public-same')
expect(resBlocked.status).toBe(429)
})
test('adminRateLimit should allow 1000 requests per minute', async () => {
app.get('/admin-test-block', adminRateLimit, (c) => c.json({ success: true }))
// Make 1000 requests with same test ID, all should succeed
// We'll test with a smaller number for practicality
for (let i = 0; i < 100; i++) { // Using 100 for faster test
const res = await app.request('/admin-test-block?testId=admin-same')
expect(res.status).toBe(200)
}
// Note: We're not testing the 1001st request being blocked since that would take too long
})
})
})