From c04e53b5a587caefe3a05535401ee41c553d64cb Mon Sep 17 00:00:00 2001 From: Keith Holliday Date: Sat, 12 Mar 2016 21:00:43 -0600 Subject: [PATCH 1/2] Added initial delete challenge tasks tests --- ...ETE-tasks_id_challenge_challengeId.test.js | 55 +++++++++++++++++++ website/src/controllers/api-v3/tasks.js | 2 +- 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 test/api/v3/integration/tasks/challenges/DELETE-tasks_id_challenge_challengeId.test.js diff --git a/test/api/v3/integration/tasks/challenges/DELETE-tasks_id_challenge_challengeId.test.js b/test/api/v3/integration/tasks/challenges/DELETE-tasks_id_challenge_challengeId.test.js new file mode 100644 index 0000000000..9ec2a65f8e --- /dev/null +++ b/test/api/v3/integration/tasks/challenges/DELETE-tasks_id_challenge_challengeId.test.js @@ -0,0 +1,55 @@ +import { + generateUser, + generateGroup, + generateChallenge, + translate as t, +} from '../../../../../helpers/api-integration/v3'; +import { v4 as generateUUID } from 'uuid'; + +describe('DELETE /tasks/:id', () => { + let user; + let guild; + let challenge; + let task; + + before(async () => { + user = await generateUser(); + guild = await generateGroup(user); + challenge = await generateChallenge(user, guild); + }); + + beforeEach(async () => { + task = await user.post(`/tasks/challenge/${challenge._id}`, { + text: 'test habit', + type: 'habit', + }); + }); + + it('cannot delete a non-existant task', async () => { + await expect(user.del(`/tasks/${generateUUID()}`)).to.eventually.be.rejected.and.eql({ + code: 404, + error: 'NotFound', + message: t('taskNotFound'), + }); + }); + + it('returns error when user is not leader of the challenge', async () => { + let anotherUser = await generateUser(); + + await expect(anotherUser.del(`/tasks/${task._id}`)).to.eventually.be.rejected.and.eql({ + code: 401, + error: 'NotAuthorized', + message: t('onlyChalLeaderEditTasks'), + }); + }); + + it('deletes a user\'s task', async () => { + await user.del(`/tasks/${task._id}`); + + await expect(user.get(`/tasks/${task._id}`)).to.eventually.be.rejected.and.eql({ + code: 404, + error: 'NotFound', + message: t('taskNotFound'), + }); + }); +}); diff --git a/website/src/controllers/api-v3/tasks.js b/website/src/controllers/api-v3/tasks.js index b78615e448..952076ab82 100644 --- a/website/src/controllers/api-v3/tasks.js +++ b/website/src/controllers/api-v3/tasks.js @@ -909,7 +909,7 @@ api.deleteTask = { if (!task) { throw new NotFound(res.t('taskNotFound')); } else if (!task.userId) { // If the task belongs to a challenge make sure the user has rights - challenge = await Challenge.find().selec({_id: task.challenge.id}).select('leader').exec(); + challenge = await Challenge.findOne({_id: task.challenge.id}).exec(); if (!challenge) throw new NotFound(res.t('challengeNotFound')); if (challenge.leader !== user._id) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks')); } else if (task.userId !== user._id) { // If the task is owned by an user make it's the current one From 534ec07b6a5eb30f73308103d2dbccb74acaf83b Mon Sep 17 00:00:00 2001 From: Keith Holliday Date: Tue, 15 Mar 2016 10:03:48 -0500 Subject: [PATCH 2/2] Added tests to ensure challenge member can not delete active challenge task and can delete broken or unlinked challenge task --- ...ETE-tasks_id_challenge_challengeId.test.js | 59 +++++++++++++++++++ website/src/controllers/api-v3/tasks.js | 2 +- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/test/api/v3/integration/tasks/challenges/DELETE-tasks_id_challenge_challengeId.test.js b/test/api/v3/integration/tasks/challenges/DELETE-tasks_id_challenge_challengeId.test.js index 9ec2a65f8e..52f257be9b 100644 --- a/test/api/v3/integration/tasks/challenges/DELETE-tasks_id_challenge_challengeId.test.js +++ b/test/api/v3/integration/tasks/challenges/DELETE-tasks_id_challenge_challengeId.test.js @@ -2,6 +2,7 @@ import { generateUser, generateGroup, generateChallenge, + sleep, translate as t, } from '../../../../../helpers/api-integration/v3'; import { v4 as generateUUID } from 'uuid'; @@ -52,4 +53,62 @@ describe('DELETE /tasks/:id', () => { message: t('taskNotFound'), }); }); + + context('challenge member', () => { + let anotherUser; + let anotherUsersNewChallengeTaskID; + let newChallengeTask; + + beforeEach(async () => { + anotherUser = await generateUser(); + await user.post(`/groups/${guild._id}/invite`, { uuids: [anotherUser._id] }); + await anotherUser.post(`/groups/${guild._id}/join`); + await anotherUser.post(`/challenges/${challenge._id}/join`); + + newChallengeTask = await user.post(`/tasks/challenge/${challenge._id}`, { + text: 'test habit', + type: 'habit', + }); + + let anotherUserWithNewChallengeTask = await anotherUser.get('/user'); + anotherUsersNewChallengeTaskID = anotherUserWithNewChallengeTask.tasksOrder.habits[0]; + }); + + it('returns error when user attempts to delete an active challenge task', async () => { + await expect(anotherUser.del(`/tasks/${anotherUsersNewChallengeTaskID}`)) + .to.eventually.be.rejected.and.eql({ + code: 401, + error: 'NotAuthorized', + message: t('cantDeleteChallengeTasks'), + }); + }); + + it('allows user to delete challenge task after user leaves challenge', async () => { + await anotherUser.post(`/challenges/${challenge._id}/leave`); + + await expect(anotherUser.del(`/tasks/${anotherUsersNewChallengeTaskID}`)); + + await expect(anotherUser.get(`/tasks/${task._id}`)).to.eventually.be.rejected.and.eql({ + code: 404, + error: 'NotFound', + message: t('taskNotFound'), + }); + }); + + it('allows user to delete challenge task after challenge task is broken', async () => { + await expect(user.del(`/tasks/${newChallengeTask._id}`)); + + await sleep(0.5); + + await expect(anotherUser.del(`/tasks/${anotherUsersNewChallengeTaskID}`)); + + await sleep(0.5); + + await expect(anotherUser.get(`/tasks/${anotherUsersNewChallengeTaskID}`)).to.eventually.be.rejected.and.eql({ + code: 404, + error: 'NotFound', + message: t('taskNotFound'), + }); + }); + }); }); diff --git a/website/src/controllers/api-v3/tasks.js b/website/src/controllers/api-v3/tasks.js index 952076ab82..bafdadaeb4 100644 --- a/website/src/controllers/api-v3/tasks.js +++ b/website/src/controllers/api-v3/tasks.js @@ -914,7 +914,7 @@ api.deleteTask = { if (challenge.leader !== user._id) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks')); } else if (task.userId !== user._id) { // If the task is owned by an user make it's the current one throw new NotFound(res.t('taskNotFound')); - } else if (task.userId && task.challenge.id) { + } else if (task.userId && task.challenge.id && !task.challenge.broken) { throw new NotAuthorized(res.t('cantDeleteChallengeTasks')); }