BattleSim/test/server/commands_spec.coffee

482 lines
20 KiB
CoffeeScript

require('../helpers')
should = require('should')
async = require 'async'
primus = require('primus')
commands = require('../../server/commands')
alts = require('../../server/alts')
auth = require('../../server/auth')
{User} = require('../../server/user')
{BattleServer} = require('../../server/server')
{Room} = require('../../server/rooms')
ratings = require('../../server/ratings')
{Factory} = require '../factory'
redis = require('../../server/redis')
generateTeam = ->
[ Factory("Magikarp")
Factory("Gyarados")
Factory('Hitmonchan')
Factory("Celebi")
Factory("Blissey")
Factory("Alakazam") ]
describe "Commands", ->
beforeEach ->
@server = new BattleServer()
@room = new Room()
@spark1 = @stubSpark()
@spark2 = @stubSpark()
@user1 = @server.findOrCreateUser(id: 1, name: "Star Fox", @spark1)
@user2 = @server.findOrCreateUser(id: 2, name: "Slippy", @spark2)
@aardvark = @server.findOrCreateUser(id: 3, name: 'aardvark', @stubSpark())
@bologna = @server.findOrCreateUser(id: 3, name: 'bologna', @stubSpark())
@offlineName = "husk"
@room.add(@spark1)
@room.add(@spark2)
@emptyRoom = new Room()
@server.rooms.push(@room)
@server.join(@spark1)
@server.join(@spark2)
describe "#executeCommand", ->
describe "an invalid command", ->
it "returns an error to the user", ->
mock1 = @sandbox.mock(@user1).expects('error').once()
mock2 = @sandbox.mock(@user2).expects('error').never()
commands.executeCommand(@server, @user1, @room, "an invalid command")
mock1.verify()
mock2.verify()
describe "rating", ->
user1Rating = 9001
user2Rating = 101
beforeEach (done) ->
ratings.setRating @user1.name, user1Rating, =>
ratings.setRating(@user2.name, user2Rating, done)
it "returns the user's rating to the user without arguments", (done) ->
spy = @sandbox.spy(@user1, 'announce')
commands.executeCommand @server, @user1, @room, "rating", =>
spy.callCount.should.equal(1)
spy.firstCall.args[2].should.containEql(@user1.name)
spy.firstCall.args[2].should.containEql(user1Rating)
done()
it "returns someone's rating to the user as an argument", (done) ->
spy = @sandbox.spy(@user1, 'announce')
commands.executeCommand @server, @user1, @room, "rating", @user2.name, =>
spy.callCount.should.equal(1)
spy.callCount.should.equal(1)
spy.firstCall.args[2].should.containEql(@user2.name)
spy.firstCall.args[2].should.containEql(user2Rating)
done()
describe "voice", ->
it "returns an error if insufficient authority", (done) ->
mock1 = @sandbox.mock(@user1).expects('error').once()
mock2 = @sandbox.mock(@user2).expects('error').never()
commands.executeCommand @server, @user1, @room, "voice", @user2.name, ->
mock1.verify()
mock2.verify()
done()
it "voices a user if owner", (done) ->
@user1.authority = auth.levels.OWNER
commands.executeCommand @server, @user1, @room, "voice", @user2.name, =>
@user2.should.have.property("authority")
@user2.authority.should.equal(auth.levels.DRIVER)
done()
it "does not crash if user isn't on yet", (done) ->
@user1.authority = auth.levels.OWNER
commands.executeCommand @server, @user1, @room, "voice", @offlineName, =>
auth.getAuth @offlineName, (err, result) ->
result.should.equal(auth.levels.DRIVER)
done()
describe "mod", ->
it "returns an error if insufficient authority", (done) ->
mock1 = @sandbox.mock(@user1).expects('error').once()
mock2 = @sandbox.mock(@user2).expects('error').never()
commands.executeCommand @server, @user1, @room, "mod", @user2.name, ->
mock1.verify()
mock2.verify()
done()
it "mods a user if owner", (done) ->
@user1.authority = auth.levels.OWNER
commands.executeCommand @server, @user1, @room, "mod", @user2.name, =>
@user2.should.have.property("authority")
@user2.authority.should.equal(auth.levels.MOD)
done()
it "does not crash if user isn't on yet", (done) ->
@user1.authority = auth.levels.OWNER
commands.executeCommand @server, @user1, @room, "mod", @offlineName, =>
auth.getAuth @offlineName, (err, result) ->
result.should.equal(auth.levels.MOD)
done()
describe "admin", ->
it "returns an error if insufficient authority", (done) ->
mock1 = @sandbox.mock(@user1).expects('error').once()
mock2 = @sandbox.mock(@user2).expects('error').never()
commands.executeCommand @server, @user1, @room, "admin", @user2.name, ->
mock1.verify()
mock2.verify()
done()
it "admins a user if owner", (done) ->
@user1.authority = auth.levels.OWNER
commands.executeCommand @server, @user1, @room, "admin", @user2.name, =>
@user2.should.have.property("authority")
@user2.authority.should.equal(auth.levels.ADMIN)
done()
it "does not crash if user isn't on yet", (done) ->
@user1.authority = auth.levels.OWNER
commands.executeCommand @server, @user1, @room, "admin", @offlineName, =>
auth.getAuth @offlineName, (err, result) ->
result.should.equal(auth.levels.ADMIN)
done()
describe "deauth", ->
it "returns an error if insufficient authority", (done) ->
mock1 = @sandbox.mock(@user1).expects('error').once()
mock2 = @sandbox.mock(@user2).expects('error').never()
commands.executeCommand @server, @user1, @room, "deauth", @user2.name, ->
mock1.verify()
mock2.verify()
done()
it "deauthes a user if owner", (done) ->
@user1.authority = auth.levels.OWNER
commands.executeCommand @server, @user1, @room, "deauth", @user2.name, =>
@user2.should.have.property("authority")
@user2.authority.should.equal(auth.levels.USER)
done()
it "does not crash if user isn't on yet", (done) ->
@user1.authority = auth.levels.OWNER
commands.executeCommand @server, @user1, @room, "deauth", @offlineName, =>
auth.getAuth @offlineName, (err, result) ->
result.should.equal(auth.levels.USER)
done()
describe "ban", ->
it "returns an error if insufficient authority", (done) ->
mock1 = @sandbox.mock(@user1).expects('error').once()
mock2 = @sandbox.mock(@spark2).expects('end').never()
commands.executeCommand @server, @user1, @room, "ban", @user2.name, ->
mock1.verify()
mock2.verify()
done()
it "bans a user if mod", (done) ->
mock1 = @sandbox.mock(@user1).expects('error').never()
mock2 = @sandbox.mock(@spark2).expects('end').once()
@user1.authority = auth.levels.MOD
commands.executeCommand @server, @user1, @room, "ban", @user2.name, =>
mock1.verify()
mock2.verify()
auth.getBanTTL @user2.name, (err, ttl) ->
should.exist(ttl)
ttl.should.equal(60 * 60)
done()
it "bans a user even if user isn't on yet", (done) ->
mock1 = @sandbox.mock(@user1).expects('error').never()
@user1.authority = auth.levels.MOD
commands.executeCommand @server, @user1, @room, "ban", @offlineName, =>
mock1.verify()
auth.getBanTTL @offlineName, (err, ttl) ->
should.exist(ttl)
ttl.should.equal(60 * 60)
done()
it "bans a user for a specified amount of time", (done) ->
mock = @sandbox.mock(@user1).expects('error').never()
@user1.authority = auth.levels.MOD
commands.executeCommand @server, @user1, @room, "ban", @user2.name, "23h", =>
mock.verify()
auth.getBanTTL @user2.name, (err, ttl) ->
should.exist(ttl)
ttl.should.equal(23 * 60 * 60)
done()
it "defaults to an hour if banning for zero minutes", (done) ->
mock = @sandbox.mock(@user1).expects('error').never()
@user1.authority = auth.levels.MOD
commands.executeCommand @server, @user1, @room, "ban", @user2.name, "0", =>
mock.verify()
auth.getBanTTL @user2.name, (err, ttl) ->
should.exist(ttl)
ttl.should.equal(60 * 60)
done()
it "cannot ban over one day if mod", (done) ->
mock = @sandbox.mock(@user1).expects('error').never()
@user1.authority = auth.levels.MOD
commands.executeCommand @server, @user1, @room, "ban", @user2.name, "1y", =>
mock.verify()
auth.getBanTTL @user2.name, (err, ttl) ->
should.exist(ttl)
ttl.should.equal(1 * 24 * 60 * 60)
done()
describe "unban", ->
it "returns an error if insufficient authority", (done) ->
mock1 = @sandbox.mock(@user1).expects('error').once()
mock2 = @sandbox.mock(@user2).expects('error').never()
commands.executeCommand @server, @user1, @room, "unban", @user2.name, =>
mock1.verify()
mock2.verify()
done()
it "unbans a user if mod", (done) ->
@user1.authority = auth.levels.MOD
commands.executeCommand @server, @user1, @room, "ban", @user2.name, =>
commands.executeCommand @server, @user1, @room, "unban", @user2.name, =>
auth.getBanTTL @user2.name, (err, ttl) ->
should.exist(ttl)
ttl.should.equal(-2)
done()
it "returns an error if user is not banned", (done) ->
mock1 = @sandbox.mock(@user1).expects('error').once()
mock2 = @sandbox.mock(@user2).expects('error').never()
@user1.authority = auth.levels.MOD
commands.executeCommand @server, @user1, @room, "unban", @user2.name, =>
mock1.verify()
mock2.verify()
done()
it "unbans a user even if user isn't on yet", (done) ->
mock = @sandbox.mock(@user1).expects('error').never()
@user1.authority = auth.levels.MOD
commands.executeCommand @server, @user1, @room, "ban", @offlineName, =>
commands.executeCommand @server, @user1, @room, "unban", @offlineName, =>
mock.verify()
auth.getBanTTL @user2.name, (err, ttl) ->
should.exist(ttl)
ttl.should.equal(-2)
done()
describe "mute", ->
it "returns an error if insufficient authority", (done) ->
mock1 = @sandbox.mock(@user1).expects('error').once()
mock2 = @sandbox.mock(@user2).expects('error').never()
commands.executeCommand @server, @user1, @room, "mute", @user2.name, ->
mock1.verify()
mock2.verify()
done()
it "mutes a user if mod", (done) ->
mock = @sandbox.mock(@user1).expects('error').never()
@user1.authority = auth.levels.MOD
commands.executeCommand @server, @user1, @room, "mute", @user2.name, =>
mock.verify()
auth.getMuteTTL @user2.name, (err, ttl) ->
should.exist(ttl)
ttl.should.equal(10 * 60)
done()
it "mutes a user even if user isn't on yet", (done) ->
mock = @sandbox.mock(@user1).expects('error').never()
@user1.authority = auth.levels.MOD
commands.executeCommand @server, @user1, @room, "mute", @offlineName, =>
mock.verify()
auth.getMuteTTL @offlineName, (err, ttl) ->
should.exist(ttl)
ttl.should.equal(10 * 60)
done()
it "mutes a user for a specified amount of time", (done) ->
mock = @sandbox.mock(@user1).expects('error').never()
@user1.authority = auth.levels.MOD
commands.executeCommand @server, @user1, @room, "mute", @user2.name, "23h", =>
mock.verify()
auth.getMuteTTL @user2.name, (err, ttl) ->
should.exist(ttl)
ttl.should.equal(23 * 60 * 60)
done()
it "defaults to 10 if muting for zero minutes", (done) ->
mock = @sandbox.mock(@user1).expects('error').never()
@user1.authority = auth.levels.MOD
commands.executeCommand @server, @user1, @room, "mute", @user2.name, "0", =>
mock.verify()
auth.getMuteTTL @user2.name, (err, ttl) ->
should.exist(ttl)
ttl.should.equal(10 * 60)
done()
it "cannot mute over two days if mod", (done) ->
mock = @sandbox.mock(@user1).expects('error').never()
@user1.authority = auth.levels.MOD
commands.executeCommand @server, @user1, @room, "mute", @user2.name, "1y", =>
mock.verify()
auth.getMuteTTL @user2.name, (err, ttl) ->
should.exist(ttl)
ttl.should.equal(2 * 24 * 60 * 60)
done()
describe "unmute", ->
it "returns an error if insufficient authority", (done) ->
mock1 = @sandbox.mock(@user1).expects('error').once()
mock2 = @sandbox.mock(@user2).expects('error').never()
commands.executeCommand @server, @user1, @room, "unmute", @user2.name, =>
mock1.verify()
mock2.verify()
done()
it "unmutes a user if mod", (done) ->
@user1.authority = auth.levels.MOD
commands.executeCommand @server, @user1, @room, "mute", @user2.name, =>
commands.executeCommand @server, @user1, @room, "unmute", @user2.name, =>
auth.getMuteTTL @user2.name, (err, ttl) ->
should.exist(ttl)
ttl.should.equal(-2)
done()
it "returns an error if user is not muted", (done) ->
mock1 = @sandbox.mock(@user1).expects('error').once()
mock2 = @sandbox.mock(@user2).expects('error').never()
@user1.authority = auth.levels.MOD
commands.executeCommand @server, @user1, @room, "unmute", @user2.name, =>
mock1.verify()
mock2.verify()
done()
it "unmutes a user even if user isn't on yet", (done) ->
mock1 = @sandbox.mock(@user1).expects('error').never()
@user1.authority = auth.levels.MOD
commands.executeCommand @server, @user1, @room, "mute", @offlineName, =>
commands.executeCommand @server, @user1, @room, "unmute", @offlineName, =>
mock1.verify()
auth.getMuteTTL @user2.name, (err, ttl) ->
should.exist(ttl)
ttl.should.equal(-2)
done()
describe "battles", ->
it "returns an error if no user is passed", (done) ->
mock1 = @sandbox.mock(@user1).expects('error').once()
mock2 = @sandbox.mock(@user2).expects('error').never()
commands.executeCommand @server, @user1, @room, "battles", ->
mock1.verify()
mock2.verify()
done()
it "returns all battles that user is in if user is passed", (done) ->
@server.queuePlayer(@user1.name, generateTeam()).should.be.empty
@server.queuePlayer(@user2.name, generateTeam()).should.be.empty
@server.queuePlayer(@aardvark.name, generateTeam()).should.be.empty
@server.queuePlayer(@bologna.name, generateTeam()).should.be.empty
@server.beginBattles (err, battleIds) =>
if err then throw err
battleIds.length.should.equal(2)
spy = @sandbox.spy(@user1, 'announce')
commands.executeCommand @server, @user1, @room, "battles", @user2.name, =>
spy.callCount.should.equal(1)
spy.firstCall.args[2].should.containEql(@user2.name)
spy.firstCall.args[2].should.containEql(battleIds[0])
spy.firstCall.args[2].should.not.containEql(@user1.name)
spy.firstCall.args[2].should.not.containEql(battleIds[1])
done()
it "does not containEql alts in the battle list", (done) ->
@server.queuePlayer(@user1.name, [ Factory("Magikarp") ])
@server.queuePlayer(@user2.name, [ Factory("Magikarp") ], "Im an Alt")
@server.beginBattles (err, battleIds) =>
if err then throw err
spy = @sandbox.spy(@user1, 'announce')
commands.executeCommand @server, @user1, @room, "battles", @user2.name, =>
if err then throw err
spy.callCount.should.equal(1)
spy.firstCall.args[2].should.containEql(@user2.name)
done()
describe "topic", ->
it "returns an error if insufficient authority", (done) ->
mock1 = @sandbox.mock(@user1).expects('error').once()
commands.executeCommand @server, @user1, @room, "topic", "test topic", ->
mock1.verify()
done()
it "updates the channel topic", (done) ->
topicName = "a test"
@user1.authority = auth.levels.ADMIN
mock = @sandbox.mock(@room).expects("setTopic").withArgs(topicName).once()
commands.executeCommand @server, @user1, @room, "topic", topicName, ->
mock.verify()
done()
describe "wall", ->
it "returns an error if insufficient authority", (done) ->
mock1 = @sandbox.mock(@user1).expects('error').once()
commands.executeCommand @server, @user1, @room, "wall", "hi", ->
mock1.verify()
done()
it "messages all rooms and all battles", (done) ->
mock = @sandbox.mock(@room).expects('announce').once()
spy1 = @sandbox.spy(@spark1, 'send')
spy2 = @sandbox.spy(@spark2, 'send')
@server.queuePlayer(@user1.name, generateTeam()).should.be.empty
@server.queuePlayer(@user2.name, generateTeam()).should.be.empty
@server.beginBattles (err, battleIds) =>
if err then throw err
@user1.authority = auth.levels.ADMIN
commands.executeCommand @server, @user1, @room, "wall", "derper", =>
mock.verify()
spy1.calledWithMatch("announce", battleIds[0], 'warning', "derper").should.be.true
spy2.calledWithMatch("announce", battleIds[0], 'warning', "derper").should.be.true
done()
describe "lockdown", ->
it "returns an error if insufficient authority", (done) ->
mock = @sandbox.mock(@user1).expects('error').once()
commands.executeCommand @server, @user1, @room, "lockdown", ->
mock.verify()
done()
it "stops battles from occuring", (done) ->
mock = @sandbox.mock(@server).expects('lockdown').once()
@user1.authority = auth.levels.OWNER
commands.executeCommand @server, @user1, @room, "lockdown", ->
mock.verify()
done()
it "can start them again", (done) ->
mock = @sandbox.mock(@server).expects('unlockdown').once()
@user1.authority = auth.levels.OWNER
commands.executeCommand @server, @user1, @room, "lockdown", "off", ->
mock.verify()
done()
describe "whois", ->
beforeEach (done) ->
async.parallel([
alts.createAlt.bind(alts, @user1.name, 'alt1')
alts.createAlt.bind(alts, @user1.name, 'alt2')
], done)
it "returns an error if insufficient authority", (done) ->
mock = @sandbox.mock(@user1).expects('error').once()
commands.executeCommand @server, @user1, @room, "whois", @user1.name, =>
mock.verify()
done()
it "returns a list of alts and the main account", (done) ->
@user1.authority = auth.levels.MOD
spy = @sandbox.spy(@user1, 'announce')
commands.executeCommand @server, @user1, @room, "whois", @user1.name, =>
spy.callCount.should.equal(1)
spy.firstCall.args[2].should.containEql(@user1.name)
spy.firstCall.args[2].should.containEql("alt1")
spy.firstCall.args[2].should.containEql("alt2")
done()