1 | var chai = require('chai')
|
2 | , expect = chai.expect
|
3 | , request = require('supertest')
|
4 | , sinon = require('sinon')
|
5 | , redis = require('redis').createClient()
|
6 | , v = require('valentine')
|
7 | , subject = require('../')
|
8 |
|
9 | chai.use(require('sinon-chai'))
|
10 |
|
11 | describe('rate-limitter', function () {
|
12 | var express, app
|
13 |
|
14 | beforeEach(function () {
|
15 | express = require('express')
|
16 | app = express()
|
17 | limitter = subject(app, redis)
|
18 | })
|
19 |
|
20 | afterEach(function (done) {
|
21 | redis.flushdb(done)
|
22 | })
|
23 |
|
24 | it('should work', function (done) {
|
25 | var map = [10, 9, 8, 7, 6, 5, 4, 3, 2]
|
26 | var clock = sinon.useFakeTimers()
|
27 | limitter({
|
28 | path: '/route',
|
29 | method: 'get',
|
30 | lookup: ['connection.remoteAddress'],
|
31 | total: 10,
|
32 | expire: 1000 * 60 * 60
|
33 | })
|
34 |
|
35 | app.get('/route', function (req, res) {
|
36 | res.send(200, 'hello')
|
37 | })
|
38 |
|
39 | var out = (map).map(function (item) {
|
40 | return function (f) {
|
41 | process.nextTick(function () {
|
42 | request(app)
|
43 | .get('/route')
|
44 | .expect('X-RateLimit-Limit', 10)
|
45 | .expect('X-RateLimit-Remaining', item - 1)
|
46 | .expect(200, function (e) {f(e)})
|
47 | })
|
48 | }
|
49 | })
|
50 | out.push(function (f) {
|
51 | request(app)
|
52 | .get('/route')
|
53 | .expect('X-RateLimit-Limit', 10)
|
54 | .expect('X-RateLimit-Remaining', 0)
|
55 | .expect('Retry-After', /\d+/)
|
56 | .expect(429, function (e) {f(e)})
|
57 | })
|
58 | out.push(function (f) {
|
59 |
|
60 | clock.tick(1000 * 60 * 60 + 1)
|
61 | request(app)
|
62 | .get('/route')
|
63 | .expect('X-RateLimit-Limit', 10)
|
64 | .expect('X-RateLimit-Remaining', 9)
|
65 | .expect(200, function (e) {
|
66 | clock.restore()
|
67 | f(e)
|
68 | })
|
69 | })
|
70 | v.waterfall(out, done)
|
71 | })
|
72 | })
|