| | const mongoose = require('mongoose'); |
| | const { MongoMemoryServer } = require('mongodb-memory-server'); |
| | const banViolation = require('./banViolation'); |
| |
|
| | |
| | jest.mock('~/models', () => ({ |
| | ...jest.requireActual('~/models'), |
| | deleteAllUserSessions: jest.fn().mockResolvedValue(true), |
| | })); |
| |
|
| | describe('banViolation', () => { |
| | let mongoServer; |
| | let req, res, errorMessage; |
| |
|
| | beforeAll(async () => { |
| | mongoServer = await MongoMemoryServer.create(); |
| | const mongoUri = mongoServer.getUri(); |
| | await mongoose.connect(mongoUri); |
| | }); |
| |
|
| | afterAll(async () => { |
| | await mongoose.disconnect(); |
| | await mongoServer.stop(); |
| | }); |
| |
|
| | beforeEach(() => { |
| | req = { |
| | ip: '127.0.0.1', |
| | cookies: { |
| | refreshToken: 'someToken', |
| | }, |
| | }; |
| | res = { |
| | clearCookie: jest.fn(), |
| | }; |
| | errorMessage = { |
| | type: 'someViolation', |
| | user_id: new mongoose.Types.ObjectId().toString(), |
| | prev_count: 0, |
| | violation_count: 0, |
| | }; |
| | process.env.BAN_VIOLATIONS = 'true'; |
| | process.env.BAN_DURATION = '7200000'; |
| | process.env.BAN_INTERVAL = '20'; |
| | }); |
| |
|
| | afterEach(() => { |
| | jest.clearAllMocks(); |
| | }); |
| |
|
| | it('should not ban if BAN_VIOLATIONS are not enabled', async () => { |
| | process.env.BAN_VIOLATIONS = 'false'; |
| | await banViolation(req, res, errorMessage); |
| | expect(errorMessage.ban).toBeFalsy(); |
| | }); |
| |
|
| | it('should not ban if errorMessage is not provided', async () => { |
| | await banViolation(req, res, null); |
| | expect(errorMessage.ban).toBeFalsy(); |
| | }); |
| |
|
| | it('[1/3] should ban if violation_count crosses the interval threshold: 19 -> 39', async () => { |
| | errorMessage.prev_count = 19; |
| | errorMessage.violation_count = 39; |
| | await banViolation(req, res, errorMessage); |
| | expect(errorMessage.ban).toBeTruthy(); |
| | }); |
| |
|
| | it('[2/3] should ban if violation_count crosses the interval threshold: 19 -> 20', async () => { |
| | errorMessage.prev_count = 19; |
| | errorMessage.violation_count = 20; |
| | await banViolation(req, res, errorMessage); |
| | expect(errorMessage.ban).toBeTruthy(); |
| | }); |
| |
|
| | const randomValueAbove = Math.floor(20 + Math.random() * 100); |
| | it(`[3/3] should ban if violation_count crosses the interval threshold: 19 -> ${randomValueAbove}`, async () => { |
| | errorMessage.prev_count = 19; |
| | errorMessage.violation_count = randomValueAbove; |
| | await banViolation(req, res, errorMessage); |
| | expect(errorMessage.ban).toBeTruthy(); |
| | }); |
| |
|
| | it('should handle invalid BAN_INTERVAL and default to 20', async () => { |
| | process.env.BAN_INTERVAL = 'invalid'; |
| | errorMessage.prev_count = 19; |
| | errorMessage.violation_count = 39; |
| | await banViolation(req, res, errorMessage); |
| | expect(errorMessage.ban).toBeTruthy(); |
| | }); |
| |
|
| | it('should ban if BAN_DURATION is invalid as default is 2 hours', async () => { |
| | process.env.BAN_DURATION = 'invalid'; |
| | errorMessage.prev_count = 19; |
| | errorMessage.violation_count = 39; |
| | await banViolation(req, res, errorMessage); |
| | expect(errorMessage.ban).toBeTruthy(); |
| | }); |
| |
|
| | it('should not ban if BAN_DURATION is 0 but should clear cookies', async () => { |
| | process.env.BAN_DURATION = '0'; |
| | errorMessage.prev_count = 19; |
| | errorMessage.violation_count = 39; |
| | await banViolation(req, res, errorMessage); |
| | expect(res.clearCookie).toHaveBeenCalledWith('refreshToken'); |
| | }); |
| |
|
| | it('should not ban if violation_count does not change', async () => { |
| | errorMessage.prev_count = 0; |
| | errorMessage.violation_count = 0; |
| | await banViolation(req, res, errorMessage); |
| | expect(errorMessage.ban).toBeFalsy(); |
| | }); |
| |
|
| | it('[1/2] should not ban if violation_count does not cross the interval threshold: 0 -> 19', async () => { |
| | errorMessage.prev_count = 0; |
| | errorMessage.violation_count = 19; |
| | await banViolation(req, res, errorMessage); |
| | expect(errorMessage.ban).toBeFalsy(); |
| | }); |
| |
|
| | const randomValueUnder = Math.floor(1 + Math.random() * 19); |
| | it(`[2/2] should not ban if violation_count does not cross the interval threshold: 0 -> ${randomValueUnder}`, async () => { |
| | errorMessage.prev_count = 0; |
| | errorMessage.violation_count = randomValueUnder; |
| | await banViolation(req, res, errorMessage); |
| | expect(errorMessage.ban).toBeFalsy(); |
| | }); |
| |
|
| | it('[EDGE CASE] should not ban if violation_count is lower', async () => { |
| | errorMessage.prev_count = 0; |
| | errorMessage.violation_count = -10; |
| | await banViolation(req, res, errorMessage); |
| | expect(errorMessage.ban).toBeFalsy(); |
| | }); |
| | }); |
| |
|