Merge branch 'develop' into release

This commit is contained in:
SabreCat
2017-09-28 16:02:47 +00:00
2213 changed files with 121882 additions and 101395 deletions
@@ -48,8 +48,10 @@ describe('GET /challenges/:challengeId', () => {
});
expect(chal.group).to.eql({
_id: group._id,
categories: [],
id: group.id,
name: group.name,
summary: group.name,
type: group.type,
privacy: group.privacy,
leader: groupLeader.id,
@@ -100,8 +102,10 @@ describe('GET /challenges/:challengeId', () => {
});
expect(chal.group).to.eql({
_id: group._id,
categories: [],
id: group.id,
name: group.name,
summary: group.name,
type: group.type,
privacy: group.privacy,
leader: groupLeader.id,
@@ -153,7 +157,9 @@ describe('GET /challenges/:challengeId', () => {
expect(chal.group).to.eql({
_id: group._id,
id: group.id,
categories: [],
name: group.name,
summary: group.name,
type: group.type,
privacy: group.privacy,
leader: groupLeader.id,
@@ -41,10 +41,12 @@ describe('GET challenges/user', () => {
});
expect(foundChallenge.group).to.eql({
_id: publicGuild._id,
categories: [],
id: publicGuild._id,
type: publicGuild.type,
privacy: publicGuild.privacy,
name: publicGuild.name,
summary: publicGuild.name,
leader: publicGuild.leader._id,
});
});
@@ -61,10 +63,12 @@ describe('GET challenges/user', () => {
});
expect(foundChallenge1.group).to.eql({
_id: publicGuild._id,
categories: [],
id: publicGuild._id,
type: publicGuild.type,
privacy: publicGuild.privacy,
name: publicGuild.name,
summary: publicGuild.name,
leader: publicGuild.leader._id,
});
let foundChallenge2 = _.find(challenges, { _id: challenge2._id });
@@ -76,10 +80,12 @@ describe('GET challenges/user', () => {
});
expect(foundChallenge2.group).to.eql({
_id: publicGuild._id,
categories: [],
id: publicGuild._id,
type: publicGuild.type,
privacy: publicGuild.privacy,
name: publicGuild.name,
summary: publicGuild.name,
leader: publicGuild.leader._id,
});
});
@@ -96,10 +102,12 @@ describe('GET challenges/user', () => {
});
expect(foundChallenge1.group).to.eql({
_id: publicGuild._id,
categories: [],
id: publicGuild._id,
type: publicGuild.type,
privacy: publicGuild.privacy,
name: publicGuild.name,
summary: publicGuild.name,
leader: publicGuild.leader._id,
});
let foundChallenge2 = _.find(challenges, { _id: challenge2._id });
@@ -111,14 +119,26 @@ describe('GET challenges/user', () => {
});
expect(foundChallenge2.group).to.eql({
_id: publicGuild._id,
categories: [],
id: publicGuild._id,
type: publicGuild.type,
privacy: publicGuild.privacy,
name: publicGuild.name,
summary: publicGuild.name,
leader: publicGuild.leader._id,
});
});
it('should return not return challenges in user groups if we send member true param', async () => {
let challenges = await member.get(`/challenges/user?member=${true}`);
let foundChallenge1 = _.find(challenges, { _id: challenge._id });
expect(foundChallenge1).to.not.exist;
let foundChallenge2 = _.find(challenges, { _id: challenge2._id });
expect(foundChallenge2).to.not.exist;
});
it('should return newest challenges first', async () => {
let challenges = await user.get('/challenges/user');
@@ -137,6 +157,7 @@ describe('GET challenges/user', () => {
let { group, groupLeader } = await createAndPopulateGroup({
groupDetails: {
name: 'TestPrivateGuild',
summary: 'summary for TestPrivateGuild',
type: 'guild',
privacy: 'private',
},
@@ -158,6 +179,7 @@ describe('GET challenges/user', () => {
let { group, groupLeader } = await createAndPopulateGroup({
groupDetails: {
name: 'TestGuild',
summary: 'summary for TestGuild',
type: 'guild',
privacy: 'public',
},
@@ -224,7 +224,7 @@ describe('POST /chat', () => {
color: 'danger',
author_name: `${user.profile.name} - ${user.auth.local.email} - ${user._id}`,
title: 'Slur in Test Guild',
title_link: `${BASE_URL}/#/options/groups/guilds/${groupWithChat.id}`,
title_link: `${BASE_URL}/groups/guild/${groupWithChat.id}`,
text: testSlurMessage,
// footer: sandbox.match(/<.*?groupId=group-id&chatId=chat-id\|Flag this message>/),
mrkdwn_in: [
@@ -0,0 +1,32 @@
import {
generateUser,
generateGroup,
} from '../../../../helpers/api-v3-integration.helper';
describe('GET /group-plans', () => {
let user;
let groupPlan;
before(async () => {
user = await generateUser({balance: 4});
groupPlan = await generateGroup(user,
{
name: 'public guild - is member',
type: 'guild',
privacy: 'public',
},
{
purchased: {
plan: {
customerId: 'existings',
},
},
});
});
it('returns group plans for the user', async () => {
let groupPlans = await user.get('/group-plans');
expect(groupPlans[0]._id).to.eql(groupPlan._id);
});
});
@@ -6,7 +6,7 @@ import superagent from 'superagent';
import nconf from 'nconf';
const API_TEST_SERVER_PORT = nconf.get('PORT');
describe('GET /qr-code/user/:memberId', () => {
xdescribe('GET /qr-code/user/:memberId', () => {
let user;
before(async () => {
@@ -13,7 +13,7 @@ describe('GET /tasks/user', () => {
it('returns all user\'s tasks', async () => {
let createdTasks = await user.post('/tasks/user', [{text: 'test habit', type: 'habit'}, {text: 'test todo', type: 'todo'}]);
let tasks = await user.get('/tasks/user');
expect(tasks.length).to.equal(createdTasks.length + 1); // + 1 because 1 is a default task
expect(tasks.length).to.equal(createdTasks.length + 1); // Plus one for generated todo
});
it('returns only a type of user\'s tasks if req.query.type is specified', async () => {
@@ -95,7 +95,7 @@ describe('POST /tasks/unlink-all/:challengeId', () => {
// Have the leader delete the challenge and unlink the tasks
await user.del(`/challenges/${challenge._id}`);
await user.post(`/tasks/unlink-all/${challenge._id}?keep=keep-all`);
// Get the second task for the second user
// Get the task for the second user
const [, anotherUserTask] = await anotherUser.get('/tasks/user');
// Expect the second user to still have the task, but unlinked
expect(anotherUserTask.challenge).to.eql({
@@ -106,4 +106,4 @@ describe('POST /tasks/unlink-all/:challengeId', () => {
winner: null,
});
});
});
});
@@ -131,7 +131,7 @@ describe('POST /tasks/user', () => {
expect(task.updatedAt).not.to.equal('tomorrow');
expect(task.challenge).not.to.equal('no');
expect(task.completed).to.equal(false);
expect(task.streak).not.to.equal('never');
expect(task.dateCompleted).not.to.equal('never');
expect(task.value).not.to.equal(324);
expect(task.yesterDaily).to.equal(true);
});
@@ -86,6 +86,12 @@ describe('DELETE /user', () => {
});
it('deletes the user\'s tasks', async () => {
await user.post('/tasks/user', {
text: 'test habit',
type: 'habit',
});
await user.sync();
// gets the user's tasks ids
let ids = [];
each(user.tasksOrder, (idsForOrder) => {
@@ -82,7 +82,7 @@ describe('GET /user/anonymized', () => {
});
// tasks
expect(tasks2).to.exist;
expect(tasks2.length).to.eql(5); // +1 because generateUser() assigns one todo
expect(tasks2.length).to.eql(5);
expect(tasks2[0].checklist).to.exist;
_.forEach(tasks2, (task) => {
expect(task.text).to.eql('task text');
@@ -10,43 +10,31 @@ import nconf from 'nconf';
const API_TEST_SERVER_PORT = nconf.get('PORT');
describe('GET /user/auth/local/reset-password-set-new-one', () => {
// @TODO skipped because on travis the client isn't available and the redirect fails
xdescribe('GET /user/auth/local/reset-password-set-new-one', () => {
let endpoint = `http://localhost:${API_TEST_SERVER_PORT}/static/user/auth/local/reset-password-set-new-one`;
// Tests to validate the validatePasswordResetCodeAndFindUser function
it('renders an error page if the code is missing', async () => {
try {
await superagent.get(endpoint);
throw new Error('Request should fail.');
} catch (err) {
expect(err.status).to.equal(401);
}
const res = await superagent.get(endpoint);
expect(res.req.path.indexOf('hasError=true') !== -1).to.equal(true);
});
it('renders an error page if the code is invalid json', async () => {
try {
await superagent.get(`${endpoint}?code=invalid`);
throw new Error('Request should fail.');
} catch (err) {
expect(err.status).to.equal(401);
}
const res = await superagent.get(`${endpoint}?code=invalid`);
expect(res.req.path.indexOf('hasError=true') !== -1).to.equal(true);
});
it('renders an error page if the code cannot be decrypted', async () => {
let user = await generateUser();
try {
let code = JSON.stringify({ // not encrypted
userId: user._id,
expiresAt: new Date(),
});
await superagent.get(`${endpoint}?code=${code}`);
throw new Error('Request should fail.');
} catch (err) {
expect(err.status).to.equal(401);
}
let code = JSON.stringify({ // not encrypted
userId: user._id,
expiresAt: new Date(),
});
const res = await superagent.get(`${endpoint}?code=${code}`);
expect(res.req.path.indexOf('hasError=true') !== -1).to.equal(true);
});
it('renders an error page if the code is expired', async () => {
@@ -60,12 +48,8 @@ describe('GET /user/auth/local/reset-password-set-new-one', () => {
'auth.local.passwordResetCode': code,
});
try {
await superagent.get(`${endpoint}?code=${code}`);
throw new Error('Request should fail.');
} catch (err) {
expect(err.status).to.equal(401);
}
const res = await superagent.get(`${endpoint}?code=${code}`);
expect(res.req.path.indexOf('hasError=true') !== -1).to.equal(true);
});
it('renders an error page if the user does not exist', async () => {
@@ -74,12 +58,8 @@ describe('GET /user/auth/local/reset-password-set-new-one', () => {
expiresAt: moment().add({days: 1}),
}));
try {
await superagent.get(`${endpoint}?code=${code}`);
throw new Error('Request should fail.');
} catch (err) {
expect(err.status).to.equal(401);
}
const res = await superagent.get(`${endpoint}?code=${code}`);
expect(res.req.path.indexOf('hasError=true') !== -1).to.equal(true);
});
it('renders an error page if the user has no local auth', async () => {
@@ -93,12 +73,8 @@ describe('GET /user/auth/local/reset-password-set-new-one', () => {
auth: 'not an object with valid fields',
});
try {
await superagent.get(`${endpoint}?code=${code}`);
throw new Error('Request should fail.');
} catch (err) {
expect(err.status).to.equal(401);
}
const res = await superagent.get(`${endpoint}?code=${code}`);
expect(res.req.path.indexOf('hasError=true') !== -1).to.equal(true);
});
it('renders an error page if the code doesn\'t match the one saved at user.auth.passwordResetCode', async () => {
@@ -112,12 +88,8 @@ describe('GET /user/auth/local/reset-password-set-new-one', () => {
'auth.local.passwordResetCode': 'invalid',
});
try {
await superagent.get(`${endpoint}?code=${code}`);
throw new Error('Request should fail.');
} catch (err) {
expect(err.status).to.equal(401);
}
const res = await superagent.get(`${endpoint}?code=${code}`);
expect(res.req.path.indexOf('hasError=true') !== -1).to.equal(true);
});
//
@@ -134,7 +106,8 @@ describe('GET /user/auth/local/reset-password-set-new-one', () => {
});
let res = await superagent.get(`${endpoint}?code=${code}`);
expect(res.status).to.equal(200);
expect(res.req.path.indexOf('hasError=false') !== -1).to.equal(true);
expect(res.req.path.indexOf('code=') !== -1).to.equal(true);
});
});
@@ -10,49 +10,46 @@ import {
import moment from 'moment';
import {
generateUser,
requester,
translate as t,
} from '../../../../../helpers/api-integration/v3';
import superagent from 'superagent';
import nconf from 'nconf';
const API_TEST_SERVER_PORT = nconf.get('PORT');
describe('POST /user/auth/local/reset-password-set-new-one', () => {
let endpoint = `http://localhost:${API_TEST_SERVER_PORT}/static/user/auth/local/reset-password-set-new-one`;
describe('POST /user/auth/reset-password-set-new-one', () => {
const endpoint = '/user/auth/reset-password-set-new-one';
const api = requester();
// Tests to validate the validatePasswordResetCodeAndFindUser function
it('renders an error page if the code is missing', async () => {
try {
await superagent.post(endpoint);
throw new Error('Request should fail.');
} catch (err) {
expect(err.status).to.equal(401);
}
await expect(api.post(endpoint)).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('invalidPasswordResetCode'),
});
});
it('renders an error page if the code is invalid json', async () => {
try {
await superagent.post(`${endpoint}?code=invalid`);
throw new Error('Request should fail.');
} catch (err) {
expect(err.status).to.equal(401);
}
await expect(api.post(`${endpoint}?code=invalid`)).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('invalidPasswordResetCode'),
});
});
it('renders an error page if the code cannot be decrypted', async () => {
let user = await generateUser();
try {
let code = JSON.stringify({ // not encrypted
userId: user._id,
expiresAt: new Date(),
});
await superagent.post(`${endpoint}?code=${code}`);
let code = JSON.stringify({ // not encrypted
userId: user._id,
expiresAt: new Date(),
});
throw new Error('Request should fail.');
} catch (err) {
expect(err.status).to.equal(401);
}
await expect(api.post(`${endpoint}`, {
code,
})).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('invalidPasswordResetCode'),
});
});
it('renders an error page if the code is expired', async () => {
@@ -66,12 +63,13 @@ describe('POST /user/auth/local/reset-password-set-new-one', () => {
'auth.local.passwordResetCode': code,
});
try {
await superagent.post(`${endpoint}?code=${code}`);
throw new Error('Request should fail.');
} catch (err) {
expect(err.status).to.equal(401);
}
await expect(api.post(`${endpoint}`, {
code,
})).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('invalidPasswordResetCode'),
});
});
it('renders an error page if the user does not exist', async () => {
@@ -80,12 +78,13 @@ describe('POST /user/auth/local/reset-password-set-new-one', () => {
expiresAt: moment().add({days: 1}),
}));
try {
await superagent.post(`${endpoint}?code=${code}`);
throw new Error('Request should fail.');
} catch (err) {
expect(err.status).to.equal(401);
}
await expect(api.post(`${endpoint}`, {
code,
})).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('invalidPasswordResetCode'),
});
});
it('renders an error page if the user has no local auth', async () => {
@@ -99,12 +98,13 @@ describe('POST /user/auth/local/reset-password-set-new-one', () => {
auth: 'not an object with valid fields',
});
try {
await superagent.post(`${endpoint}?code=${code}`);
throw new Error('Request should fail.');
} catch (err) {
expect(err.status).to.equal(401);
}
await expect(api.post(`${endpoint}`, {
code,
})).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('invalidPasswordResetCode'),
});
});
it('renders an error page if the code doesn\'t match the one saved at user.auth.passwordResetCode', async () => {
@@ -118,12 +118,13 @@ describe('POST /user/auth/local/reset-password-set-new-one', () => {
'auth.local.passwordResetCode': 'invalid',
});
try {
await superagent.post(`${endpoint}?code=${code}`);
throw new Error('Request should fail.');
} catch (err) {
expect(err.status).to.equal(401);
}
await expect(api.post(`${endpoint}`, {
code,
})).to.eventually.be.rejected.and.eql({
code: 401,
error: 'NotAuthorized',
message: t('invalidPasswordResetCode'),
});
});
//
@@ -139,12 +140,13 @@ describe('POST /user/auth/local/reset-password-set-new-one', () => {
'auth.local.passwordResetCode': code,
});
try {
await superagent.post(`${endpoint}?code=${code}`);
throw new Error('Request should fail.');
} catch (err) {
expect(err.status).to.equal(401);
}
await expect(api.post(`${endpoint}`, {
code,
})).to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
message: t('invalidReqParams'),
});
});
it('renders the error page if the password confirmation is missing', async () => {
@@ -158,14 +160,14 @@ describe('POST /user/auth/local/reset-password-set-new-one', () => {
'auth.local.passwordResetCode': code,
});
try {
await superagent
.post(`${endpoint}?code=${code}`)
.send({newPassword: 'my new password'});
throw new Error('Request should fail.');
} catch (err) {
expect(err.status).to.equal(401);
}
await expect(api.post(`${endpoint}`, {
newPassword: 'my new password',
code,
})).to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
message: t('invalidReqParams'),
});
});
it('renders the error page if the password confirmation does not match', async () => {
@@ -179,17 +181,15 @@ describe('POST /user/auth/local/reset-password-set-new-one', () => {
'auth.local.passwordResetCode': code,
});
try {
await superagent
.post(`${endpoint}?code=${code}`)
.send({
newPassword: 'my new password',
confirmPassword: 'not matching',
});
throw new Error('Request should fail.');
} catch (err) {
expect(err.status).to.equal(401);
}
await expect(api.post(`${endpoint}`, {
newPassword: 'my new password',
confirmPassword: 'not matching',
code,
})).to.eventually.be.rejected.and.eql({
code: 400,
error: 'BadRequest',
message: t('passwordConfirmationMatch'),
});
});
it('renders the success page and save the user', async () => {
@@ -203,14 +203,13 @@ describe('POST /user/auth/local/reset-password-set-new-one', () => {
'auth.local.passwordResetCode': code,
});
let res = await superagent
.post(`${endpoint}?code=${code}`)
.send({
newPassword: 'my new password',
confirmPassword: 'my new password',
});
let res = await api.post(`${endpoint}`, {
newPassword: 'my new password',
confirmPassword: 'my new password',
code,
});
expect(res.status).to.equal(200);
expect(res.message).to.equal(t('passwordChangeSuccess'));
await user.sync();
expect(user.auth.local.passwordResetCode).to.equal(undefined);
@@ -246,14 +245,13 @@ describe('POST /user/auth/local/reset-password-set-new-one', () => {
'auth.local.passwordResetCode': code,
});
let res = await superagent
.post(`${endpoint}?code=${code}`)
.send({
newPassword: 'my new password',
confirmPassword: 'my new password',
});
let res = await api.post(`${endpoint}`, {
newPassword: 'my new password',
confirmPassword: 'my new password',
code,
});
expect(res.status).to.equal(200);
expect(res.message).to.equal(t('passwordChangeSuccess'));
await user.sync();
expect(user.auth.local.passwordResetCode).to.equal(undefined);
@@ -59,13 +59,8 @@ describe('POST /user/auth/local/register', () => {
let tags = await requests.get('/tags');
expect(habits).to.have.a.lengthOf(0);
expect(dailys).to.have.a.lengthOf(0);
expect(todos).to.have.a.lengthOf(1);
expect(todos[0].text).to.eql(t('defaultTodo1Text'));
expect(todos[0].notes).to.eql(t('defaultTodoNotes'));
expect(rewards).to.have.a.lengthOf(0);
expect(tags).to.have.a.lengthOf(7);
@@ -78,7 +73,7 @@ describe('POST /user/auth/local/register', () => {
expect(tags[6].name).to.eql(t('defaultTag7'));
});
it('for Web', async () => {
xit('for Web', async () => {
api = requester(
null,
{'x-client': 'habitica-web'},
@@ -623,10 +618,10 @@ describe('POST /user/auth/local/register', () => {
confirmPassword: password,
});
expect(user.tasksOrder.todos).to.not.be.empty;
expect(user.tasksOrder.todos).to.be.empty;
expect(user.tasksOrder.dailys).to.be.empty;
expect(user.tasksOrder.habits).to.not.be.empty;
expect(user.tasksOrder.rewards).to.not.be.empty;
expect(user.tasksOrder.habits).to.be.empty;
expect(user.tasksOrder.rewards).to.be.empty;
});
it('populates user with default tags', async () => {
@@ -653,23 +648,8 @@ describe('POST /user/auth/local/register', () => {
let habits = await requests.get('/tasks/user?type=habits');
let todos = await requests.get('/tasks/user?type=todos');
function findTag (tagName) {
let tag = user.tags.find((userTag) => {
return userTag.name === t(tagName);
});
return tag.id;
}
expect(habits[0].tags).to.have.a.lengthOf(3);
expect(habits[0].tags).to.include.members(['defaultTag1', 'defaultTag4', 'defaultTag6'].map(findTag));
expect(habits[1].tags).to.have.a.lengthOf(1);
expect(habits[1].tags).to.include.members(['defaultTag3'].map(findTag));
expect(habits[2].tags).to.have.a.lengthOf(2);
expect(habits[2].tags).to.include.members(['defaultTag2', 'defaultTag3'].map(findTag));
expect(todos[0].tags).to.have.a.lengthOf(0);
expect(habits).to.have.a.lengthOf(0);
expect(todos).to.have.a.lengthOf(0);
});
});
});
+2 -2
View File
@@ -142,12 +142,12 @@ describe('emails', () => {
describe('getGroupUrl', () => {
it('returns correct url if group is the tavern', () => {
let getGroupUrl = require(pathToEmailLib).getGroupUrl;
expect(getGroupUrl({_id: TAVERN_ID, type: 'guild'})).to.eql('/#/options/groups/tavern');
expect(getGroupUrl({_id: TAVERN_ID, type: 'guild'})).to.eql('/groups/tavern');
});
it('returns correct url if group is a guild', () => {
let getGroupUrl = require(pathToEmailLib).getGroupUrl;
expect(getGroupUrl({_id: 'random _id', type: 'guild'})).to.eql('/#/options/groups/guilds/random _id');
expect(getGroupUrl({_id: 'random _id', type: 'guild'})).to.eql('/groups/guild/random _id');
});
it('returns correct url if group is a party', () => {
+2 -2
View File
@@ -71,7 +71,7 @@ describe('slack', () => {
expect(IncomingWebhook.prototype.send).to.be.calledWithMatch({
attachments: [sandbox.match({
title: 'Flag in Some group',
title_link: sandbox.match(/.*\/#\/options\/groups\/guilds\/group-id/),
title_link: sandbox.match(/.*\/groups\/guild\/group-id/),
})],
});
});
@@ -86,7 +86,7 @@ describe('slack', () => {
expect(IncomingWebhook.prototype.send).to.be.calledWithMatch({
attachments: [sandbox.match({
title: 'Flag in Tavern',
title_link: sandbox.match(/.*\/#\/options\/groups\/tavern/),
title_link: sandbox.match(/.*\/groups\/tavern/),
})],
});
});
+5 -2
View File
@@ -33,6 +33,7 @@ describe('response middleware', () => {
success: true,
data: {field: 1},
notifications: [],
userV: res.locals.user._v,
});
});
@@ -49,6 +50,7 @@ describe('response middleware', () => {
data: {field: 1},
message: 'hello',
notifications: [],
userV: res.locals.user._v,
});
});
@@ -64,12 +66,12 @@ describe('response middleware', () => {
success: false,
data: {field: 1},
notifications: [],
userV: res.locals.user._v,
});
});
it('returns userV if a user is authenticated req.query.userV is passed', () => {
it('returns userV if a user is authenticated', () => {
responseMiddleware(req, res, next);
req.query.userV = 3;
res.respond(200, {field: 1});
expect(res.json).to.be.calledOnce;
@@ -101,6 +103,7 @@ describe('response middleware', () => {
data: {},
},
],
userV: res.locals.user._v,
});
});
});