UNPKG

insight-via-api

Version:

A Viacoin blockchain REST and web socket API service for Viacore Node.

190 lines (180 loc) 5.62 kB
'use strict'; var should = require('should'); var sinon = require('sinon'); var RateLimiter = require('../lib/ratelimiter'); describe('RateLimiter', function() { describe('@constructor', function() { it('will instantiate without options', function() { var limiter = new RateLimiter(); should.exist(limiter); }); it('will instantiate without new', function() { /* jshint newcap:false */ var limiter = RateLimiter(); should.exist(limiter); }); it('will instantiate with options', function() { var whitelist = []; var blacklist = []; var node = {}; var limiter = new RateLimiter({ node: node, whitelist: whitelist, blacklist: blacklist, limit: 1, interval: 1, whitelistLimit: 1, whitelistInterval: 1, blacklistLimit: 1, blacklistInterval: 1 }); should.exist(limiter); should.exist(limiter.config); should.exist(limiter.clients); should.exist(limiter.node); limiter.whitelist.should.equal(whitelist); limiter.blacklist.should.equal(blacklist); limiter.config.whitelist.totalRequests.should.equal(1); limiter.config.whitelist.interval.should.equal(1); limiter.config.blacklist.totalRequests.should.equal(1); limiter.config.blacklist.interval.should.equal(1); limiter.config.normal.interval.should.equal(1); limiter.config.normal.totalRequests.should.equal(1); }); }); describe('#middleware', function() { it('will set ratelimit headers', function(done) { var limiter = new RateLimiter(); var req = { headers: { 'cf-connecting-ip': '127.0.0.1' } }; var setHeader = sinon.stub(); var res = { setHeader: setHeader }; limiter.middleware()(req, res, function() { setHeader.callCount.should.equal(2); setHeader.args[0][0].should.equal('X-RateLimit-Limit'); setHeader.args[0][1].should.equal(10800); setHeader.args[1][0].should.equal('X-RateLimit-Remaining'); setHeader.args[1][1].should.equal(10799); done(); }); }); it('will give rate limit error', function() { var node = { log: { warn: sinon.stub() } }; var limiter = new RateLimiter({node: node}); limiter.exceeded = sinon.stub().returns(true); var req = { headers: { 'cf-connecting-ip': '127.0.0.1' } }; var jsonp = sinon.stub(); var status = sinon.stub().returns({ jsonp: jsonp }); var res = { status: status, setHeader: sinon.stub() }; limiter.middleware()(req, res); status.callCount.should.equal(1); status.args[0][0].should.equal(429); jsonp.callCount.should.equal(1); jsonp.args[0][0].should.eql({ status: 429, error: 'Rate limit exceeded' }); }); }); describe('#exceeded', function() { it('should not be exceeded', function() { var node = {}; var limiter = new RateLimiter({node: node}); var client = limiter.addClient('127.0.0.1'); var exceeded = limiter.exceeded(client); exceeded.should.equal(false); }); it('should be exceeded', function() { var node = {}; var limiter = new RateLimiter({node: node}); var client = limiter.addClient('127.0.0.1'); client.visits = 3 * 60 * 60 + 1; var exceeded = limiter.exceeded(client); exceeded.should.equal(true); }); it('should exclude whitelisted with no limit', function() { var node = {}; var limiter = new RateLimiter({ whitelist: [ '127.0.0.1' ], node: node, whitelistLimit: -1 }); var client = limiter.addClient('127.0.0.1'); client.visits = Infinity; var exceeded = limiter.exceeded(client); exceeded.should.equal(false); }); }); describe('#getClientName', function() { it('should get client name from cloudflare header', function() { var node = {}; var limiter = new RateLimiter({node: node}); var req = { headers: { 'cf-connecting-ip': '127.0.0.1' } }; var name = limiter.getClientName(req); name.should.equal('127.0.0.1'); }); it('should get client name from x forwarded header', function() { var node = {}; var limiter = new RateLimiter({node: node}); var req = { headers: { 'x-forwarded-for': '127.0.0.1' } }; var name = limiter.getClientName(req); name.should.equal('127.0.0.1'); }); it('should get client name from connection remote address', function() { var node = {}; var limiter = new RateLimiter({node: node}); var req = { headers: {}, connection: { remoteAddress: '127.0.0.1' } }; var name = limiter.getClientName(req); name.should.equal('127.0.0.1'); }); }); describe('#addClient', function() { var sandbox = sinon.sandbox.create(); afterEach(function() { sandbox.restore(); }); it('will remove client after interval', function() { var THREE_HOURS_PLUS = 3 * 60 * 60 * 1000 + 1; var clock = sandbox.useFakeTimers(); var node = {}; var limiter = new RateLimiter({node: node}); limiter.addClient('127.0.0.1'); should.exist(limiter.clients['127.0.0.1']); clock.tick(THREE_HOURS_PLUS); should.not.exist(limiter.clients['127.0.0.1']); }); }); });