Merge branch 'develop' into api-v3

This commit is contained in:
Matteo Pagliazzi
2015-11-27 17:05:29 +01:00
56 changed files with 3747 additions and 3338 deletions
+23 -16
View File
@@ -1,4 +1,11 @@
/* eslint-disable camelcase, func-names, no-shadow */
import {
DAY_MAPPING,
startOfWeek,
startOfDay,
daysSince,
} from '../../common/script/cron';
let expect = require('expect.js');
let sinon = require('sinon');
let moment = require('moment');
@@ -205,7 +212,7 @@ let repeatWithoutLastWeekday = () => {
s: true,
};
if (shared.startOfWeek(moment().zone(0)).isoWeekday() === 1) {
if (startOfWeek(moment().zone(0)).isoWeekday() === 1) {
repeat.su = false;
} else {
repeat.s = false;
@@ -301,7 +308,7 @@ describe('User', () => {
let yesterday = moment().subtract(1, 'days');
user.dailys[0].repeat[shared.dayMapping[yesterday.day()]] = false;
user.dailys[0].repeat[DAY_MAPPING[yesterday.day()]] = false;
_.each(user.dailys.slice(1), (d) => {
d.completed = true;
});
@@ -383,7 +390,7 @@ describe('User', () => {
it('does not reset checklist on grey incomplete dailies', () => {
let yesterday = moment().subtract(1, 'days');
user.dailys[0].repeat[shared.dayMapping[yesterday.day()]] = false;
user.dailys[0].repeat[DAY_MAPPING[yesterday.day()]] = false;
user.dailys[0].checklist = [
{
text: '1',
@@ -407,7 +414,7 @@ describe('User', () => {
it('resets checklist on complete grey complete dailies', () => {
let yesterday = moment().subtract(1, 'days');
user.dailys[0].repeat[shared.dayMapping[yesterday.day()]] = false;
user.dailys[0].repeat[DAY_MAPPING[yesterday.day()]] = false;
user.dailys[0].checklist = [
{
text: '1',
@@ -1185,7 +1192,7 @@ describe('Cron', () => {
let fstr = 'YYYY-MM-DD HH: mm: ss';
it('startOfDay before dayStart', () => {
let start = shared.startOfDay({
let start = startOfDay({
now: moment('2014-10-09 02: 30: 00'),
dayStart,
});
@@ -1193,7 +1200,7 @@ describe('Cron', () => {
expect(start.format(fstr)).to.eql('2014-10-08 04: 00: 00');
});
it('startOfDay after dayStart', () => {
let start = shared.startOfDay({
let start = startOfDay({
now: moment('2014-10-09 05: 30: 00'),
dayStart,
});
@@ -1202,7 +1209,7 @@ describe('Cron', () => {
});
it('daysSince cron before, now after', () => {
let lastCron = moment('2014-10-09 02: 30: 00');
let days = shared.daysSince(lastCron, {
let days = daysSince(lastCron, {
now: moment('2014-10-09 11: 30: 00'),
dayStart,
});
@@ -1211,7 +1218,7 @@ describe('Cron', () => {
});
it('daysSince cron before, now before', () => {
let lastCron = moment('2014-10-09 02: 30: 00');
let days = shared.daysSince(lastCron, {
let days = daysSince(lastCron, {
now: moment('2014-10-09 03: 30: 00'),
dayStart,
});
@@ -1220,7 +1227,7 @@ describe('Cron', () => {
});
it('daysSince cron after, now after', () => {
let lastCron = moment('2014-10-09 05: 30: 00');
let days = shared.daysSince(lastCron, {
let days = daysSince(lastCron, {
now: moment('2014-10-09 06: 30: 00'),
dayStart,
});
@@ -1229,7 +1236,7 @@ describe('Cron', () => {
});
it('daysSince cron after, now tomorrow before', () => {
let lastCron = moment('2014-10-09 12: 30: 00');
let days = shared.daysSince(lastCron, {
let days = daysSince(lastCron, {
now: moment('2014-10-10 01: 30: 00'),
dayStart,
});
@@ -1238,7 +1245,7 @@ describe('Cron', () => {
});
it('daysSince cron after, now tomorrow after', () => {
let lastCron = moment('2014-10-09 12: 30: 00');
let days = shared.daysSince(lastCron, {
let days = daysSince(lastCron, {
now: moment('2014-10-10 10: 30: 00'),
dayStart,
});
@@ -1247,7 +1254,7 @@ describe('Cron', () => {
});
xit('daysSince, last cron before new dayStart', () => {
let lastCron = moment('2014-10-09 01: 00: 00');
let days = shared.daysSince(lastCron, {
let days = daysSince(lastCron, {
now: moment('2014-10-09 05: 00: 00'),
dayStart,
});
@@ -1266,7 +1273,7 @@ describe('Cron', () => {
function runCron (options) {
_.each([480, 240, 0, -120], function (timezoneOffset) {
let now = shared.startOfWeek({
let now = startOfWeek({
timezoneOffset,
}).add(options.currentHour || 0, 'hours');
@@ -1496,17 +1503,17 @@ describe('Helper', () => {
let today = '2013-01-01 00: 00: 00';
let zone = moment(today).zone();
expect(shared.startOfDay({
expect(startOfDay({
now: new Date(2013, 0, 1, 0),
}, {
timezoneOffset: zone,
}).format(fstr)).to.eql(today);
expect(shared.startOfDay({
expect(startOfDay({
now: new Date(2013, 0, 1, 5),
}, {
timezoneOffset: zone,
}).format(fstr)).to.eql(today);
expect(shared.startOfDay({
expect(startOfDay({
now: new Date(2013, 0, 1, 23, 59, 59),
timezoneOffset: zone,
}).format(fstr)).to.eql(today);
+4 -1
View File
@@ -1,4 +1,7 @@
/* eslint-disable camelcase */
import {
startOfWeek,
} from '../../common/script/cron';
let expect = require('expect.js'); // eslint-disable-line no-shadow
let moment = require('moment');
@@ -17,7 +20,7 @@ let repeatWithoutLastWeekday = () => { // eslint-disable-line no-unused-vars
s: true,
};
if (shared.startOfWeek(moment().zone(0)).isoWeekday() === 1) {
if (startOfWeek(moment().zone(0)).isoWeekday() === 1) {
repeat.su = false;
} else {
repeat.s = false;
+66
View File
@@ -0,0 +1,66 @@
import {
maxHealth,
maxLevel,
capByLevel,
tnl,
diminishingReturns,
} from '../../common/script/index';
describe('helper functions used in stat calculations', () => {
describe('maxHealth', () => {
it('provides a maximum Health value', () => {
const HEALTH_CAP = 50;
expect(maxHealth).to.eql(HEALTH_CAP);
});
});
const LEVEL_CAP = 100;
const LEVEL = 57;
describe('maxLevel', () => {
it('returns a maximum level for attribute gain', () => {
expect(maxLevel).to.eql(LEVEL_CAP);
});
});
describe('capByLevel', () => {
it('returns level given if below cap', () => {
expect(capByLevel(LEVEL)).to.eql(LEVEL);
});
it('returns level given if equal to cap', () => {
expect(capByLevel(LEVEL_CAP)).to.eql(LEVEL_CAP);
});
it('returns level cap if above cap', () => {
expect(capByLevel(LEVEL_CAP + LEVEL)).to.eql(LEVEL_CAP);
});
});
describe('toNextLevel', () => {
it('increases Experience target from one level to the next', () => {
_.times(110, (level) => {
expect(tnl(level + 1)).to.be.greaterThan(tnl(level));
});
});
});
describe('diminishingReturns', () => {
const BONUS = 600;
const MAXIMUM = 200;
const HALFWAY = 75;
it('provides a value under the maximum, given a bonus and maximum', () => {
expect(diminishingReturns(BONUS, MAXIMUM)).to.be.lessThan(MAXIMUM);
});
it('provides a value under the maximum, given a bonus, maximum, and halfway point', () => {
expect(diminishingReturns(BONUS, MAXIMUM, HALFWAY)).to.be.lessThan(MAXIMUM);
});
it('provides a different curve if a halfway point is defined', () => {
expect(diminishingReturns(BONUS, MAXIMUM, HALFWAY)).to.not.eql(diminishingReturns(BONUS, MAXIMUM));
});
});
});
+28
View File
@@ -101,6 +101,34 @@ describe('user.fns.buy', () => {
expect(user.items.gear.equipped).to.not.have.property('armor');
});
it('removes one-handed weapon and shield if auto-equip is on and a two-hander is bought', () => {
user.stats.gp = 100;
user.preferences.autoEquip = true;
user.ops.buy({params: {key: 'shield_warrior_1'}});
user.ops.equip({params: {key: 'shield_warrior_1'}});
user.ops.buy({params: {key: 'weapon_warrior_1'}});
user.ops.equip({params: {key: 'weapon_warrior_1'}});
user.ops.buy({params: {key: 'weapon_wizard_1'}});
expect(user.items.gear.equipped).to.have.property('shield', 'shield_base_0');
expect(user.items.gear.equipped).to.have.property('weapon', 'weapon_wizard_1');
});
it('buys two-handed equipment but does not automatically remove sword or shield', () => {
user.stats.gp = 100;
user.preferences.autoEquip = false;
user.ops.buy({params: {key: 'shield_warrior_1'}});
user.ops.equip({params: {key: 'shield_warrior_1'}});
user.ops.buy({params: {key: 'weapon_warrior_1'}});
user.ops.equip({params: {key: 'weapon_warrior_1'}});
user.ops.buy({params: {key: 'weapon_wizard_1'}});
expect(user.items.gear.equipped).to.have.property('shield', 'shield_warrior_1');
expect(user.items.gear.equipped).to.have.property('weapon', 'weapon_warrior_1');
});
it('does not buy equipment without enough Gold', () => {
user.stats.gp = 20;
+1 -1
View File
@@ -194,7 +194,7 @@ describe('Groups Controller', function() {
expect(group.leave).to.not.be.called;
expect(res.json).to.be.calledOnce;
expect(res.json).to.be.calledWith(403, 'You cannot leave party during an active quest. Please leave the quest first');
expect(res.json).to.be.calledWith(403, 'You cannot leave party during an active quest. Please leave the quest first.');
});
it('prevents quest leader from leaving a party if they have started a quest', function() {
@@ -148,6 +148,19 @@ describe('Challenges Controller', function() {
expect(scope.filterChallenges(notOwnMem)).to.eql(false);
expect(scope.filterChallenges(notOwnNotMem)).to.eql(true);
});
it('it filters challenges to a single group when group id filter is set', inject(function($controller) {
scope.search = { };
scope.groups = {
0: specHelper.newGroup({_id: 'group-one'}),
1: specHelper.newGroup({_id: 'group-two'}),
2: specHelper.newGroup({_id: 'group-three'})
};
scope.groupIdFilter = 'group-one';
scope.filterInitialChallenges();
expect(scope.search.group).to.eql({'group-one': true});
}));
});
describe('selectAll', function() {
+91 -1
View File
@@ -78,7 +78,21 @@ describe('Inventory Controller', function() {
expect(rootScope.openModal).to.have.been.calledOnce;
expect(rootScope.openModal).to.have.been.calledWith('hatchPet');
});
it('does not show modal if user tries to hatch a pet they own', function(){
scope.chooseEgg('Cactus');
scope.choosePotion('Base');
expect(user.items.eggs).to.eql({Cactus: 0});
expect(user.items.hatchingPotions).to.eql({Base: 0});
expect(user.items.pets).to.eql({'Cactus-Base': 5});
expect(scope.selectedEgg).to.eql(null);
expect(scope.selectedPotion).to.eql(null);
expect(rootScope.openModal).to.have.been.calledOnce;
scope.chooseEgg('Cactus');
scope.choosePotion('Base');
expect(rootScope.openModal).to.not.have.been.calledTwice;
});
it('does not show pet hatching modal if user has opted out', function(){
user.preferences.suppressModals.hatchPet = true;
scope.chooseEgg('Cactus');
@@ -88,6 +102,82 @@ describe('Inventory Controller', function() {
});
});
describe('Feeding and Raising Pets', function() {
beforeEach(function() {
sandbox.stub(rootScope, 'openModal');
user.items.pets = {'PandaCub-Base':5};
user.items.mounts = {'PandaCub-Base':false};
});
it('feeds a pet', function() {
scope.chooseFood('Meat');
scope.choosePet('PandaCub','Base');
expect(user.items.pets['PandaCub-Base']).to.eql(10);
});
it('gives weaker benefit when feeding inappropriate food', function() {
user.items.food.Honey = 1;
scope.chooseFood('Honey');
scope.choosePet('PandaCub','Base');
expect(user.items.pets['PandaCub-Base']).to.eql(7);
});
it('raises pet to a mount when feeding gauge maxes out', function() {
user.items.pets['PandaCub-Base'] = 45;
scope.chooseFood('Meat');
scope.choosePet('PandaCub','Base');
expect(user.items.pets['PandaCub-Base']).to.eql(-1);
expect(user.items.mounts['PandaCub-Base']).to.exist;
});
it('raises pet to a mount instantly when using a Saddle', function() {
user.items.food.Saddle = 1;
scope.chooseFood('Saddle');
scope.choosePet('PandaCub','Base');
expect(user.items.pets['PandaCub-Base']).to.eql(-1);
expect(user.items.mounts['PandaCub-Base']).to.exist;
});
it('displays mount raising modal for drop pets', function() {
user.items.food.Saddle = 1;
scope.chooseFood('Saddle');
scope.choosePet('PandaCub','Base');
expect(rootScope.openModal).to.have.been.calledOnce;
expect(rootScope.openModal).to.have.been.calledWith('raisePet');
});
it('displays mount raising modal for quest pets', function() {
user.items.food.Saddle = 1;
user.items.pets['Snake-Base'] = 1;
scope.chooseFood('Saddle');
scope.choosePet('Snake','Base');
expect(rootScope.openModal).to.have.been.calledOnce;
expect(rootScope.openModal).to.have.been.calledWith('raisePet');
});
it('displays mount raising modal for premium pets', function() {
user.items.food.Saddle = 1;
user.items.pets['TigerCub-Spooky'] = 1;
scope.chooseFood('Saddle');
scope.choosePet('TigerCub','Spooky');
expect(rootScope.openModal).to.have.been.calledOnce;
expect(rootScope.openModal).to.have.been.calledWith('raisePet');
});
});
it('sells an egg', function(){
scope.chooseEgg('Cactus');
scope.sellInventory();