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');
|
||
});
|
||
});
|