forked from badges/shields
/
token-pool.spec.js
125 lines (103 loc) · 3.17 KB
/
token-pool.spec.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
'use strict'
const { expect } = require('chai')
const sinon = require('sinon')
const times = require('lodash.times')
const { Token, TokenPool } = require('./token-pool')
function expectPoolToBeExhausted(pool) {
expect(() => {
pool.next()
}).to.throw(Error, /^Token pool is exhausted$/)
}
describe('The token pool', function() {
const ids = [1, 2, 3, 4, 5]
const batchSize = 3
let tokenPool
beforeEach(function() {
// Set up.
tokenPool = new TokenPool(batchSize)
ids.forEach(id => tokenPool.add(id))
})
it('allValidTokenIds() should return the full list', function() {
expect(tokenPool.allValidTokenIds()).to.deep.equal(ids)
})
it('should yield the expected tokens', function() {
ids.forEach(id =>
times(batchSize, () => expect(tokenPool.next().id).to.equal(id))
)
})
it('should repeat when reaching the end', function() {
ids.forEach(id =>
times(batchSize, () => expect(tokenPool.next().id).to.equal(id))
)
ids.forEach(id =>
times(batchSize, () => expect(tokenPool.next().id).to.equal(id))
)
})
context('tokens are marked exhausted immediately', function() {
it('should be exhausted', function() {
ids.forEach(() => {
const token = tokenPool.next()
token.update(0, Token.nextResetNever)
})
expectPoolToBeExhausted(tokenPool)
})
})
context('tokens are marked after the last request', function() {
it('should be exhausted', function() {
ids.forEach(() => {
const token = times(batchSize, () => tokenPool.next()).pop()
token.update(0, Token.nextResetNever)
})
expectPoolToBeExhausted(tokenPool)
})
})
context('tokens are renewed', function() {
it('should keep using them', function() {
const tokensToRenew = [2, 4]
const renewalCount = 3
ids.forEach(id => {
const token = times(batchSize, () => tokenPool.next()).pop()
const usesRemaining = tokensToRenew.includes(token.id)
? renewalCount
: 0
token.update(usesRemaining, Token.nextResetNever)
})
tokensToRenew.forEach(id => {
let token
times(renewalCount, () => {
token = tokenPool.next()
expect(token.id).to.equal(id)
}).pop()
token.update(0, Token.nextResetNever)
})
expectPoolToBeExhausted(tokenPool)
})
})
context('tokens reset', function() {
let clock
beforeEach(function() {
clock = sinon.useFakeTimers()
})
afterEach(function() {
clock.restore()
})
it('should start using them', function() {
const tokensToReset = [2, 4]
const futureTime = 1440
ids.forEach(id => {
const token = times(batchSize, () => tokenPool.next()).pop()
const nextReset = tokensToReset.includes(token.id)
? futureTime
: Token.nextResetNever
token.update(0, nextReset)
})
expectPoolToBeExhausted(tokenPool)
clock.tick(1000 * futureTime)
tokensToReset.forEach(id => {
const token = times(batchSize, () => tokenPool.next()).pop()
token.update(0, Token.nextResetNever)
})
expectPoolToBeExhausted(tokenPool)
})
})
})