import { RateLimit } from 'src/rate-limit'; import httpContext from 'express-http-context'; let next: any; let rateLimitMiddleware: any; let limitRequest: any; let mockRes: any; const service = { team: 'api', slack: 'api-dev', name: 'hello world', description: 'Service to manage HELLO WORLD API', remarks: '', permission: '', oAuthProduct: '', envUrl: { dev: 'HELLO_WORLD_DEV_URL', live: 'HELLO_WORLD_LIVE_URL' }, apiKey: { dev: 'HELLO_WORLD_DEV_KEY', live: 'HELLO_WORLD_LIVE_KEY' }, path: { source: '/hello_world', destination: '/public_for_api_gw/hello_world' } }; describe('RateLimit', () => { beforeEach(() => { next = jest.fn(); rateLimitMiddleware = new RateLimit(); limitRequest = 10; mockRes = { json: undefined, status: undefined }; mockRes.status = jest.fn().mockReturnValue(mockRes); mockRes.json = jest.fn().mockReturnValue(mockRes); mockRes.header = jest.fn(); }); describe('getMiddleware', () => { it('Should continue if req.authorization_response not exist', async () => { const req = {}; const res = {}; await rateLimitMiddleware.getMiddleware()(req, res, next); expect(next).toHaveBeenCalledWith(); expect(next).toHaveBeenCalledTimes(1); }); it('Should continue if get middleware return INVALID', async () => { const mockReq = { originalUrl: '/hello_world', authorization_response: { master_acc_id: 'mocked_business_id', business: { id: 'mocked_business_id' } }, method: 'POST', context: { api_settings: { environment: 'TEST', rate_limit: [ { method: 'POST', path: 'hello_world', request_limit: 20, request_time_frame: 60, is_active: true }, { method: 'GET', path: 'hello_world', request_limit: 10, request_time_frame: 60, is_active: true } ] } } }; const rateLimitResp = { status_code: 'INVALID_DATA_FORMAT', rate_limit_limit: limitRequest, rate_limit_remaining: 0, rate_limit_reset: 0 }; httpContext.get = jest.fn().mockReturnValue(service); rateLimitMiddleware.redisClient.processRateLimitSlidingWindow = jest.fn().mockReturnValue(rateLimitResp); await rateLimitMiddleware.getMiddleware()(mockReq, mockRes, next); expect(next).toHaveBeenCalledWith(); expect(next).toHaveBeenCalledTimes(1); }); it('Should return 429 if get middleware return RATE_LIMIT_ACTIVE_AND_EXCEEDED', async () => { const mockReq = { originalUrl: '/hello_world', authorization_response: { master_acc_id: 'mocked_business_id', business: { id: 'mocked_business_id' } }, method: 'POST', context: { api_settings: { environment: 'TEST', rate_limit: [ { method: 'POST', path: 'hello_world', request_limit: 20, request_time_frame: 60, is_active: true }, { method: 'GET', path: 'hello_world', request_limit: 10, request_time_frame: 60, is_active: true } ] } } }; const rateLimitResp = { status_code: 'RATE_LIMIT_ACTIVE_AND_EXCEEDED', rate_limit_limit: limitRequest, rate_limit_remaining: 0, rate_limit_reset: 0 }; httpContext.get = jest.fn().mockReturnValue(service); rateLimitMiddleware.redisClient.processRateLimitSlidingWindow = jest.fn().mockReturnValue(rateLimitResp); await rateLimitMiddleware.getMiddleware()(mockReq, mockRes, next); expect(mockRes.header).toHaveBeenCalledTimes(3); expect(mockRes.header).toHaveBeenCalledWith('Rate-Limit-Limit', rateLimitResp.rate_limit_limit); expect(mockRes.status).toHaveBeenCalledWith(429); expect(next).not.toBeCalled(); }); it('Should continue if get rate limit config not found', async () => { const mockReq = { originalUrl: '/hello_world', authorization_response: { master_acc_id: 'mocked_business_id', business: { id: 'mocked_business_id' } }, method: 'POST', context: { api_settings: { environment: 'TEST', rate_limit: [{}] } } }; httpContext.get = jest.fn().mockReturnValue(service); await rateLimitMiddleware.getMiddleware()(mockReq, mockRes, next); expect(next).toHaveBeenCalledWith(); expect(next).toHaveBeenCalledTimes(1); }); }); });