1
0
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:
Deukhoofd
2016-02-01 23:19:30 +01:00
commit d7316d5799
6681 changed files with 527969 additions and 0 deletions

View 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()

View 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()

View 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()

View 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()

View 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

View 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

View 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

View 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

View 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

View 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)

View 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)

View 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()

View 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

View 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)