Skip to content

Commit de7283c

Browse files
committed
add throttle login request test
1 parent 396c262 commit de7283c

1 file changed

Lines changed: 91 additions & 0 deletions

File tree

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import { Controller, Get, HttpStatus } from '@nestjs/common';
2+
import { APP_GUARD } from '@nestjs/core';
3+
import { FastifyAdapter } from '@nestjs/platform-fastify';
4+
import type { NestFastifyApplication } from '@nestjs/platform-fastify';
5+
import { Test } from '@nestjs/testing';
6+
import { ThrottlerGuard, ThrottlerModule } from '@nestjs/throttler';
7+
import { afterEach, describe, expect, it, vi } from 'vitest';
8+
9+
const MOCK_DEFAULT_LOGIN_REQUEST_THROTTLER_LIMIT = 5;
10+
11+
// use lower limit to avoid slowing down tests
12+
vi.mock('../../constants', () => ({
13+
DEFAULT_LOGIN_REQUEST_THROTTLER_LIMIT: MOCK_DEFAULT_LOGIN_REQUEST_THROTTLER_LIMIT,
14+
DEFAULT_LOGIN_REQUEST_THROTTLER_TTL: 60_000
15+
}));
16+
17+
async function createMockApp() {
18+
// need to use async import here to apply mocked env every time
19+
const { ThrottleLoginRequest } = await import('../throttle-login-request.decorator');
20+
21+
@Controller()
22+
class AppController {
23+
@Get()
24+
@ThrottleLoginRequest()
25+
get() {
26+
return { success: true };
27+
}
28+
}
29+
const moduleRef = await Test.createTestingModule({
30+
controllers: [AppController],
31+
imports: [
32+
ThrottlerModule.forRoot([
33+
{
34+
limit: 1000,
35+
name: 'long',
36+
ttl: 60_000
37+
}
38+
])
39+
],
40+
providers: [
41+
{
42+
provide: APP_GUARD,
43+
useClass: ThrottlerGuard
44+
}
45+
]
46+
}).compile();
47+
const app = moduleRef.createNestApplication<NestFastifyApplication>(new FastifyAdapter({}));
48+
await app.init();
49+
await app.getHttpAdapter().getInstance().ready();
50+
return app;
51+
}
52+
53+
describe('ThrottleLoginRequest', () => {
54+
let app: NestFastifyApplication;
55+
56+
afterEach(async () => {
57+
if (app) {
58+
await app.close();
59+
}
60+
vi.resetModules();
61+
});
62+
63+
it('should use default values when environment variables are not set', async () => {
64+
app = await createMockApp();
65+
for (let i = 0; i < MOCK_DEFAULT_LOGIN_REQUEST_THROTTLER_LIMIT; i++) {
66+
const response = await app.inject({ method: 'GET', url: '/' });
67+
expect(response.json()).toMatchObject({ success: true });
68+
expect(response.statusCode).toBe(HttpStatus.OK);
69+
}
70+
const response = await app.inject({ method: 'GET', url: '/' });
71+
expect(response.statusCode).toBe(HttpStatus.TOO_MANY_REQUESTS);
72+
});
73+
74+
it('should use custom values from environment variables', async () => {
75+
vi.stubEnv('LOGIN_REQUEST_THROTTLER_LIMIT', '3');
76+
vi.stubEnv('LOGIN_REQUEST_THROTTLER_TTL', '30000');
77+
78+
app = await createMockApp();
79+
80+
for (let i = 0; i < 3; i++) {
81+
const response = await app.inject({ method: 'GET', url: '/' });
82+
expect(response.json()).toMatchObject({ success: true });
83+
expect(response.statusCode).toBe(HttpStatus.OK);
84+
}
85+
86+
const response = await app.inject({ method: 'GET', url: '/' });
87+
expect(response.statusCode).toBe(HttpStatus.TOO_MANY_REQUESTS);
88+
89+
vi.unstubAllEnvs();
90+
});
91+
});

0 commit comments

Comments
 (0)