Merge branch 'develop' into new_api_test_infrastructure

This commit is contained in:
Blade Barringer
2015-10-16 14:54:03 -05:00
634 changed files with 23948 additions and 13380 deletions
+137 -79
View File
@@ -31,103 +31,109 @@ describe "Users", ->
], done
it "Should choose a new group leader when deleting a user", (done) ->
userToDelete = undefined
userToBecomeLeader = undefined
guildToHaveNewLeader = undefined
async.waterfall [
(cb) ->
registerManyUsers 2, cb
context "handle group changes when user cancels", ->
it "Should choose a new group leader when deleting a user", (done) ->
userToDelete = undefined
userToBecomeLeader = undefined
guildToHaveNewLeader = undefined
async.waterfall [
(cb) ->
registerManyUsers 2, cb
(_users, cb) ->
userToDelete = _users[0]
userToBecomeLeader = _users[1]
User.findByIdAndUpdate userToDelete._id,
$set:
"balance": 4
, (err, _user) ->
(_users, cb) ->
userToDelete = _users[0]
userToBecomeLeader = _users[1]
User.findByIdAndUpdate userToDelete._id,
$set:
"balance": 4
, (err, _user) ->
cb()
(cb) ->
request.post(baseURL + "/groups").send(
name: "GuildToGainNewLeader"
type: "guild"
)
.set("X-API-User", userToDelete._id)
.set("X-API-Key", userToDelete.apiToken)
.end (res) ->
expectCode res, 200
guildToHaveNewLeader = res.body
expect(guildToHaveNewLeader.leader).to.eql(userToDelete._id)
cb()
(cb) ->
request.post(baseURL + "/groups").send(
name: "GuildToGainNewLeader"
type: "guild"
)
.set("X-API-User", userToDelete._id)
.set("X-API-Key", userToDelete.apiToken)
.end (res) ->
expectCode res, 200
guildToHaveNewLeader = res.body
expect(guildToHaveNewLeader.leader).to.eql(userToDelete._id)
cb()
(cb) ->
inviteURL = baseURL + "/groups/" + guildToHaveNewLeader._id + "/invite"
request.post(inviteURL)
.send( uuids: [userToBecomeLeader._id])
.end (res) ->
expectCode res, 200
cb()
(cb) ->
inviteURL = baseURL + "/groups/" + guildToHaveNewLeader._id + "/invite"
request.post(inviteURL)
.send( uuids: [userToBecomeLeader._id])
(cb) ->
request.post(baseURL + "/groups/" + guildToHaveNewLeader._id + "/join")
.set("X-API-User", userToBecomeLeader._id)
.set("X-API-Key", userToBecomeLeader.apiToken)
.end (res) ->
expectCode res, 200
cb()
(cb) ->
request.del(baseURL + "/user")
.set("X-API-User", userToDelete._id)
.set("X-API-Key", userToDelete.apiToken)
.end (res) ->
expectCode res, 200
cb()
(cb) ->
request.post(baseURL + "/groups/" + guildToHaveNewLeader._id + "/join")
(cb) ->
request.get(baseURL + "/groups/" + guildToHaveNewLeader._id)
.set("X-API-User", userToBecomeLeader._id)
.set("X-API-Key", userToBecomeLeader.apiToken)
.end (res) ->
expectCode res, 200
g = res.body
userInGroup = _.find(g.members, (member) -> return member._id == userToDelete._id; )
expect(userInGroup).to.equal(undefined)
expect(g.leader._id).to.equal(userToBecomeLeader._id)
cb()
(cb) ->
request.del(baseURL + "/user")
.set("X-API-User", userToDelete._id)
.set("X-API-Key", userToDelete.apiToken)
.end (res) ->
expectCode res, 200
cb()
], done
(cb) ->
request.get(baseURL + "/groups/" + guildToHaveNewLeader._id)
.set("X-API-User", userToBecomeLeader._id)
.set("X-API-Key", userToBecomeLeader.apiToken)
.end (res) ->
expectCode res, 200
g = res.body
userInGroup = _.find(g.members, (member) -> return member._id == userToDelete._id; )
expect(userInGroup).to.equal(undefined)
expect(g.leader._id).to.equal(userToBecomeLeader._id)
cb()
context "handle group and invite removals", ->
guild = undefined
party = undefined
before (done) ->
User.findByIdAndUpdate user._id,
$set:
"balance": 4
, (err, _user) ->
async.waterfall [
(cb) ->
request.post(baseURL + "/groups").send(
name: "TestPrivateGroup"
type: "party"
)
.end (res) ->
expectCode res, 200
party = res.body
cb()
], done
(cb) ->
request.post(baseURL + "/groups").send(
name: "TestPrivateGroup"
type: "guild"
)
.end (res) ->
expectCode res, 200
guild = res.body
cb()
it 'Should remove a user from a group when deleting a user', (done) ->
userToDelete = undefined
guild = undefined
party = undefined
User.findByIdAndUpdate user._id,
$set:
"balance": 4
, (err, _user) ->
], done
it 'Should remove a user from a group when deleting a user', (done) ->
userToDelete = undefined
async.waterfall [
(cb) ->
request.post(baseURL + "/groups").send(
name: "TestPrivateGroup"
type: "party"
)
.end (res) ->
expectCode res, 200
party = res.body
cb()
(cb) ->
request.post(baseURL + "/groups").send(
name: "TestPrivateGroup"
type: "guild"
)
.end (res) ->
expectCode res, 200
guild = res.body
cb()
(cb) ->
registerManyUsers 1, cb
@@ -192,3 +198,55 @@ describe "Users", ->
cb()
], done
it 'Should remove invitations when deleting a user', (done) ->
userToDeleteInvites = undefined
async.waterfall [
(cb) ->
registerManyUsers 1, cb
# Send them invitations
(_users, cb) ->
userToDeleteInvites = _users[0]
inviteURL = baseURL + "/groups/" + party._id + "/invite"
request.post(inviteURL)
.send( uuids: [userToDeleteInvites._id])
.end (res) ->
expectCode res, 200
cb()
(cb) ->
inviteURL = baseURL + "/groups/" + guild._id + "/invite"
request.post(inviteURL)
.send( uuids: [userToDeleteInvites._id])
.end (res) ->
expectCode res, 200
cb()
(cb) ->
request.del(baseURL + "/user")
.set("X-API-User", userToDeleteInvites._id)
.set("X-API-Key", userToDeleteInvites.apiToken)
.end (res) ->
expectCode res, 200
cb()
(cb) ->
request.get(baseURL + "/groups/" + party._id)
.end (res) ->
expectCode res, 200
g = res.body
userInviteForGroup = _.find(g.invites, (invite) -> return invite._id == userToDeleteInvites._id; )
expect(userInviteForGroup).to.equal(undefined)
cb()
(cb) ->
request.get(baseURL + "/groups/" + guild._id)
.end (res) ->
expectCode res, 200
g = res.body
userInviteForGroup = _.find(g.invites, (invite) -> return invite._id == userToDeleteInvites._id; )
expect(userInviteForGroup).to.equal(undefined)
cb()
], done
+31 -29
View File
@@ -490,40 +490,45 @@ describe 'User', ->
describe 'drop system', ->
user = null
MIN_RANGE_FOR_POTION = 0
MAX_RANGE_FOR_POTION = .3
MIN_RANGE_FOR_EGG = .4
MAX_RANGE_FOR_EGG = .6
MIN_RANGE_FOR_FOOD = .7
MAX_RANGE_FOR_FOOD = 1
beforeEach ->
user = newUser()
user.flags.dropsEnabled = true
# too many predictableRandom calls to stub, let's return the last element
sinon.stub(user.fns, 'randomVal', (obj)->
result = undefined
for key, val of obj
result = val
result
)
@task_id = shared.uuid()
user.ops.addTask({body: {type: 'daily', id: @task_id}})
it 'gets a golden potion', ->
sinon.stub(user.fns, 'predictableRandom').returns 0
user.ops.score {params: { id: @task_id, direction: 'up'}}
expect(user.items.eggs).to.eql {}
expect(user.items.hatchingPotions).to.eql {'Golden': 1}
expect(user.items.food).to.eql {}
it 'drops a hatching potion', ->
for random in [MIN_RANGE_FOR_POTION..MAX_RANGE_FOR_POTION] by .1
sinon.stub(user.fns, 'predictableRandom').returns random
user.ops.score {params: { id: @task_id, direction: 'up'}}
expect(user.items.eggs).to.be.empty
expect(user.items.hatchingPotions).to.not.be.empty
expect(user.items.food).to.be.empty
user.fns.predictableRandom.restore()
it 'gets a bear cub egg', ->
sinon.stub(user.fns, 'predictableRandom', cycle [0, 0, 0.55])
user.ops.score {params: { id: @task_id, direction: 'up'}}
expect(user.items.eggs).to.eql {'BearCub': 1}
expect(user.items.hatchingPotions).to.eql {}
expect(user.items.food).to.eql {}
it 'drops a pet egg', ->
for random in [MIN_RANGE_FOR_EGG..MAX_RANGE_FOR_EGG] by .1
sinon.stub(user.fns, 'predictableRandom').returns random
user.ops.score {params: { id: @task_id, direction: 'up'}}
expect(user.items.eggs).to.not.be.empty
expect(user.items.hatchingPotions).to.be.empty
expect(user.items.food).to.be.empty
user.fns.predictableRandom.restore()
it 'gets honey', ->
sinon.stub(user.fns, 'predictableRandom', cycle [0, 0, 0.9])
user.ops.score {params: { id: @task_id, direction: 'up'}}
expect(user.items.eggs).to.eql {}
expect(user.items.hatchingPotions).to.eql {}
expect(user.items.food).to.eql {'Honey': 1}
it 'drops food', ->
for random in [MIN_RANGE_FOR_FOOD..MAX_RANGE_FOR_FOOD] by .1
sinon.stub(user.fns, 'predictableRandom').returns random
user.ops.score {params: { id: @task_id, direction: 'up'}}
expect(user.items.eggs).to.be.empty
expect(user.items.hatchingPotions).to.be.empty
expect(user.items.food).to.not.be.empty
user.fns.predictableRandom.restore()
it 'does not get a drop', ->
sinon.stub(user.fns, 'predictableRandom').returns 0.5
@@ -531,9 +536,6 @@ describe 'User', ->
expect(user.items.eggs).to.eql {}
expect(user.items.hatchingPotions).to.eql {}
expect(user.items.food).to.eql {}
afterEach ->
user.fns.randomVal.restore()
user.fns.predictableRandom.restore()
describe 'Quests', ->
@@ -542,7 +544,7 @@ describe 'User', ->
expect(quest.notes()).to.be.an('string')
expect(quest.completion()).to.be.an('string') if quest.completion
expect(quest.previous).to.be.an('string') if quest.previous
expect(quest.value).to.be.greaterThan 0 if quest.canBuy
expect(quest.value).to.be.greaterThan 0 if quest.canBuy()
expect(quest.drop.gp).to.not.be.lessThan 0
expect(quest.drop.exp).to.not.be.lessThan 0
expect(quest.category).to.match(/pet|unlockable|gold|world/)
+19
View File
@@ -26,6 +26,16 @@ describe('count', function() {
expect(beastMasterTotal).to.eql(1);
});
it('does not count pets hatched with premium potions', function() {
var pets = {
"Wolf-Spooky": 5,
"Dragon-Spooky": 5,
"FlyingPig-Base": 5
}
var beastMasterTotal = count.beastMasterProgress(pets);
expect(beastMasterTotal).to.eql(1);
});
it('does not count special pets', function() {
var pets = {
"Wolf-Base": 2,
@@ -65,6 +75,15 @@ describe('count', function() {
expect(mountMasterTotal).to.eql(2);
});
it('does not count premium mounts', function() {
var mounts = {
"Dragon-Red": true,
"FlyingPig-Spooky": true
}
var mountMasterTotal = count.mountMasterProgress(mounts);
expect(mountMasterTotal).to.eql(1);
});
it('does not count quest mounts', function() {
var mounts = { "Dragon-Red": true, "Gryphon-Base": true };
var mountMasterTotal = count.mountMasterProgress(mounts);
+4 -5
View File
@@ -6,7 +6,6 @@ var _ = require('lodash');
require('coffee-script');
var shared = require('../../common/script/index.coffee');
var Content = require('../../common/script/content/index.coffee');
describe('user.fns.buy', function() {
var user;
@@ -63,8 +62,8 @@ describe('user.fns.buy', function() {
var fullArmoire = {}
_(Content.gearTypes).each(function(type) {
_(Content.gear.tree[type].armoire).each(function(gearObject, gearName) {
_(shared.content.gearTypes).each(function(type) {
_(shared.content.gear.tree[type].armoire).each(function(gearObject, gearName) {
armoireKey = gearObject.key;
fullArmoire[armoireKey] = true;
});
@@ -118,7 +117,7 @@ describe('user.fns.buy', function() {
});
it('gives food', function() {
var honey = Content.food.Honey;
var honey = shared.content.food.Honey;
user.fns.randomVal.returns(honey);
user.fns.predictableRandom.returns(YIELD_FOOD);
@@ -148,7 +147,7 @@ describe('user.fns.buy', function() {
context('gear awards', function() {
beforeEach(function() {
var shield = Content.gear.tree.shield.armoire.gladiatorShield;
var shield = shared.content.gear.tree.shield.armoire.gladiatorShield;
user.fns.randomVal.returns(shield);
});
@@ -0,0 +1,84 @@
var sinon = require('sinon');
var chai = require("chai")
chai.use(require("sinon-chai"))
var expect = chai.expect
require('coffee-script');
var shared = require('../../common/script/index.coffee');
var Content = require('../../common/script/content/index.coffee');
describe('user.ops.buyMysterySet', function() {
var user;
beforeEach(function() {
user = {
items: {
gear: {
owned: {
weapon_warrior_0: true
}
}
},
purchased: {
plan: {
consecutive: {
trinkets: 0
}
}
}
};
shared.wrap(user);
});
context('Mystery Sets', function() {
context('failure conditions', function() {
it('does not grant mystery sets without Mystic Hourglasses', function(done) {
user.ops.buyMysterySet({params:{key:'201501'}}, function(response) {
expect(response.message).to.eql("You don't have enough Mystic Hourglasses.");
expect(user.items.gear.owned).to.eql({'weapon_warrior_0': true});
done();
});
});
it('does not grant mystery set that has already been purchased', function(done) {
user.purchased.plan.consecutive.trinkets = 1;
user.items.gear.owned = {
weapon_warrior_0: true,
weapon_mystery_301404: true,
armor_mystery_301404: true,
head_mystery_301404: true,
eyewear_mystery_301404: true
};
user.ops.buyMysterySet({params:{key:'301404'}}, function(response) {
expect(response.message).to.eql("Mystery set not found, or set already owned");
expect(user.purchased.plan.consecutive.trinkets).to.eql(1);
done();
});
});
});
context('successful purchases', function() {
it('buys Steampunk Accessories Set', function(done) {
user.purchased.plan.consecutive.trinkets = 1;
user.ops.buyMysterySet({params:{key:'301404'}}, function() {
expect(user.purchased.plan.consecutive.trinkets).to.eql(0);
expect(user.items.gear.owned).to.eql({
weapon_warrior_0: true,
weapon_mystery_301404: true,
armor_mystery_301404: true,
head_mystery_301404: true,
eyewear_mystery_301404: true
});
done();
});
});
});
});
});
+139
View File
@@ -0,0 +1,139 @@
var sinon = require('sinon');
var chai = require('chai');
chai.use(require('sinon-chai'))
var expect = chai.expect
require('coffee-script');
var shared = require('../../common/script/index.coffee');
var content = require('../../common/script/content/index.coffee');
describe('user.ops.hatch', function() {
var user;
beforeEach(function() {
user = {
items: {
eggs: {},
hatchingPotions: {},
pets: {}
}
};
shared.wrap(user);
});
context('Pet Hatching', function() {
context('failure conditions', function() {
it('does not allow hatching without specifying egg and potion', function(done) {
user.ops.hatch({params:{}},function(response) {
expect(response.message).to.eql('Please specify query.egg & query.hatchingPotion');
expect(user.items.pets).to.be.empty;
done();
});
});
it('does not allow hatching if user lacks specified egg', function(done) {
user.items.eggs = {'Wolf':1};
user.items.hatchingPotions = {'Base':1};
user.ops.hatch({params:{egg:'Dragon',hatchingPotion:'Base'}}, function(response) {
expect(response.message).to.eql(shared.i18n.t('messageMissingEggPotion'));
expect(user.items.pets).to.be.empty;
expect(user.items.eggs).to.eql({'Wolf':1});
expect(user.items.hatchingPotions).to.eql({'Base':1});
done();
});
});
it('does not allow hatching if user lacks specified hatching potion', function(done) {
user.items.eggs = {'Wolf':1};
user.items.hatchingPotions = {'Base':1};
user.ops.hatch({params:{egg:'Wolf',hatchingPotion:'Golden'}}, function(response) {
expect(response.message).to.eql(shared.i18n.t('messageMissingEggPotion'));
expect(user.items.pets).to.be.empty;
expect(user.items.eggs).to.eql({'Wolf':1});
expect(user.items.hatchingPotions).to.eql({'Base':1});
done();
});
});
it('does not allow hatching if user already owns target pet', function(done) {
user.items.eggs = {'Wolf':1};
user.items.hatchingPotions = {'Base':1};
user.items.pets = {'Wolf-Base':10};
user.ops.hatch({params:{egg:'Wolf',hatchingPotion:'Base'}}, function(response) {
expect(response.message).to.eql(shared.i18n.t('messageAlreadyPet'));
expect(user.items.pets).to.eql({'Wolf-Base':10});
expect(user.items.eggs).to.eql({'Wolf':1});
expect(user.items.hatchingPotions).to.eql({'Base':1});
done();
});
});
it('does not allow hatching quest pet egg using premium potion', function(done) {
user.items.eggs = {'Cheetah':1};
user.items.hatchingPotions = {'Spooky':1};
user.ops.hatch({params:{egg:'Cheetah',hatchingPotion:'Spooky'}}, function(response) {
expect(response.message).to.eql(shared.i18n.t('messageInvalidEggPotionCombo'));
expect(user.items.pets).to.be.empty;
expect(user.items.eggs).to.eql({'Cheetah':1});
expect(user.items.hatchingPotions).to.eql({'Spooky':1});
done();
});
});
});
context('successful hatching', function() {
it('hatches a basic pet', function(done) {
user.items.eggs = {'Wolf':1};
user.items.hatchingPotions = {'Base':1};
user.ops.hatch({params:{egg:'Wolf',hatchingPotion:'Base'}}, function(response) {
expect(response.message).to.eql(shared.i18n.t('messageHatched'));
expect(user.items.pets).to.eql({'Wolf-Base':5});
expect(user.items.eggs).to.eql({'Wolf':0});
expect(user.items.hatchingPotions).to.eql({'Base':0});
done();
});
});
it('hatches a quest pet', function(done) {
user.items.eggs = {'Cheetah':1};
user.items.hatchingPotions = {'Base':1};
user.ops.hatch({params:{egg:'Cheetah',hatchingPotion:'Base'}}, function(response) {
expect(response.message).to.eql(shared.i18n.t('messageHatched'));
expect(user.items.pets).to.eql({'Cheetah-Base':5});
expect(user.items.eggs).to.eql({'Cheetah':0});
expect(user.items.hatchingPotions).to.eql({'Base':0});
done();
});
});
it('hatches a premium pet', function(done) {
user.items.eggs = {'Wolf':1};
user.items.hatchingPotions = {'Spooky':1};
user.ops.hatch({params:{egg:'Wolf',hatchingPotion:'Spooky'}}, function(response) {
expect(response.message).to.eql(shared.i18n.t('messageHatched'));
expect(user.items.pets).to.eql({'Wolf-Spooky':5});
expect(user.items.eggs).to.eql({'Wolf':0});
expect(user.items.hatchingPotions).to.eql({'Spooky':0});
done();
});
});
it('hatches a pet previously raised to a mount', function(done) {
user.items.eggs = {'Wolf':1};
user.items.hatchingPotions = {'Base':1};
user.items.pets = {'Wolf-Base':-1};
user.ops.hatch({params:{egg:'Wolf',hatchingPotion:'Base'}}, function(response) {
expect(response.message).to.eql(shared.i18n.t('messageHatched'));
expect(user.items.pets).to.eql({'Wolf-Base':5});
expect(user.items.eggs).to.eql({'Wolf':0});
expect(user.items.hatchingPotions).to.eql({'Base':0});
done();
});
});
});
});
});
@@ -0,0 +1,132 @@
var sinon = require('sinon');
var chai = require("chai")
chai.use(require("sinon-chai"))
var expect = chai.expect
require('coffee-script');
var shared = require('../../common/script/index.coffee');
var Content = require('../../common/script/content/index.coffee');
describe('user.ops.hourglassPurchase', function() {
var user;
beforeEach(function() {
user = {
items: {
pets: {},
mounts: {},
hatchingPotions: {}
},
purchased: {
plan: {
consecutive: {
trinkets: 0
}
}
}
};
shared.wrap(user);
});
context('Time Travel Stable', function() {
context('failure conditions', function() {
it('does not allow purchase of unsupported item types', function(done) {
user.ops.hourglassPurchase({params:{type: 'hatchingPotions', key: 'Base'}}, function(response) {
expect(response.message).to.eql('Item type not supported for purchase with Mystic Hourglass. Allowed types: ["pets","mounts"]');
expect(user.items.hatchingPotions).to.eql({});
done();
});
});
it('does not grant pets without Mystic Hourglasses', function(done) {
user.ops.hourglassPurchase({params:{type: 'pets', key: 'MantisShrimp-Base'}}, function(response) {
expect(response.message).to.eql("You don't have enough Mystic Hourglasses.");
expect(user.items.pets).to.eql({});
done();
});
});
it('does not grant mounts without Mystic Hourglasses', function(done) {
user.ops.hourglassPurchase({params:{type: 'mounts', key: 'MantisShrimp-Base'}}, function(response) {
expect(response.message).to.eql("You don't have enough Mystic Hourglasses.");
expect(user.items.mounts).to.eql({});
done();
});
});
it('does not grant pet that has already been purchased', function(done) {
user.purchased.plan.consecutive.trinkets = 1;
user.items.pets = {
'MantisShrimp-Base': true
};
user.ops.hourglassPurchase({params:{type: 'pets', key: 'MantisShrimp-Base'}}, function(response) {
expect(response.message).to.eql("Pet already owned.");
expect(user.purchased.plan.consecutive.trinkets).to.eql(1);
done();
});
});
it('does not grant mount that has already been purchased', function(done) {
user.purchased.plan.consecutive.trinkets = 1;
user.items.mounts = {
'MantisShrimp-Base': true
};
user.ops.hourglassPurchase({params:{type: 'mounts', key: 'MantisShrimp-Base'}}, function(response) {
expect(response.message).to.eql("Mount already owned.");
expect(user.purchased.plan.consecutive.trinkets).to.eql(1);
done();
});
});
it('does not grant pet that is not part of the Time Travel Stable', function(done) {
user.purchased.plan.consecutive.trinkets = 1;
user.ops.hourglassPurchase({params: {type: 'pets', key: 'Wolf-Veteran'}}, function(response) {
expect(response.message).to.eql('Pet not available for purchase with Mystic Hourglass.');
expect(user.purchased.plan.consecutive.trinkets).to.eql(1);
done();
});
});
it('does not grant mount that is not part of the Time Travel Stable', function(done) {
user.purchased.plan.consecutive.trinkets = 1;
user.ops.hourglassPurchase({params: {type: 'mounts', key: 'Orca-Base'}}, function(response) {
expect(response.message).to.eql('Mount not available for purchase with Mystic Hourglass.');
expect(user.purchased.plan.consecutive.trinkets).to.eql(1);
done();
});
});
});
context('successful purchases', function() {
it('buys a pet', function(done) {
user.purchased.plan.consecutive.trinkets = 2;
user.ops.hourglassPurchase({params: {type: 'pets', key: 'MantisShrimp-Base'}}, function(response) {
expect(response.message).to.eql('Purchased an item using a Mystic Hourglass!');
expect(user.purchased.plan.consecutive.trinkets).to.eql(1);
expect(user.items.pets).to.eql({'MantisShrimp-Base':5});
done();
});
});
it('buys a mount', function(done) {
user.purchased.plan.consecutive.trinkets = 2;
user.ops.hourglassPurchase({params: {type: 'mounts', key: 'MantisShrimp-Base'}}, function(response) {
expect(response.message).to.eql('Purchased an item using a Mystic Hourglass!');
expect(user.purchased.plan.consecutive.trinkets).to.eql(1);
expect(user.items.mounts).to.eql({'MantisShrimp-Base':true});
done();
});
});
});
});
});
+11
View File
@@ -0,0 +1,11 @@
import {
expectValidTranslationString
} from '../helpers/content.helper';
import armoire from '../../common/script/src/content/armoire';
describe('Armoire Locales', () => {
it('has a valid text attribute', () => {
expectValidTranslationString(armoire.text);
});
});
+22
View File
@@ -0,0 +1,22 @@
import {
expectValidTranslationString,
describeEachItem
} from '../helpers/content.helper';
import {each} from 'lodash';
import backgroundSets from '../../common/script/src/content/backgrounds';
describe('Backgrounds', () => {
each(backgroundSets, (set, name) => {
describeEachItem(name, set, (bg, key) => {
it('has a valid text attribute', () => {
expectValidTranslationString(bg.text);
});
it('has a valid notes attribute', () => {
expectValidTranslationString(bg.notes);
});
});
});
});
+36
View File
@@ -0,0 +1,36 @@
import {
expectValidTranslationString,
describeEachItem
} from '../helpers/content.helper';
import {allEggs} from '../../common/script/src/content/eggs';
describeEachItem('Eggs', allEggs, (egg, key) => {
it('has a key attribute', () => {
expect(egg.key).to.eql(key);
});
it('has a valid text attribute', () => {
expectValidTranslationString(egg.text);
});
it('has a valid mountText attribute', () => {
expectValidTranslationString(egg.mountText);
});
it('has a valid notes attribute', () => {
expectValidTranslationString(egg.notes);
});
it('has a valid ajective attribute', () => {
expectValidTranslationString(egg.adjective);
});
it('has a canBuy function', () => {
expect(egg.canBuy).to.be.a('function');
});
it('has a value attribute', () => {
expect(egg.value).to.be.greaterThan(0);
});
});
+32
View File
@@ -0,0 +1,32 @@
import {
expectValidTranslationString,
describeEachItem
} from '../helpers/content.helper';
import {questions, stillNeedHelp} from '../../common/script/src/content/faq';
describe('FAQ Locales', () => {
describeEachItem('Questions', questions, (question, index) => {
it('has a valid question', () => {
expectValidTranslationString(question.question);
});
it('has a valid ios answer', () => {
expectValidTranslationString(question.ios);
});
it('has a valid web answer', () => {
expectValidTranslationString(question.web);
});
});
describe('Still Need Help Message', () => {
it('has a valid ios message', () => {
expectValidTranslationString(stillNeedHelp.ios);
});
it('has a valid web message', () => {
expectValidTranslationString(stillNeedHelp.web);
});
});
});
+29
View File
@@ -0,0 +1,29 @@
import {
expectValidTranslationString,
describeEachItem
} from '../helpers/content.helper';
import {each} from 'lodash';
import allFood from '../../common/script/src/content/food';
describeEachItem('Food', allFood, (food, key) => {
it('has a valid key', () => {
expect(food.key).to.eql(key);
});
it('has a valid value attribute', () => {
expect(food.value).to.be.greaterThan(0);
});
it('has a canBuy function', () => {
expect(food.canBuy).to.be.a('function');
});
it('has a valid text attribute', () => {
expectValidTranslationString(food.text);
});
it('has a valid notes attribute', () => {
expectValidTranslationString(food.notes);
});
});
+54
View File
@@ -0,0 +1,54 @@
import {
expectValidTranslationString,
describeEachItem
} from '../helpers/content.helper';
import {each} from 'lodash';
import {tree as allGear} from '../../common/script/src/content/gear';
describe('Gear', () => {
each(allGear, (piece, type) => {
describeEachItem(type, piece, (set, key) => {
checkGearAttributes(set);
});
});
});
function checkGearAttributes(set) {
each(set, (gear, key) => {
describe(`${key}`, () => {
it('has a value attribute', () => {
expect(gear.value).to.be.at.least(0);
});
it('has a valid con attribute', () => {
expect(gear.con).to.be.at.least(0);
});
it('has a valid int attribute', () => {
expect(gear.int).to.be.at.least(0);
});
it('has a valid per attribute', () => {
expect(gear.per).to.be.at.least(0);
});
it('has a valid str attribute', () => {
expect(gear.str).to.be.at.least(0);
});
it('has a canBuy function', () => {
expect(gear.canBuy).to.be.a('function');
});
it('has a valid text attribute', () => {
expectValidTranslationString(gear.text);
});
it('has a valid notes attribute', () => {
expectValidTranslationString(gear.notes);
});
});
});
}
+29
View File
@@ -0,0 +1,29 @@
import {
expectValidTranslationString,
describeEachItem
} from '../helpers/content.helper';
import {each} from 'lodash';
import { all as potions } from '../../common/script/src/content/hatching-potions';
describeEachItem('Hatching Potions', potions, (potion, key) => {
it('has a valid key', () => {
expect(potion.key).to.eql(key);
});
it('has a canBuy function', () => {
expect(potion.canBuy).to.be.a('function');
});
it('has a valid text attribute', () => {
expectValidTranslationString(potion.text);
});
it('has a valid notes attribute', () => {
expectValidTranslationString(potion.notes);
});
it('has a valid value', () => {
expect(potion.value).to.be.greaterThan(0);
});
});
+16
View File
@@ -0,0 +1,16 @@
import {
expectValidTranslationString
} from '../helpers/content.helper';
import healthPotion from '../../common/script/src/content/health-potion';
describe('Health Potion Locales', () => {
it('has a valid text attribute', () => {
expectValidTranslationString(healthPotion.text);
});
it('has a valid notes attribute', () => {
expectValidTranslationString(healthPotion.notes);
});
});
+7
View File
@@ -0,0 +1,7 @@
--colors
--reporter spec
--timeout 8000
--check-leaks
--growl
--compilers js:babel/register
--require ./test/helpers/content.helper.js
+145
View File
@@ -0,0 +1,145 @@
import {
expectValidTranslationString,
describeEachItem
} from '../helpers/content.helper';
import {each} from 'lodash';
import {
all as allQuests,
byLevel as questsByLevel
} from '../../common/script/src/content/quests';
describeEachItem('Quests', allQuests, (quest, key) => {
context('attributes', () => {
it('has a key', () => {
expect(quest.key).to.eql(key);
});
it('has a category', () => {
expect(quest.category).to.not.be.empty;
});
it('has a valid text attribute', () => {
expectValidTranslationString(quest.text);
});
it('has a valid notes attribute', () => {
expectValidTranslationString(quest.notes);
});
if (quest.previous) {
it('has a valid previous quest', () => {
expect(allQuests[quest.previous]).to.exist;
});
}
if (quest.completion) {
it('has a valid completion attribute', () => {
expectValidTranslationString(quest.completion);
});
}
it('has a canBuy function', () => {
expect(quest.canBuy).to.be.a('function');
});
it('has a value', () => {
expect(quest.value).to.be.at.least(0);
});
});
if (quest.boss) {
context('boss', () => {
it('has a valid boss name attribute', () => {
expectValidTranslationString(quest.boss.name);
});
it('has an hp attribute', () => {
expect(quest.boss.hp).to.be.greaterThan(0);
});
it('has a str attribute', () => {
expect(quest.boss.str).to.be.greaterThan(0);
});
it('has a def attribute', () => {
expect(quest.boss.def).to.be.greaterThan(0);
});
if (quest.boss.rage) {
context('rage', () => {
it('has a title attribute', () => {
expectValidTranslationString(quest.boss.rage.title);
});
it('has a description attribute', () => {
expectValidTranslationString(quest.boss.rage.description);
});
it('has a value attribute', () => {
expect(quest.boss.rage.value).to.be.greaterThan(0);
});
if (quest.boss.rage.healing) {
it('has a healing attribute', () => {
expect(quest.boss.rage.healing).to.be.greaterThan(0);
});
}
if (quest.boss.rage.effect) {
it('has an effect attribute', () => {
expectValidTranslationString(quest.boss.rage.effect);
});
}
});
}
});
}
if (quest.collect) {
context('collection', () => {
each(quest.collect, (item, key) => {
it(`${key} has a valid text attribute`, () => {
expectValidTranslationString(item.text);
expect(item.count).to.be.greaterThan(0);
});
});
});
}
context('drops', () => {
it('has drops', () => {
expect(quest.drop).to.exist;
});
it('has a gold value', () => {
expect(quest.drop.gp).to.be.at.least(0);
});
it('has a exp value', () => {
expect(quest.drop.exp).to.be.at.least(0);
});
if (quest.items) {
it('has items', () => {
expect(quest.drop.items).to.be.an('array');
expect(quest.drop.items).to.have.length.above(0);
});
}
});
});
describe('Quests by Level', () => {
let lastLevel = 0;
it('orders quests by level', () => {
each(questsByLevel, (quest, key) => {
let questLvl = quest.lvl || 0;
expect(questLvl).to.be.at.least(lastLevel);
lastLevel = questLvl;
});
expect(lastLevel).to.be.greaterThan(0);
});
});
+47
View File
@@ -0,0 +1,47 @@
import {
expectValidTranslationString,
describeEachItem
} from '../helpers/content.helper';
import {each} from 'lodash';
import spells from '../../common/script/src/content/spells';
describe('Spells', () => {
each(spells, (spellSet, klass) => {
describeEachItem(klass, spellSet, (spell, key) => {
checkSpellAttributes(spell, key);
});
});
});
function checkSpellAttributes(spell, key) {
describe(`${key}`, () => {
it('has a key attribute', () => {
expect(spell.key).to.eql(key);
});
it('has a valid text attribute', () => {
expectValidTranslationString(spell.text);
});
it('has a valid notes attribute', () => {
expectValidTranslationString(spell.notes);
});
it('has a cast function', () => {
expect(spell.cast).to.be.a('function');
});
it('has a mana attribute', () => {
expect(spell.mana).to.be.at.least(0);
});
it('has a valid target attribute', () => {
expect(spell.target).to.match(/self|user|party|task/);
});
it('has a mana attribute', () => {
expect(spell.mana).to.be.at.least(0);
});
});
}
+14
View File
@@ -0,0 +1,14 @@
import {STRING_ERROR_MSG, STRING_DOES_NOT_EXIST_MSG} from '../helpers/content.helper';
import {translator} from '../../common/script/src/content/helpers';
describe('Translator', () => {
it('returns error message if string is not properly formatted', () => {
let improperlyFormattedString = translator('petName', {attr: 0})();
expect(improperlyFormattedString).to.eql(STRING_ERROR_MSG);
});
it('returns an error message if string does not exist', () => {
let stringDoesNotExist = translator('stringDoesNotExist')();
expect(stringDoesNotExist).to.match(STRING_DOES_NOT_EXIST_MSG);
});
});
+47
View File
@@ -0,0 +1,47 @@
import {
expectValidTranslationString,
describeEachItem
} from '../helpers/content.helper';
import {each} from 'lodash';
import {
habits,
dailys,
todos,
rewards,
tags
} from '../../common/script/src/content/user-defaults';
describe('User Defaults', () => {
let tasks = {
habits: habits,
dailys: dailys,
todos: todos,
rewards: rewards
};
describeEachItem('Tasks', tasks, (type, name) => {
each(type, (task, index) => {
it('has a valid text attribute', () => {
expectValidTranslationString(task.text);
});
it('has a valid type attribute', () => {
expect(task.type).to.match(/todo|daily|habit|reward/);
});
if (task.notes) {
it('has a valid notes attribute', () => {
expectValidTranslationString(task.notes);
});
}
});
});
describeEachItem('Tags', tags, (tag, index) => {
it('has a valid name attribute', () => {
expectValidTranslationString(tag.name);
});
});
});
+42
View File
@@ -0,0 +1,42 @@
require('./globals.helper');
import {each} from 'lodash';
import i18n from '../../common/script/src/i18n';
require('coffee-script');
i18n.translations = require('../../website/src/i18n.js').translations;
export const STRING_ERROR_MSG = 'Error processing the string. Please see Help > Report a Bug.';
export const STRING_DOES_NOT_EXIST_MSG = /^String '.*' not found.$/;
export function expectValidTranslationString (attribute) {
expect(attribute).to.be.a('function');
let translatedString = attribute();
expect(translatedString).to.not.be.empty;
expect(translatedString).to.not.eql(STRING_ERROR_MSG);
expect(translatedString).to.not.match(STRING_DOES_NOT_EXIST_MSG);
};
export function describeEachItem (testDescription, set, cb, describeFunction) {
// describeFunction allows you to pass in 'only' or 'skip'
// as the last argument for writing/debugging tests.
// This should only be used with the helper functions .only and .skip below
let describeBlock = describe[describeFunction] || describe;
describeBlock(testDescription, () => {
each(set, (item, key) => {
describe(key, () => {
cb(item, key);
});
});
});
}
describeEachItem.only = (des, set, cb) => {
describeEachItem(des, set, cb, 'only');
}
describeEachItem.skip = (des, set, cb) => {
describeEachItem(des, set, cb, 'skip');
}
+8
View File
@@ -0,0 +1,8 @@
//------------------------------
// Global modules
//------------------------------
global._ = require("lodash")
global.chai = require("chai")
chai.use(require("sinon-chai"))
global.expect = chai.expect
+52 -2
View File
@@ -224,14 +224,64 @@ describe('Inventory Controller', function() {
});
describe('#hasAllTimeTravelerItems', function() {
it('returns false if there are items left in the time traveler store', function() {
it('returns false if items remain for purchase with Mystic Hourglasses', function() {
expect(scope.hasAllTimeTravelerItems()).to.eql(false);
});
it('returns true if there are no items left to purchase', inject(function(Content) {
sandbox.stub(Content, 'timeTravelerStore').returns({});
_.forEach(Content.gear.flat, function(v,item) {
if (item.indexOf('mystery') > -1) {
user.items.gear.owned[item] = true;
}
});
_.forEach(Content.timeTravelStable.pets, function(v,pet) {
user.items.pets[pet] = 5;
});
_.forEach(Content.timeTravelStable.mounts, function(v,mount) {
user.items.mounts[mount] = true;
});
expect(scope.hasAllTimeTravelerItems()).to.eql(true);
}));
});
describe('#hasAllTimeTravelerItemsOfType', function() {
it('returns false for Mystery Sets if there are sets left in the time traveler store', function() {
expect(scope.hasAllTimeTravelerItemsOfType('mystery')).to.eql(false);
});
it('returns true for Mystery Sets if there are no sets left to purchase', inject(function(Content) {
_.forEach(Content.gear.flat, function(v,item) {
if (item.indexOf('mystery') > -1) {
user.items.gear.owned[item] = true;
}
});
expect(scope.hasAllTimeTravelerItemsOfType('mystery')).to.eql(true);
}));
it('returns false for pets if user does not own all pets in the Time Travel Stable', function() {
expect(scope.hasAllTimeTravelerItemsOfType('pets')).to.eql(false);
});
it('returns true for pets if user owns all pets in the Time Travel Stable', inject(function(Content) {
_.forEach(Content.timeTravelStable.pets, function(v,pet) {
user.items.pets[pet] = 5;
});
expect(scope.hasAllTimeTravelerItemsOfType('pets')).to.eql(true);
}));
it('returns false for mounts if user does not own all mounts in the Time Travel Stable', function() {
expect(scope.hasAllTimeTravelerItemsOfType('mounts')).to.eql(false);
});
it('returns true for mounts if user owns all mounts in the Time Travel Stable', inject(function(Content) {
_.forEach(Content.timeTravelStable.mounts, function(v,mount) {
user.items.mounts[mount] = true;
});
expect(scope.hasAllTimeTravelerItemsOfType('mounts')).to.eql(true);
}));
});
});
+9 -5
View File
@@ -24,7 +24,8 @@ describe('Stats Service', function() {
"Deer-Golden" : 5,
"Deer-Red" : 5,
"Egg-Desert" : 5,
"MantisShrimp-Base" : 5
"MantisShrimp-Base" : 5,
"Wolf-Spooky": 5
}
var beastMasterDisplay = statCalc.beastMasterProgress(user.items.pets);
@@ -38,9 +39,10 @@ describe('Stats Service', function() {
"BearCub-CottonCandyBlue" : -1,
"Cactus-Zombie" : 5,
"Deer-Golden" : 5,
"Deer-Red" : 5,
"Deer-Red" : -1,
"Egg-Desert" : 5,
"MantisShrimp-Base" : 5
"MantisShrimp-Base" : 5,
"Wolf-Spooky": -1
}
var beastMasterDisplay = statCalc.beastMasterProgress(user.items.pets);
@@ -221,7 +223,8 @@ describe('Stats Service', function() {
"Wolf-Golden" : true,
"Owl-CottonCandyBlue" : true,
"Mammoth-Base" : true,
"Bunny-Skeleton" : true
"Bunny-Skeleton" : true,
"Tiger-Spooky": true
}
var mountMasterDisplay = statCalc.mountMasterProgress(user.items.mounts);
@@ -237,7 +240,8 @@ describe('Stats Service', function() {
"Wolf-Golden" : false,
"Owl-CottonCandyBlue" : true,
"Mammoth-Base" : true,
"Bunny-Skeleton" : true
"Bunny-Skeleton" : true,
"Tiger-Spooky": true
}
var mountMasterDisplay = statCalc.mountMasterProgress(user.items.mounts);
File diff suppressed because one or more lines are too long