123 lines
2.8 KiB
TypeScript
123 lines
2.8 KiB
TypeScript
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import RateLimiter from '../../src/libs/RateLimiter'
|
|
|
|
|
|
// Mock Response
|
|
vi.stubGlobal('Response', class {
|
|
public constructor(
|
|
public body?: any,
|
|
public init?: any
|
|
) {}
|
|
})
|
|
|
|
describe('Rate Limit', () => {
|
|
beforeEach(() => {
|
|
vi.useFakeTimers()
|
|
})
|
|
|
|
|
|
it('should work with global variant', () => {
|
|
const now1 = new Date(1000)
|
|
vi.setSystemTime(now1)
|
|
const limit = RateLimiter.getInstance()
|
|
|
|
const result1 = limit.consume('key')
|
|
expect(result1).toEqual({
|
|
"X-RateLimit-Limit": '10',
|
|
"X-RateLimit-Remaining": '9',
|
|
"X-RateLimit-Reset": '61'
|
|
})
|
|
const limit2 = RateLimiter.getInstance()
|
|
const result2 = limit2.consume('key')
|
|
expect(result2).toEqual({
|
|
"X-RateLimit-Limit": '10',
|
|
"X-RateLimit-Remaining": '8',
|
|
"X-RateLimit-Reset": '61'
|
|
})
|
|
})
|
|
|
|
it('should consume points', () => {
|
|
const now1 = new Date(1000)
|
|
vi.setSystemTime(now1)
|
|
const limit = new RateLimiter(2, 10)
|
|
|
|
const result1 = limit.consume('key')
|
|
expect(result1).toEqual({
|
|
"X-RateLimit-Limit": '2',
|
|
"X-RateLimit-Remaining": '1',
|
|
"X-RateLimit-Reset": '11'
|
|
})
|
|
const result2 = limit.consume('key')
|
|
expect(result2).toEqual({
|
|
"X-RateLimit-Limit": '2',
|
|
"X-RateLimit-Remaining": '0',
|
|
"X-RateLimit-Reset": '11'
|
|
})
|
|
})
|
|
|
|
it('should rate limit', () => {
|
|
const now1 = new Date(1000)
|
|
vi.setSystemTime(now1)
|
|
const limit = new RateLimiter(1, 10)
|
|
|
|
const result1 = limit.consume('key')
|
|
expect(result1).toEqual({
|
|
"X-RateLimit-Limit": '1',
|
|
"X-RateLimit-Remaining": '0',
|
|
"X-RateLimit-Reset": '11'
|
|
})
|
|
const result2 = limit.consume('key')
|
|
expect(result2).instanceOf(Response)
|
|
const result3 = limit.consume('key')
|
|
expect(result3).instanceOf(Response)
|
|
})
|
|
|
|
it('should reset after some time', () => {
|
|
const now1 = new Date(1000)
|
|
vi.setSystemTime(now1)
|
|
const limit = new RateLimiter(2, 10)
|
|
|
|
const result1 = limit.consume('key')
|
|
expect(result1).toEqual({
|
|
"X-RateLimit-Limit": '2',
|
|
"X-RateLimit-Remaining": '1',
|
|
"X-RateLimit-Reset": '11'
|
|
})
|
|
const result2 = limit.consume('key')
|
|
expect(result2).toEqual({
|
|
"X-RateLimit-Limit": '2',
|
|
"X-RateLimit-Remaining": '0',
|
|
"X-RateLimit-Reset": '11'
|
|
})
|
|
|
|
|
|
const result3 = limit.consume('key')
|
|
expect(result3).instanceOf(Response)
|
|
|
|
const now2 = new Date(11000)
|
|
vi.setSystemTime(now2)
|
|
const result4 = limit.consume('key')
|
|
expect(result4).toEqual({
|
|
"X-RateLimit-Limit": '2',
|
|
"X-RateLimit-Remaining": '1',
|
|
"X-RateLimit-Reset": '21'
|
|
})
|
|
|
|
|
|
const result5 = limit.consume('key')
|
|
expect(result5).toEqual({
|
|
"X-RateLimit-Limit": '2',
|
|
"X-RateLimit-Remaining": '0',
|
|
"X-RateLimit-Reset": '21'
|
|
})
|
|
|
|
|
|
const result6 = limit.consume('key')
|
|
expect(result6).instanceOf(Response)
|
|
})
|
|
|
|
afterEach(() => {
|
|
vi.useRealTimers()
|
|
})
|
|
})
|