v3 fix tests and use coroutines instead of regenerator

This commit is contained in:
Matteo Pagliazzi
2016-05-11 15:59:18 +02:00
parent 84b198f17f
commit 95aff08de3
24 changed files with 80 additions and 2702 deletions

View File

@@ -1,4 +1,9 @@
{ {
"presets": ["es2015"], "presets": ["es2015"],
"plugins": ["syntax-async-functions","transform-regenerator"] "plugins": [
["transform-async-to-module-method", {
"module": "bluebird",
"method": "coroutine"
}]
]
} }

View File

@@ -30,7 +30,6 @@ newrelic.js
test/api-legacy/**/* test/api-legacy/**/*
test/common/simulations/**/* test/common/simulations/**/*
test/common_old/
test/content/**/* test/content/**/*
test/server_side/**/* test/server_side/**/*
test/spec/**/* test/spec/**/*

View File

@@ -30,7 +30,7 @@ var MONGODB_NEW = nconf.get('MONGODB_NEW');
var MongoClient = MongoDB.MongoClient; var MongoClient = MongoDB.MongoClient;
mongoose.Promise = Bluebird.all; // otherwise mongoose models won't work mongoose.Promise = Bluebird; // otherwise mongoose models won't work
// Load new models // Load new models
var NewChallenge = require('../../website/src/models/challenge').model; var NewChallenge = require('../../website/src/models/challenge').model;

View File

@@ -30,7 +30,7 @@ var MONGODB_NEW = nconf.get('MONGODB_NEW');
var MongoClient = MongoDB.MongoClient; var MongoClient = MongoDB.MongoClient;
mongoose.Promise = Bluebird.all; // otherwise mongoose models won't work mongoose.Promise = Bluebird; // otherwise mongoose models won't work
// To be defined later when MongoClient connects // To be defined later when MongoClient connects
var mongoDbOldInstance; var mongoDbOldInstance;

View File

@@ -29,7 +29,7 @@ var MONGODB_NEW = nconf.get('MONGODB_NEW');
var MongoClient = MongoDB.MongoClient; var MongoClient = MongoDB.MongoClient;
mongoose.Promise = Bluebird.all; // otherwise mongoose models won't work mongoose.Promise = Bluebird; // otherwise mongoose models won't work
// Load new models // Load new models
var Coupon = require('../../website/src/models/coupon').model; var Coupon = require('../../website/src/models/coupon').model;

View File

@@ -29,7 +29,7 @@ var MONGODB_NEW = nconf.get('MONGODB_NEW');
var MongoClient = MongoDB.MongoClient; var MongoClient = MongoDB.MongoClient;
mongoose.Promise = Bluebird.all; // otherwise mongoose models won't work mongoose.Promise = Bluebird; // otherwise mongoose models won't work
// Load new models // Load new models
var EmailUnsubscription = require('../../website/src/models/emailUnsubscription').model; var EmailUnsubscription = require('../../website/src/models/emailUnsubscription').model;

View File

@@ -37,7 +37,7 @@ var MONGODB_NEW = nconf.get('MONGODB_NEW');
var MongoClient = MongoDB.MongoClient; var MongoClient = MongoDB.MongoClient;
mongoose.Promise = Bluebird.all; // otherwise mongoose models won't work mongoose.Promise = Bluebird; // otherwise mongoose models won't work
// Load new models // Load new models
var NewGroup = require('../../website/src/models/group').model; var NewGroup = require('../../website/src/models/group').model;

View File

@@ -33,7 +33,7 @@ var MONGODB_NEW = nconf.get('MONGODB_NEW');
var taskDefaults = common.taskDefaults; var taskDefaults = common.taskDefaults;
var MongoClient = MongoDB.MongoClient; var MongoClient = MongoDB.MongoClient;
mongoose.Promise = Bluebird.all; // otherwise mongoose models won't work mongoose.Promise = Bluebird; // otherwise mongoose models won't work
// Load new models // Load new models
var NewUser = require('../../website/src/models/user').model; var NewUser = require('../../website/src/models/user').model;

View File

@@ -10,8 +10,7 @@
"apidoc": "^0.16.0", "apidoc": "^0.16.0",
"async": "^1.5.0", "async": "^1.5.0",
"aws-sdk": "^2.0.25", "aws-sdk": "^2.0.25",
"babel-plugin-syntax-async-functions": "^6.5.0", "babel-plugin-transform-async-to-module-method": "^6.8.0",
"babel-plugin-transform-regenerator": "^6.6.0",
"babel-polyfill": "^6.6.1", "babel-polyfill": "^6.6.1",
"babel-preset-es2015": "^6.6.0", "babel-preset-es2015": "^6.6.0",
"babel-register": "^6.6.0", "babel-register": "^6.6.0",

View File

@@ -1,3 +1,5 @@
/* eslint-disable camelcase */
import { import {
generateUser, generateUser,
translate as t, translate as t,
@@ -46,6 +48,15 @@ describe('POST /user/buy/:key', () => {
await user.post(`/user/buy/${key}`); await user.post(`/user/buy/${key}`);
await user.sync(); await user.sync();
expect(user.items.gear.owned).to.eql({ armor_warrior_1: true }); // eslint-disable-line camelcase expect(user.items.gear.owned).to.eql({
armor_warrior_1: true,
eyewear_special_blackTopFrame: true,
eyewear_special_blueTopFrame: true,
eyewear_special_greenTopFrame: true,
eyewear_special_pinkTopFrame: true,
eyewear_special_redTopFrame: true,
eyewear_special_whiteTopFrame: true,
eyewear_special_yellowTopFrame: true,
});
}); });
}); });

View File

@@ -1,3 +1,5 @@
/* eslint-disable camelcase */
import { import {
generateUser, generateUser,
translate as t, translate as t,
@@ -29,6 +31,15 @@ describe('POST /user/buy-gear/:key', () => {
await user.post(`/user/buy-gear/${key}`); await user.post(`/user/buy-gear/${key}`);
await user.sync(); await user.sync();
expect(user.items.gear.owned).to.eql({ armor_warrior_1: true }); // eslint-disable-line camelcase expect(user.items.gear.owned).to.eql({
armor_warrior_1: true,
eyewear_special_blackTopFrame: true,
eyewear_special_blueTopFrame: true,
eyewear_special_greenTopFrame: true,
eyewear_special_pinkTopFrame: true,
eyewear_special_redTopFrame: true,
eyewear_special_whiteTopFrame: true,
eyewear_special_yellowTopFrame: true,
});
}); });
}); });

View File

@@ -46,6 +46,16 @@ describe('shared.ops.buy', () => {
it('adds equipment to inventory', () => { it('adds equipment to inventory', () => {
user.stats.gp = 31; user.stats.gp = 31;
buy(user, {params: {key: 'armor_warrior_1'}}); buy(user, {params: {key: 'armor_warrior_1'}});
expect(user.items.gear.owned).to.eql({ weapon_warrior_0: true, armor_warrior_1: true }); expect(user.items.gear.owned).to.eql({
weapon_warrior_0: true,
armor_warrior_1: true,
eyewear_special_blackTopFrame: true,
eyewear_special_blueTopFrame: true,
eyewear_special_greenTopFrame: true,
eyewear_special_pinkTopFrame: true,
eyewear_special_redTopFrame: true,
eyewear_special_whiteTopFrame: true,
eyewear_special_yellowTopFrame: true,
});
}); });
}); });

View File

@@ -69,7 +69,16 @@ describe('shared.ops.buyArmoire', () => {
} catch (err) { } catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized); expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('messageNotEnoughGold')); expect(err.message).to.equal(i18n.t('messageNotEnoughGold'));
expect(user.items.gear.owned).to.eql({weapon_warrior_0: true}); expect(user.items.gear.owned).to.eql({
weapon_warrior_0: true,
eyewear_special_blackTopFrame: true,
eyewear_special_blueTopFrame: true,
eyewear_special_greenTopFrame: true,
eyewear_special_pinkTopFrame: true,
eyewear_special_redTopFrame: true,
eyewear_special_whiteTopFrame: true,
eyewear_special_yellowTopFrame: true,
});
expect(user.items.food).to.be.empty; expect(user.items.food).to.be.empty;
expect(user.stats.exp).to.eql(0); expect(user.stats.exp).to.eql(0);
done(); done();
@@ -85,7 +94,16 @@ describe('shared.ops.buyArmoire', () => {
} catch (err) { } catch (err) {
expect(err).to.be.an.instanceof(NotAuthorized); expect(err).to.be.an.instanceof(NotAuthorized);
expect(err.message).to.equal(i18n.t('cannotBuyItem')); expect(err.message).to.equal(i18n.t('cannotBuyItem'));
expect(user.items.gear.owned).to.eql({weapon_warrior_0: true}); expect(user.items.gear.owned).to.eql({
weapon_warrior_0: true,
eyewear_special_blackTopFrame: true,
eyewear_special_blueTopFrame: true,
eyewear_special_greenTopFrame: true,
eyewear_special_pinkTopFrame: true,
eyewear_special_redTopFrame: true,
eyewear_special_whiteTopFrame: true,
eyewear_special_yellowTopFrame: true,
});
expect(user.items.food).to.be.empty; expect(user.items.food).to.be.empty;
expect(user.stats.exp).to.eql(0); expect(user.stats.exp).to.eql(0);
done(); done();

View File

@@ -44,7 +44,17 @@ describe('shared.ops.buyGear', () => {
buyGear(user, {params: {key: 'armor_warrior_1'}}); buyGear(user, {params: {key: 'armor_warrior_1'}});
expect(user.items.gear.owned).to.eql({ weapon_warrior_0: true, armor_warrior_1: true }); expect(user.items.gear.owned).to.eql({
weapon_warrior_0: true,
armor_warrior_1: true,
eyewear_special_blackTopFrame: true,
eyewear_special_blueTopFrame: true,
eyewear_special_greenTopFrame: true,
eyewear_special_pinkTopFrame: true,
eyewear_special_redTopFrame: true,
eyewear_special_whiteTopFrame: true,
eyewear_special_yellowTopFrame: true,
});
}); });
it('deducts gold from user', () => { it('deducts gold from user', () => {

File diff suppressed because it is too large Load Diff

View File

@@ -1,499 +0,0 @@
/* eslint-disable camelcase */
import {
startOfWeek,
} from '../../common/script/cron';
let expect = require('expect.js'); // eslint-disable-line no-shadow
let moment = require('moment');
let shared = require('../../common/script/index.js');
shared.i18n.translations = require('../../website/src/libs/api-v2/i18n.js').translations;
let repeatWithoutLastWeekday = () => { // eslint-disable-line no-unused-vars
let repeat = {
su: true,
m: true,
t: true,
w: true,
th: true,
f: true,
s: true,
};
if (startOfWeek(moment().zone(0)).isoWeekday() === 1) {
repeat.su = false;
} else {
repeat.s = false;
}
return {
repeat,
};
};
/* Helper Functions */
import {
generateUser,
} from '../helpers/common.helper';
let cron = (usr, missedDays = 1) => {
usr.lastCron = moment().subtract(missedDays, 'days');
usr.fns.cron();
};
describe('daily/weekly that repeats everyday (default)', () => {
let user = null;
let daily = null;
let weekly = null;
describe('when startDate is in the future', () => {
beforeEach(() => {
user = generateUser();
user.dailys = [
shared.taskDefaults({
type: 'daily',
startDate: moment().add(7, 'days'),
frequency: 'daily',
}), shared.taskDefaults({
type: 'daily',
startDate: moment().add(7, 'days'),
frequency: 'weekly',
repeat: {
su: true,
m: true,
t: true,
w: true,
th: true,
f: true,
s: true,
},
}),
];
daily = user.dailys[0];
weekly = user.dailys[1];
});
it('does not damage user for not completing it', () => {
cron(user);
expect(user.stats.hp).to.be(50);
});
it('does not change value on cron if daily is incomplete', () => {
cron(user);
expect(daily.value).to.be(0);
expect(weekly.value).to.be(0);
});
it('does not reset checklists if daily is not marked as complete', () => {
let checklist = [
{
text: '1',
id: 'checklist-one',
completed: true,
}, {
text: '2',
id: 'checklist-two',
completed: true,
}, {
text: '3',
id: 'checklist-three',
completed: false,
},
];
daily.checklist = checklist;
weekly.checklist = checklist;
cron(user);
expect(daily.checklist[0].completed).to.be(true);
expect(daily.checklist[1].completed).to.be(true);
expect(daily.checklist[2].completed).to.be(false);
expect(weekly.checklist[0].completed).to.be(true);
expect(weekly.checklist[1].completed).to.be(true);
expect(weekly.checklist[2].completed).to.be(false);
});
it('resets checklists if daily is marked as complete', () => {
let checklist = [
{
text: '1',
id: 'checklist-one',
completed: true,
}, {
text: '2',
id: 'checklist-two',
completed: true,
}, {
text: '3',
id: 'checklist-three',
completed: false,
},
];
daily.checklist = checklist;
weekly.checklist = checklist;
daily.completed = true;
weekly.completed = true;
cron(user);
_.each(daily.checklist, (box) => {
expect(box.completed).to.be(false);
});
_.each(weekly.checklist, (box) => {
expect(box.completed).to.be(false);
});
});
it('is due on startDate', () => {
let daily_due_today = shared.shouldDo(moment(), daily);
let daily_due_on_start_date = shared.shouldDo(moment().add(7, 'days'), daily);
expect(daily_due_today).to.be(false);
expect(daily_due_on_start_date).to.be(true);
let weekly_due_today = shared.shouldDo(moment(), weekly);
let weekly_due_on_start_date = shared.shouldDo(moment().add(7, 'days'), weekly);
expect(weekly_due_today).to.be(false);
expect(weekly_due_on_start_date).to.be(true);
});
});
describe('when startDate is in the past', () => {
beforeEach(() => {
user = generateUser();
user.dailys = [
shared.taskDefaults({
type: 'daily',
startDate: moment().subtract(7, 'days'),
frequency: 'daily',
}), shared.taskDefaults({
type: 'daily',
startDate: moment().subtract(7, 'days'),
frequency: 'weekly',
}),
];
daily = user.dailys[0];
weekly = user.dailys[1];
});
it('does damage user for not completing it', () => {
cron(user);
expect(user.stats.hp).to.be.lessThan(50);
});
it('decreases value on cron if daily is incomplete', () => {
cron(user, 1);
expect(daily.value).to.be(-1);
expect(weekly.value).to.be(-1);
});
it('decreases value on cron once only if daily is incomplete and multiple days are missed', () => {
cron(user, 7);
expect(daily.value).to.be(-1);
expect(weekly.value).to.be(-1);
});
it('resets checklists if daily is not marked as complete', () => {
let checklist;
checklist = [
{
text: '1',
id: 'checklist-one',
completed: true,
}, {
text: '2',
id: 'checklist-two',
completed: true,
}, {
text: '3',
id: 'checklist-three',
completed: false,
},
];
daily.checklist = checklist;
weekly.checklist = checklist;
cron(user);
_.each(daily.checklist, (box) => {
expect(box.completed).to.be(false);
});
_.each(weekly.checklist, (box) => {
expect(box.completed).to.be(false);
});
});
it('resets checklists if daily is marked as complete', () => {
let checklist = [
{
text: '1',
id: 'checklist-one',
completed: true,
}, {
text: '2',
id: 'checklist-two',
completed: true,
}, {
text: '3',
id: 'checklist-three',
completed: false,
},
];
daily.checklist = checklist;
daily.completed = true;
weekly.checklist = checklist;
weekly.completed = true;
cron(user);
_.each(daily.checklist, (box) => {
expect(box.completed).to.be(false);
});
_.each(weekly.checklist, (box) => {
expect(box.completed).to.be(false);
});
});
});
describe('when startDate is today', () => {
beforeEach(() => {
user = generateUser();
user.dailys = [
shared.taskDefaults({
type: 'daily',
startDate: moment().subtract(1, 'days'),
frequency: 'daily',
}), shared.taskDefaults({
type: 'daily',
startDate: moment().subtract(1, 'days'),
frequency: 'weekly',
}),
];
daily = user.dailys[0];
weekly = user.dailys[1];
});
it('does damage user for not completing it', () => {
cron(user);
expect(user.stats.hp).to.be.lessThan(50);
});
it('decreases value on cron if daily is incomplete', () => {
cron(user);
expect(daily.value).to.be.lessThan(0);
expect(weekly.value).to.be.lessThan(0);
});
it('resets checklists if daily is not marked as complete', () => {
let checklist;
checklist = [
{
text: '1',
id: 'checklist-one',
completed: true,
}, {
text: '2',
id: 'checklist-two',
completed: true,
}, {
text: '3',
id: 'checklist-three',
completed: false,
},
];
daily.checklist = checklist;
weekly.checklist = checklist;
cron(user);
_.each(daily.checklist, (box) => {
expect(box.completed).to.be(false);
});
_.each(weekly.checklist, (box) => {
expect(box.completed).to.be(false);
});
});
it('resets checklists if daily is marked as complete', () => {
let checklist;
checklist = [
{
text: '1',
id: 'checklist-one',
completed: true,
}, {
text: '2',
id: 'checklist-two',
completed: true,
}, {
text: '3',
id: 'checklist-three',
completed: false,
},
];
daily.checklist = checklist;
daily.completed = true;
weekly.checklist = checklist;
weekly.completed = true;
cron(user);
_.each(daily.checklist, (box) => {
expect(box.completed).to.be(false);
});
_.each(weekly.checklist, (box) => {
expect(box.completed).to.be(false);
});
});
});
});
describe('daily that repeats every x days', () => {
let user = null;
let daily = null;
beforeEach(() => {
user = generateUser();
user.dailys = [
shared.taskDefaults({
type: 'daily',
startDate: moment(),
frequency: 'daily',
}),
];
daily = user.dailys[0];
});
_.times(11, (due) => {
it(`where x equals ${due}`, () => {
daily.everyX = due;
_.times(30, (day) => {
let isDue;
isDue = shared.shouldDo(moment().add(day, 'days'), daily);
if (day % due === 0) {
expect(isDue).to.be(true);
}
if (day % due !== 0) {
expect(isDue).to.be(false);
}
});
});
});
});
describe('daily that repeats every X days when multiple days are missed', () => {
let everyX = 3;
let startDateDaysAgo = everyX * 3;
let user = null;
let daily = null;
describe('including missing a due date', () => {
let missedDays = everyX * 2 + 1;
beforeEach(() => {
user = generateUser();
user.dailys = [
shared.taskDefaults({
type: 'daily',
startDate: moment().subtract(startDateDaysAgo, 'days'),
frequency: 'daily',
everyX,
}),
];
daily = user.dailys[0];
});
it('decreases value on cron once only if daily is incomplete', () => {
cron(user, missedDays);
expect(daily.value).to.be(-1);
});
it('resets checklists if daily is incomplete', () => {
let checklist = [
{
text: '1',
id: 'checklist-one',
completed: true,
},
];
daily.checklist = checklist;
cron(user, missedDays);
_.each(daily.checklist, (box) => {
expect(box.completed).to.be(false);
});
});
it('resets checklists if daily is marked as complete', () => {
let checklist;
checklist = [
{
text: '1',
id: 'checklist-one',
completed: true,
},
];
daily.checklist = checklist;
daily.completed = true;
cron(user, missedDays);
_.each(daily.checklist, (box) => {
expect(box.completed).to.be(false);
});
});
});
describe('but not missing a due date', () => {
let missedDays;
missedDays = everyX - 1;
beforeEach(() => {
user = generateUser();
user.dailys = [
shared.taskDefaults({
type: 'daily',
startDate: moment().subtract(startDateDaysAgo, 'days'),
frequency: 'daily',
everyX,
}),
];
daily = user.dailys[0];
});
it('does not decrease value on cron', () => {
cron(user, missedDays);
expect(daily.value).to.be(0);
});
it('does not reset checklists if daily is incomplete', () => {
let checklist;
checklist = [
{
text: '1',
id: 'checklist-one',
completed: true,
},
];
daily.checklist = checklist;
cron(user, missedDays);
_.each(daily.checklist, (box) => {
expect(box.completed).to.be(true);
});
});
it('resets checklists if daily is marked as complete', () => {
let checklist;
checklist = [
{
text: 1,
id: 'checklist-one',
completed: true,
},
];
daily.checklist = checklist;
daily.completed = true;
cron(user, missedDays);
_.each(daily.checklist, (box) => {
expect(box.completed).to.be(false);
});
});
});
});

View File

@@ -1,76 +0,0 @@
import moment from 'moment';
import { generateTodo } from '../helpers/common.helper';
import { preenTodos } from '../../common/script/index.js';
describe('#preenTodos', () => {
let todos, uncompletedTodo, completedChallengeTodo, newlyCompletedTodo, completedTodoFromTwoDaysAgo, completedTodoFromThreeDaysAgo, completedTodoFromTenDaysAgo;
beforeEach(() => {
uncompletedTodo = generateTodo({ completed: false });
completedChallengeTodo = generateTodo({
completed: true,
challenge: { id: 'some-challenge' },
});
newlyCompletedTodo = generateTodo({
completed: true,
dateCompleted: moment(),
});
completedTodoFromTwoDaysAgo = generateTodo({
completed: true,
dateCompleted: moment().subtract({ days: 2 }),
});
completedTodoFromThreeDaysAgo = generateTodo({
completed: true,
dateCompleted: moment().subtract({ days: 3 }),
});
completedTodoFromTenDaysAgo = generateTodo({
completed: true,
dateCompleted: moment().subtract({ days: 10 }),
});
todos = [
uncompletedTodo,
completedChallengeTodo,
newlyCompletedTodo,
completedTodoFromTwoDaysAgo,
completedTodoFromThreeDaysAgo,
completedTodoFromTenDaysAgo,
];
});
it('includes uncompleted todos', () => {
let preenedTodos = preenTodos(todos);
expect(preenedTodos).to.include(uncompletedTodo);
});
it('includes completed challenge todos', () => {
let preenedTodos = preenTodos(todos);
expect(preenedTodos).to.include(completedChallengeTodo);
});
it('includes recently completed todos', () => {
let preenedTodos = preenTodos(todos);
expect(preenedTodos).to.include(newlyCompletedTodo);
});
it('includes todos completed two days ago', () => {
let preenedTodos = preenTodos(todos);
expect(preenedTodos).to.include(completedTodoFromTwoDaysAgo);
});
it('does not include todos completed three days ago', () => {
let preenedTodos = preenTodos(todos);
expect(preenedTodos).to.not.include(completedTodoFromThreeDaysAgo);
});
it('does not include todos completed more than three days ago', () => {
let preenedTodos = preenTodos(todos);
expect(preenedTodos).to.not.include(completedTodoFromTenDaysAgo);
});
});

View File

@@ -1,103 +0,0 @@
import shared from '../../common/script/index.js';
import {
generateUser,
generateTodo,
} from '../helpers/common.helper';
describe('Spells', () => {
let user;
beforeEach(() => {
let todo = generateTodo();
user = generateUser({
stats: {
int: 20,
str: 20,
con: 20,
per: 20,
lvl: 20,
},
});
user.todos.push(todo);
});
context('Rogue Spells', () => {
beforeEach(() => {
user.stats.class = 'rogue';
});
describe('#backstab', () => {
it('adds exp to user', () => {
const PREVIOUS_EXP = user.stats.exp;
shared.content.spells.rogue.backStab.cast(user, user.todos[0]);
expect(user.stats.exp).to.be.greaterThan(PREVIOUS_EXP);
});
it('adds gp to user', () => {
const PREVIOUS_GP = user.stats.gp;
shared.content.spells.rogue.backStab.cast(user, user.todos[0]);
expect(user.stats.gp).to.be.greaterThan(PREVIOUS_GP);
});
it('levels up user if the gain in experience will level up the user', () => {
user.stats.exp = 399;
user.stats.lvl = 17;
shared.content.spells.rogue.backStab.cast(user, user.todos[0]);
expect(user.stats.lvl).to.eql(18);
});
it('adds quest scroll to inventory when passing level milestone', () => {
user.stats.exp = 329;
user.stats.lvl = 14;
expect(user.items.quests).to.not.have.property('atom1');
shared.content.spells.rogue.backStab.cast(user, user.todos[0]);
expect(user.items.quests).to.have.property('atom1', 1);
});
});
});
context('Wizard Spells', () => {
beforeEach(() => {
user.stats.class = 'wizard';
});
describe('#fireball (Burst of flames)', () => {
it('adds exp to user', () => {
const PREVIOUS_EXP = user.stats.exp;
shared.content.spells.wizard.fireball.cast(user, user.todos[0]);
expect(user.stats.exp).to.be.greaterThan(PREVIOUS_EXP);
});
it('levels up user if the gain in experience will level up the user', () => {
user.stats.exp = 399;
user.stats.lvl = 17;
shared.content.spells.wizard.fireball.cast(user, user.todos[0]);
expect(user.stats.lvl).to.eql(18);
});
it('adds quest scroll to inventory when passing level milestone', () => {
user.stats.exp = 329;
user.stats.lvl = 14;
expect(user.items.quests).to.not.have.property('atom1');
shared.content.spells.wizard.fireball.cast(user, user.todos[0]);
expect(user.items.quests).to.have.property('atom1', 1);
});
});
});
});

View File

@@ -1,161 +0,0 @@
var $w, _, id, modes, shared, user;
shared = require('../../../common/script/index.js');
_ = require('lodash');
$w = function(s) {
return s.split(' ');
};
id = shared.uuid();
user = {
stats: {
"class": 'warrior',
lvl: 1,
hp: 50,
gp: 0,
exp: 10,
per: 0,
int: 0,
con: 0,
str: 0,
buffs: {
per: 0,
int: 0,
con: 0,
str: 0
},
training: {
int: 0,
con: 0,
per: 0,
str: 0
}
},
preferences: {
automaticAllocation: false
},
party: {
quest: {
key: 'evilsanta',
progress: {
up: 0,
down: 0
}
}
},
achievements: {},
items: {
eggs: {},
hatchingPotions: {},
food: {},
gear: {
equipped: {
weapon: 'weapon_warrior_4',
armor: 'armor_warrior_4',
shield: 'shield_warrior_4',
head: 'head_warrior_4'
}
}
},
habits: [
{
id: 'a',
value: 1,
type: 'habit',
attribute: 'str'
}
],
dailys: [
{
id: 'b',
value: 1,
type: 'daily',
attribute: 'str'
}
],
todos: [
{
id: 'c',
value: 1,
type: 'todo',
attribute: 'con'
}, {
id: 'd',
value: 1,
type: 'todo',
attribute: 'per'
}, {
id: 'e',
value: 1,
type: 'todo',
attribute: 'int'
}
],
rewards: []
};
modes = {
flat: _.cloneDeep(user),
classbased_warrior: _.cloneDeep(user),
classbased_rogue: _.cloneDeep(user),
classbased_wizard: _.cloneDeep(user),
classbased_healer: _.cloneDeep(user),
taskbased: _.cloneDeep(user)
};
modes.classbased_warrior.stats["class"] = 'warrior';
modes.classbased_rogue.stats["class"] = 'rogue';
modes.classbased_wizard.stats["class"] = 'wizard';
modes.classbased_healer.stats["class"] = 'healer';
_.each($w('flat classbased_warrior classbased_rogue classbased_wizard classbased_healer taskbased'), function(mode) {
_.merge(modes[mode].preferences, {
automaticAllocation: true,
allocationMode: mode.indexOf('classbased') === 0 ? 'classbased' : mode
});
return shared.wrap(modes[mode]);
});
console.log("\n\n================================================");
console.log("New Simulation");
console.log("================================================\n\n");
_.times([20], function(lvl) {
console.log("[lvl " + lvl + "]\n--------------\n");
return _.each($w('flat classbased_warrior classbased_rogue classbased_wizard classbased_healer taskbased'), function(mode) {
var str, u;
u = modes[mode];
u.stats.exp = shared.tnl(lvl) + 1;
if (mode === 'taskbased') {
_.merge(u.stats, {
per: 0,
con: 0,
int: 0,
str: 0
});
}
u.habits[0].attribute = u.fns.randomVal({
str: 'str',
int: 'int',
per: 'per',
con: 'con'
});
u.ops.score({
params: {
id: u.habits[0].id
},
direction: 'up'
});
u.fns.updateStats(u.stats);
str = mode + (mode === 'taskbased' ? " (" + u.habits[0].attribute + ")" : "");
return console.log(str, _.pick(u.stats, $w('per int con str')));
});
});

View File

@@ -1,291 +0,0 @@
var _, clearUser, id, party, s, shared, task, user;
shared = require('../../../common/script/index.js');
_ = require('lodash');
id = shared.uuid();
user = {
stats: {
"class": 'warrior',
buffs: {
per: 0,
int: 0,
con: 0,
str: 0
}
},
party: {
quest: {
key: 'evilsanta',
progress: {
up: 0,
down: 0
}
}
},
preferences: {
automaticAllocation: false
},
achievements: {},
flags: {
levelDrops: {}
},
items: {
eggs: {},
hatchingPotions: {},
food: {},
quests: {},
gear: {
equipped: {
weapon: 'weapon_warrior_4',
armor: 'armor_warrior_4',
shield: 'shield_warrior_4',
head: 'head_warrior_4'
}
}
},
habits: [
shared.taskDefaults({
id: id,
value: 0
})
],
dailys: [
{
"text": "1"
}, {
"text": "1"
}, {
"text": "1"
}, {
"text": "1"
}, {
"text": "1"
}, {
"text": "1"
}, {
"text": "1"
}, {
"text": "1"
}, {
"text": "1"
}, {
"text": "1"
}, {
"text": "1"
}, {
"text": "1"
}, {
"text": "1"
}, {
"text": "1"
}, {
"text": "1"
}
],
todos: [],
rewards: []
};
shared.wrap(user);
s = user.stats;
task = user.tasks[id];
party = [user];
console.log("\n\n================================================");
console.log("New Simulation");
console.log("================================================\n\n");
clearUser = function(lvl) {
if (lvl == null) {
lvl = 1;
}
_.merge(user.stats, {
exp: 0,
gp: 0,
hp: 50,
lvl: lvl,
str: lvl * 1.5,
con: lvl * 1.5,
per: lvl * 1.5,
int: lvl * 1.5,
mp: 100
});
_.merge(s.buffs, {
str: 0,
con: 0,
int: 0,
per: 0
});
_.merge(user.party.quest.progress, {
up: 0,
down: 0
});
return user.items.lastDrop = {
count: 0
};
};
_.each([1, 25, 50, 75, 100], function(lvl) {
console.log("[LEVEL " + lvl + "] (" + (lvl * 2) + " points total in every attr)\n\n");
_.each({
red: -25,
yellow: 0,
green: 35
}, function(taskVal, color) {
var _party, b4, str;
console.log("[task.value = " + taskVal + " (" + color + ")]");
console.log("direction\texpΔ\t\thpΔ\tgpΔ\ttask.valΔ\ttask.valΔ bonus\t\tboss-hit");
_.each(['up', 'down'], function(direction) {
var b4, delta;
clearUser(lvl);
b4 = {
hp: s.hp,
taskVal: taskVal
};
task.value = taskVal;
if (direction === 'up') {
task.type = 'daily';
}
delta = user.ops.score({
params: {
id: id,
direction: direction
}
});
return console.log((direction === 'up' ? '↑' : '↓') + "\t\t" + s.exp + "/" + (shared.tnl(s.lvl)) + "\t\t" + ((b4.hp - s.hp).toFixed(1)) + "\t" + (s.gp.toFixed(1)) + "\t" + (delta.toFixed(1)) + "\t\t" + ((task.value - b4.taskVal - delta).toFixed(1)) + "\t\t\t" + (user.party.quest.progress.up.toFixed(1)));
});
str = '- [Wizard]';
task.value = taskVal;
clearUser(lvl);
b4 = {
taskVal: taskVal
};
shared.content.spells.wizard.fireball.cast(user, task);
str += "\tfireball(task.valΔ:" + ((task.value - taskVal).toFixed(1)) + " exp:" + (s.exp.toFixed(1)) + " bossHit:" + (user.party.quest.progress.up.toFixed(2)) + ")";
task.value = taskVal;
clearUser(lvl);
_party = [
user, {
stats: {
mp: 0
}
}
];
shared.content.spells.wizard.mpheal.cast(user, _party);
str += "\t| mpheal(mp:" + _party[1].stats.mp + ")";
task.value = taskVal;
clearUser(lvl);
shared.content.spells.wizard.earth.cast(user, party);
str += "\t\t\t\t| earth(buffs.int:" + s.buffs.int + ")";
s.buffs.int = 0;
task.value = taskVal;
clearUser(lvl);
shared.content.spells.wizard.frost.cast(user, {});
str += "\t\t\t| frost(N/A)";
console.log(str);
str = '- [Warrior]';
task.value = taskVal;
clearUser(lvl);
shared.content.spells.warrior.smash.cast(user, task);
b4 = {
taskVal: taskVal
};
str += "\tsmash(task.valΔ:" + ((task.value - taskVal).toFixed(1)) + ")";
task.value = taskVal;
clearUser(lvl);
shared.content.spells.warrior.defensiveStance.cast(user, {});
str += "\t\t| defensiveStance(buffs.con:" + s.buffs.con + ")";
s.buffs.con = 0;
task.value = taskVal;
clearUser(lvl);
shared.content.spells.warrior.valorousPresence.cast(user, party);
str += "\t\t\t| valorousPresence(buffs.str:" + s.buffs.str + ")";
s.buffs.str = 0;
task.value = taskVal;
clearUser(lvl);
shared.content.spells.warrior.intimidate.cast(user, party);
str += "\t\t| intimidate(buffs.con:" + s.buffs.con + ")";
s.buffs.con = 0;
console.log(str);
str = '- [Rogue]';
task.value = taskVal;
clearUser(lvl);
shared.content.spells.rogue.pickPocket.cast(user, task);
str += "\tpickPocket(gp:" + (s.gp.toFixed(1)) + ")";
task.value = taskVal;
clearUser(lvl);
shared.content.spells.rogue.backStab.cast(user, task);
b4 = {
taskVal: taskVal
};
str += "\t\t| backStab(task.valΔ:" + ((task.value - b4.taskVal).toFixed(1)) + " exp:" + (s.exp.toFixed(1)) + " gp:" + (s.gp.toFixed(1)) + ")";
task.value = taskVal;
clearUser(lvl);
shared.content.spells.rogue.toolsOfTrade.cast(user, party);
str += "\t| toolsOfTrade(buffs.per:" + s.buffs.per + ")";
s.buffs.per = 0;
task.value = taskVal;
clearUser(lvl);
shared.content.spells.rogue.stealth.cast(user, {});
str += "\t\t| stealth(avoiding " + user.stats.buffs.stealth + " tasks)";
user.stats.buffs.stealth = 0;
console.log(str);
str = '- [Healer]';
task.value = taskVal;
clearUser(lvl);
s.hp = 0;
shared.content.spells.healer.heal.cast(user, {});
str += "\theal(hp:" + (s.hp.toFixed(1)) + ")";
task.value = taskVal;
clearUser(lvl);
shared.content.spells.healer.brightness.cast(user, {});
b4 = {
taskVal: taskVal
};
str += "\t\t\t| brightness(task.valΔ:" + ((task.value - b4.taskVal).toFixed(1)) + ")";
task.value = taskVal;
clearUser(lvl);
shared.content.spells.healer.protectAura.cast(user, party);
str += "\t\t\t| protectAura(buffs.con:" + s.buffs.con + ")";
s.buffs.con = 0;
task.value = taskVal;
clearUser(lvl);
s.hp = 0;
shared.content.spells.healer.heallAll.cast(user, party);
str += "\t\t| heallAll(hp:" + (s.hp.toFixed(1)) + ")";
console.log(str);
return console.log('\n');
});
return console.log('------------------------------------------------------------');
});
/*
_.each [1,25,50,75,100,125], (lvl) ->
console.log "[LEVEL #{lvl}] (#{lvl*2} points in every attr)\n\n"
_.each {red:-25,yellow:0,green:35}, (taskVal, color) ->
console.log "[task.value = #{taskVal} (#{color})]"
console.log "direction\texpΔ\t\thpΔ\tgpΔ\ttask.valΔ\ttask.valΔ bonus\t\tboss-hit"
_.each ['up','down'], (direction) ->
clearUser(lvl)
b4 = {hp:s.hp, taskVal}
task.value = taskVal
task.type = 'daily' if direction is 'up'
delta = user.ops.score params:{id, direction}
console.log "#{if direction is 'up' then '↑' else '↓'}\t\t#{s.exp}/#{shared.tnl(s.lvl)}\t\t#{(b4.hp-s.hp).toFixed(1)}\t#{s.gp.toFixed(1)}\t#{delta.toFixed(1)}\t\t#{(task.value-b4.taskVal-delta).toFixed(1)}\t\t\t#{user.party.quest.progress.up.toFixed(1)}"
task.value = taskVal;clearUser(lvl)
shared.content.spells.rogue.stealth.cast(user,{})
console.log "\t\t| stealth(avoiding #{user.stats.buffs.stealth} tasks)"
user.stats.buffs.stealth = 0
console.log user.dailys.length
*/

View File

@@ -1,134 +0,0 @@
import {
generateUser,
} from '../helpers/common.helper';
describe('user.fns.updateStats', () => {
let user;
beforeEach(() => {
user = generateUser({});
});
context('No Hp', () => {
it('returns 0 if user\'s hp is 0', () => {
let stats = {
hp: 0,
};
expect(user.fns.updateStats(stats)).to.eql(0);
});
it('returns 0 if user\'s hp is less than 0', () => {
let stats = {
hp: -5,
};
expect(user.fns.updateStats(stats)).to.eql(0);
});
it('sets user\'s hp to 0 if it is less than 0', () => {
let stats = {
hp: -5,
};
user.fns.updateStats(stats);
expect(user.stats.hp).to.eql(0);
});
});
context('Stat Allocation', () => {
it('adds only attribute points up to user\'s level', () => {
let stats = {
exp: 261,
};
user.stats.lvl = 10;
user.fns.updateStats(stats);
expect(user.stats.points).to.eql(11);
});
it('adds an attibute point when user\'s stat points are less than max level', () => {
let stats = {
exp: 3581,
};
user.stats.lvl = 99;
user.stats.str = 25;
user.stats.int = 25;
user.stats.con = 25;
user.stats.per = 24;
user.fns.updateStats(stats);
expect(user.stats.points).to.eql(1);
});
it('does not add an attibute point when user\'s stat points are equal to max level', () => {
let stats = {
exp: 3581,
};
user.stats.lvl = 99;
user.stats.str = 25;
user.stats.int = 25;
user.stats.con = 25;
user.stats.per = 25;
user.fns.updateStats(stats);
expect(user.stats.points).to.eql(0);
});
it('does not add an attibute point when user\'s stat points + unallocated points are equal to max level', () => {
let stats = {
exp: 3581,
};
user.stats.lvl = 99;
user.stats.str = 25;
user.stats.int = 25;
user.stats.con = 25;
user.stats.per = 15;
user.stats.points = 10;
user.fns.updateStats(stats);
expect(user.stats.points).to.eql(10);
});
it('only awards stat points up to level 100 if user is missing unallocated stat points and is over level 100', () => {
let stats = {
exp: 5581,
};
user.stats.lvl = 104;
user.stats.str = 25;
user.stats.int = 25;
user.stats.con = 25;
user.stats.per = 15;
user.stats.points = 0;
user.fns.updateStats(stats);
expect(user.stats.points).to.eql(10);
});
// @TODO: Set up sinon sandbox
xit('auto allocates stats if automaticAllocation is turned on', () => {
sandbox.stub(user.fns, 'autoAllocate');
let stats = {
exp: 261,
};
user.stats.lvl = 10;
user.fns.updateStats(stats);
expect(user.fns.autoAllocate).to.be.calledOnce;
});
});
});

View File

@@ -1,122 +0,0 @@
let shared = require('../../common/script/index.js');
describe('user.ops.hourglassPurchase', () => {
let user;
beforeEach(() => {
user = {
items: {
pets: {},
mounts: {},
hatchingPotions: {},
},
purchased: {
plan: {
consecutive: {
trinkets: 0,
},
},
},
};
shared.wrap(user);
});
context('Time Travel Stable', () => {
context('failure conditions', () => {
it('does not allow purchase of unsupported item types', (done) => {
user.ops.hourglassPurchase({params: {type: 'hatchingPotions', key: 'Base'}}, (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', (done) => {
user.ops.hourglassPurchase({params: {type: 'pets', key: 'MantisShrimp-Base'}}, (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', (done) => {
user.ops.hourglassPurchase({params: {type: 'mounts', key: 'MantisShrimp-Base'}}, (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', (done) => {
user.purchased.plan.consecutive.trinkets = 1;
user.items.pets = {
'MantisShrimp-Base': true,
};
user.ops.hourglassPurchase({params: {type: 'pets', key: 'MantisShrimp-Base'}}, (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', (done) => {
user.purchased.plan.consecutive.trinkets = 1;
user.items.mounts = {
'MantisShrimp-Base': true,
};
user.ops.hourglassPurchase({params: {type: 'mounts', key: 'MantisShrimp-Base'}}, (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', (done) => {
user.purchased.plan.consecutive.trinkets = 1;
user.ops.hourglassPurchase({params: {type: 'pets', key: 'Wolf-Veteran'}}, (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', (done) => {
user.purchased.plan.consecutive.trinkets = 1;
user.ops.hourglassPurchase({params: {type: 'mounts', key: 'Orca-Base'}}, (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', () => {
it('buys a pet', (done) => {
user.purchased.plan.consecutive.trinkets = 2;
user.ops.hourglassPurchase({params: {type: 'pets', key: 'MantisShrimp-Base'}}, (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', (done) => {
user.purchased.plan.consecutive.trinkets = 2;
user.ops.hourglassPurchase({params: {type: 'mounts', key: 'MantisShrimp-Base'}}, (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();
});
});
});
});
});

View File

@@ -1,34 +0,0 @@
let shared = require('../../common/script/index.js');
describe('user.ops', () => {
let user;
beforeEach(() => {
user = {
items: {
gear: { },
special: { },
},
achievements: { },
flags: { },
};
shared.wrap(user);
});
describe('readCard', () => {
it('removes card from invitation array', () => {
user.items.special.valentineReceived = ['Leslie'];
user.ops.readCard({ params: { cardType: 'valentine' } });
expect(user.items.special.valentineReceived).to.be.empty;
});
it('removes the first card from invitation array', () => {
user.items.special.valentineReceived = ['Leslie', 'Vicky'];
user.ops.readCard({ params: { cardType: 'valentine' } });
expect(user.items.special.valentineReceived).to.eql(['Vicky']);
});
});
});

View File

@@ -274,7 +274,7 @@ api.joinGroup = {
} }
} }
await Bluebird.all(promises); promises = await Bluebird.all(promises);
let response = Group.toJSONCleanChat(promises[0], user); let response = Group.toJSONCleanChat(promises[0], user);
response.leader = (await User.findById(response.leader).select(nameFields).exec()).toJSON({minimize: true}); response.leader = (await User.findById(response.leader).select(nameFields).exec()).toJSON({minimize: true});