Merge branch 'api-v3' into sabrecat/v3-payments

This commit is contained in:
Matteo Pagliazzi
2016-04-30 16:51:51 +02:00
3365 changed files with 7060 additions and 5409 deletions

View File

@@ -236,7 +236,7 @@ describe('POST /challenges', () => {
official: true,
});
expect(challenge.official).to.be.undefined;
expect(challenge.official).to.eql(false);
});
it('returns an error when challenge validation fails; doesn\'s save user or group', async () => {
@@ -284,7 +284,7 @@ describe('POST /challenges', () => {
expect(challenge.name).to.eql(name);
expect(challenge.shortName).to.eql(shortName);
expect(challenge.description).to.eql(description);
expect(challenge.official).to.be.undefined;
expect(challenge.official).to.eql(false);
expect(challenge.group).to.eql({
_id: group._id,
privacy: group.privacy,

View File

@@ -44,6 +44,15 @@ describe('POST /group/:groupId/join', () => {
expect(res.leader.profile.name).to.eql(user.profile.name);
});
it('returns an error is user was already a member', async () => {
await joiningUser.post(`/groups/${publicGuild._id}/join`);
await expect(joiningUser.post(`/groups/${publicGuild._id}/join`)).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('userAlreadyInGroup'),
});
});
it('promotes joining member in a public empty guild to leader', async () => {
await user.post(`/groups/${publicGuild._id}/leave`);

View File

@@ -36,6 +36,6 @@ describe('POST /user/allocate', () => {
await user.sync();
expect(user.stats.con).to.equal(1);
expect(user.stats.points).to.equal(0);
expect(res.stats.con).to.equal(1);
expect(res.con).to.equal(1);
});
});

View File

@@ -18,11 +18,7 @@ describe('POST /user/allocate-now', () => {
let res = await user.post('/user/allocate-now');
await user.sync();
expect(res).to.eql({
data: {
stats: user.stats,
},
});
expect(res).to.eql(user.stats);
expect(user.stats.points).to.equal(0);
expect(user.stats.con).to.equal(9);
expect(user.stats.int).to.equal(8);

View File

@@ -36,9 +36,7 @@ describe('POST /user/buy/:key', () => {
await user.sync();
expect(user.stats.hp).to.equal(50);
expect(res.data).to.eql({
stats: user.stats,
});
expect(res.data).to.eql(user.stats);
expect(res.message).to.equal(t('messageBought', {itemText: potion.text()}));
});

View File

@@ -31,11 +31,7 @@ describe('POST /user/buy-mystery-set/:key', () => {
expect(res.data).to.eql({
items: JSON.parse(JSON.stringify(user.items)), // otherwise dates can't be compared
purchased: {
plan: {
consecutive: user.purchased.plan.consecutive,
},
},
purchasedPlanConsecutive: user.purchased.plan.consecutive,
});
expect(res.message).to.equal(t('hourglassPurchaseSet'));
});

View File

@@ -36,9 +36,7 @@ describe('POST /user/buy-potion', () => {
await user.sync();
expect(user.stats.hp).to.equal(50);
expect(res.data).to.eql({
stats: user.stats,
});
expect(res.data).to.eql(user.stats);
expect(res.message).to.equal(t('messageBought', {itemText: potion.text()}));
});
});

View File

@@ -18,13 +18,13 @@ describe('POST /user/change-class', () => {
let res = await user.post('/user/change-class?class=rogue');
await user.sync();
expect(res).to.eql({
data: JSON.parse(JSON.stringify({
expect(res).to.eql(JSON.parse(
JSON.stringify({
preferences: user.preferences,
stats: user.stats,
flags: user.flags,
items: user.items,
})),
});
})
));
});
});

View File

@@ -15,12 +15,12 @@ describe('POST /user/disable-classes', () => {
let res = await user.post('/user/disable-classes');
await user.sync();
expect(res).to.eql({
data: JSON.parse(JSON.stringify({
expect(res).to.eql(JSON.parse(
JSON.stringify({
preferences: user.preferences,
stats: user.stats,
flags: user.flags,
})),
});
})
));
});
});

View File

@@ -35,8 +35,6 @@ describe('POST /user/equip/:type/:key', () => {
let res = await user.post('/user/equip/equipped/weapon_warrior_2');
await user.sync();
expect(res).to.eql({
data: JSON.parse(JSON.stringify(user.items)),
});
expect(res).to.eql(JSON.parse(JSON.stringify(user.items)));
});
});

View File

@@ -13,16 +13,12 @@ describe('POST /user/sleep', () => {
it('toggles sleep status', async () => {
let res = await user.post('/user/sleep');
expect(res).to.eql({
preferences: {sleep: true},
});
expect(res).to.eql(true);
await user.sync();
expect(user.preferences.sleep).to.be.true;
let res2 = await user.post('/user/sleep');
expect(res2).to.eql({
preferences: {sleep: false},
});
expect(res2).to.eql(false);
await user.sync();
expect(user.preferences.sleep).to.be.false;
});

View File

@@ -16,7 +16,7 @@ describe('POST /user/reset-password', async () => {
let response = await user.post(endpoint, {
email: user.auth.local.email,
});
expect(response).to.eql({ message: t('passwordReset') });
expect(response).to.eql({ data: {}, message: t('passwordReset') });
await user.sync();
expect(user.auth.local.hashed_password).to.not.eql(previousPassword);
});
@@ -25,7 +25,7 @@ describe('POST /user/reset-password', async () => {
let response = await user.post(endpoint, {
email: 'nonExistent@email.com',
});
expect(response).to.eql({ message: t('passwordReset') });
expect(response).to.eql({ data: {}, message: t('passwordReset') });
});
it('errors if email is not provided', async () => {
@@ -36,4 +36,3 @@ describe('POST /user/reset-password', async () => {
});
});
});

View File

@@ -0,0 +1,573 @@
/* eslint-disable global-require */
import moment from 'moment';
import { cron } from '../../../../../website/src/libs/api-v3/cron';
import { model as User } from '../../../../../website/src/models/user';
import * as Tasks from '../../../../../website/src/models/task';
import { clone } from 'lodash';
import common from '../../../../../common';
// const scoreTask = common.ops.scoreTask;
describe('cron', () => {
let user;
let tasksByType = {habits: [], dailys: [], todos: [], rewards: []};
let daysMissed = 0;
let analytics = {
track: sinon.spy(),
};
beforeEach(() => {
user = new User({
auth: {
local: {
username: 'username',
lowerCaseUsername: 'username',
email: 'email@email.email',
salt: 'salt',
hashed_password: 'hashed_password', // eslint-disable-line camelcase
},
},
});
user._statsComputed = {
mp: 10,
};
});
it('updates user.auth.timestamps.loggedin and lastCron', () => {
let now = new Date();
cron({user, tasksByType, daysMissed, analytics, now});
expect(user.auth.timestamps.loggedin).to.equal(now);
expect(user.lastCron).to.equal(now);
});
it('updates user.preferences.timezoneOffsetAtLastCron', () => {
let timezoneOffsetFromUserPrefs = 1;
cron({user, tasksByType, daysMissed, analytics, timezoneOffsetFromUserPrefs});
expect(user.preferences.timezoneOffsetAtLastCron).to.equal(timezoneOffsetFromUserPrefs);
});
it('resets user.items.lastDrop.count', () => {
user.items.lastDrop.count = 4;
cron({user, tasksByType, daysMissed, analytics});
expect(user.items.lastDrop.count).to.equal(0);
});
it('increments user cron count', () => {
let cronCountBefore = user.flags.cronCount;
cron({user, tasksByType, daysMissed, analytics});
expect(user.flags.cronCount).to.be.greaterThan(cronCountBefore);
});
describe('end of the month perks', () => {
beforeEach(() => {
user.purchased.plan.customerId = 'subscribedId';
user.purchased.plan.dateUpdated = moment('012013', 'MMYYYY');
});
it('resets plan.gemsBought on a new month', () => {
user.purchased.plan.gemsBought = 10;
cron({user, tasksByType, daysMissed, analytics});
expect(user.purchased.plan.gemsBought).to.equal(0);
});
it('resets plan.dateUpdated on a new month', () => {
let currentMonth = moment().format('MMYYYY');
cron({user, tasksByType, daysMissed, analytics});
expect(moment(user.purchased.plan.dateUpdated).format('MMYYYY')).to.equal(currentMonth);
});
it('increments plan.consecutive.count', () => {
user.purchased.plan.consecutive.count = 0;
cron({user, tasksByType, daysMissed, analytics});
expect(user.purchased.plan.consecutive.count).to.equal(1);
});
it('decrements plan.consecutive.offset when offset is greater than 0', () => {
user.purchased.plan.consecutive.offset = 1;
cron({user, tasksByType, daysMissed, analytics});
expect(user.purchased.plan.consecutive.offset).to.equal(0);
});
it('increments plan.consecutive.trinkets when user has reached a month that is a multiple of 3', () => {
user.purchased.plan.consecutive.count = 5;
cron({user, tasksByType, daysMissed, analytics});
expect(user.purchased.plan.consecutive.trinkets).to.equal(1);
});
it('increments plan.consecutive.gemCapExtra when user has reached a month that is a multiple of 3', () => {
user.purchased.plan.consecutive.count = 5;
cron({user, tasksByType, daysMissed, analytics});
expect(user.purchased.plan.consecutive.gemCapExtra).to.equal(5);
});
it('does not increment plan.consecutive.gemCapExtra when user has reached the gemCap limit', () => {
user.purchased.plan.consecutive.gemCapExtra = 25;
user.purchased.plan.consecutive.count = 5;
cron({user, tasksByType, daysMissed, analytics});
expect(user.purchased.plan.consecutive.gemCapExtra).to.equal(25);
});
it('does not reset plan stats if we are before the last day of the cancelled month', () => {
user.purchased.plan.dateTerminated = moment(new Date()).add({days: 1});
cron({user, tasksByType, daysMissed, analytics});
expect(user.purchased.plan.customerId).to.exist;
});
it('does reset plan stats until we are after the last day of the cancelled month', () => {
user.purchased.plan.dateTerminated = moment(new Date()).subtract({days: 1});
user.purchased.plan.consecutive.gemCapExtra = 20;
user.purchased.plan.consecutive.count = 5;
user.purchased.plan.consecutive.offset = 1;
cron({user, tasksByType, daysMissed, analytics});
expect(user.purchased.plan.customerId).to.not.exist;
expect(user.purchased.plan.consecutive.gemCapExtra).to.be.empty;
expect(user.purchased.plan.consecutive.count).to.be.empty;
expect(user.purchased.plan.consecutive.offset).to.be.empty;
});
});
describe('end of the month perks when user is not subscribed', () => {
it('does not reset plan.gemsBought on a new month', () => {
user.purchased.plan.gemsBought = 10;
cron({user, tasksByType, daysMissed, analytics});
expect(user.purchased.plan.gemsBought).to.equal(10);
});
it('does not reset plan.dateUpdated on a new month', () => {
cron({user, tasksByType, daysMissed, analytics});
expect(user.purchased.plan.dateUpdated).to.be.empty;
});
it('does not increment plan.consecutive.count', () => {
user.purchased.plan.consecutive.count = 0;
cron({user, tasksByType, daysMissed, analytics});
expect(user.purchased.plan.consecutive.count).to.equal(0);
});
it('does not decrement plan.consecutive.offset when offset is greater than 0', () => {
user.purchased.plan.consecutive.offset = 1;
cron({user, tasksByType, daysMissed, analytics});
expect(user.purchased.plan.consecutive.offset).to.equal(1);
});
it('does not increment plan.consecutive.trinkets when user has reached a month that is a multiple of 3', () => {
user.purchased.plan.consecutive.count = 5;
cron({user, tasksByType, daysMissed, analytics});
expect(user.purchased.plan.consecutive.trinkets).to.equal(0);
});
it('doest not increment plan.consecutive.gemCapExtra when user has reached a month that is a multiple of 3', () => {
user.purchased.plan.consecutive.count = 5;
cron({user, tasksByType, daysMissed, analytics});
expect(user.purchased.plan.consecutive.gemCapExtra).to.equal(0);
});
it('does not increment plan.consecutive.gemCapExtra when user has reached the gemCap limit', () => {
user.purchased.plan.consecutive.gemCapExtra = 25;
user.purchased.plan.consecutive.count = 5;
cron({user, tasksByType, daysMissed, analytics});
expect(user.purchased.plan.consecutive.gemCapExtra).to.equal(25);
});
it('does nothing to plan stats if we are before the last day of the cancelled month', () => {
user.purchased.plan.dateTerminated = moment(new Date()).add({days: 1});
cron({user, tasksByType, daysMissed, analytics});
expect(user.purchased.plan.customerId).to.not.exist;
});
xit('does nothing to plan stats when we are after the last day of the cancelled month', () => {
user.purchased.plan.dateTerminated = moment(new Date()).subtract({days: 1});
user.purchased.plan.consecutive.gemCapExtra = 20;
user.purchased.plan.consecutive.count = 5;
user.purchased.plan.consecutive.offset = 1;
cron({user, tasksByType, daysMissed, analytics});
expect(user.purchased.plan.customerId).to.exist;
expect(user.purchased.plan.consecutive.gemCapExtra).to.exist;
expect(user.purchased.plan.consecutive.count).to.exist;
expect(user.purchased.plan.consecutive.offset).to.exist;
});
});
describe('user is sleeping', () => {
beforeEach(() => {
user.preferences.sleep = true;
});
it('clears user buffs', () => {
user.stats.buffs = {
str: 1,
int: 1,
per: 1,
con: 1,
stealth: 1,
streaks: true,
};
cron({user, tasksByType, daysMissed, analytics});
expect(user.stats.buffs.str).to.equal(0);
expect(user.stats.buffs.int).to.equal(0);
expect(user.stats.buffs.per).to.equal(0);
expect(user.stats.buffs.con).to.equal(0);
expect(user.stats.buffs.stealth).to.equal(0);
expect(user.stats.buffs.streaks).to.be.false;
});
it('resets all dailies without damaging user', () => {
let daily = {
text: 'test daily',
type: 'daily',
frequency: 'daily',
everyX: 5,
startDate: new Date(),
};
let task = new Tasks.daily(Tasks.Task.sanitize(daily)); // eslint-disable-line babel/new-cap
tasksByType.dailys.push(task);
tasksByType.dailys[0].completed = true;
let healthBefore = user.stats.hp;
cron({user, tasksByType, daysMissed, analytics});
expect(tasksByType.dailys[0].completed).to.be.false;
expect(user.stats.hp).to.equal(healthBefore);
});
});
describe('todos', () => {
beforeEach(() => {
let todo = {
text: 'test todo',
type: 'todo',
value: 0,
};
let task = new Tasks.todo(Tasks.Task.sanitize(todo)); // eslint-disable-line babel/new-cap
tasksByType.todos.push(task);
});
it('should make uncompleted todos redder', () => {
let valueBefore = tasksByType.todos[0].value;
cron({user, tasksByType, daysMissed, analytics});
expect(tasksByType.todos[0].value).to.be.lessThan(valueBefore);
});
it('should add history of completed todos to user history', () => {
tasksByType.todos[0].completed = true;
cron({user, tasksByType, daysMissed, analytics});
expect(user.history.todos).to.be.lengthOf(1);
});
});
describe('dailys', () => {
beforeEach(() => {
let daily = {
text: 'test daily',
type: 'daily',
};
let task = new Tasks.daily(Tasks.Task.sanitize(daily)); // eslint-disable-line babel/new-cap
tasksByType.dailys = [];
tasksByType.dailys.push(task);
user._statsComputed = {
con: 1,
};
});
it('should add history', () => {
cron({user, tasksByType, daysMissed, analytics});
expect(tasksByType.dailys[0].history).to.be.lengthOf(1);
});
it('should set tasks completed to false', () => {
tasksByType.dailys[0].completed = true;
cron({user, tasksByType, daysMissed, analytics});
expect(tasksByType.dailys[0].completed).to.be.false;
});
it('should set task checklist to completed for completed dailys', () => {
tasksByType.dailys[0].checklist.push({title: 'test', completed: false});
tasksByType.dailys[0].completed = true;
cron({user, tasksByType, daysMissed, analytics});
expect(tasksByType.dailys[0].checklist[0].completed).to.be.true;
});
it('should set task checklist to completed for dailys with scheduled misses', () => {
daysMissed = 10;
tasksByType.dailys[0].checklist.push({title: 'test', completed: false});
tasksByType.dailys[0].startDate = moment(new Date()).subtract({days: 1});
cron({user, tasksByType, daysMissed, analytics});
expect(tasksByType.dailys[0].checklist[0].completed).to.be.true;
});
it('should do damage for missing a daily', () => {
daysMissed = 1;
let hpBefore = user.stats.hp;
tasksByType.dailys[0].startDate = moment(new Date()).subtract({days: 1});
cron({user, tasksByType, daysMissed, analytics});
expect(user.stats.hp).to.be.lessThan(hpBefore);
});
it('should not do damage for missing a daily if user stealth buff is greater than or equal to days missed', () => {
daysMissed = 1;
let hpBefore = user.stats.hp;
user.stats.buffs.stealth = 2;
tasksByType.dailys[0].startDate = moment(new Date()).subtract({days: 1});
cron({user, tasksByType, daysMissed, analytics});
expect(user.stats.hp).to.equal(hpBefore);
});
it('should do less damage for missing a daily with partial completion', () => {
daysMissed = 1;
let hpBefore = user.stats.hp;
tasksByType.dailys[0].startDate = moment(new Date()).subtract({days: 1});
cron({user, tasksByType, daysMissed, analytics});
let hpDifferenceOfFullyIncompleteDaily = hpBefore - user.stats.hp;
hpBefore = user.stats.hp;
tasksByType.dailys[0].checklist.push({title: 'test', completed: true});
tasksByType.dailys[0].checklist.push({title: 'test2', completed: false});
cron({user, tasksByType, daysMissed, analytics});
let hpDifferenceOfPartiallyIncompleteDaily = hpBefore - user.stats.hp;
expect(hpDifferenceOfPartiallyIncompleteDaily).to.be.lessThan(hpDifferenceOfFullyIncompleteDaily);
});
it('should decrement quest progress down for missing a daily', () => {
daysMissed = 1;
tasksByType.dailys[0].startDate = moment(new Date()).subtract({days: 1});
let progress = cron({user, tasksByType, daysMissed, analytics});
expect(progress.down).to.equal(-1);
});
});
describe('habits', () => {
beforeEach(() => {
let habit = {
text: 'test habit',
type: 'habit',
};
let task = new Tasks.habit(Tasks.Task.sanitize(habit)); // eslint-disable-line babel/new-cap
tasksByType.habits = [];
tasksByType.habits.push(task);
});
it('should decrement only up value', () => {
tasksByType.habits[0].value = 1;
tasksByType.habits[0].down = false;
cron({user, tasksByType, daysMissed, analytics});
expect(tasksByType.habits[0].value).to.be.lessThan(1);
});
it('should decrement only down value', () => {
tasksByType.habits[0].value = 1;
tasksByType.habits[0].up = false;
cron({user, tasksByType, daysMissed, analytics});
expect(tasksByType.habits[0].value).to.be.lessThan(1);
});
it('should do nothing to habits with both up and down', () => {
tasksByType.habits[0].value = 1;
tasksByType.habits[0].up = true;
tasksByType.habits[0].down = true;
cron({user, tasksByType, daysMissed, analytics});
expect(tasksByType.habits[0].value).to.equal(1);
});
});
describe('perfect day', () => {
beforeEach(() => {
let daily = {
text: 'test daily',
type: 'daily',
};
let task = new Tasks.daily(Tasks.Task.sanitize(daily)); // eslint-disable-line babel/new-cap
tasksByType.dailys = [];
tasksByType.dailys.push(task);
user._statsComputed = {
con: 1,
};
});
it('stores a new entry in user.history.exp', () => {
user.stats.lvl = 2;
cron({user, tasksByType, daysMissed, analytics});
expect(user.history.exp).to.have.lengthOf(1);
expect(user.history.exp[0].value).to.equal(150);
});
it('increments perfect day achievement', () => {
tasksByType.dailys[0].completed = true;
cron({user, tasksByType, daysMissed, analytics});
expect(user.achievements.perfect).to.equal(1);
});
it('increments user buffs if they have a perfect day', () => {
tasksByType.dailys[0].completed = true;
let previousBuffs = clone(user.stats.buffs);
cron({user, tasksByType, daysMissed, analytics});
expect(user.stats.buffs.str).to.be.greaterThan(previousBuffs.str);
expect(user.stats.buffs.int).to.be.greaterThan(previousBuffs.int);
expect(user.stats.buffs.per).to.be.greaterThan(previousBuffs.per);
expect(user.stats.buffs.con).to.be.greaterThan(previousBuffs.con);
});
it('clears buffs if user does not have a perfect day', () => {
daysMissed = 1;
tasksByType.dailys[0].completed = false;
tasksByType.dailys[0].startDate = moment(new Date()).subtract({days: 1});
user.stats.buffs = {
str: 1,
int: 1,
per: 1,
con: 1,
stealth: 0,
streaks: true,
};
cron({user, tasksByType, daysMissed, analytics});
expect(user.stats.buffs.str).to.equal(0);
expect(user.stats.buffs.int).to.equal(0);
expect(user.stats.buffs.per).to.equal(0);
expect(user.stats.buffs.con).to.equal(0);
expect(user.stats.buffs.stealth).to.equal(0);
expect(user.stats.buffs.streaks).to.be.false;
});
});
describe('adding mp', () => {
it('should add mp to user', () => {
let mpBefore = user.stats.mp;
tasksByType.dailys[0].completed = true;
user._statsComputed.maxMP = 100;
cron({user, tasksByType, daysMissed, analytics});
expect(user.stats.mp).to.be.greaterThan(mpBefore);
});
it('set user\'s mp to user._statsComputed.maxMP when user.stats.mp is greater', () => {
user.stats.mp = 120;
user._statsComputed.maxMP = 100;
cron({user, tasksByType, daysMissed, analytics});
expect(user.stats.mp).to.equal(user._statsComputed.maxMP);
});
});
describe('quest progress', () => {
beforeEach(() => {
let daily = {
text: 'test daily',
type: 'daily',
};
let task = new Tasks.daily(Tasks.Task.sanitize(daily)); // eslint-disable-line babel/new-cap
tasksByType.dailys = [];
tasksByType.dailys.push(task);
user._statsComputed = {
con: 1,
};
daysMissed = 1;
tasksByType.dailys[0].startDate = moment(new Date()).subtract({days: 1});
});
it('resets user progress', () => {
cron({user, tasksByType, daysMissed, analytics});
expect(user.party.quest.progress.up).to.equal(0);
expect(user.party.quest.progress.down).to.equal(0);
expect(user.party.quest.progress.collect).to.be.empty;
});
it('applies the user progress', () => {
let progress = cron({user, tasksByType, daysMissed, analytics});
expect(progress.down).to.equal(-1);
});
});
describe('private messages', () => {
let lastMessageId;
beforeEach(() => {
let maxPMs = 200;
for (let index = 0; index < maxPMs - 1; index += 1) {
let messageId = common.uuid();
user.inbox.messages[messageId] = {
id: messageId,
text: `test ${index}`,
timestamp: Number(new Date()),
likes: {},
flags: {},
flagCount: 0,
};
}
lastMessageId = common.uuid();
user.inbox.messages[lastMessageId] = {
id: lastMessageId,
text: `test ${lastMessageId}`,
timestamp: Number(new Date()),
likes: {},
flags: {},
flagCount: 0,
};
});
xit('does not clear pms under 200', () => {
cron({user, tasksByType, daysMissed, analytics});
expect(user.inbox.messages[lastMessageId]).to.exist;
});
xit('clears pms over 200', () => {
let messageId = common.uuid();
user.inbox.messages[messageId] = {
id: messageId,
text: `test ${messageId}`,
timestamp: Number(new Date()),
likes: {},
flags: {},
flagCount: 0,
};
cron({user, tasksByType, daysMissed, analytics});
expect(user.inbox.messages[messageId]).to.not.exist;
});
});
});

View File

@@ -0,0 +1,176 @@
import {
generateRes,
generateReq,
generateNext,
generateTodo,
generateDaily,
} from '../../../../helpers/api-unit.helper';
import cronMiddleware from '../../../../../website/src/middlewares/api-v3/cron';
import moment from 'moment';
import { model as User } from '../../../../../website/src/models/user';
import { model as Group } from '../../../../../website/src/models/group';
import * as Tasks from '../../../../../website/src/models/task';
import analyticsService from '../../../../../website/src/libs/api-v3/analyticsService';
import { v4 as generateUUID } from 'uuid';
describe('cron middleware', () => {
let res, req, next;
let user;
beforeEach(() => {
res = generateRes();
req = generateReq();
next = generateNext();
user = new User({
auth: {
local: {
username: 'username',
lowerCaseUsername: 'username',
email: 'email@email.email',
salt: 'salt',
hashed_password: 'hashed_password', // eslint-disable-line camelcase
},
},
});
user._statsComputed = {
mp: 10,
maxMP: 100,
};
res.locals.user = user;
res.analytics = analyticsService;
});
it('calls next when user is not attached', () => {
res.locals.user = null;
cronMiddleware(req, res, next);
expect(next).to.be.calledOnce;
});
it('calls next when days have not been missed', () => {
cronMiddleware(req, res, next);
expect(next).to.be.calledOnce;
});
it('should clear todos older than 30 days for free users', async (done) => {
user.lastCron = moment(new Date()).subtract({days: 2});
let task = generateTodo(user);
task.dateCompleted = moment(new Date()).subtract({days: 31});
task.completed = true;
await task.save();
cronMiddleware(req, res, () => {
Tasks.Task.findOne({_id: task}, function (err, taskFound) {
expect(err).to.not.exist;
expect(taskFound).to.not.exist;
done();
});
});
});
it('should not clear todos older than 30 days for subscribed users', (done) => {
user.purchased.plan.customerId = 'subscribedId';
user.purchased.plan.dateUpdated = moment('012013', 'MMYYYY');
user.lastCron = moment(new Date()).subtract({days: 2});
let task = generateTodo(user);
task.dateCompleted = moment(new Date()).subtract({days: 31});
task.completed = true;
task.save();
cronMiddleware(req, res, () => {
Tasks.Task.findOne({_id: task}, function (err, taskFound) {
expect(err).to.not.exist;
expect(taskFound).to.exist;
done();
});
});
});
it('should clear todos older than 90 days for subscribed users', (done) => {
user.purchased.plan.customerId = 'subscribedId';
user.purchased.plan.dateUpdated = moment('012013', 'MMYYYY');
user.lastCron = moment(new Date()).subtract({days: 2});
let task = generateTodo(user);
task.dateCompleted = moment(new Date()).subtract({days: 91});
task.completed = true;
task.save();
cronMiddleware(req, res, () => {
Tasks.Task.findOne({_id: task}, function (err, taskFound) {
expect(err).to.not.exist;
expect(taskFound).to.not.exist;
done();
});
});
});
it('should call next is user was not modified after cron', (done) => {
let hpBefore = user.stats.hp;
user.lastCron = moment(new Date()).subtract({days: 2});
generateDaily(user);
cronMiddleware(req, res, () => {
expect(user.stats.hp).to.be.equal(hpBefore);
done();
});
});
it('does damage for missing dailies', (done) => {
let hpBefore = user.stats.hp;
user.lastCron = moment(new Date()).subtract({days: 2});
let daily = generateDaily(user);
daily.startDate = moment(new Date()).subtract({days: 2});
daily.save();
cronMiddleware(req, res, () => {
expect(user.stats.hp).to.be.lessThan(hpBefore);
done();
});
});
it('updates tasks', (done) => {
user.lastCron = moment(new Date()).subtract({days: 2});
let todo = generateTodo(user);
let todoValueBefore = todo.value;
cronMiddleware(req, res, () => {
Tasks.Task.findOne({_id: todo._id}, function (err, todoFound) {
expect(err).to.not.exist;
expect(todoFound.value).to.be.lessThan(todoValueBefore);
done();
});
});
});
it('applies quest progress', async (done) => {
let hpBefore = user.stats.hp;
user.lastCron = moment(new Date()).subtract({days: 2});
let daily = generateDaily(user);
daily.startDate = moment(new Date()).subtract({days: 2});
daily.save();
let questKey = 'dilatory';
user.party.quest.key = questKey;
let party = new Group({
type: 'party',
name: generateUUID(),
leader: user._id,
});
party.quest.members[user._id] = true;
party.quest.key = questKey;
await party.save();
user.party._id = party._id;
await user.save();
party.startQuest(user);
cronMiddleware(req, res, () => {
expect(user.stats.hp).to.be.lessThan(hpBefore);
done();
});
});
});

View File

@@ -35,6 +35,21 @@ describe('response middleware', () => {
});
});
it('can be passed a third parameter to be used as optional message', () => {
responseMiddleware(req, res, next);
res.respond(200, {field: 1}, 'hello');
expect(res.status).to.be.calledOnce;
expect(res.json).to.be.calledOnce;
expect(res.status).to.be.calledWith(200);
expect(res.json).to.be.calledWith({
success: true,
data: {field: 1},
message: 'hello',
});
});
it('treats status >= 400 as failures', () => {
responseMiddleware(req, res, next);
res.respond(403, {field: 1});

View File

@@ -110,7 +110,7 @@ describe('Challenge Model', () => {
};
Tasks.Task.sanitize(req.body);
_.assign(task, common.ops.updateTask(task.toObject(), req));
_.assign(task, common.ops.updateTask(task.toObject(), req)[0]);
await challenge.updateTask(task);