diff --git a/test/api/v3/integration/tasks/POST-tasks_unlink-all_challengeId.test.js b/test/api/v3/integration/tasks/POST-tasks_unlink-all_challengeId.test.js new file mode 100644 index 0000000000..5d50cd91f2 --- /dev/null +++ b/test/api/v3/integration/tasks/POST-tasks_unlink-all_challengeId.test.js @@ -0,0 +1,109 @@ +import { + generateUser, + generateGroup, + generateChallenge, + translate as t, +} from '../../../../helpers/api-integration/v3'; + +describe('POST /tasks/unlink-all/:challengeId', () => { + let user; + let guild; + let challenge; + let tasksToTest = { + habit: { + text: 'test habit', + type: 'habit', + up: false, + down: true, + }, + todo: { + text: 'test todo', + type: 'todo', + }, + daily: { + text: 'test daily', + type: 'daily', + frequency: 'daily', + everyX: 5, + startDate: new Date(), + }, + reward: { + text: 'test reward', + type: 'reward', + }, + }; + + beforeEach(async () => { + user = await generateUser(); + guild = await generateGroup(user); + challenge = await generateChallenge(user, guild); + }); + + it('fails if no keep query', async () => { + await expect(user.post(`/tasks/unlink-all/${challenge._id}`)) + .to.eventually.be.rejected.and.eql({ + code: 400, + error: 'BadRequest', + message: t('invalidReqParams'), + }); + }); + + it('fails if invalid challenge id', async () => { + await expect(user.post('/tasks/unlink-all/123?keep=remove-all')) + .to.eventually.be.rejected.and.eql({ + code: 400, + error: 'BadRequest', + message: t('invalidReqParams'), + }); + }); + + it('fails on an unbroken challenge', async () => { + await user.post(`/tasks/challenge/${challenge._id}`, tasksToTest.daily); + await expect(user.post(`/tasks/unlink-all/${challenge._id}?keep=remove-all`)) + .to.eventually.be.rejected.and.eql({ + code: 400, + error: 'BadRequest', + message: t('cantOnlyUnlinkChalTask'), + }); + }); + + it('unlinks all tasks from a challenge and deletes them on keep=remove-all', async () => { + const daily = await user.post(`/tasks/challenge/${challenge._id}`, tasksToTest.daily); + await user.post(`/tasks/challenge/${challenge._id}`, tasksToTest.habit); + await user.post(`/tasks/challenge/${challenge._id}`, tasksToTest.reward); + await user.post(`/tasks/challenge/${challenge._id}`, tasksToTest.todo); + await user.del(`/challenges/${challenge._id}`); + const response = await user.post(`/tasks/unlink-all/${challenge._id}?keep=remove-all`); + expect(response).to.eql({}); + + await expect(user.get(`/tasks/${daily._id}`)).to.eventually.be.rejected.and.eql({ + code: 404, + error: 'NotFound', + message: t('taskNotFound'), + }); + }); + + it('unlinks a task from a challenge on keep=keep-all', async () => { + const daily = await user.post(`/tasks/challenge/${challenge._id}`, tasksToTest.daily); + const anotherUser = await generateUser(); + await user.post(`/groups/${guild._id}/invite`, { + uuids: [anotherUser._id], + }); + // Have the second user join the group and challenge + await anotherUser.post(`/groups/${guild._id}/join`); + await anotherUser.post(`/challenges/${challenge._id}/join`); + // 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 + const [, anotherUserTask] = await anotherUser.get('/tasks/user'); + // Expect the second user to still have the task, but unlinked + expect(anotherUserTask.challenge).to.eql({ + taskId: daily._id, + id: challenge._id, + shortName: challenge.shortName, + broken: 'CHALLENGE_DELETED', + winner: null, + }); + }); +}); \ No newline at end of file diff --git a/test/api/v3/integration/tasks/POST-tasks_unlink-one_taskId.test.js b/test/api/v3/integration/tasks/POST-tasks_unlink-one_taskId.test.js new file mode 100644 index 0000000000..570f46c92e --- /dev/null +++ b/test/api/v3/integration/tasks/POST-tasks_unlink-one_taskId.test.js @@ -0,0 +1,110 @@ +import { + generateUser, + generateGroup, + generateChallenge, + translate as t, +} from '../../../../helpers/api-integration/v3'; +import { v4 as generateUUID } from 'uuid'; + +describe('POST /tasks/unlink-one/:taskId', () => { + let user; + let guild; + let challenge; + let tasksToTest = { + habit: { + text: 'test habit', + type: 'habit', + up: false, + down: true, + }, + todo: { + text: 'test todo', + type: 'todo', + }, + daily: { + text: 'test daily', + type: 'daily', + frequency: 'daily', + everyX: 5, + startDate: new Date(), + }, + reward: { + text: 'test reward', + type: 'reward', + }, + }; + + beforeEach(async () => { + user = await generateUser(); + guild = await generateGroup(user); + challenge = await generateChallenge(user, guild); + }); + + it('fails if no keep query', async () => { + const daily = await user.post(`/tasks/challenge/${challenge._id}`, tasksToTest.daily); + await expect(user.post(`/tasks/unlink-one/${daily._id}`)) + .to.eventually.be.rejected.and.eql({ + code: 400, + error: 'BadRequest', + message: t('invalidReqParams'), + }); + }); + + it('fails if invalid task id', async () => { + await expect(user.post('/tasks/unlink-one/123?keep=remove')) + .to.eventually.be.rejected.and.eql({ + code: 400, + error: 'BadRequest', + message: t('invalidReqParams'), + }); + }); + + it('fails on task not found', async () => { + await expect(user.post(`/tasks/unlink-one/${generateUUID()}?keep=keep`)) + .to.eventually.be.rejected.and.eql({ + code: 404, + error: 'NotFound', + message: t('taskNotFound'), + }); + }); + + it('fails on task unlinked to challenge', async () => { + let daily = await user.post('/tasks/user', tasksToTest.daily); + await expect(user.post(`/tasks/unlink-one/${daily._id}?keep=keep`)) + .to.eventually.be.rejected.and.eql({ + code: 400, + error: 'BadRequest', + message: t('cantOnlyUnlinkChalTask'), + }); + }); + + it('fails on unbroken challenge', async () => { + await user.post(`/tasks/challenge/${challenge._id}`, tasksToTest.daily); + let [daily] = await user.get('/tasks/user'); + await expect(user.post(`/tasks/unlink-one/${daily._id}?keep=keep`)) + .to.eventually.be.rejected.and.eql({ + code: 400, + error: 'BadRequest', + message: t('cantOnlyUnlinkChalTask'), + }); + }); + + it('unlinks a task from a challenge and saves it on keep=keep', async () => { + await user.post(`/tasks/challenge/${challenge._id}`, tasksToTest.daily); + let [, daily] = await user.get('/tasks/user'); + await user.del(`/challenges/${challenge._id}`); + await user.post(`/tasks/unlink-one/${daily._id}?keep=keep`); + [, daily] = await user.get('/tasks/user'); + expect(daily.challenge).to.eql({}); + }); + + it('unlinks a task from a challenge and deletes it on keep=remove', async () => { + await user.post(`/tasks/challenge/${challenge._id}`, tasksToTest.daily); + let [, daily] = await user.get('/tasks/user'); + await user.del(`/challenges/${challenge._id}`); + await user.post(`/tasks/unlink-one/${daily._id}?keep=remove`); + const tasks = await user.get('/tasks/user'); + // Only the default task should remain + expect(tasks.length).to.eql(1); + }); +}); \ No newline at end of file