mirror of
https://gitlab.com/Deukhoofd/BattleSim.git
synced 2025-10-27 18:00:03 +00:00
Lots of stuff
This commit is contained in:
16
test/server/auth_spec.coffee
Normal file
16
test/server/auth_spec.coffee
Normal file
@@ -0,0 +1,16 @@
|
||||
auth = require("../../server/auth")
|
||||
|
||||
describe "Authorization", ->
|
||||
describe "setAuth", ->
|
||||
it "changes/gets the auth level for a user", (done) ->
|
||||
username = "a user"
|
||||
auth.setAuth username, auth.levels.MOD, ->
|
||||
auth.getAuth username, (err, level) ->
|
||||
level.should.equal(auth.levels.MOD)
|
||||
done()
|
||||
|
||||
describe "getAuth", ->
|
||||
it "returns the default auth of a user if non-existent", (done) ->
|
||||
auth.getAuth "derpa", (err, level) ->
|
||||
level.should.equal(auth.levels.USER)
|
||||
done()
|
||||
481
test/server/commands_spec.coffee
Normal file
481
test/server/commands_spec.coffee
Normal file
@@ -0,0 +1,481 @@
|
||||
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()
|
||||
54
test/server/conditions/evasion_clause_spec.coffee
Normal file
54
test/server/conditions/evasion_clause_spec.coffee
Normal file
@@ -0,0 +1,54 @@
|
||||
require '../../helpers'
|
||||
|
||||
{BattleServer} = require('../../../server/server')
|
||||
{User} = require('../../../server/user')
|
||||
{Conditions} = require '../../../shared/conditions'
|
||||
{Factory} = require '../../factory'
|
||||
should = require('should')
|
||||
|
||||
generateTeam = ->
|
||||
[ Factory("Magikarp")
|
||||
Factory("Gyarados")
|
||||
Factory('Hitmonchan')
|
||||
Factory("Celebi")
|
||||
Factory("Blissey")
|
||||
Factory("Alakazam") ]
|
||||
|
||||
describe 'Validations: Evasion Clause', ->
|
||||
it "returns an error if a pokemon has an evasion move", ->
|
||||
server = new BattleServer()
|
||||
format = 'xy1000'
|
||||
team = generateTeam()
|
||||
team[0] = Factory("Umbreon", moves: [ "Double Team" ])
|
||||
conditions = [ Conditions.EVASION_CLAUSE ]
|
||||
|
||||
server.validateTeam(team, format, conditions).should.not.be.empty
|
||||
|
||||
it "returns an error if a pokemon has a banned evasion ability", ->
|
||||
server = new BattleServer()
|
||||
format = 'xy1000'
|
||||
team = generateTeam()
|
||||
team[0] = Factory("Smeargle", ability: "Moody", moves: [ "Sketch" ])
|
||||
conditions = [ Conditions.EVASION_CLAUSE ]
|
||||
|
||||
server.validateTeam(team, format, conditions).should.not.be.empty
|
||||
|
||||
it "returns no error if no pokemon has an evasion move", ->
|
||||
server = new BattleServer()
|
||||
format = 'xy1000'
|
||||
team = generateTeam()
|
||||
team[0] = Factory("Magikarp", moves: [ "Splash" ])
|
||||
team[1] = Factory("Gyarados", moves: [ "Dragon Dance" ])
|
||||
conditions = [ Conditions.EVASION_CLAUSE ]
|
||||
|
||||
server.validateTeam(team, format, conditions).should.be.empty
|
||||
|
||||
it "ignores invalid moves", ->
|
||||
server = new BattleServer()
|
||||
format = 'xy1000'
|
||||
team = generateTeam()
|
||||
team[0] = Factory("Magikarp", moves: [ "GHOSTFACE KILLAH" ])
|
||||
team[1] = Factory("Gyarados", moves: [ "Dragon Dance" ])
|
||||
conditions = [ Conditions.EVASION_CLAUSE ]
|
||||
|
||||
(-> server.validateTeam(team, format, conditions)).should.not.throw()
|
||||
45
test/server/conditions/ohko_clause_spec.coffee
Normal file
45
test/server/conditions/ohko_clause_spec.coffee
Normal file
@@ -0,0 +1,45 @@
|
||||
require '../../helpers'
|
||||
|
||||
{BattleServer} = require('../../../server/server')
|
||||
{User} = require('../../../server/user')
|
||||
{Conditions} = require '../../../shared/conditions'
|
||||
{Factory} = require '../../factory'
|
||||
should = require('should')
|
||||
|
||||
generateTeam = ->
|
||||
[ Factory("Magikarp")
|
||||
Factory("Gyarados")
|
||||
Factory('Hitmonchan')
|
||||
Factory("Celebi")
|
||||
Factory("Blissey")
|
||||
Factory("Alakazam") ]
|
||||
|
||||
describe 'Validations: OHKO Clause', ->
|
||||
it "returns an error if a pokemon has an OHKO move", ->
|
||||
server = new BattleServer()
|
||||
format = 'xy1000'
|
||||
team = generateTeam()
|
||||
team[0] = Factory("Lapras", moves: [ "Surf", "Sheer Cold" ])
|
||||
conditions = [ Conditions.OHKO_CLAUSE ]
|
||||
|
||||
server.validateTeam(team, format, conditions).should.not.be.empty
|
||||
|
||||
it "returns no error if no pokemon has an evasion move", ->
|
||||
server = new BattleServer()
|
||||
format = 'xy1000'
|
||||
team = generateTeam()
|
||||
team[0] = Factory("Magikarp", moves: [ "Splash" ])
|
||||
team[1] = Factory("Gyarados", moves: [ "Dragon Dance" ])
|
||||
conditions = [ Conditions.OHKO_CLAUSE ]
|
||||
|
||||
server.validateTeam(team, format, conditions).should.be.empty
|
||||
|
||||
it "ignores invalid moves", ->
|
||||
server = new BattleServer()
|
||||
format = 'xy1000'
|
||||
team = generateTeam()
|
||||
team[0] = Factory("Magikarp", moves: [ "GHOSTFACE KILLAH" ])
|
||||
team[1] = Factory("Gyarados", moves: [ "Dragon Dance" ])
|
||||
conditions = [ Conditions.OHKO_CLAUSE ]
|
||||
|
||||
(-> server.validateTeam(team, format, conditions)).should.not.throw()
|
||||
53
test/server/conditions/pbv_1000_spec.coffee
Normal file
53
test/server/conditions/pbv_1000_spec.coffee
Normal file
@@ -0,0 +1,53 @@
|
||||
require '../../helpers'
|
||||
|
||||
{BattleServer} = require('../../../server/server')
|
||||
{User} = require('../../../server/user')
|
||||
pbv = require('../../../shared/pokebattle_values')
|
||||
{Factory} = require '../../factory'
|
||||
should = require('should')
|
||||
|
||||
describe 'Validations: PBV 1000', ->
|
||||
it "returns an error if the team is over 1000 PBV", ->
|
||||
server = new BattleServer()
|
||||
format = 'xy1000'
|
||||
team = [ Factory("Arceus", move: "Recover")
|
||||
Factory("Gyarados")
|
||||
Factory('Hitmonchan')
|
||||
Factory("Celebi")
|
||||
Factory("Blissey")
|
||||
Factory("Alakazam") ]
|
||||
|
||||
server.validateTeam(team, format).should.not.be.empty
|
||||
|
||||
it "returns an error if the team has under 6 pokemon", ->
|
||||
server = new BattleServer()
|
||||
format = 'xy1000'
|
||||
team = [ Factory("Magikarp", moves: [ "Splash" ]) ]
|
||||
|
||||
server.validateTeam(team, format).should.not.be.empty
|
||||
|
||||
it "returns an error if the team has a pokemon that's over 1/3 the cap", ->
|
||||
server = new BattleServer()
|
||||
format = 'xy1000'
|
||||
team = [ Factory("Magikarp")
|
||||
Factory("Gyarados")
|
||||
Factory('Hitmonchan')
|
||||
Factory("Celebi")
|
||||
Factory("Blissey")
|
||||
Factory("Alakazam") ]
|
||||
|
||||
stub = @sandbox.stub(pbv, 'determinePBV', -> 335)
|
||||
|
||||
server.validateTeam(team, format).should.not.be.empty
|
||||
|
||||
it "returns no error if the team is under 1000 PBV", ->
|
||||
server = new BattleServer()
|
||||
format = 'xy1000'
|
||||
team = [ Factory("Magikarp")
|
||||
Factory("Gyarados")
|
||||
Factory('Hitmonchan')
|
||||
Factory("Celebi")
|
||||
Factory("Blissey")
|
||||
Factory("Alakazam") ]
|
||||
|
||||
server.validateTeam(team, format).should.be.empty
|
||||
53
test/server/conditions/pbv_500_spec.coffee
Normal file
53
test/server/conditions/pbv_500_spec.coffee
Normal file
@@ -0,0 +1,53 @@
|
||||
require '../../helpers'
|
||||
|
||||
{BattleServer} = require('../../../server/server')
|
||||
{User} = require('../../../server/user')
|
||||
pbv = require('../../../shared/pokebattle_values')
|
||||
{Factory} = require '../../factory'
|
||||
should = require('should')
|
||||
|
||||
describe 'Validations: PBV 500', ->
|
||||
it "returns an error if the team is over 500 PBV", ->
|
||||
server = new BattleServer()
|
||||
format = 'xy500'
|
||||
team = [ Factory("Arceus", move: "Recover")
|
||||
Factory("Gyarados")
|
||||
Factory('Hitmonchan')
|
||||
Factory("Celebi")
|
||||
Factory("Blissey")
|
||||
Factory("Alakazam") ]
|
||||
|
||||
server.validateTeam(team, format).should.not.be.empty
|
||||
|
||||
it "returns an error if the team has under 6 pokemon", ->
|
||||
server = new BattleServer()
|
||||
format = 'xy500'
|
||||
team = [ Factory("Magikarp", moves: [ "Splash" ]) ]
|
||||
|
||||
server.validateTeam(team, format).should.not.be.empty
|
||||
|
||||
it "returns an error if the team has a pokemon that's over 1/3 the cap", ->
|
||||
server = new BattleServer()
|
||||
format = 'xy500'
|
||||
team = [ Factory("Magikarp")
|
||||
Factory("Gyarados")
|
||||
Factory('Hitmonchan')
|
||||
Factory("Celebi")
|
||||
Factory("Blissey")
|
||||
Factory("Alakazam") ]
|
||||
|
||||
stub = @sandbox.stub(pbv, 'determinePBV', -> 170)
|
||||
|
||||
server.validateTeam(team, format).should.not.be.empty
|
||||
|
||||
it "returns no error if the team is under 500 PBV", ->
|
||||
server = new BattleServer()
|
||||
format = 'xy500'
|
||||
team = [ Factory("Magikarp")
|
||||
Factory("Unown", moves: ['Hidden Power'])
|
||||
Factory('Hitmonchan', moves: ['Mach Punch'])
|
||||
Factory("Abra", moves: ['Psychic'])
|
||||
Factory("Froakie", moves: ['Surf'])
|
||||
Factory("Raticate", moves: ['Tackle']) ]
|
||||
|
||||
server.validateTeam(team, format).should.be.empty
|
||||
32
test/server/conditions/prankster_swagger_clause_spec.coffee
Normal file
32
test/server/conditions/prankster_swagger_clause_spec.coffee
Normal file
@@ -0,0 +1,32 @@
|
||||
require '../../helpers'
|
||||
|
||||
{BattleServer} = require('../../../server/server')
|
||||
{User} = require('../../../server/user')
|
||||
{Conditions} = require '../../../shared/conditions'
|
||||
{Factory} = require '../../factory'
|
||||
should = require('should')
|
||||
|
||||
generateTeam = ->
|
||||
[ Factory("Magikarp")
|
||||
Factory("Gyarados")
|
||||
Factory('Hitmonchan')
|
||||
Factory("Celebi")
|
||||
Factory("Blissey")
|
||||
Factory("Alakazam") ]
|
||||
|
||||
describe 'Validations: Prankster + Swagger', ->
|
||||
it "returns an error if the team has a Pokemon with Prankster + Swagger", ->
|
||||
server = new BattleServer()
|
||||
format = 'xy1000'
|
||||
team = generateTeam()
|
||||
team[0] = Factory("Sableye", ability: "Prankster", moves: [ "Swagger" ])
|
||||
conditions = [ Conditions.PRANKSTER_SWAGGER_CLAUSE ]
|
||||
|
||||
server.validateTeam(team, format, conditions).should.not.be.empty
|
||||
|
||||
it "returns no error if the team has no Prankster + Swagger Pokemon", ->
|
||||
server = new BattleServer()
|
||||
format = 'xy1000'
|
||||
conditions = [ Conditions.PRANKSTER_SWAGGER_CLAUSE ]
|
||||
|
||||
server.validateTeam(generateTeam(), format, conditions).should.be.empty
|
||||
95
test/server/conditions/sleep_clause_spec.coffee
Normal file
95
test/server/conditions/sleep_clause_spec.coffee
Normal file
@@ -0,0 +1,95 @@
|
||||
require '../../helpers'
|
||||
|
||||
shared = require '../../shared'
|
||||
{Conditions} = require '../../../shared/conditions'
|
||||
{Attachment, Status} = require '../../../server/bw/attachment'
|
||||
{Protocol} = require '../../../shared/protocol'
|
||||
{Factory} = require '../../factory'
|
||||
|
||||
describe "Sleep Clause", ->
|
||||
it "prevents Sleep if the opponent was already slept by this team", ->
|
||||
conditions = [ Conditions.SLEEP_CLAUSE ]
|
||||
team1 = [ Factory("Magikarp"), Factory("Magikarp") ]
|
||||
team2 = [ Factory("Magikarp"), Factory("Magikarp") ]
|
||||
shared.create.call(this, {conditions, team1, team2})
|
||||
|
||||
spore = @battle.getMove("Spore")
|
||||
@battle.performMove(@p1, spore)
|
||||
@battle.performSwitch(@p2, 1)
|
||||
|
||||
mock = @sandbox.mock(spore).expects('fail').once()
|
||||
@battle.performMove(@p1, spore)
|
||||
mock.verify()
|
||||
|
||||
@team2.at(0).has(Status.Sleep).should.be.false
|
||||
@team2.at(1).has(Status.Sleep).should.be.true
|
||||
|
||||
it "prevents Sleep from Yawn", ->
|
||||
conditions = [ Conditions.SLEEP_CLAUSE ]
|
||||
team1 = [ Factory("Magikarp"), Factory("Magikarp") ]
|
||||
team2 = [ Factory("Magikarp"), Factory("Magikarp") ]
|
||||
shared.create.call(this, {conditions, team1, team2})
|
||||
|
||||
yawn = @battle.getMove("Yawn")
|
||||
@battle.performMove(@p1, yawn)
|
||||
@battle.endTurn()
|
||||
@battle.endTurn()
|
||||
@battle.performSwitch(@p2, 1)
|
||||
|
||||
@battle.performMove(@p1, yawn)
|
||||
@battle.endTurn()
|
||||
@battle.endTurn()
|
||||
|
||||
@team2.at(0).has(Status.Sleep).should.be.false
|
||||
@team2.at(1).has(Status.Sleep).should.be.true
|
||||
|
||||
it "doesn't prevent other statuses", ->
|
||||
conditions = [ Conditions.SLEEP_CLAUSE ]
|
||||
team1 = [ Factory("Magikarp"), Factory("Magikarp") ]
|
||||
team2 = [ Factory("Magikarp"), Factory("Magikarp") ]
|
||||
shared.create.call(this, {conditions, team1, team2})
|
||||
|
||||
thunderWave = @battle.getMove("Thunder Wave")
|
||||
@battle.performMove(@p1, thunderWave)
|
||||
@battle.performSwitch(@p2, 1)
|
||||
|
||||
mock = @sandbox.mock(thunderWave).expects('fail').never()
|
||||
@battle.performMove(@p1, thunderWave)
|
||||
mock.verify()
|
||||
|
||||
@team2.at(0).has(Status.Paralyze).should.be.true
|
||||
@team2.at(1).has(Status.Paralyze).should.be.true
|
||||
|
||||
it "doesn't prevent Sleep if the opponent was slept, but not by this team", ->
|
||||
conditions = [ Conditions.SLEEP_CLAUSE ]
|
||||
team1 = [ Factory("Magikarp"), Factory("Magikarp") ]
|
||||
team2 = [ Factory("Magikarp"), Factory("Magikarp") ]
|
||||
shared.create.call(this, {conditions, team1, team2})
|
||||
|
||||
@team2.at(1).attach(Status.Sleep)
|
||||
|
||||
spore = @battle.getMove("Spore")
|
||||
mock = @sandbox.mock(spore).expects('fail').never()
|
||||
@battle.performMove(@p1, spore)
|
||||
mock.verify()
|
||||
|
||||
@team2.at(0).has(Status.Sleep).should.be.true
|
||||
@team2.at(1).has(Status.Sleep).should.be.true
|
||||
|
||||
it "doesn't prevent Sleep if the opponent was slept, but fainted", ->
|
||||
conditions = [ Conditions.SLEEP_CLAUSE ]
|
||||
team1 = [ Factory("Magikarp"), Factory("Magikarp") ]
|
||||
team2 = [ Factory("Magikarp"), Factory("Magikarp") ]
|
||||
shared.create.call(this, {conditions, team1, team2})
|
||||
|
||||
spore = @battle.getMove("Spore")
|
||||
@battle.performMove(@p1, spore)
|
||||
@battle.performSwitch(@p2, 1)
|
||||
|
||||
@p2.faint()
|
||||
|
||||
mock = @sandbox.mock(spore).expects('fail').never()
|
||||
@battle.performMove(@p1, spore)
|
||||
mock.verify()
|
||||
|
||||
@team2.at(0).has(Status.Sleep).should.be.true
|
||||
34
test/server/conditions/species_clause_spec.coffee
Normal file
34
test/server/conditions/species_clause_spec.coffee
Normal file
@@ -0,0 +1,34 @@
|
||||
require '../../helpers'
|
||||
|
||||
{BattleServer} = require('../../../server/server')
|
||||
{User} = require('../../../server/user')
|
||||
{Conditions} = require '../../../shared/conditions'
|
||||
{Factory} = require '../../factory'
|
||||
should = require('should')
|
||||
|
||||
generateTeam = ->
|
||||
[ Factory("Magikarp")
|
||||
Factory("Gyarados")
|
||||
Factory('Hitmonchan')
|
||||
Factory("Celebi")
|
||||
Factory("Blissey")
|
||||
Factory("Alakazam") ]
|
||||
|
||||
describe 'Validations: Species Clause', ->
|
||||
it "returns an error if the team has more than one of the same species", ->
|
||||
server = new BattleServer()
|
||||
format = 'xy1000'
|
||||
team = generateTeam()
|
||||
team[0] = Factory("Rotom", forme: "wash")
|
||||
team[1] = Factory("Rotom", forme: "heat")
|
||||
conditions = [ Conditions.SPECIES_CLAUSE ]
|
||||
|
||||
server.validateTeam(team, format, conditions).should.not.be.empty
|
||||
|
||||
it "returns no error if the team shares no species", ->
|
||||
server = new BattleServer()
|
||||
format = 'xy1000'
|
||||
team = generateTeam()
|
||||
conditions = [ Conditions.SPECIES_CLAUSE ]
|
||||
|
||||
server.validateTeam(team, format, conditions).should.be.empty
|
||||
136
test/server/conditions/team_preview_spec.coffee
Normal file
136
test/server/conditions/team_preview_spec.coffee
Normal file
@@ -0,0 +1,136 @@
|
||||
require '../../helpers'
|
||||
|
||||
shared = require '../../shared'
|
||||
{Conditions} = require '../../../shared/conditions'
|
||||
{Protocol} = require '../../../shared/protocol'
|
||||
{Factory} = require '../../factory'
|
||||
|
||||
describe "Team preview", ->
|
||||
it "starts the battle by passing team info and requesting team order", ->
|
||||
conditions = [ Conditions.TEAM_PREVIEW ]
|
||||
team1 = [ Factory("Magikarp") ]
|
||||
team2 = [ Factory("Magikarp") ]
|
||||
shared.build(this, {conditions, team1, team2})
|
||||
mock = @sandbox.mock(@battle).expects('startBattle').never()
|
||||
spy = @sandbox.spy(@battle, 'tell')
|
||||
@controller.beginBattle()
|
||||
mock.verify()
|
||||
spy.calledWith(Protocol.TEAM_PREVIEW).should.be.true
|
||||
|
||||
it "waits until all players have arranged their teams before starting", ->
|
||||
conditions = [ Conditions.TEAM_PREVIEW ]
|
||||
team1 = [ Factory("Magikarp") ]
|
||||
team2 = [ Factory("Magikarp") ]
|
||||
shared.build(this, {conditions, team1, team2})
|
||||
mock = @sandbox.mock(@battle).expects('startBattle').never()
|
||||
@controller.beginBattle()
|
||||
@controller.arrangeTeam(@id1, [ 0 ])
|
||||
mock.verify()
|
||||
@battle.startBattle.restore()
|
||||
|
||||
mock = @sandbox.mock(@battle).expects('startBattle').once()
|
||||
@controller.arrangeTeam(@id2, [ 0 ])
|
||||
mock.verify()
|
||||
|
||||
it "rejects team arrangements that aren't arrays", ->
|
||||
conditions = [ Conditions.TEAM_PREVIEW ]
|
||||
team1 = [ Factory("Magikarp") ]
|
||||
team2 = [ Factory("Magikarp") ]
|
||||
shared.create.call(this, {conditions, team1, team2})
|
||||
arrangement = true
|
||||
@controller.arrangeTeam(@id1, arrangement).should.be.false
|
||||
|
||||
it "accepts arrays of integers (arrangements) matching team length", ->
|
||||
conditions = [ Conditions.TEAM_PREVIEW ]
|
||||
team1 = [ Factory("Magikarp") ]
|
||||
team2 = [ Factory("Magikarp") ]
|
||||
shared.create.call(this, {conditions, team1, team2})
|
||||
arrangement = [ 0 ]
|
||||
@controller.arrangeTeam(@id1, arrangement).should.be.true
|
||||
|
||||
it "rejects team arrangements that are smaller than the team length", ->
|
||||
conditions = [ Conditions.TEAM_PREVIEW ]
|
||||
team1 = [ Factory("Magikarp") ]
|
||||
team2 = [ Factory("Magikarp") ]
|
||||
shared.create.call(this, {conditions, team1, team2})
|
||||
arrangement = []
|
||||
@controller.arrangeTeam(@id1, arrangement).should.be.false
|
||||
|
||||
it "rejects team arrangements that are larger than the team length", ->
|
||||
conditions = [ Conditions.TEAM_PREVIEW ]
|
||||
team1 = [ Factory("Magikarp") ]
|
||||
team2 = [ Factory("Magikarp") ]
|
||||
shared.create.call(this, {conditions, team1, team2})
|
||||
arrangement = [ 0, 1 ]
|
||||
@controller.arrangeTeam(@id1, arrangement).should.be.false
|
||||
|
||||
it "rejects team arrangements containing negative indices", ->
|
||||
conditions = [ Conditions.TEAM_PREVIEW ]
|
||||
team1 = [ Factory("Magikarp") ]
|
||||
team2 = [ Factory("Magikarp") ]
|
||||
shared.create.call(this, {conditions, team1, team2})
|
||||
arrangement = [ -1 ]
|
||||
@controller.arrangeTeam(@id1, arrangement).should.be.false
|
||||
|
||||
it "rejects team arrangements containing indices out of bounds", ->
|
||||
conditions = [ Conditions.TEAM_PREVIEW ]
|
||||
team1 = [ Factory("Magikarp") ]
|
||||
team2 = [ Factory("Magikarp") ]
|
||||
shared.create.call(this, {conditions, team1, team2})
|
||||
arrangement = [ 1 ]
|
||||
@controller.arrangeTeam(@id1, arrangement).should.be.false
|
||||
|
||||
it "rejects team arrangements containing non-unique indices", ->
|
||||
conditions = [ Conditions.TEAM_PREVIEW ]
|
||||
team1 = (Factory("Magikarp") for x in [0..1])
|
||||
shared.create.call(this, {conditions, team1})
|
||||
arrangement = [ 1, 1 ]
|
||||
@controller.arrangeTeam(@id1, arrangement).should.be.false
|
||||
|
||||
it "rejects team arrangements that have some non-numbers", ->
|
||||
conditions = [ Conditions.TEAM_PREVIEW ]
|
||||
team1 = (Factory("Magikarp") for x in [0..1])
|
||||
shared.create.call(this, {conditions, team1})
|
||||
arrangement = [ 1, "a" ]
|
||||
@controller.arrangeTeam(@id1, arrangement).should.be.false
|
||||
|
||||
it "rejects team arrangements that don't point to a correct index", ->
|
||||
conditions = [ Conditions.TEAM_PREVIEW ]
|
||||
team1 = (Factory("Magikarp") for x in [0..1])
|
||||
shared.create.call(this, {conditions, team1})
|
||||
arrangement = [ 1, .5 ]
|
||||
@controller.arrangeTeam(@id1, arrangement).should.be.false
|
||||
|
||||
it "rejects team arrangements if the battle has already begun", ->
|
||||
conditions = [ Conditions.TEAM_PREVIEW ]
|
||||
team1 = (Factory("Magikarp") for x in [0..1])
|
||||
shared.create.call(this, {conditions, team1})
|
||||
arrangement = [ 1, 0 ]
|
||||
@controller.arrangeTeam(@id1, arrangement)
|
||||
@controller.arrangeTeam(@id2, arrangement)
|
||||
@controller.arrangeTeam(@id1, arrangement).should.be.false
|
||||
|
||||
it "rearranges team when given a valid array of indices", ->
|
||||
conditions = [ Conditions.TEAM_PREVIEW ]
|
||||
team1 = [ Factory("Magikarp"), Factory("Gyarados"), Factory("Celebi") ]
|
||||
team2 = [ Factory("Magikarp"), Factory("Gyarados"), Factory("Celebi") ]
|
||||
shared.create.call(this, {conditions, team1, team2})
|
||||
@controller.arrangeTeam(@id1, [ 0, 2, 1 ])
|
||||
@controller.arrangeTeam(@id2, [ 2, 0, 1 ])
|
||||
@team1.at(0).species.should.equal("Magikarp")
|
||||
@team1.at(1).species.should.equal("Celebi")
|
||||
@team1.at(2).species.should.equal("Gyarados")
|
||||
@team2.at(0).species.should.equal("Celebi")
|
||||
@team2.at(1).species.should.equal("Magikarp")
|
||||
@team2.at(2).species.should.equal("Gyarados")
|
||||
|
||||
it "is isomorphic", ->
|
||||
conditions = [ Conditions.TEAM_PREVIEW ]
|
||||
team1 = [ Factory("Magikarp"), Factory("Gyarados"), Factory("Celebi") ]
|
||||
team2 = [ Factory("Magikarp"), Factory("Gyarados"), Factory("Celebi") ]
|
||||
arrangedTeamNames = [ "Celebi", "Magikarp", "Gyarados" ]
|
||||
shared.create.call(this, {conditions, team1, team2})
|
||||
@controller.arrangeTeam(@id1, [ 2, 0, 1 ])
|
||||
@controller.arrangeTeam(@id1, [ 2, 0, 1 ])
|
||||
@controller.arrangeTeam(@id2, [ 2, 0, 1 ])
|
||||
@team1.pokemon.map((p) -> p.species).should.eql(arrangedTeamNames)
|
||||
190
test/server/conditions/timer_spec.coffee
Normal file
190
test/server/conditions/timer_spec.coffee
Normal file
@@ -0,0 +1,190 @@
|
||||
require '../../helpers'
|
||||
|
||||
{_} = require 'underscore'
|
||||
shared = require '../../shared'
|
||||
{Conditions} = require '../../../shared/conditions'
|
||||
{Protocol} = require '../../../shared/protocol'
|
||||
|
||||
describe "Battle timer", ->
|
||||
describe "without team preview", ->
|
||||
beforeEach ->
|
||||
@clock.tick(10000)
|
||||
shared.create.call this,
|
||||
conditions: [ Conditions.TIMED_BATTLE ]
|
||||
@battle.TIMER_CAP = Infinity
|
||||
|
||||
it "starts a timer that ends the battle in 5 minutes", ->
|
||||
@battle.isOver().should.be.false
|
||||
delta = 100
|
||||
@clock.tick(@battle.DEFAULT_TIMER - delta)
|
||||
@battle.isOver().should.be.false
|
||||
@clock.tick(delta)
|
||||
@battle.isOver().should.be.true
|
||||
|
||||
it "declares a timer win for the player that didn't run out of time", ->
|
||||
@battle.playerTimes[@id1] += 1000
|
||||
spy = @sandbox.spy(@battle, 'tell')
|
||||
@clock.tick(@battle.DEFAULT_TIMER)
|
||||
index1 = @battle.getPlayerIndex(@id1)
|
||||
spy.calledWith(Protocol.TIMER_WIN, index1).should.be.true
|
||||
|
||||
it "increases time remaining by 20 seconds for each player each turn", ->
|
||||
@battle.timeRemainingFor(@id1).should.equal(@battle.DEFAULT_TIMER)
|
||||
|
||||
@battle.beginTurn()
|
||||
delta = @battle.TIMER_PER_TURN_INCREASE
|
||||
@battle.timeRemainingFor(@id1).should.equal(@battle.DEFAULT_TIMER + delta)
|
||||
@battle.timeRemainingFor(@id2).should.equal(@battle.DEFAULT_TIMER + delta)
|
||||
|
||||
@battle.beginTurn()
|
||||
delta *= 2
|
||||
@battle.timeRemainingFor(@id1).should.equal(@battle.DEFAULT_TIMER + delta)
|
||||
@battle.timeRemainingFor(@id2).should.equal(@battle.DEFAULT_TIMER + delta)
|
||||
|
||||
it "recalculates timer after increasing time remaining", ->
|
||||
@battle.beginTurn()
|
||||
delta = @battle.TIMER_PER_TURN_INCREASE
|
||||
spy = @sandbox.spy(@battle, 'tell')
|
||||
|
||||
@clock.tick(@battle.DEFAULT_TIMER + delta / 2)
|
||||
spy.calledWith(Protocol.TIMER_WIN).should.be.false
|
||||
|
||||
@clock.tick(delta / 2)
|
||||
spy.calledWith(Protocol.TIMER_WIN).should.be.true
|
||||
|
||||
it "stops timer for players who have moved", ->
|
||||
delta = 5000
|
||||
@battle.timeRemainingFor(@id1).should.equal(@battle.DEFAULT_TIMER)
|
||||
@battle.timeRemainingFor(@id2).should.equal(@battle.DEFAULT_TIMER)
|
||||
|
||||
@clock.tick(delta)
|
||||
@battle.timeRemainingFor(@id1).should.equal(@battle.DEFAULT_TIMER - delta)
|
||||
@battle.timeRemainingFor(@id2).should.equal(@battle.DEFAULT_TIMER - delta)
|
||||
|
||||
@battle.recordMove(@id1, @battle.getMove("Splash"))
|
||||
|
||||
@clock.tick(delta)
|
||||
@battle.timeRemainingFor(@id1).should.equal(@battle.DEFAULT_TIMER - delta)
|
||||
@battle.timeRemainingFor(@id2).should.equal(@battle.DEFAULT_TIMER - 2 * delta)
|
||||
|
||||
it "recalculates the timer after a player chooses an action", ->
|
||||
delta = 4000
|
||||
# give player 2 more time
|
||||
@battle.playerTimes[@id2] += delta
|
||||
|
||||
@battle.recordMove(@id1, @battle.getMove("Splash"))
|
||||
|
||||
spy = @sandbox.spy(@battle, 'tell')
|
||||
@clock.tick(@battle.DEFAULT_TIMER)
|
||||
spy.calledWith(Protocol.TIMER_WIN).should.be.false
|
||||
|
||||
@clock.tick(delta)
|
||||
spy.calledWith(Protocol.TIMER_WIN).should.be.true
|
||||
|
||||
it "grants time if player selected a move before the battle continued", ->
|
||||
@clock.tick(2500)
|
||||
|
||||
spy = @sandbox.spy(@battle, 'requestActions')
|
||||
@controller.makeMove(@id1, "Splash")
|
||||
|
||||
# 5 seconds after the player moves, the battle progresses
|
||||
@clock.tick(5000)
|
||||
@controller.makeMove(@id2, "Splash")
|
||||
(@battle.DEFAULT_TIMER + @battle.TIMER_PER_TURN_INCREASE -
|
||||
@battle.timeRemainingFor(@id1)).should.equal(2500)
|
||||
|
||||
# Turn has progressed. Make another move and check the time.
|
||||
@clock.tick(2500)
|
||||
@controller.makeMove(@id1, "Splash")
|
||||
@clock.tick(5000)
|
||||
@controller.makeMove(@id2, "Splash")
|
||||
(@battle.DEFAULT_TIMER + 2 * @battle.TIMER_PER_TURN_INCREASE -
|
||||
@battle.timeRemainingFor(@id1)).should.equal(5000)
|
||||
|
||||
it "ends battle if canceling after which they'd lose to timer", ->
|
||||
# So the second player won't trigger the end condition.
|
||||
@battle.playerTimes[@id2] += 4000
|
||||
|
||||
@clock.tick(2500)
|
||||
|
||||
@controller.makeMove(@id1, "Splash")
|
||||
@clock.tick(@battle.DEFAULT_TIMER)
|
||||
|
||||
mock = @sandbox.mock(@battle).expects('timerWin').once()
|
||||
@controller.undoCompletedRequest(@id1)
|
||||
@battle.timeRemainingFor(@id1).should.equal(-2500)
|
||||
mock.verify()
|
||||
|
||||
it "sends timer updates when battle enters a new turn", ->
|
||||
@battle.recordMove(@id1, @battle.getMove("Splash"))
|
||||
@battle.recordMove(@id2, @battle.getMove("Splash"))
|
||||
|
||||
spy = @sandbox.spy(@battle, 'send')
|
||||
@battle.continueTurn()
|
||||
spy.calledWith('updateTimers').should.be.false
|
||||
@battle.beginTurn()
|
||||
spy.calledWith('updateTimers').should.be.true
|
||||
|
||||
it "gets cleared if the battle ends prematurely", ->
|
||||
@battle.endBattle()
|
||||
|
||||
mock = @sandbox.mock(@battle).expects('timerWin').never()
|
||||
@clock.tick(@battle.DEFAULT_TIMER)
|
||||
mock.verify()
|
||||
|
||||
it "has a cap every time a new turn begins", ->
|
||||
@battle.TIMER_CAP = @battle.DEFAULT_TIMER
|
||||
|
||||
@clock.tick(@battle.TIMER_PER_TURN_INCREASE >> 1)
|
||||
@battle.beginTurn()
|
||||
|
||||
@battle.timeRemainingFor(@id1).should.equal(@battle.TIMER_CAP)
|
||||
|
||||
it "has a cap every time a player gains time after a new action request", ->
|
||||
@battle.TIMER_CAP = @battle.DEFAULT_TIMER
|
||||
@battle.recordMove(@id1, @battle.getMove("U-turn"))
|
||||
|
||||
@clock.tick(@battle.TIMER_PER_TURN_INCREASE >> 1)
|
||||
@battle.continueTurn()
|
||||
|
||||
@battle.timeRemainingFor(@id1).should.equal(@battle.TIMER_CAP)
|
||||
|
||||
it "recalculates timer every time an action is requested", ->
|
||||
# Player 2 has more time.
|
||||
delta = 4000
|
||||
@battle.playerTimes[@id2] += delta
|
||||
@battle.recordMove(@id2, @battle.getMove("U-turn"))
|
||||
@battle.recordMove(@id1, @battle.getMove("Splash"))
|
||||
|
||||
@battle.continueTurn()
|
||||
# Action requested due to U-turn
|
||||
|
||||
spy = @sandbox.spy(@battle, 'tell')
|
||||
@clock.tick(@battle.DEFAULT_TIMER)
|
||||
spy.calledWith(Protocol.TIMER_WIN).should.be.false
|
||||
|
||||
@clock.tick(delta)
|
||||
spy.calledWith(Protocol.TIMER_WIN).should.be.true
|
||||
|
||||
describe "with team preview", ->
|
||||
beforeEach ->
|
||||
@clock.tick(10000)
|
||||
shared.create.call this,
|
||||
conditions: [ Conditions.TIMED_BATTLE, Conditions.TEAM_PREVIEW ]
|
||||
|
||||
it "starts a timer that auto-starts the battle after 1.5 mins", ->
|
||||
@battle.arranging.should.be.true
|
||||
spy = @sandbox.spy(@battle, 'startBattle')
|
||||
@clock.tick(@battle.TEAM_PREVIEW_TIMER)
|
||||
spy.calledOnce.should.be.true
|
||||
@battle.arranging.should.be.false
|
||||
|
||||
it "arranges teams of those who already submitted arrangements", ->
|
||||
@battle.arranging.should.be.true
|
||||
arrangement = [0...@team1.size()]
|
||||
arrangement.reverse()
|
||||
pokemon = _.clone(@team1.pokemon)
|
||||
pokemon.reverse()
|
||||
@controller.arrangeTeam(@id1, arrangement)
|
||||
@clock.tick(@battle.TEAM_PREVIEW_TIMER)
|
||||
@team1.pokemon.should.eql(pokemon)
|
||||
70
test/server/conditions/unreleased_ban_spec.coffee
Normal file
70
test/server/conditions/unreleased_ban_spec.coffee
Normal file
@@ -0,0 +1,70 @@
|
||||
require '../../helpers'
|
||||
|
||||
{BattleServer} = require('../../../server/server')
|
||||
{User} = require('../../../server/user')
|
||||
{Conditions} = require '../../../shared/conditions'
|
||||
{Factory} = require '../../factory'
|
||||
should = require('should')
|
||||
|
||||
generateTeam = ->
|
||||
[ Factory("Magikarp")
|
||||
Factory("Gyarados")
|
||||
Factory('Hitmonchan')
|
||||
Factory("Celebi")
|
||||
Factory("Blissey")
|
||||
Factory("Alakazam") ]
|
||||
|
||||
describe 'Validations: Unreleased Ban', ->
|
||||
it "returns an error if a pokemon is unreleased", ->
|
||||
server = new BattleServer()
|
||||
format = 'xy1000'
|
||||
team = generateTeam()
|
||||
team[0] = Factory("Hoopa", item: "Leftovers", moves: [ "Moonblast" ])
|
||||
conditions = [ Conditions.UNRELEASED_BAN ]
|
||||
|
||||
server.validateTeam(team, format, conditions).should.not.be.empty
|
||||
|
||||
it "returns an error if a pokemon has an unreleased item", ->
|
||||
server = new BattleServer()
|
||||
format = 'xy1000'
|
||||
team = generateTeam()
|
||||
team[0] = Factory("Latias", item: "Soul Dew", moves: [ "Psychic" ])
|
||||
conditions = [ Conditions.UNRELEASED_BAN ]
|
||||
|
||||
server.validateTeam(team, format, conditions).should.not.be.empty
|
||||
|
||||
it "returns an error if a pokemon has an unreleased ability", ->
|
||||
server = new BattleServer()
|
||||
format = 'xy1000'
|
||||
team = generateTeam()
|
||||
team[0] = Factory("Suicune", ability: "Water Absorb", moves: [ "Surf" ])
|
||||
conditions = [ Conditions.UNRELEASED_BAN ]
|
||||
|
||||
server.validateTeam(team, format, conditions).should.not.be.empty
|
||||
|
||||
it "returns no error if all pokemon have nothing unreleased", ->
|
||||
server = new BattleServer()
|
||||
format = 'xy1000'
|
||||
team = generateTeam()
|
||||
team[0] = Factory("Latias", item: "Leftovers", moves: [ "Psychic" ])
|
||||
conditions = [ Conditions.UNRELEASED_BAN ]
|
||||
|
||||
server.validateTeam(team, format, conditions).should.be.empty
|
||||
|
||||
it "returns no error if a pokemon has a dream world ability that is the same as a regular ability", ->
|
||||
server = new BattleServer()
|
||||
format = 'xy1000'
|
||||
team = generateTeam()
|
||||
team[0] = Factory("Metapod", ability: "Shed Skin", moves: [ "Tackle" ])
|
||||
conditions = [ Conditions.UNRELEASED_BAN ]
|
||||
|
||||
server.validateTeam(team, format, conditions).should.be.empty
|
||||
|
||||
it "ignores invalid pokemon", ->
|
||||
server = new BattleServer()
|
||||
format = 'xy1000'
|
||||
team = generateTeam()
|
||||
team[0] = {species: "I'm a totally fake Pokemon."}
|
||||
conditions = [ Conditions.UNRELEASED_BAN ]
|
||||
|
||||
(-> server.validateTeam(team, format, conditions)).should.not.throw()
|
||||
76
test/server/rooms_spec.coffee
Normal file
76
test/server/rooms_spec.coffee
Normal file
@@ -0,0 +1,76 @@
|
||||
require '../helpers'
|
||||
|
||||
{BattleServer} = require('../../server/server')
|
||||
{Room} = require '../../server/rooms'
|
||||
{User} = require '../../server/user'
|
||||
|
||||
describe "A server room:", ->
|
||||
beforeEach ->
|
||||
@server = new BattleServer()
|
||||
@spark1 = @stubSpark()
|
||||
@spark2 = @stubSpark()
|
||||
@user1 = @server.findOrCreateUser(id: 1, name: 'aaaa', @spark1)
|
||||
@user2 = @server.findOrCreateUser(id: 2, name: 'bbbb', @spark2)
|
||||
@room = new Room('derp')
|
||||
@room.add(@spark1)
|
||||
@room.add(@spark2)
|
||||
|
||||
describe "#message", ->
|
||||
it "sends a message to all users in that room", ->
|
||||
mock1 = @sandbox.mock(@user1)
|
||||
mock1.expects('send').withArgs("rawMessage", @room.name, "hello").once()
|
||||
mock2 = @sandbox.mock(@user2)
|
||||
mock2.expects('send').withArgs("rawMessage", @room.name, "hello").once()
|
||||
|
||||
@room.message("hello")
|
||||
mock1.verify()
|
||||
mock2.verify()
|
||||
|
||||
describe "#userMessage", ->
|
||||
it "sends a message to all users in that room", ->
|
||||
mock1 = @sandbox.mock(@user1).expects('send')
|
||||
mock1.withArgs("userMessage", @room.name, @user1.name, "hello").once()
|
||||
mock2 = @sandbox.mock(@user2).expects('send').once()
|
||||
mock2.withArgs("userMessage", @room.name, @user1.name, "hello").once()
|
||||
|
||||
@room.userMessage(@user1, "hello")
|
||||
mock1.verify()
|
||||
mock2.verify()
|
||||
|
||||
describe "#setTopic", ->
|
||||
it "sends a topic message to all users in that room", ->
|
||||
mock1 = @sandbox.mock(@user1).expects('send')
|
||||
mock1.withArgs("topic", "a test").once()
|
||||
mock2 = @sandbox.mock(@user2).expects('send').once()
|
||||
mock2.withArgs("topic", "a test").once()
|
||||
|
||||
@room.setTopic("a test")
|
||||
mock1.verify()
|
||||
mock2.verify()
|
||||
|
||||
describe "#userJSON", ->
|
||||
it "returns an array containing the JSON of all users", ->
|
||||
@room.toJSON().should.eql([ @user1.toJSON(), @user2.toJSON() ])
|
||||
|
||||
describe "#send", ->
|
||||
it "broadcasts to every single user, including ones on the same account", ->
|
||||
mock1 = @sandbox.mock(@user1).expects('send').withArgs('hello').once()
|
||||
mock2 = @sandbox.mock(@user2).expects('send').withArgs('hello').once()
|
||||
@room.send("hello")
|
||||
mock1.verify()
|
||||
mock2.verify()
|
||||
|
||||
it "stops broadcasting to sparks that leave", ->
|
||||
spy1 = @sandbox.spy(@user1, 'send')
|
||||
spy2 = @sandbox.spy(@user2, 'send')
|
||||
|
||||
@room.remove(@spark1)
|
||||
@room.send("hello")
|
||||
|
||||
spy1.withArgs('hello').called.should.be.false
|
||||
spy2.withArgs('hello').calledOnce.should.be.true
|
||||
|
||||
@room.remove(@spark2)
|
||||
@room.send("hello")
|
||||
spy1.withArgs('hello').called.should.be.false
|
||||
spy2.withArgs('hello').calledOnce.should.be.true
|
||||
57
test/server/scheduler_spec.coffee
Normal file
57
test/server/scheduler_spec.coffee
Normal file
@@ -0,0 +1,57 @@
|
||||
sinon = require('sinon')
|
||||
async = require('async')
|
||||
|
||||
ratings = require('../../server/ratings')
|
||||
scheduler = require('../../server/schedule')
|
||||
|
||||
require '../helpers'
|
||||
|
||||
describe 'Scheduler', ->
|
||||
beforeEach ->
|
||||
date = new Date()
|
||||
date.setHours(23)
|
||||
date.setMinutes(59)
|
||||
date.setSeconds(59)
|
||||
# Get rid of existing clock
|
||||
@clock.restore()
|
||||
@clock = sinon.useFakeTimers(date.getTime())
|
||||
@jobs = scheduler.createScheduler()
|
||||
@callbacks = @jobs.map (job) ->
|
||||
(callback) -> job.on('finished', callback)
|
||||
|
||||
it 'decays elo ratings', (done) ->
|
||||
players = ['guy', 'lady']
|
||||
oldRatings = [ 2000, 4000 ]
|
||||
oldGuyRating = 2000
|
||||
oldLadyRating = 4000
|
||||
ratings.setRatings players, oldRatings, =>
|
||||
async.parallel @callbacks, =>
|
||||
ratings.getRatings players, (err, newRatings) =>
|
||||
throw err if err
|
||||
newRatings.should.eql(oldRatings.map((r) -> r - ratings.DECAY_AMOUNT))
|
||||
done()
|
||||
@clock.tick(2000)
|
||||
|
||||
it 'does not decay the minimum rating possible', (done) ->
|
||||
minRating = ratings.algorithm.createPlayer().rating
|
||||
ratings.setRating 'sonic', minRating, =>
|
||||
async.parallel @callbacks, =>
|
||||
ratings.getRating 'sonic', (err, rating) =>
|
||||
throw err if err
|
||||
rating.should.equal(minRating)
|
||||
done()
|
||||
@clock.tick(2000)
|
||||
|
||||
it 'does not decay active players', (done) ->
|
||||
players = ['guy', 'lady']
|
||||
oldRatings = [ 2000, 4000 ]
|
||||
oldGuyRating = 2000
|
||||
oldLadyRating = 4000
|
||||
ratings.setActive players, =>
|
||||
ratings.setRatings players, oldRatings, =>
|
||||
async.parallel @callbacks, =>
|
||||
ratings.getRatings players, (err, newRatings) =>
|
||||
throw err if err
|
||||
newRatings.should.eql(oldRatings)
|
||||
done()
|
||||
@clock.tick(2000)
|
||||
Reference in New Issue
Block a user