Skip to content

Commit

Permalink
chore: migrate from tap to node:test and c8 (#378)
Browse files Browse the repository at this point in the history
  • Loading branch information
dancastillo authored Aug 25, 2024
1 parent 20454fb commit e5f6a46
Show file tree
Hide file tree
Showing 10 changed files with 2,439 additions and 1,836 deletions.
3 changes: 0 additions & 3 deletions .taprc

This file was deleted.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"lint:fix": "standard --fix",
"redis": "docker run -p 6379:6379 --name rate-limit-redis -d --rm redis",
"test": "npm run test:unit && npm run test:typescript",
"test:unit": "tap",
"test:unit": "c8 --100 node --test",
"test:typescript": "tsd"
},
"repository": {
Expand All @@ -32,12 +32,12 @@
"@fastify/pre-commit": "^2.1.0",
"@sinonjs/fake-timers": "^11.2.2",
"@types/node": "^22.0.0",
"c8": "^10.1.2",
"fastify": "^5.0.0-alpha.3",
"ioredis": "^5.4.1",
"knex": "^3.1.0",
"sqlite3": "^5.1.7",
"standard": "^17.1.0",
"tap": "20.0.3",
"tsd": "^0.31.1"
},
"dependencies": {
Expand Down
118 changes: 76 additions & 42 deletions test/github-issues/issue-207.test.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,33 @@
'use strict'

const FakeTimers = require('@sinonjs/fake-timers')
const t = require('tap')
const test = t.test
const { test, mock } = require('node:test')
const Fastify = require('fastify')
const rateLimit = require('../../index')

t.beforeEach(t => {
t.context.clock = FakeTimers.install()
})

t.afterEach(t => {
t.context.clock.uninstall()
})

test('issue #207 - when continueExceeding is true and the store is local then it should reset the rate-limit', async t => {
test('issue #207 - when continueExceeding is true and the store is local then it should reset the rate-limit', async (t) => {
const clock = mock.timers
clock.enable()
const fastify = Fastify()

await fastify.register(rateLimit, {
global: false
})

fastify.get('/', {
config: {
rateLimit: {
max: 1,
timeWindow: 5000,
continueExceeding: true
fastify.get(
'/',
{
config: {
rateLimit: {
max: 1,
timeWindow: 5000,
continueExceeding: true
}
}
},
async () => {
return 'hello!'
}
}, async () => {
return 'hello!'
})
)

const firstOkResponse = await fastify.inject({
url: '/',
Expand All @@ -42,45 +38,83 @@ test('issue #207 - when continueExceeding is true and the store is local then it
method: 'GET'
})

t.context.clock.tick(3000)
clock.tick(3000)

const secondRateLimitWithResettingTheRateLimitTimer = await fastify.inject({
url: '/',
method: 'GET'
})

// after this the total time passed is 6s which WITHOUT `continueExceeding` the next request should be OK
t.context.clock.tick(3000)
clock.tick(3000)

const thirdRateLimitWithResettingTheRateLimitTimer = await fastify.inject({
url: '/',
method: 'GET'
})

// After this the rate limiter should allow for new requests
t.context.clock.tick(5000)
clock.tick(5000)

const okResponseAfterRateLimitCompleted = await fastify.inject({
url: '/',
method: 'GET'
})

t.equal(firstOkResponse.statusCode, 200)

t.equal(firstRateLimitResponse.statusCode, 429)
t.equal(firstRateLimitResponse.headers['x-ratelimit-limit'], '1')
t.equal(firstRateLimitResponse.headers['x-ratelimit-remaining'], '0')
t.equal(firstRateLimitResponse.headers['x-ratelimit-reset'], '5')

t.equal(secondRateLimitWithResettingTheRateLimitTimer.statusCode, 429)
t.equal(secondRateLimitWithResettingTheRateLimitTimer.headers['x-ratelimit-limit'], '1')
t.equal(secondRateLimitWithResettingTheRateLimitTimer.headers['x-ratelimit-remaining'], '0')
t.equal(secondRateLimitWithResettingTheRateLimitTimer.headers['x-ratelimit-reset'], '5')

t.equal(thirdRateLimitWithResettingTheRateLimitTimer.statusCode, 429)
t.equal(thirdRateLimitWithResettingTheRateLimitTimer.headers['x-ratelimit-limit'], '1')
t.equal(thirdRateLimitWithResettingTheRateLimitTimer.headers['x-ratelimit-remaining'], '0')
t.equal(thirdRateLimitWithResettingTheRateLimitTimer.headers['x-ratelimit-reset'], '5')

t.equal(okResponseAfterRateLimitCompleted.statusCode, 200)
t.assert.deepStrictEqual(firstOkResponse.statusCode, 200)

t.assert.deepStrictEqual(firstRateLimitResponse.statusCode, 429)
t.assert.deepStrictEqual(
firstRateLimitResponse.headers['x-ratelimit-limit'],
'1'
)
t.assert.deepStrictEqual(
firstRateLimitResponse.headers['x-ratelimit-remaining'],
'0'
)
t.assert.deepStrictEqual(
firstRateLimitResponse.headers['x-ratelimit-reset'],
'5'
)

t.assert.deepStrictEqual(
secondRateLimitWithResettingTheRateLimitTimer.statusCode,
429
)
t.assert.deepStrictEqual(
secondRateLimitWithResettingTheRateLimitTimer.headers['x-ratelimit-limit'],
'1'
)
t.assert.deepStrictEqual(
secondRateLimitWithResettingTheRateLimitTimer.headers[
'x-ratelimit-remaining'
],
'0'
)
t.assert.deepStrictEqual(
secondRateLimitWithResettingTheRateLimitTimer.headers['x-ratelimit-reset'],
'5'
)

t.assert.deepStrictEqual(
thirdRateLimitWithResettingTheRateLimitTimer.statusCode,
429
)
t.assert.deepStrictEqual(
thirdRateLimitWithResettingTheRateLimitTimer.headers['x-ratelimit-limit'],
'1'
)
t.assert.deepStrictEqual(
thirdRateLimitWithResettingTheRateLimitTimer.headers[
'x-ratelimit-remaining'
],
'0'
)
t.assert.deepStrictEqual(
thirdRateLimitWithResettingTheRateLimitTimer.headers['x-ratelimit-reset'],
'5'
)

t.assert.deepStrictEqual(okResponseAfterRateLimitCompleted.statusCode, 200)
clock.reset(0)
})
66 changes: 36 additions & 30 deletions test/github-issues/issue-215.test.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,32 @@
'use strict'

const FakeTimers = require('@sinonjs/fake-timers')
const t = require('tap')
const test = t.test
const { test, mock } = require('node:test')
const Fastify = require('fastify')
const rateLimit = require('../../index')

t.beforeEach(t => {
t.context.clock = FakeTimers.install()
})

t.afterEach(t => {
t.context.clock.uninstall()
})

test('issue #215 - when using local store, 2nd user should not be rate limited when the time window is passed for the 1st user', async t => {
test('issue #215 - when using local store, 2nd user should not be rate limited when the time window is passed for the 1st user', async (t) => {
t.plan(5)
const clock = mock.timers
clock.enable()
const fastify = Fastify()

await fastify.register(rateLimit, {
global: false
})

fastify.get('/', {
config: {
rateLimit: {
max: 1,
timeWindow: 5000,
continueExceeding: false
fastify.get(
'/',
{
config: {
rateLimit: {
max: 1,
timeWindow: 5000,
continueExceeding: false
}
}
}
}, async () => 'hello!')
},
async () => 'hello!'
)

const user1FirstRequest = await fastify.inject({
url: '/',
Expand All @@ -39,7 +35,7 @@ test('issue #215 - when using local store, 2nd user should not be rate limited w
})

// Waiting for the time to pass to make the 2nd user start in a different start point
t.context.clock.tick(3000)
clock.tick(3000)

const user2FirstRequest = await fastify.inject({
url: '/',
Expand All @@ -54,7 +50,7 @@ test('issue #215 - when using local store, 2nd user should not be rate limited w
})

// After this the total time passed for the 1st user is 6s and for the 2nd user only 3s
t.context.clock.tick(3000)
clock.tick(3000)

const user2ThirdRequestAndShouldStillBeRateLimited = await fastify.inject({
url: '/',
Expand All @@ -63,19 +59,29 @@ test('issue #215 - when using local store, 2nd user should not be rate limited w
})

// After this the total time passed for the 2nd user is 5.1s - he should not be rate limited
t.context.clock.tick(2100)
clock.tick(2100)

const user2OkResponseAfterRateLimitCompleted = await fastify.inject({
url: '/',
method: 'GET',
remoteAddress: '2.2.2.2'
})

t.equal(user1FirstRequest.statusCode, 200)
t.equal(user2FirstRequest.statusCode, 200)

t.equal(user2SecondRequestAndShouldBeRateLimited.statusCode, 429)
t.equal(user2ThirdRequestAndShouldStillBeRateLimited.statusCode, 429)

t.equal(user2OkResponseAfterRateLimitCompleted.statusCode, 200)
t.assert.deepStrictEqual(user1FirstRequest.statusCode, 200)
t.assert.deepStrictEqual(user2FirstRequest.statusCode, 200)

t.assert.deepStrictEqual(
user2SecondRequestAndShouldBeRateLimited.statusCode,
429
)
t.assert.deepStrictEqual(
user2ThirdRequestAndShouldStillBeRateLimited.statusCode,
429
)

t.assert.deepStrictEqual(
user2OkResponseAfterRateLimitCompleted.statusCode,
200
)
clock.reset()
})
66 changes: 36 additions & 30 deletions test/github-issues/issue-284.test.js
Original file line number Diff line number Diff line change
@@ -1,44 +1,40 @@
'use strict'

const FakeTimers = require('@sinonjs/fake-timers')
const t = require('tap')
const test = t.test
const { test, mock } = require('node:test')
const Fastify = require('fastify')
const rateLimit = require('../../index')

t.beforeEach(t => {
t.context.clock = FakeTimers.install()
})

t.afterEach(t => {
t.context.clock.uninstall()
})

test("issue #284 - don't set the reply code automatically", async t => {
test("issue #284 - don't set the reply code automatically", async (t) => {
const clock = mock.timers
clock.enable()
const fastify = Fastify()

await fastify.register(rateLimit, {
global: false
})

fastify.setErrorHandler((err, req, res) => {
t.equal(res.statusCode, 200)
t.equal(err.statusCode, 429)
t.assert.deepStrictEqual(res.statusCode, 200)
t.assert.deepStrictEqual(err.statusCode, 429)

res.redirect('/')
})

fastify.get('/', {
config: {
rateLimit: {
max: 1,
timeWindow: 5000,
continueExceeding: true
fastify.get(
'/',
{
config: {
rateLimit: {
max: 1,
timeWindow: 5000,
continueExceeding: true
}
}
},
async () => {
return 'hello!'
}
}, async () => {
return 'hello!'
})
)

const firstOkResponse = await fastify.inject({
url: '/',
Expand All @@ -50,19 +46,29 @@ test("issue #284 - don't set the reply code automatically", async t => {
})

// After this the rate limiter should allow for new requests
t.context.clock.tick(5000)
clock.tick(5000)

const okResponseAfterRateLimitCompleted = await fastify.inject({
url: '/',
method: 'GET'
})

t.equal(firstOkResponse.statusCode, 200)
t.assert.deepStrictEqual(firstOkResponse.statusCode, 200)

t.equal(firstRateLimitResponse.statusCode, 302)
t.equal(firstRateLimitResponse.headers['x-ratelimit-limit'], '1')
t.equal(firstRateLimitResponse.headers['x-ratelimit-remaining'], '0')
t.equal(firstRateLimitResponse.headers['x-ratelimit-reset'], '5')
t.assert.deepStrictEqual(firstRateLimitResponse.statusCode, 302)
t.assert.deepStrictEqual(
firstRateLimitResponse.headers['x-ratelimit-limit'],
'1'
)
t.assert.deepStrictEqual(
firstRateLimitResponse.headers['x-ratelimit-remaining'],
'0'
)
t.assert.deepStrictEqual(
firstRateLimitResponse.headers['x-ratelimit-reset'],
'5'
)

t.equal(okResponseAfterRateLimitCompleted.statusCode, 200)
t.assert.deepStrictEqual(okResponseAfterRateLimitCompleted.statusCode, 200)
clock.reset(0)
})
Loading

0 comments on commit e5f6a46

Please sign in to comment.