From 6d38caf78bd32925b961cef140170d668d7eb735 Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Wed, 27 Jan 2016 20:52:47 +0100 Subject: [PATCH] tests for challengeExportCsv --- ...-challenges_challengeId_export_csv.test.js | 59 +++++++++++++++++++ website/src/controllers/api-v3/challenges.js | 19 +++--- 2 files changed, 69 insertions(+), 9 deletions(-) create mode 100644 test/api/v3/integration/challenges/GET-challenges_challengeId_export_csv.test.js diff --git a/test/api/v3/integration/challenges/GET-challenges_challengeId_export_csv.test.js b/test/api/v3/integration/challenges/GET-challenges_challengeId_export_csv.test.js new file mode 100644 index 0000000000..cc7f408951 --- /dev/null +++ b/test/api/v3/integration/challenges/GET-challenges_challengeId_export_csv.test.js @@ -0,0 +1,59 @@ +import { + generateUser, + createAndPopulateGroup, + generateChallenge, + translate as t, + sleep, +} from '../../../../helpers/api-v3-integration.helper'; +import { v4 as generateUUID } from 'uuid'; + +describe('GET /challenges/:challengeId/export/csv', () => { + let groupLeader; + let group; + let challenge; + let members; + let user; + + beforeEach(async () => { + user = await generateUser(); + + let populatedGroup = await createAndPopulateGroup({ + members: 3, + }); + + groupLeader = populatedGroup.groupLeader; + group = populatedGroup.group; + members = populatedGroup.members; + + challenge = await generateChallenge(groupLeader, group); + await members[0].post(`/challenges/${challenge._id}/join`); + await members[1].post(`/challenges/${challenge._id}/join`); + await members[2].post(`/challenges/${challenge._id}/join`); + + await groupLeader.post(`/tasks/challenge/${challenge._id}`, [ + {type: 'habit', text: 'Task 1'}, + {type: 'todo', text: 'Task 2'}, + ]); + await sleep(1); + }); + + it('fails if challenge doesn\'t exists', async () => { + await expect(user.get(`/challenges/${generateUUID()}/export/csv`)).to.eventually.be.rejected.and.eql({ + code: 404, + error: 'NotFound', + message: t('challengeNotFound'), + }); + }); + + it('fails if user doesn\'t have access to the challenge', async () => { + await expect(user.get(`/challenges/${challenge._id}/export/csv`)).to.eventually.be.rejected.and.eql({ + code: 404, + error: 'NotFound', + message: t('challengeNotFound'), + }); + }); + + it('should return a valid CSV file with export data', async () => { + await members[0].get(`/challenges/${challenge._id}/export/csv`); + }); +}); diff --git a/website/src/controllers/api-v3/challenges.js b/website/src/controllers/api-v3/challenges.js index ea3e787602..3169650a0d 100644 --- a/website/src/controllers/api-v3/challenges.js +++ b/website/src/controllers/api-v3/challenges.js @@ -264,7 +264,7 @@ api.exportChallengeCsv = { let user = res.locals.user; let challengeId = req.params.challengeId; - let challenge = await Challenge.findById(challengeId).select('_id groupId leader').exec(); + let challenge = await Challenge.findById(challengeId).select('_id groupId leader tasksOrder').exec(); if (!challenge) throw new NotFound(res.t('challengeNotFound')); let group = await Group.getGroup({user, groupId: challenge.groupId, fields: '_id type privacy', optionalMembership: true}); if (!group || !challenge.canView(user, group)) throw new NotFound(res.t('challengeNotFound')); @@ -272,19 +272,15 @@ api.exportChallengeCsv = { // In v2 this used the aggregation framework to run some computation on MongoDB but then iterated through all // results on the server so the perf difference isn't that big (hopefully) - let challengeTasks = _.reduce(challenge.tasksOrder, (result, array) => { - return result.concat(array); - }, []).sort(); - let [members, tasks] = await Q.all([ User.find({challenges: challengeId}) .select(nameFields) - .sortBy({_id: 1}) + .sort({_id: 1}) .lean() // so we don't involve mongoose .exec(), - Tasks.Task.find({'task.challenge.id': challengeId, userId: {$exists: true}}) - .sortBy({userId: 1, _id: 1}).select('userId type text value notes').lean().exec(), + Tasks.Task.find({'challenge.id': challengeId, userId: {$exists: true}}) + .sort({userId: 1, _id: 1}).select('userId type text value notes').lean().exec(), ]); let resArray = members.map(member => [member._id, member.profile.name]); @@ -302,6 +298,9 @@ api.exportChallengeCsv = { }); // The first row is going to be UUID name Task Value Notes repeated n times for the n challenge tasks + let challengeTasks = _.reduce(challenge.tasksOrder.toObject(), (result, array) => { + return result.concat(array); + }, []).sort(); resArray.unshift(['UUID', 'name']); _.times(challengeTasks.length, () => resArray[0].push('Task', 'Value', 'Notes')); @@ -309,7 +308,9 @@ api.exportChallengeCsv = { 'Content-Type': 'text/csv', 'Content-disposition': `attachment; filename=${challengeId}.csv`, }); - res.status(200).send(await csvStringify(resArray)); + + let csvRes = await csvStringify(resArray); + res.status(200).send(csvRes); }, };