unit tests for calcPoints()

This commit is contained in:
Chris Troutner
2020-02-07 00:05:40 -08:00
parent 8a558db690
commit 4c80776754
2 changed files with 135 additions and 6 deletions
+11 -6
View File
@@ -235,7 +235,7 @@ class RateLimits {
async newRateLimit(req, res, next) { async newRateLimit(req, res, next) {
try { try {
let userId let userId
let decoded let decoded = {}
// Create a res.locals object if not passed in. // Create a res.locals object if not passed in.
if (!req.locals) { if (!req.locals) {
@@ -275,16 +275,18 @@ class RateLimits {
console.log(`resource: ${resource}`) console.log(`resource: ${resource}`)
let key = userId ? userId : req.ip let key = userId ? userId : req.ip
key = `${key}-${resource}`
// const pointsToConsume = userId ? 1 : 30 // const pointsToConsume = userId ? 1 : 30
decoded.resource = resource decoded.resource = resource
const pointsToConsume = _this.calcPoints(decoded) const pointsToConsume = _this.calcPoints(decoded)
console.log( console.log(
`User ${userId} consuming ${pointsToConsume} point for resource ${resource}.` `User ${key} consuming ${pointsToConsume} point for resource ${resource}.`
) )
// Update the key so that rate limits track both the user and the resource.
key = `${key}-${resource}`
await _this.rateLimiter.consume(key, pointsToConsume) await _this.rateLimiter.consume(key, pointsToConsume)
} catch (err) { } catch (err) {
console.log(`err: `, err) console.log(`err: `, err)
@@ -317,18 +319,21 @@ class RateLimits {
const level20Routes = ["insight", "bitcore", "blockbook"] const level20Routes = ["insight", "bitcore", "blockbook"]
const level30Routes = ["slp"] const level30Routes = ["slp"]
// console.log(`apiLevel: ${apiLevel}`)
// Only evaluate if user is using a JWT token. // Only evaluate if user is using a JWT token.
if (jwtInfo.id) { if (jwtInfo.id) {
// SLP indexer routes // SLP indexer routes
if (level30Routes.includes(resource)) { if (level30Routes.includes(resource)) {
if (apiLevel >= 30) retVal = 1 if (apiLevel >= 30) retVal = 1
else retVal = 30 // else if (apiLevel >= 10) retVal = 10
else retVal = 10
} }
// Normal indexer routes // Normal indexer routes
else if (level20Routes.includes(resource)) { else if (level20Routes.includes(resource)) {
if (apiLevel >= 20) retVal = 1 if (apiLevel >= 20) retVal = 1
else retVal = 30 else retVal = 10
} }
// Free tier, full node only. // Free tier, full node only.
@@ -353,7 +358,7 @@ class RateLimits {
// what kind of variations will be seen in production. // what kind of variations will be seen in production.
getResource(url) { getResource(url) {
try { try {
// console.log(`url: ${JSON.stringify(url, null, 2)}`) console.log(`url: ${JSON.stringify(url, null, 2)}`)
const splitUrl = url.split("/") const splitUrl = url.split("/")
const resource = splitUrl[1] const resource = splitUrl[1]
+124
View File
@@ -252,6 +252,130 @@ describe("#route-ratelimits & jwt-auth", () => {
assert.equal(result, "blockchain") assert.equal(result, "blockchain")
}) })
}) })
describe("#calcPoints", () => {
it("should return 30 points for anonymous user", () => {
const result = rateLimits.calcPoints()
// console.log(`result: ${result}`)
assert.equal(result, 30)
})
it("should return 1 point for free tier requesting full node access", () => {
const jwtInfo = {
apiLevel: 10,
resource: "blockchain",
id: "5e3a0415eb29a962da2708b4"
}
const result = rateLimits.calcPoints(jwtInfo)
assert.equal(result, 1)
})
it("should return 10 points for free tier requesting indexer access", () => {
const jwtInfo = {
apiLevel: 10,
resource: "blockbook",
id: "5e3a0415eb29a962da2708b4"
}
const result = rateLimits.calcPoints(jwtInfo)
assert.equal(result, 10)
})
it("should return 10 points for free tier requesting SLPDB access", () => {
const jwtInfo = {
apiLevel: 10,
resource: "slp",
id: "5e3a0415eb29a962da2708b4"
}
const result = rateLimits.calcPoints(jwtInfo)
assert.equal(result, 10)
})
it("should return 1 point for indexer tier requesting full node access", () => {
const jwtInfo = {
apiLevel: 20,
resource: "blockchain",
id: "5e3a0415eb29a962da2708b4"
}
const result = rateLimits.calcPoints(jwtInfo)
assert.equal(result, 1)
})
it("should return 1 points for indexer tier requesting indexer access", () => {
const jwtInfo = {
apiLevel: 20,
resource: "blockbook",
id: "5e3a0415eb29a962da2708b4"
}
const result = rateLimits.calcPoints(jwtInfo)
assert.equal(result, 1)
})
it("should return 10 points for indexer tier requesting SLPDB access", () => {
const jwtInfo = {
apiLevel: 20,
resource: "slp",
id: "5e3a0415eb29a962da2708b4"
}
const result = rateLimits.calcPoints(jwtInfo)
assert.equal(result, 10)
})
it("should return 1 point for SLP tier requesting full node access", () => {
const jwtInfo = {
apiLevel: 30,
resource: "blockchain",
id: "5e3a0415eb29a962da2708b4"
}
const result = rateLimits.calcPoints(jwtInfo)
assert.equal(result, 1)
})
it("should return 1 points for SLP tier requesting indexer access", () => {
const jwtInfo = {
apiLevel: 30,
resource: "blockbook",
id: "5e3a0415eb29a962da2708b4"
}
const result = rateLimits.calcPoints(jwtInfo)
assert.equal(result, 1)
})
it("should return 1 points for SLP tier requesting SLPDB access", () => {
const jwtInfo = {
apiLevel: 30,
resource: "slp",
id: "5e3a0415eb29a962da2708b4"
}
const result = rateLimits.calcPoints(jwtInfo)
assert.equal(result, 1)
})
})
describe("#newRateLimit", () => {
it("should pass through rate-limit middleware", async () => {
req.baseUrl = "/v3"
req.path = "/control/getNetworkInfo"
req.url = req.path
req.method = "GET"
// Call the route twice to trigger the rate handling.
await rateLimits.newRateLimit(req, res, next)
await rateLimits.newRateLimit(req, res, next)
// next() will be called if rate-limit is not triggered
assert.equal(next.called, true)
})
})
}) })
// Generates a Basic authorization header. // Generates a Basic authorization header.