mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-15 13:47:33 +01:00
improve test coverage
This commit is contained in:
@@ -7,6 +7,7 @@ import {
|
|||||||
} from '../../../helpers/api-unit.helper';
|
} from '../../../helpers/api-unit.helper';
|
||||||
import { Forbidden } from '../../../../website/server/libs/errors';
|
import { Forbidden } from '../../../../website/server/libs/errors';
|
||||||
import { apiError } from '../../../../website/server/libs/apiError';
|
import { apiError } from '../../../../website/server/libs/apiError';
|
||||||
|
import { model as Blocker } from '../../../../website/server/models/blocker';
|
||||||
|
|
||||||
function checkIPBlockedErrorThrown (next) {
|
function checkIPBlockedErrorThrown (next) {
|
||||||
expect(next).to.have.been.calledOnce;
|
expect(next).to.have.been.calledOnce;
|
||||||
@@ -15,6 +16,13 @@ function checkIPBlockedErrorThrown (next) {
|
|||||||
expect(calledWith[0] instanceof Forbidden).to.equal(true);
|
expect(calledWith[0] instanceof Forbidden).to.equal(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function checkClientBlockedErrorThrown (next) {
|
||||||
|
expect(next).to.have.been.calledOnce;
|
||||||
|
const calledWith = next.getCall(0).args;
|
||||||
|
expect(calledWith[0].message).to.equal(apiError('clientBlocked'));
|
||||||
|
expect(calledWith[0] instanceof Forbidden).to.equal(true);
|
||||||
|
}
|
||||||
|
|
||||||
function checkErrorNotThrown (next) {
|
function checkErrorNotThrown (next) {
|
||||||
expect(next).to.have.been.calledOnce;
|
expect(next).to.have.been.calledOnce;
|
||||||
const calledWith = next.getCall(0).args;
|
const calledWith = next.getCall(0).args;
|
||||||
@@ -35,24 +43,24 @@ describe('Blocker middleware', () => {
|
|||||||
describe('Blocking IPs', () => {
|
describe('Blocking IPs', () => {
|
||||||
it('is disabled when the env var is not defined', () => {
|
it('is disabled when the env var is not defined', () => {
|
||||||
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns(undefined);
|
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns(undefined);
|
||||||
const attachIpBlocker = requireAgain(pathToBlocker).default;
|
const attachBlocker = requireAgain(pathToBlocker).default;
|
||||||
attachIpBlocker(req, res, next);
|
attachBlocker(req, res, next);
|
||||||
|
|
||||||
checkErrorNotThrown(next);
|
checkErrorNotThrown(next);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('is disabled when the env var is an empty string', () => {
|
it('is disabled when the env var is an empty string', () => {
|
||||||
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns('');
|
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns('');
|
||||||
const attachIpBlocker = requireAgain(pathToBlocker).default;
|
const attachBlocker = requireAgain(pathToBlocker).default;
|
||||||
attachIpBlocker(req, res, next);
|
attachBlocker(req, res, next);
|
||||||
|
|
||||||
checkErrorNotThrown(next);
|
checkErrorNotThrown(next);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('is disabled when the env var contains comma separated empty strings', () => {
|
it('is disabled when the env var contains comma separated empty strings', () => {
|
||||||
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns(' , , ');
|
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns(' , , ');
|
||||||
const attachIpBlocker = requireAgain(pathToBlocker).default;
|
const attachBlocker = requireAgain(pathToBlocker).default;
|
||||||
attachIpBlocker(req, res, next);
|
attachBlocker(req, res, next);
|
||||||
|
|
||||||
checkErrorNotThrown(next);
|
checkErrorNotThrown(next);
|
||||||
});
|
});
|
||||||
@@ -60,19 +68,139 @@ describe('Blocker middleware', () => {
|
|||||||
it('does not throw when the ip does not match', () => {
|
it('does not throw when the ip does not match', () => {
|
||||||
req.ip = '192.168.1.1';
|
req.ip = '192.168.1.1';
|
||||||
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns('192.168.1.2');
|
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns('192.168.1.2');
|
||||||
const attachIpBlocker = requireAgain(pathToBlocker).default;
|
const attachBlocker = requireAgain(pathToBlocker).default;
|
||||||
attachIpBlocker(req, res, next);
|
attachBlocker(req, res, next);
|
||||||
|
|
||||||
checkErrorNotThrown(next);
|
checkErrorNotThrown(next);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not throw when the blocker IP does not match', async () => {
|
||||||
|
req.ip = '192.168.1.1';
|
||||||
|
sandbox.stub(Blocker, 'watchBlockers').returns({
|
||||||
|
on: (event, callback) => {
|
||||||
|
if (event === 'change') {
|
||||||
|
callback({ operation: 'add', blocker: { type: 'ipaddress', area: 'full', value: '192.168.1.2' } });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const attachBlocker = requireAgain(pathToBlocker).default;
|
||||||
|
attachBlocker(req, res, next);
|
||||||
|
|
||||||
|
checkErrorNotThrown(next);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not throw when a client is blocked', async () => {
|
||||||
|
sandbox.stub(Blocker, 'watchBlockers').returns({
|
||||||
|
on: (event, callback) => {
|
||||||
|
if (event === 'change') {
|
||||||
|
callback({ operation: 'add', blocker: { type: 'client', area: 'full', value: '192.168.1.1' } });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const attachBlocker = requireAgain(pathToBlocker).default;
|
||||||
|
attachBlocker(req, res, next);
|
||||||
|
|
||||||
|
checkErrorNotThrown(next);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws when the blocker IP is blocked', async () => {
|
||||||
|
req.ip = '192.168.1.1';
|
||||||
|
sandbox.stub(Blocker, 'watchBlockers').returns({
|
||||||
|
on: (event, callback) => {
|
||||||
|
if (event === 'change') {
|
||||||
|
callback({ operation: 'add', blocker: { type: 'ipaddress', area: 'full', value: '192.168.1.1' } });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const attachBlocker = requireAgain(pathToBlocker).default;
|
||||||
|
attachBlocker(req, res, next);
|
||||||
|
|
||||||
|
checkIPBlockedErrorThrown(next);
|
||||||
|
});
|
||||||
|
|
||||||
it('throws when the ip is blocked', () => {
|
it('throws when the ip is blocked', () => {
|
||||||
req.ip = '192.168.1.1';
|
req.ip = '192.168.1.1';
|
||||||
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns('192.168.1.1');
|
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns('192.168.1.1');
|
||||||
const attachIpBlocker = requireAgain(pathToBlocker).default;
|
const attachBlocker = requireAgain(pathToBlocker).default;
|
||||||
attachIpBlocker(req, res, next);
|
attachBlocker(req, res, next);
|
||||||
|
|
||||||
checkIPBlockedErrorThrown(next);
|
checkIPBlockedErrorThrown(next);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Blocking clients', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
sandbox.stub(nconf, 'get').withArgs('BLOCKED_IPS').returns('');
|
||||||
|
req.headers['x-client'] = 'test-client';
|
||||||
|
});
|
||||||
|
it('is disabled when no clients are blocked', () => {
|
||||||
|
const attachBlocker = requireAgain(pathToBlocker).default;
|
||||||
|
attachBlocker(req, res, next);
|
||||||
|
|
||||||
|
checkErrorNotThrown(next);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not throw when the client does not match', async () => {
|
||||||
|
sandbox.stub(Blocker, 'watchBlockers').returns({
|
||||||
|
on: (event, callback) => {
|
||||||
|
if (event === 'change') {
|
||||||
|
callback({ operation: 'add', blocker: { type: 'client', area: 'full', value: 'another-client' } });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const attachBlocker = requireAgain(pathToBlocker).default;
|
||||||
|
attachBlocker(req, res, next);
|
||||||
|
|
||||||
|
checkErrorNotThrown(next);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws when the client is blocked', async () => {
|
||||||
|
sandbox.stub(Blocker, 'watchBlockers').returns({
|
||||||
|
on: (event, callback) => {
|
||||||
|
if (event === 'change') {
|
||||||
|
callback({ operation: 'add', blocker: { type: 'client', area: 'full', value: 'test-client' } });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const attachBlocker = requireAgain(pathToBlocker).default;
|
||||||
|
attachBlocker(req, res, next);
|
||||||
|
|
||||||
|
checkClientBlockedErrorThrown(next);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not throw when an ip is blocked', async () => {
|
||||||
|
sandbox.stub(Blocker, 'watchBlockers').returns({
|
||||||
|
on: (event, callback) => {
|
||||||
|
if (event === 'change') {
|
||||||
|
callback({ operation: 'add', blocker: { type: 'ipaddress', area: 'full', value: 'test-client' } });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const attachBlocker = requireAgain(pathToBlocker).default;
|
||||||
|
attachBlocker(req, res, next);
|
||||||
|
|
||||||
|
checkErrorNotThrown(next);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('updates the list when data changes', async () => {
|
||||||
|
let blockCallback;
|
||||||
|
sandbox.stub(Blocker, 'watchBlockers').returns({
|
||||||
|
on: (event, callback) => {
|
||||||
|
blockCallback = callback;
|
||||||
|
if (event === 'change') {
|
||||||
|
callback({ operation: 'add', blocker: { type: 'client', area: 'full', value: 'another-client' } });
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const attachBlocker = requireAgain(pathToBlocker).default;
|
||||||
|
attachBlocker(req, res, next);
|
||||||
|
checkErrorNotThrown(next);
|
||||||
|
blockCallback({ operation: 'add', blocker: { type: 'client', area: 'full', value: 'test-client' } });
|
||||||
|
attachBlocker(req, res, next);
|
||||||
|
expect(next).to.have.been.calledTwice;
|
||||||
|
const calledWith = next.getCall(1).args;
|
||||||
|
expect(calledWith[0].message).to.equal(apiError('clientBlocked'));
|
||||||
|
expect(calledWith[0] instanceof Forbidden).to.equal(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export const schema = new mongoose.Schema({
|
|||||||
$type: String, required: true, // e.g. IP address
|
$type: String, required: true, // e.g. IP address
|
||||||
},
|
},
|
||||||
blockSource: {
|
blockSource: {
|
||||||
$type: String, enum: ['user', 'system', 'worker'], default: 'user', // who created the block
|
$type: String, enum: ['administrator', 'system', 'worker'], default: 'administrator', // who created the block
|
||||||
},
|
},
|
||||||
reason: {
|
reason: {
|
||||||
$type: String, required: false, // e.g. 'abusive behavior'
|
$type: String, required: false, // e.g. 'abusive behavior'
|
||||||
|
|||||||
Reference in New Issue
Block a user