50 lines
1.6 KiB
JavaScript
50 lines
1.6 KiB
JavaScript
import { describe, it, before, after, beforeEach } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import Koa from 'koa';
|
|
import bodyParser from 'koa-bodyparser';
|
|
import supertest from 'supertest';
|
|
import { rateLimit } from '../middleware/ratelimit.js';
|
|
|
|
describe('rateLimit 中间件', () => {
|
|
let app, agent;
|
|
|
|
before(() => {
|
|
app = new Koa();
|
|
app.use(bodyParser());
|
|
app.use(rateLimit(3, 60_000));
|
|
app.use(async (ctx) => {
|
|
ctx.body = { ok: true };
|
|
});
|
|
agent = supertest(app.callback());
|
|
});
|
|
|
|
it('前3次请求应正常通过', async () => {
|
|
for (let i = 0; i < 3; i++) {
|
|
const res = await agent.post('/test').send({});
|
|
assert.equal(res.status, 200);
|
|
assert.equal(res.body.ok, true);
|
|
}
|
|
});
|
|
|
|
it('第4次请求应被限流', async () => {
|
|
const res = await agent.post('/test').send({});
|
|
assert.equal(res.status, 200); // HTTP 200,业务码 429
|
|
assert.equal(res.body.code, 429);
|
|
assert.ok(res.body.msg.includes('请求过于频繁'));
|
|
assert.ok(res.headers['retry-after']);
|
|
});
|
|
|
|
it('限流响应头应包含 X-RateLimit 信息', async () => {
|
|
// 新建一个不受之前计数影响的中间件(不同限流阈值 + 不同路径)
|
|
const freshApp = new Koa();
|
|
freshApp.use(bodyParser());
|
|
freshApp.use(rateLimit(100, 60_000));
|
|
freshApp.use(async (ctx) => { ctx.body = { ok: true }; });
|
|
const freshAgent = supertest(freshApp.callback());
|
|
|
|
const res = await freshAgent.post('/headercheck').send({});
|
|
assert.equal(res.headers['x-ratelimit-limit'], '100');
|
|
assert.equal(res.headers['x-ratelimit-remaining'], '99');
|
|
});
|
|
});
|