- 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
120 lines
4.6 KiB
TypeScript
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
|
|
})
|
|
})
|
|
}) |