Merge branch 'develop' into api-v3

This commit is contained in:
Blade Barringer
2015-12-13 16:39:59 -06:00
502 changed files with 5583 additions and 3160 deletions
@@ -240,4 +240,55 @@ describe('POST /register', () => {
});
});
});
context('successful login with habitica-android header', () => {
let api, username, email, password;
beforeEach(() => {
api = requester({}, {'x-client': 'habitica-android'});
username = generateRandomUserName();
email = `${username}@example.com`;
password = 'password';
});
it('sets all common tutorial flags to true', () => {
return api.post('/register', {
username: username,
email: email,
password: password,
confirmPassword: password,
}).then((user) => {
expect(user.flags.tour).to.not.be.empty;
each(user.flags.tutorial.common, (value, attribute) => {
expect(value).to.eql(true);
});
});
});
it('populates user with default todos, habits, and rewards', () => {
return api.post('/register', {
username: username,
email: email,
password: password,
confirmPassword: password,
}).then((user) => {
expect(user.todos).to.not.be.empty;
expect(user.dailys).to.be.empty;
expect(user.habits).to.not.be.empty;
expect(user.rewards).to.not.be.empty;
});
});
it('populates user with default tags', () => {
return api.post('/register', {
username: username,
email: email,
password: password,
confirmPassword: password,
}).then((user) => {
expect(user.tags).to.not.be.empty;
});
});
});
});
+127 -165
View File
@@ -1,4 +1,12 @@
/* eslint-disable camelcase, func-names, no-shadow */
import {
generateUser,
generateDaily,
generateHabit,
generateTodo,
} from '../helpers/common.helper';
import {
DAY_MAPPING,
startOfWeek,
@@ -19,81 +27,6 @@ shared.i18n.translations = require('../../website/src/libs/api-v2/i18n').transla
test_helper.addCustomMatchers();
/* Helper Functions */
let newUser = (addTasks = true) => {
let buffs = {
per: 0,
int: 0,
con: 0,
str: 0,
stealth: 0,
streaks: false,
};
let user = {
auth: {
timestamps: {},
},
stats: {
str: 1,
con: 1,
per: 1,
int: 1,
mp: 32,
class: 'warrior',
buffs,
},
items: {
lastDrop: {
count: 0,
},
hatchingPotions: {},
eggs: {},
food: {},
gear: {
equipped: {},
costume: {},
owned: {},
},
quests: {},
},
party: {
quest: {
progress: {
down: 0,
},
},
},
preferences: {
autoEquip: true,
},
dailys: [],
todos: [],
rewards: [],
flags: {},
achievements: {
ultimateGearSets: {},
},
contributor: {
level: 2,
},
_tmp: {},
};
shared.wrap(user);
user.ops.reset(null, () => {});
if (addTasks) {
_.each(['habit', 'todo', 'daily'], (task) => {
user.ops.addTask({
body: {
type: task,
id: shared.uuid(),
},
});
});
}
return user;
};
let rewrapUser = (user) => {
user._wrapped = false;
shared.wrap(user);
@@ -102,7 +35,15 @@ let rewrapUser = (user) => {
let beforeAfter = (options = {}) => {
let lastCron;
let user = newUser();
let user = generateUser();
let daily = generateDaily();
let habit = generateHabit();
let todo = generateTodo();
user.dailys.push(daily);
user.habits.push(habit);
user.todos.push(todo);
let ref = [user, _.cloneDeep(user)];
let before = ref[0];
let after = ref[1];
@@ -223,52 +164,10 @@ let repeatWithoutLastWeekday = () => {
};
describe('User', () => {
it('sets correct user defaults', () => {
let user = newUser();
let base_gear = {
armor: 'armor_base_0',
weapon: 'weapon_base_0',
head: 'head_base_0',
shield: 'shield_base_0',
};
let buffs = {
per: 0,
int: 0,
con: 0,
str: 0,
stealth: 0,
streaks: false,
};
expect(user.stats).to.eql({
str: 1,
con: 1,
per: 1,
int: 1,
hp: 50,
mp: 32,
lvl: 1,
exp: 0,
gp: 0,
class: 'warrior',
buffs,
});
expect(user.items.gear).to.eql({
equipped: base_gear,
costume: base_gear,
owned: {
weapon_warrior_0: true,
},
});
expect(user.preferences).to.eql({
autoEquip: true,
costume: false,
});
});
it('calculates max MP', () => {
let user = newUser();
let user = generateUser();
expect(user).toHaveMaxMP(32);
expect(user).toHaveMaxMP(30);
user.stats.int = 10;
expect(user).toHaveMaxMP(50);
user.stats.lvl = 5;
@@ -277,8 +176,9 @@ describe('User', () => {
user.items.gear.equipped.weapon = 'weapon_wizard_1';
expect(user).toHaveMaxMP(63);
});
it('handles perfect days', () => {
let user = newUser();
let user = generateUser();
user.dailys = [];
_.times(3, () => {
@@ -316,12 +216,13 @@ describe('User', () => {
expect(user.stats.buffs.str).to.be(1);
expect(user.achievements.perfect).to.be(2);
});
describe('Resting in the Inn', () => {
let user = null;
let cron = null;
beforeEach(() => {
user = newUser();
user = generateUser();
user.preferences.sleep = true;
cron = () => {
user.lastCron = moment().subtract(1, 'days');
@@ -335,15 +236,18 @@ describe('User', () => {
}));
});
});
it('remains in the inn on cron', () => {
cron();
expect(user.preferences.sleep).to.be(true);
});
it('resets dailies', () => {
user.dailys[0].completed = true;
cron();
expect(user.dailys[0].completed).to.be(false);
});
it('resets checklist on incomplete dailies', () => {
user.dailys[0].checklist = [
{
@@ -365,6 +269,7 @@ describe('User', () => {
expect(box.completed).to.be(false);
});
});
it('resets checklist on complete dailies', () => {
user.dailys[0].checklist = [
{
@@ -387,6 +292,7 @@ describe('User', () => {
expect(box.completed).to.be(false);
});
});
it('does not reset checklist on grey incomplete dailies', () => {
let yesterday = moment().subtract(1, 'days');
@@ -411,6 +317,7 @@ describe('User', () => {
expect(box.completed).to.be(true);
});
});
it('resets checklist on complete grey complete dailies', () => {
let yesterday = moment().subtract(1, 'days');
@@ -436,6 +343,7 @@ describe('User', () => {
expect(box.completed).to.be(false);
});
});
it('does not damage user for incomplete dailies', () => {
expect(user).toHaveHP(50);
user.dailys[0].completed = true;
@@ -443,12 +351,14 @@ describe('User', () => {
cron();
expect(user).toHaveHP(50);
});
it('gives credit for complete dailies', () => {
user.dailys[0].completed = true;
expect(user.dailys[0].history).to.be.empty;
cron();
expect(user.dailys[0].history).to.not.be.empty;
});
it('damages user for incomplete dailies after checkout', () => {
expect(user).toHaveHP(50);
user.dailys[0].completed = true;
@@ -458,11 +368,12 @@ describe('User', () => {
expect(user.stats.hp).to.be.lessThan(50);
});
});
describe('Death', () => {
let user;
beforeEach(() => {
user = newUser();
user = generateUser();
});
it('revives correctly', () => {
@@ -473,7 +384,9 @@ describe('User', () => {
hp: 0,
class: 'warrior',
};
user.items.gear.owned.weapon_warrior_0 = true;
user.ops.revive();
expect(user).toHaveGP(0);
expect(user).toHaveExp(0);
expect(user).toHaveLevel(1);
@@ -484,21 +397,30 @@ describe('User', () => {
});
it('doesn\'t break unbreakables', () => {
let ce;
let ce = shared.countExists;
user.items.gear.owned = {
weapon_warrior_0: true,
shield_warrior_1: true,
shield_rogue_1: true,
head_special_nye: true,
};
ce = shared.countExists;
user.items.gear.owned.shield_warrior_1 = true;
user.items.gear.owned.shield_rogue_1 = true;
user.items.gear.owned.head_special_nye = true;
expect(ce(user.items.gear.owned)).to.be(4);
user.stats.hp = 0;
user.ops.revive();
expect(ce(user.items.gear.owned)).to.be(3);
user.stats.hp = 0;
user.ops.revive();
expect(ce(user.items.gear.owned)).to.be(2);
user.stats.hp = 0;
user.ops.revive();
expect(ce(user.items.gear.owned)).to.be(2);
expect(user.items.gear.owned).to.eql({
weapon_warrior_0: false,
@@ -521,9 +443,10 @@ describe('User', () => {
expect(shared.content.gear.flat.head_special_nye.canOwn(user)).to.be(true);
});
});
describe('Rebirth', () => {
it('removes correct gear', () => {
let user = newUser();
let user = generateUser();
user.stats.lvl = 100;
user.items.gear.owned = {
@@ -547,9 +470,10 @@ describe('User', () => {
});
});
});
describe('store', () => {
it('buys a Quest scroll', () => {
let user = newUser();
let user = generateUser();
user.stats.gp = 205;
user.ops.buyQuest({
@@ -562,8 +486,9 @@ describe('User', () => {
});
expect(user).toHaveGP(5);
});
it('does not buy Quests without enough Gold', () => {
let user = newUser();
let user = generateUser();
user.stats.gp = 1;
user.ops.buyQuest({
@@ -574,8 +499,9 @@ describe('User', () => {
expect(user.items.quests).to.eql({});
expect(user).toHaveGP(1);
});
it('does not buy nonexistent Quests', () => {
let user = newUser();
let user = generateUser();
user.stats.gp = 9999;
user.ops.buyQuest({
@@ -586,8 +512,9 @@ describe('User', () => {
expect(user.items.quests).to.eql({});
expect(user).toHaveGP(9999);
});
it('does not buy Gem-premium Quests', () => {
let user = newUser();
let user = generateUser();
user.stats.gp = 9999;
user.ops.buyQuest({
@@ -599,9 +526,13 @@ describe('User', () => {
expect(user).toHaveGP(9999);
});
});
describe('Gem purchases', () => {
it('does not purchase items without enough Gems', () => {
let user = newUser();
let user = generateUser();
user.items.eggs = {};
user.items.gear.owned = {};
user.ops.purchase({
params: {
@@ -621,12 +552,11 @@ describe('User', () => {
},
});
expect(user.items.eggs).to.eql({});
expect(user.items.gear.owned).to.eql({
weapon_warrior_0: true,
});
expect(user.items.gear.owned).to.eql({});
});
it('purchases an egg', () => {
let user = newUser();
let user = generateUser();
user.balance = 1;
user.ops.purchase({
@@ -640,8 +570,9 @@ describe('User', () => {
});
expect(user.balance).to.eql(0.25);
});
it('purchases fox ears', () => {
let user = newUser();
let user = generateUser();
user.balance = 1;
user.ops.purchase({
@@ -650,14 +581,13 @@ describe('User', () => {
key: 'headAccessory_special_foxEars',
},
});
expect(user.items.gear.owned).to.eql({
weapon_warrior_0: true,
headAccessory_special_foxEars: true,
});
expect(user.items.gear.owned.headAccessory_special_foxEars).to.eql(true);
expect(user.balance).to.eql(0.5);
});
it('unlocks all the animal ears at once', () => {
let user = newUser();
let user = generateUser();
user.balance = 2;
user.ops.unlock({
@@ -665,20 +595,19 @@ describe('User', () => {
path: 'items.gear.owned.headAccessory_special_bearEars,items.gear.owned.headAccessory_special_cactusEars,items.gear.owned.headAccessory_special_foxEars,items.gear.owned.headAccessory_special_lionEars,items.gear.owned.headAccessory_special_pandaEars,items.gear.owned.headAccessory_special_pigEars,items.gear.owned.headAccessory_special_tigerEars,items.gear.owned.headAccessory_special_wolfEars',
},
});
expect(user.items.gear.owned).to.eql({
weapon_warrior_0: true,
headAccessory_special_bearEars: true,
headAccessory_special_cactusEars: true,
headAccessory_special_foxEars: true,
headAccessory_special_lionEars: true,
headAccessory_special_pandaEars: true,
headAccessory_special_pigEars: true,
headAccessory_special_tigerEars: true,
headAccessory_special_wolfEars: true,
});
expect(user.items.gear.owned.headAccessory_special_bearEars).to.eql(true);
expect(user.items.gear.owned.headAccessory_special_cactusEars).to.eql(true);
expect(user.items.gear.owned.headAccessory_special_foxEars).to.eql(true);
expect(user.items.gear.owned.headAccessory_special_lionEars).to.eql(true);
expect(user.items.gear.owned.headAccessory_special_pandaEars).to.eql(true);
expect(user.items.gear.owned.headAccessory_special_pigEars).to.eql(true);
expect(user.items.gear.owned.headAccessory_special_tigerEars).to.eql(true);
expect(user.items.gear.owned.headAccessory_special_wolfEars).to.eql(true);
expect(user.balance).to.eql(0.75);
});
});
describe('spells', () => {
_.each(shared.content.spells, (spellClass) => {
_.each(spellClass, (spell) => {
@@ -694,6 +623,7 @@ describe('User', () => {
});
});
});
describe('drop system', () => {
let user = null;
const MIN_RANGE_FOR_POTION = 0;
@@ -704,7 +634,7 @@ describe('User', () => {
const MAX_RANGE_FOR_FOOD = 1;
beforeEach(function () {
user = newUser();
user = generateUser();
user.flags.dropsEnabled = true;
this.task_id = shared.uuid();
return user.ops.addTask({
@@ -733,6 +663,7 @@ describe('User', () => {
}
return results;
});
it('drops a pet egg', function () {
let results = [];
@@ -786,6 +717,7 @@ describe('User', () => {
user.fns.predictableRandom.restore();
});
});
describe('Quests', () => {
_.each(shared.content.quests, (quest) => {
it(`${ quest.text() } has valid values`, () => {
@@ -818,9 +750,12 @@ describe('User', () => {
});
});
});
describe('Achievements', () => {
_.each(shared.content.classes, (klass) => {
let user = newUser();
let user = generateUser();
user.achievements.ultimateGearSets = {};
user.stats.gp = 10000;
_.each(shared.content.gearTypes, (type) => {
@@ -844,8 +779,9 @@ describe('User', () => {
expect(user.achievements.ultimateGearSets[klass]).to.be.ok();
});
});
it('does not remove existing Ultimate Gear achievements', () => {
let user = newUser();
let user = generateUser();
user.achievements.ultimateGearSets = {
healer: true,
@@ -866,24 +802,27 @@ describe('User', () => {
});
});
});
describe('unlocking features', () => {
it('unlocks drops at level 3', () => {
let user = newUser();
let user = generateUser();
user.stats.lvl = 3;
user.fns.updateStats(user.stats);
expect(user.flags.dropsEnabled).to.be.ok();
});
it('unlocks Rebirth at level 50', () => {
let user = newUser();
let user = generateUser();
user.stats.lvl = 50;
user.fns.updateStats(user.stats);
expect(user.flags.rebirthEnabled).to.be.ok();
});
describe('level-awarded Quests', () => {
it('gets Attack of the Mundane at level 15', () => {
let user = newUser();
let user = generateUser();
user.stats.lvl = 15;
user.fns.updateStats(user.stats);
@@ -892,7 +831,7 @@ describe('User', () => {
});
it('gets Vice at level 30', () => {
let user = newUser();
let user = generateUser();
user.stats.lvl = 30;
user.fns.updateStats(user.stats);
@@ -901,7 +840,7 @@ describe('User', () => {
});
it('gets Golden Knight at level 40', () => {
let user = newUser();
let user = generateUser();
user.stats.lvl = 40;
user.fns.updateStats(user.stats);
@@ -910,7 +849,7 @@ describe('User', () => {
});
it('gets Moonstone Chain at level 60', () => {
let user = newUser();
let user = generateUser();
user.stats.lvl = 60;
user.fns.updateStats(user.stats);
@@ -941,6 +880,7 @@ describe('Simple Scoring', () => {
});
expectLostPoints(this.before, this.after, 'habit');
});
it('Habits : Down', function () {
this.after.ops.score({
params: {
@@ -953,6 +893,7 @@ describe('Simple Scoring', () => {
});
expectGainedPoints(this.before, this.after, 'habit');
});
it('Dailys : Up', function () {
this.after.ops.score({
params: {
@@ -962,6 +903,7 @@ describe('Simple Scoring', () => {
});
expectGainedPoints(this.before, this.after, 'daily');
});
it('Dailys : Up, Down', function () {
this.after.ops.score({
params: {
@@ -977,6 +919,7 @@ describe('Simple Scoring', () => {
});
expectClosePoints(this.before, this.after, 'daily');
});
it('Todos : Up', function () {
this.after.ops.score({
params: {
@@ -1005,8 +948,13 @@ describe('Simple Scoring', () => {
});
describe('Cron', () => {
let user;
beforeEach(() => {
user = generateUser();
});
it('computes shouldCron', () => {
let user = newUser();
let paths = {};
user.fns.cron({
@@ -1020,6 +968,7 @@ describe('Cron', () => {
});
expect(user.lastCron).to.be.greaterThan(0);
});
it('only dailies & todos are affected', () => {
let ref = beforeAfter({
daysAgo: 1,
@@ -1040,6 +989,7 @@ describe('Cron', () => {
expect(beforeTasks).to.eql(afterTasks);
});
describe('preening', () => {
beforeEach(function () {
this.clock = sinon.useFakeTimers(Date.parse('2013-11-20'), 'Date');
@@ -1157,6 +1107,7 @@ describe('Cron', () => {
});
});
});
describe('Todos', () => {
it('1 day missed', () => {
let ref = beforeAfter({
@@ -1174,6 +1125,7 @@ describe('Cron', () => {
expect(after.todos[0].value).to.be(-1);
expect(after.history.todos).to.have.length(1);
});
it('2 days missed', () => {
let ref = beforeAfter({
daysAgo: 2,
@@ -1187,6 +1139,7 @@ describe('Cron', () => {
expect(after.todos[0].value).to.be(-1);
});
});
describe('cron day calculations', () => {
let dayStart = 4;
let fstr = 'YYYY-MM-DD HH: mm: ss';
@@ -1199,6 +1152,7 @@ describe('Cron', () => {
expect(start.format(fstr)).to.eql('2014-10-08 04: 00: 00');
});
it('startOfDay after dayStart', () => {
let start = startOfDay({
now: moment('2014-10-09 05: 30: 00'),
@@ -1207,6 +1161,7 @@ describe('Cron', () => {
expect(start.format(fstr)).to.eql('2014-10-09 04: 00: 00');
});
it('daysSince cron before, now after', () => {
let lastCron = moment('2014-10-09 02: 30: 00');
let days = daysSince(lastCron, {
@@ -1216,6 +1171,7 @@ describe('Cron', () => {
expect(days).to.eql(1);
});
it('daysSince cron before, now before', () => {
let lastCron = moment('2014-10-09 02: 30: 00');
let days = daysSince(lastCron, {
@@ -1225,6 +1181,7 @@ describe('Cron', () => {
expect(days).to.eql(0);
});
it('daysSince cron after, now after', () => {
let lastCron = moment('2014-10-09 05: 30: 00');
let days = daysSince(lastCron, {
@@ -1234,6 +1191,7 @@ describe('Cron', () => {
expect(days).to.eql(0);
});
it('daysSince cron after, now tomorrow before', () => {
let lastCron = moment('2014-10-09 12: 30: 00');
let days = daysSince(lastCron, {
@@ -1243,6 +1201,7 @@ describe('Cron', () => {
expect(days).to.eql(0);
});
it('daysSince cron after, now tomorrow after', () => {
let lastCron = moment('2014-10-09 12: 30: 00');
let days = daysSince(lastCron, {
@@ -1486,18 +1445,21 @@ describe('Helper', () => {
expect(shared.gold(1.957)).to.eql(1);
expect(shared.gold()).to.eql(0);
});
it('calculates silver coins', () => {
expect(shared.silver(10)).to.eql(0);
expect(shared.silver(1.957)).to.eql(95);
expect(shared.silver(0.01)).to.eql('01');
expect(shared.silver()).to.eql('00');
});
it('calculates experience to next level', () => {
expect(shared.tnl(1)).to.eql(150);
expect(shared.tnl(2)).to.eql(160);
expect(shared.tnl(10)).to.eql(260);
expect(shared.tnl(99)).to.eql(3580);
});
it('calculates the start of the day', () => {
let fstr = 'YYYY-MM-DD HH: mm: ss';
let today = '2013-01-01 00: 00: 00';
+35 -74
View File
@@ -33,74 +33,12 @@ let repeatWithoutLastWeekday = () => { // eslint-disable-line no-unused-vars
/* Helper Functions */
let newUser = (addTasks = true) => {
let buffs;
let user;
buffs = {
per: 0,
int: 0,
con: 0,
str: 0,
stealth: 0,
streaks: false,
};
user = {
auth: {
timestamps: {},
},
stats: {
str: 1,
con: 1,
per: 1,
int: 1,
mp: 32,
class: 'warrior',
buffs,
},
items: {
lastDrop: {
count: 0,
},
hatchingPotions: {},
eggs: {},
food: {},
gear: {
equipped: {},
costume: {},
},
},
party: {
quest: {
progress: {
down: 0,
},
},
},
preferences: {},
dailys: [],
todos: [],
rewards: [],
flags: {},
achievements: {},
contributor: {
level: 2,
},
};
shared.wrap(user);
user.ops.reset(null, () => {});
if (addTasks) {
_.each(['habit', 'todo', 'daily'], (task) => {
user.ops.addTask({
body: {
type: task,
id: shared.uuid(),
},
});
});
}
return user;
};
import {
generateUser,
generateDaily,
generateHabit,
generateTodo,
} from '../helpers/common.helper';
let cron = (usr, missedDays = 1) => {
usr.lastCron = moment().subtract(missedDays, 'days');
@@ -114,7 +52,7 @@ describe('daily/weekly that repeats everyday (default)', () => {
describe('when startDate is in the future', () => {
beforeEach(() => {
user = newUser();
user = generateUser();
user.dailys = [
shared.taskDefaults({
type: 'daily',
@@ -138,15 +76,18 @@ describe('daily/weekly that repeats everyday (default)', () => {
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 = [
{
@@ -174,6 +115,7 @@ describe('daily/weekly that repeats everyday (default)', () => {
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 = [
{
@@ -203,6 +145,7 @@ describe('daily/weekly that repeats everyday (default)', () => {
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);
@@ -217,9 +160,10 @@ describe('daily/weekly that repeats everyday (default)', () => {
expect(weekly_due_on_start_date).to.be(true);
});
});
describe('when startDate is in the past', () => {
beforeEach(() => {
user = newUser();
user = generateUser();
user.dailys = [
shared.taskDefaults({
type: 'daily',
@@ -234,20 +178,24 @@ describe('daily/weekly that repeats everyday (default)', () => {
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;
@@ -276,6 +224,7 @@ describe('daily/weekly that repeats everyday (default)', () => {
expect(box.completed).to.be(false);
});
});
it('resets checklists if daily is marked as complete', () => {
let checklist = [
{
@@ -306,9 +255,10 @@ describe('daily/weekly that repeats everyday (default)', () => {
});
});
});
describe('when startDate is today', () => {
beforeEach(() => {
user = newUser();
user = generateUser();
user.dailys = [
shared.taskDefaults({
type: 'daily',
@@ -323,15 +273,18 @@ describe('daily/weekly that repeats everyday (default)', () => {
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;
@@ -360,6 +313,7 @@ describe('daily/weekly that repeats everyday (default)', () => {
expect(box.completed).to.be(false);
});
});
it('resets checklists if daily is marked as complete', () => {
let checklist;
@@ -398,7 +352,7 @@ describe('daily that repeats every x days', () => {
let daily = null;
beforeEach(() => {
user = newUser();
user = generateUser();
user.dailys = [
shared.taskDefaults({
type: 'daily',
@@ -436,7 +390,7 @@ describe('daily that repeats every X days when multiple days are missed', () =>
let missedDays = everyX * 2 + 1;
beforeEach(() => {
user = newUser();
user = generateUser();
user.dailys = [
shared.taskDefaults({
type: 'daily',
@@ -447,10 +401,12 @@ describe('daily that repeats every X days when multiple days are missed', () =>
];
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 = [
{
@@ -466,6 +422,7 @@ describe('daily that repeats every X days when multiple days are missed', () =>
expect(box.completed).to.be(false);
});
});
it('resets checklists if daily is marked as complete', () => {
let checklist;
@@ -484,12 +441,13 @@ describe('daily that repeats every X days when multiple days are missed', () =>
});
});
});
describe('but not missing a due date', () => {
let missedDays;
missedDays = everyX - 1;
beforeEach(() => {
user = newUser();
user = generateUser();
user.dailys = [
shared.taskDefaults({
type: 'daily',
@@ -500,10 +458,12 @@ describe('daily that repeats every X days when multiple days are missed', () =>
];
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;
@@ -520,6 +480,7 @@ describe('daily that repeats every X days when multiple days are missed', () =>
expect(box.completed).to.be(true);
});
});
it('resets checklists if daily is marked as complete', () => {
let checklist;
+103
View File
@@ -0,0 +1,103 @@
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);
});
});
});
});
+1 -1
View File
@@ -37,7 +37,7 @@ describe('front page', function() {
var login = element(by.css("#loginForm input[value='Login']"));
login.click();
var alertDialog = browser.switchTo().alert();
expect(alertDialog.getText()).toMatch("Uh-oh - your username or password is incorrect.\n- Make sure your username or email is typed correctly.\n- You may have signed up with Facebook, not email. Double-check by trying Facebook login.\n- If you forgot your password, click \"Forgot Password\".");
expect(alertDialog.getText()).toMatch("Uh-oh - your username or password is incorrect.\n- Make sure your username or email is typed correctly.\n- You may have signed up with Facebook, not email. Double-check by trying Facebook login.\n- If you forgot your password, click \"Forgot Password\" on the habitica.com website's login form.");
alertDialog.accept();
});
+42
View File
@@ -0,0 +1,42 @@
import mongoose from 'mongoose';
import { wrap as wrapUser } from '../../common/script/index';
import { model as User } from '../../website/src/models/user';
import {
DailySchema,
HabitSchema,
RewardSchema,
TodoSchema,
} from '../../website/src/models/task';
export function generateUser (options = {}) {
let user = new User(options).toObject();
wrapUser(user);
return user;
}
export function generateDaily (options = {}) {
let Daily = mongoose.model('Daily', DailySchema);
return new Daily(options).toObject();
}
export function generateHabit (options = {}) {
let Habit = mongoose.model('Habit', HabitSchema);
return new Habit(options).toObject();
}
export function generateReward (options = {}) {
let Reward = mongoose.model('Reward', RewardSchema);
return new Reward(options).toObject();
}
export function generateTodo (options = {}) {
let Todo = mongoose.model('Todo', TodoSchema);
return new Todo(options).toObject();
}
+10 -9
View File
@@ -89,17 +89,18 @@ describe('Inventory Controller', function() {
});
it('does not show modal if user tries to hatch a pet they own', function(){
user.items.pets['Cactus-Base'] = 5;
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;
expect(rootScope.openModal).to.not.have.been.called;
});
it('does not show modal if user tries to hatch a premium quest pet', function(){
user.items.eggs = {Snake: 1};
user.items.hatchingPotions = {Peppermint: 1};
scope.chooseEgg('Snake');
scope.choosePotion('Peppermint');
expect(rootScope.openModal).to.not.have.been.called;
});
it('does not show pet hatching modal if user has opted out', function(){