Fix 9248: challenge creator should not automatically join their own challenge (#10383)

* fix(challenges): creator should not join challenge automatically

* change behavior on the client side as well

* update tests and fix membercount

* update tests

* fix tests
This commit is contained in:
Matteo Pagliazzi
2018-05-25 12:03:39 +02:00
committed by GitHub
parent 9194e8226d
commit 6ef45a7fd2
33 changed files with 76 additions and 15 deletions

View File

@@ -41,6 +41,7 @@ describe('DELETE /challenges/:challengeId', () => {
group = populatedGroup.group; group = populatedGroup.group;
challenge = await generateChallenge(groupLeader, group); challenge = await generateChallenge(groupLeader, group);
await groupLeader.post(`/challenges/${challenge._id}/join`);
await groupLeader.post(`/tasks/challenge/${challenge._id}`, [ await groupLeader.post(`/tasks/challenge/${challenge._id}`, [
{type: 'habit', text: taskText}, {type: 'habit', text: taskText},

View File

@@ -33,9 +33,11 @@ describe('GET /challenges/:challengeId', () => {
group = populatedGroup.group; group = populatedGroup.group;
challenge = await generateChallenge(groupLeader, group); challenge = await generateChallenge(groupLeader, group);
await groupLeader.post(`/challenges/${challenge._id}/join`);
}); });
it('should return challenge data', async () => { it('should return challenge data', async () => {
await challenge.sync();
let chal = await user.get(`/challenges/${challenge._id}`); let chal = await user.get(`/challenges/${challenge._id}`);
expect(chal.memberCount).to.equal(challenge.memberCount); expect(chal.memberCount).to.equal(challenge.memberCount);
expect(chal.name).to.equal(challenge.name); expect(chal.name).to.equal(challenge.name);
@@ -80,6 +82,7 @@ describe('GET /challenges/:challengeId', () => {
challenge = await generateChallenge(groupLeader, group); challenge = await generateChallenge(groupLeader, group);
await members[0].post(`/challenges/${challenge._id}/join`); await members[0].post(`/challenges/${challenge._id}/join`);
await groupLeader.post(`/challenges/${challenge._id}/join`);
}); });
it('fails if user doesn\'t have access to the challenge', async () => { it('fails if user doesn\'t have access to the challenge', async () => {
@@ -134,6 +137,7 @@ describe('GET /challenges/:challengeId', () => {
challenge = await generateChallenge(groupLeader, group); challenge = await generateChallenge(groupLeader, group);
await members[0].post(`/challenges/${challenge._id}/join`); await members[0].post(`/challenges/${challenge._id}/join`);
await groupLeader.post(`/challenges/${challenge._id}/join`);
}); });
it('fails if user doesn\'t have access to the challenge', async () => { it('fails if user doesn\'t have access to the challenge', async () => {

View File

@@ -24,6 +24,7 @@ describe('GET /challenges/:challengeId/export/csv', () => {
members = populatedGroup.members; members = populatedGroup.members;
challenge = await generateChallenge(groupLeader, group); challenge = await generateChallenge(groupLeader, group);
await groupLeader.post(`/challenges/${challenge._id}/join`);
await members[0].post(`/challenges/${challenge._id}/join`); await members[0].post(`/challenges/${challenge._id}/join`);
await members[1].post(`/challenges/${challenge._id}/join`); await members[1].post(`/challenges/${challenge._id}/join`);
await members[2].post(`/challenges/${challenge._id}/join`); await members[2].post(`/challenges/${challenge._id}/join`);

View File

@@ -45,6 +45,7 @@ describe('GET /challenges/:challengeId/members', () => {
let leader = await generateUser({balance: 4}); let leader = await generateUser({balance: 4});
let group = await generateGroup(leader, {type: 'guild', privacy: 'public', name: generateUUID()}); let group = await generateGroup(leader, {type: 'guild', privacy: 'public', name: generateUUID()});
let challenge = await generateChallenge(leader, group); let challenge = await generateChallenge(leader, group);
await leader.post(`/challenges/${challenge._id}/join`);
let res = await user.get(`/challenges/${challenge._id}/members`); let res = await user.get(`/challenges/${challenge._id}/members`);
expect(res[0]).to.eql({ expect(res[0]).to.eql({
_id: leader._id, _id: leader._id,
@@ -59,6 +60,7 @@ describe('GET /challenges/:challengeId/members', () => {
let anotherUser = await generateUser({balance: 3}); let anotherUser = await generateUser({balance: 3});
let group = await generateGroup(anotherUser, {type: 'guild', privacy: 'public', name: generateUUID()}); let group = await generateGroup(anotherUser, {type: 'guild', privacy: 'public', name: generateUUID()});
let challenge = await generateChallenge(anotherUser, group); let challenge = await generateChallenge(anotherUser, group);
await anotherUser.post(`/challenges/${challenge._id}/join`);
let res = await user.get(`/challenges/${challenge._id}/members`); let res = await user.get(`/challenges/${challenge._id}/members`);
expect(res[0]).to.eql({ expect(res[0]).to.eql({
_id: anotherUser._id, _id: anotherUser._id,
@@ -72,6 +74,7 @@ describe('GET /challenges/:challengeId/members', () => {
it('returns only first 30 members if req.query.includeAllMembers is not true', async () => { it('returns only first 30 members if req.query.includeAllMembers is not true', async () => {
let group = await generateGroup(user, {type: 'party', name: generateUUID()}); let group = await generateGroup(user, {type: 'party', name: generateUUID()});
let challenge = await generateChallenge(user, group); let challenge = await generateChallenge(user, group);
await user.post(`/challenges/${challenge._id}/join`);
let usersToGenerate = []; let usersToGenerate = [];
for (let i = 0; i < 31; i++) { for (let i = 0; i < 31; i++) {
@@ -90,6 +93,7 @@ describe('GET /challenges/:challengeId/members', () => {
it('returns only first 30 members if req.query.includeAllMembers is not defined', async () => { it('returns only first 30 members if req.query.includeAllMembers is not defined', async () => {
let group = await generateGroup(user, {type: 'party', name: generateUUID()}); let group = await generateGroup(user, {type: 'party', name: generateUUID()});
let challenge = await generateChallenge(user, group); let challenge = await generateChallenge(user, group);
await user.post(`/challenges/${challenge._id}/join`);
let usersToGenerate = []; let usersToGenerate = [];
for (let i = 0; i < 31; i++) { for (let i = 0; i < 31; i++) {
@@ -108,6 +112,7 @@ describe('GET /challenges/:challengeId/members', () => {
it('returns all members if req.query.includeAllMembers is true', async () => { it('returns all members if req.query.includeAllMembers is true', async () => {
let group = await generateGroup(user, {type: 'party', name: generateUUID()}); let group = await generateGroup(user, {type: 'party', name: generateUUID()});
let challenge = await generateChallenge(user, group); let challenge = await generateChallenge(user, group);
await user.post(`/challenges/${challenge._id}/join`);
let usersToGenerate = []; let usersToGenerate = [];
for (let i = 0; i < 31; i++) { for (let i = 0; i < 31; i++) {
@@ -127,6 +132,7 @@ describe('GET /challenges/:challengeId/members', () => {
this.timeout(30000); // @TODO: times out after 8 seconds this.timeout(30000); // @TODO: times out after 8 seconds
let group = await generateGroup(user, {type: 'party', name: generateUUID()}); let group = await generateGroup(user, {type: 'party', name: generateUUID()});
let challenge = await generateChallenge(user, group); let challenge = await generateChallenge(user, group);
await user.post(`/challenges/${challenge._id}/join`);
let usersToGenerate = []; let usersToGenerate = [];
for (let i = 0; i < 57; i++) { for (let i = 0; i < 57; i++) {
@@ -147,6 +153,7 @@ describe('GET /challenges/:challengeId/members', () => {
it('supports using req.query.search to get search members', async () => { it('supports using req.query.search to get search members', async () => {
let group = await generateGroup(user, {type: 'party', name: generateUUID()}); let group = await generateGroup(user, {type: 'party', name: generateUUID()});
let challenge = await generateChallenge(user, group); let challenge = await generateChallenge(user, group);
await user.post(`/challenges/${challenge._id}/join`);
let usersToGenerate = []; let usersToGenerate = [];
for (let i = 0; i < 3; i++) { for (let i = 0; i < 3; i++) {

View File

@@ -50,6 +50,7 @@ describe('GET /challenges/:challengeId/members/:memberId', () => {
it('fails if user doesn\'t have access to the challenge', async () => { it('fails if user doesn\'t have access to the challenge', async () => {
let group = await generateGroup(user, {type: 'party', name: generateUUID()}); let group = await generateGroup(user, {type: 'party', name: generateUUID()});
let challenge = await generateChallenge(user, group); let challenge = await generateChallenge(user, group);
await user.post(`/challenges/${challenge._id}/join`);
let anotherUser = await generateUser(); let anotherUser = await generateUser();
let member = await generateUser(); let member = await generateUser();
await expect(anotherUser.get(`/challenges/${challenge._id}/members/${member._id}`)).to.eventually.be.rejected.and.eql({ await expect(anotherUser.get(`/challenges/${challenge._id}/members/${member._id}`)).to.eventually.be.rejected.and.eql({
@@ -62,6 +63,7 @@ describe('GET /challenges/:challengeId/members/:memberId', () => {
it('fails if member is not part of the challenge', async () => { it('fails if member is not part of the challenge', async () => {
let group = await generateGroup(user, {type: 'party', name: generateUUID()}); let group = await generateGroup(user, {type: 'party', name: generateUUID()});
let challenge = await generateChallenge(user, group); let challenge = await generateChallenge(user, group);
await user.post(`/challenges/${challenge._id}/join`);
let member = await generateUser(); let member = await generateUser();
await expect(user.get(`/challenges/${challenge._id}/members/${member._id}`)).to.eventually.be.rejected.and.eql({ await expect(user.get(`/challenges/${challenge._id}/members/${member._id}`)).to.eventually.be.rejected.and.eql({
code: 404, code: 404,
@@ -74,6 +76,7 @@ describe('GET /challenges/:challengeId/members/:memberId', () => {
let groupLeader = await generateUser({balance: 4}); let groupLeader = await generateUser({balance: 4});
let group = await generateGroup(groupLeader, {type: 'guild', privacy: 'public', name: generateUUID()}); let group = await generateGroup(groupLeader, {type: 'guild', privacy: 'public', name: generateUUID()});
let challenge = await generateChallenge(groupLeader, group); let challenge = await generateChallenge(groupLeader, group);
await groupLeader.post(`/challenges/${challenge._id}/join`);
let taskText = 'Test Text'; let taskText = 'Test Text';
await groupLeader.post(`/tasks/challenge/${challenge._id}`, [{type: 'habit', text: taskText}]); await groupLeader.post(`/tasks/challenge/${challenge._id}`, [{type: 'habit', text: taskText}]);
@@ -86,6 +89,7 @@ describe('GET /challenges/:challengeId/members/:memberId', () => {
it('returns the member tasks for the challenges', async () => { it('returns the member tasks for the challenges', async () => {
let group = await generateGroup(user, {type: 'party', name: generateUUID()}); let group = await generateGroup(user, {type: 'party', name: generateUUID()});
let challenge = await generateChallenge(user, group); let challenge = await generateChallenge(user, group);
await user.post(`/challenges/${challenge._id}/join`);
await user.post(`/tasks/challenge/${challenge._id}`, [{type: 'habit', text: 'Test Text'}]); await user.post(`/tasks/challenge/${challenge._id}`, [{type: 'habit', text: 'Test Text'}]);
let memberProgress = await user.get(`/challenges/${challenge._id}/members/${user._id}`); let memberProgress = await user.get(`/challenges/${challenge._id}/members/${user._id}`);
@@ -98,6 +102,7 @@ describe('GET /challenges/:challengeId/members/:memberId', () => {
it('returns the tasks without the tags and checklist', async () => { it('returns the tasks without the tags and checklist', async () => {
let group = await generateGroup(user, {type: 'party', name: generateUUID()}); let group = await generateGroup(user, {type: 'party', name: generateUUID()});
let challenge = await generateChallenge(user, group); let challenge = await generateChallenge(user, group);
await user.post(`/challenges/${challenge._id}/join`);
let taskText = 'Test Text'; let taskText = 'Test Text';
await user.post(`/tasks/challenge/${challenge._id}`, [{ await user.post(`/tasks/challenge/${challenge._id}`, [{
type: 'todo', type: 'todo',

View File

@@ -25,7 +25,9 @@ describe('GET challenges/groups/:groupId', () => {
nonMember = await generateUser(); nonMember = await generateUser();
challenge = await generateChallenge(user, group); challenge = await generateChallenge(user, group);
await user.post(`/challenges/${challenge._id}/join`);
challenge2 = await generateChallenge(user, group); challenge2 = await generateChallenge(user, group);
await user.post(`/challenges/${challenge2._id}/join`);
}); });
it('should return group challenges for non member with populated leader', async () => { it('should return group challenges for non member with populated leader', async () => {
@@ -73,6 +75,7 @@ describe('GET challenges/groups/:groupId', () => {
expect(foundChallengeIndex).to.eql(0); expect(foundChallengeIndex).to.eql(0);
let newChallenge = await generateChallenge(user, publicGuild); let newChallenge = await generateChallenge(user, publicGuild);
await user.post(`/challenges/${newChallenge._id}/join`);
challenges = await user.get(`/challenges/groups/${publicGuild._id}`); challenges = await user.get(`/challenges/groups/${publicGuild._id}`);
@@ -99,7 +102,9 @@ describe('GET challenges/groups/:groupId', () => {
nonMember = await generateUser(); nonMember = await generateUser();
challenge = await generateChallenge(user, group); challenge = await generateChallenge(user, group);
await user.post(`/challenges/${challenge._id}/join`);
challenge2 = await generateChallenge(user, group); challenge2 = await generateChallenge(user, group);
await user.post(`/challenges/${challenge2._id}/join`);
}); });
it('should prevent non-member from seeing challenges', async () => { it('should prevent non-member from seeing challenges', async () => {
@@ -156,9 +161,12 @@ describe('GET challenges/groups/:groupId', () => {
slug: 'habitica_official', slug: 'habitica_official',
}], }],
}); });
await user.post(`/challenges/${officialChallenge._id}/join`);
challenge = await generateChallenge(user, group); challenge = await generateChallenge(user, group);
await user.post(`/challenges/${challenge._id}/join`);
challenge2 = await generateChallenge(user, group); challenge2 = await generateChallenge(user, group);
await user.post(`/challenges/${challenge2._id}/join`);
}); });
it('should return official challenges first', async () => { it('should return official challenges first', async () => {
@@ -178,6 +186,7 @@ describe('GET challenges/groups/:groupId', () => {
expect(foundChallengeIndex).to.eql(1); expect(foundChallengeIndex).to.eql(1);
let newChallenge = await generateChallenge(user, publicGuild); let newChallenge = await generateChallenge(user, publicGuild);
await user.post(`/challenges/${newChallenge._id}/join`);
challenges = await user.get(`/challenges/groups/${publicGuild._id}`); challenges = await user.get(`/challenges/groups/${publicGuild._id}`);
@@ -203,7 +212,9 @@ describe('GET challenges/groups/:groupId', () => {
nonMember = await generateUser(); nonMember = await generateUser();
challenge = await generateChallenge(user, group); challenge = await generateChallenge(user, group);
await user.post(`/challenges/${challenge._id}/join`);
challenge2 = await generateChallenge(user, group); challenge2 = await generateChallenge(user, group);
await user.post(`/challenges/${challenge2._id}/join`);
}); });
it('should prevent non-member from seeing challenges', async () => { it('should prevent non-member from seeing challenges', async () => {
@@ -263,7 +274,9 @@ describe('GET challenges/groups/:groupId', () => {
tavern = await user.get(`/groups/${TAVERN_ID}`); tavern = await user.get(`/groups/${TAVERN_ID}`);
challenge = await generateChallenge(user, tavern, {prize: 1}); challenge = await generateChallenge(user, tavern, {prize: 1});
await user.post(`/challenges/${challenge._id}/join`);
challenge2 = await generateChallenge(user, tavern, {prize: 1}); challenge2 = await generateChallenge(user, tavern, {prize: 1});
await user.post(`/challenges/${challenge2._id}/join`);
}); });
it('should return tavern challenges with populated leader', async () => { it('should return tavern challenges with populated leader', async () => {

View File

@@ -24,7 +24,9 @@ describe('GET challenges/user', () => {
nonMember = await generateUser(); nonMember = await generateUser();
challenge = await generateChallenge(user, group); challenge = await generateChallenge(user, group);
await user.post(`/challenges/${challenge._id}/join`);
challenge2 = await generateChallenge(user, group); challenge2 = await generateChallenge(user, group);
await user.post(`/challenges/${challenge2._id}/join`);
}); });
it('should return challenges user has joined', async () => { it('should return challenges user has joined', async () => {
@@ -146,6 +148,7 @@ describe('GET challenges/user', () => {
expect(foundChallengeIndex).to.eql(0); expect(foundChallengeIndex).to.eql(0);
let newChallenge = await generateChallenge(user, publicGuild); let newChallenge = await generateChallenge(user, publicGuild);
await user.post(`/challenges/${newChallenge._id}/join`);
challenges = await user.get('/challenges/user'); challenges = await user.get('/challenges/user');
@@ -164,6 +167,7 @@ describe('GET challenges/user', () => {
}); });
let privateChallenge = await generateChallenge(groupLeader, group); let privateChallenge = await generateChallenge(groupLeader, group);
await groupLeader.post(`/challenges/${privateChallenge._id}/join`);
let challenges = await nonMember.get('/challenges/user'); let challenges = await nonMember.get('/challenges/user');
@@ -198,9 +202,12 @@ describe('GET challenges/user', () => {
slug: 'habitica_official', slug: 'habitica_official',
}], }],
}); });
await user.post(`/challenges/${officialChallenge._id}/join`);
challenge = await generateChallenge(user, group); challenge = await generateChallenge(user, group);
await user.post(`/challenges/${challenge._id}/join`);
challenge2 = await generateChallenge(user, group); challenge2 = await generateChallenge(user, group);
await user.post(`/challenges/${challenge2._id}/join`);
}); });
it('should return official challenges first', async () => { it('should return official challenges first', async () => {
@@ -220,6 +227,7 @@ describe('GET challenges/user', () => {
expect(foundChallengeIndex).to.eql(1); expect(foundChallengeIndex).to.eql(1);
let newChallenge = await generateChallenge(user, publicGuild); let newChallenge = await generateChallenge(user, publicGuild);
await user.post(`/challenges/${newChallenge._id}/join`);
challenges = await user.get('/challenges/user'); challenges = await user.get('/challenges/user');
@@ -252,12 +260,14 @@ describe('GET challenges/user', () => {
await user.update({balance: 20}); await user.update({balance: 20});
for (let i = 0; i < 11; i += 1) { for (let i = 0; i < 11; i += 1) {
await generateChallenge(user, group); // eslint-disable-line let challenge = await generateChallenge(user, group); // eslint-disable-line
await user.post(`/challenges/${challenge._id}/join`); // eslint-disable-line
} }
}); });
it('returns public guilds filtered by category', async () => { it('returns public guilds filtered by category', async () => {
const categoryChallenge = await generateChallenge(user, guild, {categories}); const categoryChallenge = await generateChallenge(user, guild, {categories});
await user.post(`/challenges/${categoryChallenge._id}/join`);
const challenges = await user.get(`/challenges/user?categories=${categories[0].slug}`); const challenges = await user.get(`/challenges/user?categories=${categories[0].slug}`);
expect(challenges[0]._id).to.eql(categoryChallenge._id); expect(challenges[0]._id).to.eql(categoryChallenge._id);

View File

@@ -242,7 +242,6 @@ describe('POST /challenges', () => {
it('returns an error when challenge validation fails; doesn\'s save user or group', async () => { it('returns an error when challenge validation fails; doesn\'s save user or group', async () => {
let oldChallengeCount = group.challengeCount; let oldChallengeCount = group.challengeCount;
let oldUserBalance = groupLeader.balance; let oldUserBalance = groupLeader.balance;
let oldUserChallenges = groupLeader.challenges;
let oldGroupBalance = group.balance; let oldGroupBalance = group.balance;
await expect(groupLeader.post('/challenges', { await expect(groupLeader.post('/challenges', {
@@ -260,7 +259,6 @@ describe('POST /challenges', () => {
expect(group.challengeCount).to.eql(oldChallengeCount); expect(group.challengeCount).to.eql(oldChallengeCount);
expect(group.balance).to.eql(oldGroupBalance); expect(group.balance).to.eql(oldGroupBalance);
expect(groupLeader.balance).to.eql(oldUserBalance); expect(groupLeader.balance).to.eql(oldUserBalance);
expect(groupLeader.challenges).to.eql(oldUserChallenges);
}); });
it('sets all properites of the challenge as passed', async () => { it('sets all properites of the challenge as passed', async () => {
@@ -291,18 +289,19 @@ describe('POST /challenges', () => {
name: group.name, name: group.name,
type: group.type, type: group.type,
}); });
expect(challenge.memberCount).to.eql(1); expect(challenge.memberCount).to.eql(0);
expect(challenge.prize).to.eql(prize); expect(challenge.prize).to.eql(prize);
}); });
it('adds challenge to creator\'s challenges', async () => { it('does not add challenge to creator\'s challenges', async () => {
let challenge = await groupLeader.post('/challenges', { await groupLeader.post('/challenges', {
group: group._id, group: group._id,
name: 'Test Challenge', name: 'Test Challenge',
shortName: 'TC Label', shortName: 'TC Label',
}); });
await expect(groupLeader.sync()).to.eventually.have.property('challenges').to.include(challenge._id); await groupLeader.sync();
expect(groupLeader.challenges.length).to.equal(0);
}); });
it('awards achievement if this is creator\'s first challenge', async () => { it('awards achievement if this is creator\'s first challenge', async () => {

View File

@@ -43,6 +43,7 @@ describe('POST /challenges/:challengeId/join', () => {
authorizedUser = populatedGroup.members[0]; authorizedUser = populatedGroup.members[0];
challenge = await generateChallenge(groupLeader, group); challenge = await generateChallenge(groupLeader, group);
await groupLeader.post(`/challenges/${challenge._id}/join`);
}); });
it('returns an error when user doesn\'t have permissions to access the challenge', async () => { it('returns an error when user doesn\'t have permissions to access the challenge', async () => {
@@ -91,6 +92,7 @@ describe('POST /challenges/:challengeId/join', () => {
}); });
it('increases memberCount of challenge', async () => { it('increases memberCount of challenge', async () => {
await challenge.sync();
let oldMemberCount = challenge.memberCount; let oldMemberCount = challenge.memberCount;
await authorizedUser.post(`/challenges/${challenge._id}/join`); await authorizedUser.post(`/challenges/${challenge._id}/join`);

View File

@@ -48,6 +48,7 @@ describe('POST /challenges/:challengeId/leave', () => {
notInGroupLeavingUser = populatedGroup.members[2]; notInGroupLeavingUser = populatedGroup.members[2];
challenge = await generateChallenge(groupLeader, group); challenge = await generateChallenge(groupLeader, group);
await groupLeader.post(`/challenges/${challenge._id}/join`);
taskText = 'A challenge task text'; taskText = 'A challenge task text';

View File

@@ -58,6 +58,7 @@ describe('POST /challenges/:challengeId/winner/:winnerId', () => {
challenge = await generateChallenge(groupLeader, group, { challenge = await generateChallenge(groupLeader, group, {
prize: 1, prize: 1,
}); });
await groupLeader.post(`/challenges/${challenge._id}/join`);
await groupLeader.post(`/tasks/challenge/${challenge._id}`, [ await groupLeader.post(`/tasks/challenge/${challenge._id}`, [
{type: 'habit', text: taskText}, {type: 'habit', text: taskText},

View File

@@ -25,6 +25,7 @@ describe('PUT /challenges/:challengeId', () => {
member = members[0]; member = members[0];
challenge = await generateChallenge(user, group); challenge = await generateChallenge(user, group);
await user.post(`/challenges/${challenge._id}/join`);
await member.post(`/challenges/${challenge._id}/join`); await member.post(`/challenges/${challenge._id}/join`);
}); });

View File

@@ -93,6 +93,7 @@ describe('POST /groups/:groupId/leave', () => {
beforeEach(async () => { beforeEach(async () => {
challenge = await generateChallenge(leader, groupToLeave); challenge = await generateChallenge(leader, groupToLeave);
await leader.post(`/challenges/${challenge._id}/join`);
await leader.post(`/tasks/challenge/${challenge._id}`, { await leader.post(`/tasks/challenge/${challenge._id}`, {
text: 'test habit', text: 'test habit',

View File

@@ -92,6 +92,7 @@ describe('DELETE /tasks/:id', () => {
}); });
let guild = await generateGroup(user); let guild = await generateGroup(user);
let challenge = await generateChallenge(user, guild); let challenge = await generateChallenge(user, guild);
await user.post(`/challenges/${challenge._id}/join`);
await user.post('/user/webhook', { await user.post('/user/webhook', {
url: `http://localhost:${server.port}/webhooks/${uuid}`, url: `http://localhost:${server.port}/webhooks/${uuid}`,

View File

@@ -40,6 +40,7 @@ describe('GET /tasks/:taskId', () => {
user = await generateUser(); user = await generateUser();
guild = await generateGroup(user); guild = await generateGroup(user);
challenge = await generateChallenge(user, guild); challenge = await generateChallenge(user, guild);
await user.post(`/challenges/${challenge._id}/join`);
}); });
it('returns error when incorrect id is passed', async () => { it('returns error when incorrect id is passed', async () => {

View File

@@ -9,6 +9,7 @@ describe('POST /tasks/clearCompletedTodos', () => {
let user = await generateUser({balance: 1}); let user = await generateUser({balance: 1});
let guild = await generateGroup(user); let guild = await generateGroup(user);
let challenge = await generateChallenge(user, guild); let challenge = await generateChallenge(user, guild);
await user.post(`/challenges/${challenge._id}/join`);
let initialTodoCount = user.tasksOrder.todos.length; let initialTodoCount = user.tasksOrder.todos.length;
await user.post('/tasks/user', [ await user.post('/tasks/user', [

View File

@@ -37,6 +37,7 @@ describe('POST /tasks/unlink-all/:challengeId', () => {
user = await generateUser(); user = await generateUser();
guild = await generateGroup(user); guild = await generateGroup(user);
challenge = await generateChallenge(user, guild); challenge = await generateChallenge(user, guild);
await user.post(`/challenges/${challenge._id}/join`);
}); });
it('fails if no keep query', async () => { it('fails if no keep query', async () => {

View File

@@ -38,6 +38,7 @@ describe('POST /tasks/unlink-one/:taskId', () => {
user = await generateUser(); user = await generateUser();
guild = await generateGroup(user); guild = await generateGroup(user);
challenge = await generateChallenge(user, guild); challenge = await generateChallenge(user, guild);
await user.post(`/challenges/${challenge._id}/join`);
}); });
it('fails if no keep query', async () => { it('fails if no keep query', async () => {

View File

@@ -65,6 +65,7 @@ describe('PUT /tasks/:id', () => {
fields for challenge tasks owned by a user`, async () => { fields for challenge tasks owned by a user`, async () => {
let guild = await generateGroup(user); let guild = await generateGroup(user);
let challenge = await generateChallenge(user, guild); let challenge = await generateChallenge(user, guild);
await user.post(`/challenges/${challenge._id}/join`);
let challengeTask = await user.post(`/tasks/challenge/${challenge._id}`, { let challengeTask = await user.post(`/tasks/challenge/${challenge._id}`, {
type: 'daily', type: 'daily',
@@ -198,6 +199,7 @@ describe('PUT /tasks/:id', () => {
}); });
let guild = await generateGroup(user); let guild = await generateGroup(user);
let challenge = await generateChallenge(user, guild); let challenge = await generateChallenge(user, guild);
await user.post(`/challenges/${challenge._id}/join`);
await user.post('/user/webhook', { await user.post('/user/webhook', {
url: `http://localhost:${server.port}/webhooks/${uuid}`, url: `http://localhost:${server.port}/webhooks/${uuid}`,

View File

@@ -15,6 +15,7 @@ describe('DELETE /tasks/:taskId/checklist/:itemId', () => {
user = await generateUser(); user = await generateUser();
guild = await generateGroup(user); guild = await generateGroup(user);
challenge = await generateChallenge(user, guild); challenge = await generateChallenge(user, guild);
await user.post(`/challenges/${challenge._id}/join`);
}); });
it('fails on task not found', async () => { it('fails on task not found', async () => {

View File

@@ -17,6 +17,7 @@ describe('DELETE /tasks/:id', () => {
user = await generateUser(); user = await generateUser();
guild = await generateGroup(user); guild = await generateGroup(user);
challenge = await generateChallenge(user, guild); challenge = await generateChallenge(user, guild);
await user.post(`/challenges/${challenge._id}/join`);
}); });
beforeEach(async () => { beforeEach(async () => {

View File

@@ -42,6 +42,7 @@ describe('GET /tasks/challenge/:challengeId', () => {
user = await generateUser(); user = await generateUser();
guild = await generateGroup(user); guild = await generateGroup(user);
challenge = await generateChallenge(user, guild); challenge = await generateChallenge(user, guild);
await user.post(`/challenges/${challenge._id}/join`);
}); });
it('returns error when challenge is not found', async () => { it('returns error when challenge is not found', async () => {

View File

@@ -15,6 +15,7 @@ describe('POST /tasks/:taskId/checklist/', () => {
user = await generateUser(); user = await generateUser();
guild = await generateGroup(user); guild = await generateGroup(user);
challenge = await generateChallenge(user, guild); challenge = await generateChallenge(user, guild);
await user.post(`/challenges/${challenge._id}/join`);
}); });
it('fails on task not found', async () => { it('fails on task not found', async () => {

View File

@@ -20,6 +20,7 @@ describe('POST /tasks/challenge/:challengeId', () => {
user = await generateUser({balance: 1}); user = await generateUser({balance: 1});
guild = await generateGroup(user); guild = await generateGroup(user);
challenge = await generateChallenge(user, guild); challenge = await generateChallenge(user, guild);
await user.post(`/challenges/${challenge._id}/join`);
}); });
it('returns error when challenge is not found', async () => { it('returns error when challenge is not found', async () => {

View File

@@ -15,6 +15,7 @@ describe('POST /tasks/:id/score/:direction', () => {
user = await generateUser(); user = await generateUser();
guild = await generateGroup(user); guild = await generateGroup(user);
challenge = await generateChallenge(user, guild); challenge = await generateChallenge(user, guild);
await user.post(`/challenges/${challenge._id}/join`);
}); });
context('habits', () => { context('habits', () => {

View File

@@ -15,6 +15,7 @@ describe('PUT /tasks/:id', () => {
user = await generateUser(); user = await generateUser();
guild = await generateGroup(user); guild = await generateGroup(user);
challenge = await generateChallenge(user, guild); challenge = await generateChallenge(user, guild);
await user.post(`/challenges/${challenge._id}/join`);
}); });
context('errors', () => { context('errors', () => {

View File

@@ -15,6 +15,7 @@ describe('PUT /tasks/:taskId/checklist/:itemId', () => {
user = await generateUser(); user = await generateUser();
guild = await generateGroup(user); guild = await generateGroup(user);
challenge = await generateChallenge(user, guild); challenge = await generateChallenge(user, guild);
await user.post(`/challenges/${challenge._id}/join`);
}); });
it('fails on task not found', async () => { it('fails on task not found', async () => {

View File

@@ -117,6 +117,7 @@ describe('DELETE /user', () => {
let authorizedUser = populatedGroup.members[1]; let authorizedUser = populatedGroup.members[1];
let challenge = await generateChallenge(populatedGroup.groupLeader, group); let challenge = await generateChallenge(populatedGroup.groupLeader, group);
await populatedGroup.groupLeader.post(`/challenges/${challenge._id}/join`);
await authorizedUser.post(`/challenges/${challenge._id}/join`); await authorizedUser.post(`/challenges/${challenge._id}/join`);
await challenge.sync(); await challenge.sync();

View File

@@ -109,6 +109,7 @@ describe('POST /user/class/cast/:spellId', () => {
it('returns an error if a challenge task was targeted', async () => { it('returns an error if a challenge task was targeted', async () => {
let {group, groupLeader} = await createAndPopulateGroup(); let {group, groupLeader} = await createAndPopulateGroup();
let challenge = await generateChallenge(groupLeader, group); let challenge = await generateChallenge(groupLeader, group);
await groupLeader.post(`/challenges/${challenge._id}/join`);
await groupLeader.post(`/tasks/challenge/${challenge._id}`, [ await groupLeader.post(`/tasks/challenge/${challenge._id}`, [
{type: 'habit', text: 'task text'}, {type: 'habit', text: 'task text'},
]); ]);
@@ -238,6 +239,7 @@ describe('POST /user/class/cast/:spellId', () => {
it('searing brightness does not affect challenge or group tasks', async () => { it('searing brightness does not affect challenge or group tasks', async () => {
let guild = await generateGroup(user); let guild = await generateGroup(user);
let challenge = await generateChallenge(user, guild); let challenge = await generateChallenge(user, guild);
await user.post(`/challenges/${challenge._id}/join`);
await user.post(`/tasks/challenge/${challenge._id}`, { await user.post(`/tasks/challenge/${challenge._id}`, {
text: 'test challenge habit', text: 'test challenge habit',
type: 'habit', type: 'habit',

View File

@@ -90,6 +90,7 @@ describe('POST /user/reset', () => {
it('does not delete challenge or group tasks', async () => { it('does not delete challenge or group tasks', async () => {
let guild = await generateGroup(user); let guild = await generateGroup(user);
let challenge = await generateChallenge(user, guild); let challenge = await generateChallenge(user, guild);
await user.post(`/challenges/${challenge._id}/join`);
await user.post(`/tasks/challenge/${challenge._id}`, { await user.post(`/tasks/challenge/${challenge._id}`, {
text: 'test challenge habit', text: 'test challenge habit',
type: 'habit', type: 'habit',

View File

@@ -6,15 +6,13 @@ export async function createChallenge (store, payload) {
let response = await axios.post('/api/v3/challenges', payload.challenge); let response = await axios.post('/api/v3/challenges', payload.challenge);
let newChallenge = response.data.data; let newChallenge = response.data.data;
store.state.user.data.challenges.push(newChallenge._id);
return newChallenge; return newChallenge;
} }
export async function cloneChallenge (store, payload) { export async function cloneChallenge (store, payload) {
const response = await axios.post(`/api/v3/challenges/${payload.cloningChallengeId}/clone`, payload.challenge); const response = await axios.post(`/api/v3/challenges/${payload.cloningChallengeId}/clone`, payload.challenge);
const newChallenge = response.data.data.clonedChallenge; const newChallenge = response.data.data.clonedChallenge;
store.state.user.data.challenges.push(newChallenge._id);
return newChallenge; return newChallenge;
} }

View File

@@ -82,12 +82,10 @@ export async function createChallenge (user, req, res) {
addUserJoinChallengeNotification(user); addUserJoinChallengeNotification(user);
let results = await Promise.all([challenge.save({ let results = await Promise.all([challenge.save({
validateBeforeSave: false, // already validate validateBeforeSave: false, // already validated
}), group.save()]); }), group.save(), user.save()]);
let savedChal = results[0]; let savedChal = results[0];
await savedChal.syncToUser(user); // (it also saves the user)
return {savedChal, group}; return {savedChal, group};
} }

View File

@@ -33,7 +33,7 @@ let schema = new Schema({
}, },
leader: {type: String, ref: 'User', validate: [validator.isUUID, 'Invalid uuid.'], required: true}, leader: {type: String, ref: 'User', validate: [validator.isUUID, 'Invalid uuid.'], required: true},
group: {type: String, ref: 'Group', validate: [validator.isUUID, 'Invalid uuid.'], required: true}, group: {type: String, ref: 'Group', validate: [validator.isUUID, 'Invalid uuid.'], required: true},
memberCount: {type: Number, default: 1}, memberCount: {type: Number, default: 0},
prize: {type: Number, default: 0, min: 0}, prize: {type: Number, default: 0, min: 0},
categories: [{ categories: [{
slug: {type: String}, slug: {type: String},