Spaces:
Running
Running
; | |
/** | |
* Tests for Punishments. | |
* | |
* @author mia-pi-git | |
* @author Annika | |
*/ | |
const assert = require('../assert'); | |
const { makeUser, makeConnection } = require('../users-utils'); | |
const { Punishments } = require('../../dist/server/punishments'); | |
const TEST_PUNISHMENT_DURATION = 1000; // 1 second | |
describe("Punishments", () => { | |
it("Should properly sort punishments by weight", () => { | |
const list = [ | |
{ type: "LOCK", id: "User 1", expireTime: Date.now() + 1000, reason: '' }, | |
{ type: "SEMILOCK", id: "User 2", expireTime: Date.now() + 1000, reason: '' }, | |
{ type: "BAN", id: "", expireTime: Date.now() + 1000, reason: '' }, | |
]; | |
Punishments.byWeight(list); | |
assert.equal(list[0].type, 'BAN'); | |
}); | |
it("Should prevent a user from having two punishments of the same type", () => { | |
Punishments.userids.add('banmeplease', { type: 'BAN', expireTime: Date.now() + 30 * 1000, id: 'banmeplease', reason: '' }); | |
Punishments.userids.add("banmeplease", { type: 'BAN', expireTime: Date.now() + 30 * 1000, id: 'banmeplease', reason: 'ok' }); | |
assert.equal(Punishments.userids.get('banmeplease').length, 1); | |
}); | |
it("Should overwrite the old reason when a user receives two of the same punishment", () => { | |
Punishments.userids.add('banmeplease', { type: 'BAN', expireTime: Date.now() + 30 * 1000, id: 'banmeplease', reason: '' }); | |
Punishments.userids.add("banmeplease", { type: 'BAN', expireTime: Date.now() + 30 * 1000, id: 'banmeplease', reason: 'ok' }); | |
assert.equal(Punishments.userids.getByType('banmeplease', 'BAN').reason, 'ok'); | |
}); | |
it("Should properly filter out expiring punishments", () => { | |
const punishments = [{ type: 'BAN', expireTime: Date.now() - 1000, id: 'banmeplease', reason: '' }]; | |
Punishments.userids.removeExpiring(punishments); | |
assert.equal(punishments.length, 0); | |
}); | |
it("Should be able to remove only one punishment from the list by passing an object", () => { | |
const [expireTime, reason, id] = [Date.now() + 1000, '', 'banmeplease']; | |
Punishments.userids.add(id, { type: 'BAN', expireTime, reason, id }); | |
Punishments.userids.add(id, { type: 'RICKROLL', expireTime, reason, id }); | |
Punishments.userids.deleteOne(id, { type: 'RICKROLL', expireTime, reason, id }); | |
assert.equal(Punishments.userids.get(id).length, 1); | |
}); | |
it('should properly search for IP punishments by type', () => { | |
const [expireTime, reason, id] = [Date.now() + 1000, '', 'banmeplease']; | |
Punishments.ips.add('127.0.0.1', { type: 'BAN', expireTime, reason, id }); | |
Punishments.ips.add('127.0.0.1', { type: 'RICKROLL', expireTime, reason, id }); | |
Punishments.ips.add('127.0.*', { type: 'RANGEBAN', expireTime, reason, id }); | |
const allIPPunishments = Punishments.ipSearch('127.0.0.1'); | |
assert(Array.isArray(allIPPunishments)); | |
assert.equal(allIPPunishments.length, 3); | |
const ban = Punishments.ipSearch('127.0.0.1', 'BAN'); | |
assert(!Array.isArray(ban)); | |
assert.equal(ban.type, 'BAN'); | |
const rickroll = Punishments.ipSearch('127.0.0.1', 'RICKROLL'); | |
assert(!Array.isArray(rickroll)); | |
assert.equal(rickroll.type, 'RICKROLL'); | |
}); | |
}); | |
describe('broader, more integrated Punishments tests', function () { | |
before(() => { | |
this.room = Rooms.get('lobby'); | |
this.parse = async function (message) { | |
Chat.loadPlugins(); | |
const context = new Chat.CommandContext({ | |
message, | |
room: this.room, | |
user: this.user, | |
connection: this.connection, | |
}); | |
return context.parse(); | |
}; | |
}); | |
describe('room bans', () => { | |
before(() => { | |
this.user = makeUser("Roomban Me Please", '127.0.0.8'); | |
this.connection = this.user.connections[0]; | |
this.user.joinRoom(this.room.roomid, this.connection); | |
}); | |
beforeEach(async () => Punishments.roomBan(this.room, this.user, Date.now() + TEST_PUNISHMENT_DURATION, this.user.id, false, 'test')); | |
afterEach(() => Punishments.roomUnban(this.room, this.user.id)); | |
it('should force the user to leave the room and prevent them from rejoining', async () => { | |
assert.equal(this.user.id in this.room.users, false, `user should not be in the room`); | |
let joinAttempt = await this.user.tryJoinRoom(this.room, this.connection); | |
assert.equal(joinAttempt, false, `user should be unable to join a room they are banned from`); | |
Punishments.roomUnban(this.room, this.user.id); | |
joinAttempt = await this.user.tryJoinRoom(this.room, this.connection); | |
assert.equal(joinAttempt, true, `user should be able to join the room once they are unbanned`); | |
}); | |
it.skip('should expire on its own', done => { | |
assert(Punishments.hasRoomPunishType(this.room, 'roombanmeplease', 'ROOMBAN'), `should be in effect`); | |
setTimeout(() => { | |
assert(!Punishments.hasRoomPunishType(this.room, 'roombanmeplease', 'ROOMBAN'), `should have expired`); | |
done(); | |
}, TEST_PUNISHMENT_DURATION); | |
}); | |
}); | |
describe('locks (network) (slow)', () => { | |
before(() => { | |
this.user = makeUser("Lock Me Please", '127.0.0.3'); | |
this.connection = this.user.connections[0]; | |
this.user.joinRoom(this.room.roomid, this.connection); | |
}); | |
beforeEach(async () => Punishments.lock(this.user, Date.now() + TEST_PUNISHMENT_DURATION, this.user.id, false, 'test')); | |
afterEach(() => Punishments.unlock(this.user.id)); | |
it('should prevent users from chatting in rooms while they are locked', async () => { | |
const initialLogLength = this.room.log.log.length; | |
await this.parse("Hi! I'm a locked user!"); | |
assert.equal(this.room.log.log.length, initialLogLength, `user should be unable to sucessfully chat while locked`); | |
Punishments.unlock(this.user.id); | |
await this.parse("/msgroom lobby,Hi! I'm no longer locked!"); | |
// we can't just check the roomlog length because unlocking adds a |n| message to | |
const lastMessage = this.room.log.log.pop(); | |
assert(lastMessage.endsWith(` Lock Me Please|Hi! I'm no longer locked!`), `user should have sucessfuly sent a message after being locked`); | |
}); | |
// This test relies on Chat#parse returning `false` when permission is denied. | |
// I'm not sure if this is an intended feature, but the way Chat is currently implemented, | |
// an `ErrorMessage` is the only time `false` will be returned by Chat#parse (unless a chat command returns it, which /msg does not). | |
// If you are here because this test is failing, check if the above assumptions are still valid. | |
// If they are not, the test should either be refactored to use another way of | |
// determining whether a PM was sucessful (such as modifying Chat.sendPM), or skipped entirely. | |
it('should prevent users from sending PMs other than to staff while they are locked', async () => { | |
makeUser("Some Random Reg", '127.0.0.4'); | |
makeUser("Annika", '127.0.0.5').tempGroup = '~'; | |
let result = await this.parse("/msg Some Random Reg, Hi! I'm a locked user!"); | |
assert.equal(result, false, `user should be unable to sucessfully send PMs while locked`); | |
result = await this.parse("/msg Annika, Hi! I'm a locked user!"); | |
assert.notEqual(result, false, `user should be able to send PMs to global staff while locked`); | |
Punishments.unlock(this.user.id); | |
result = await this.parse("/msg Annika, Hi! I'm a locked user!"); | |
assert.notEqual(result, false, `user should be able to send PMs after being unlocked`); | |
result = await this.parse("/msg Some Random Reg, Hi! I'm a locked user!"); | |
assert.notEqual(result, false, `user should be able to send PMs after being unlocked`); | |
}); | |
// expiry tests are skipped because they fail when another test fails. | |
// I don't know why this happens; I'm guessing it's an ideosycrasy of Mocha. | |
it.skip('should expire on its own', done => { | |
assert(this.user.locked); | |
assert(Punishments.hasPunishType(this.user.id, 'LOCK')); | |
setTimeout(() => { | |
assert(!this.user.locked); | |
assert(!Punishments.hasPunishType(this.user.id, 'LOCK')); | |
done(); | |
}, TEST_PUNISHMENT_DURATION); | |
}); | |
}); | |
describe('namelocks (network) (slow)', () => { | |
before(() => { | |
this.user = makeUser("Namelock Me Please", '127.0.0.6'); | |
this.connection = this.user.connections[0]; | |
this.user.joinRoom(this.room.roomid, this.connection); | |
}); | |
beforeEach(async () => Punishments.namelock(this.user, Date.now() + TEST_PUNISHMENT_DURATION, this.user.id, false, 'test')); | |
afterEach(() => Punishments.unnamelock(this.user.id)); | |
it('should prevent the user from having a username', async () => { | |
assert(this.user.id.startsWith('guest')); | |
await this.user.rename('some other name', '', false, this.connection); | |
assert(this.user.id.startsWith('guest')); | |
}); | |
it.skip('should expire on its own', done => { | |
assert(this.user.locked); | |
assert(this.user.namelocked); | |
assert(Punishments.hasPunishType('namelockmeplease', 'NAMELOCK')); | |
setTimeout(() => { | |
assert(!this.user.locked); | |
assert(!this.user.namelocked); | |
assert(!Punishments.hasPunishType('namelockmeplease', 'NAMELOCK')); | |
done(); | |
}, TEST_PUNISHMENT_DURATION); | |
}); | |
}); | |
describe('global bans (network) (slow)', () => { | |
before(() => { | |
this.user = makeUser("Ban Me Please", '127.0.0.7'); | |
this.connection = this.user.connections[0]; | |
this.user.joinRoom(this.room.roomid, this.connection); | |
}); | |
beforeEach(async () => Punishments.ban(this.user, Date.now() + TEST_PUNISHMENT_DURATION, this.user.id, false, 'test')); | |
afterEach(() => Punishments.unban(this.user.id)); | |
it('should disconnect the user and prevent them from reconnecting', () => { | |
assert.equal(this.user.connected, false, `user should be disconnected`); | |
const conn = makeConnection('127.0.0.7'); | |
assert(Punishments.checkIpBanned(conn), `IP should be banned`); | |
}); | |
it.skip('should expire on its own', done => { | |
assert(Punishments.checkIpBanned(makeConnection('127.0.0.7')), `IP should be banned`); | |
assert(Punishments.hasPunishType('banmeplease', 'BAN')); | |
setTimeout(() => { | |
assert(!Punishments.checkIpBanned(makeConnection('127.0.0.7')), `IP should no longer be banned`); | |
assert(!Punishments.hasPunishType('banmeplease', 'BAN')); | |
done(); | |
}, TEST_PUNISHMENT_DURATION); | |
}); | |
}); | |
}); | |