diff --git a/test/api/v3/integration/tasks/DELETE-tasks_id.test.js b/test/api/v3/integration/tasks/DELETE-tasks_id.test.js index 7cdd2209dd..5543345220 100644 --- a/test/api/v3/integration/tasks/DELETE-tasks_id.test.js +++ b/test/api/v3/integration/tasks/DELETE-tasks_id.test.js @@ -18,18 +18,52 @@ describe('DELETE /tasks/:id', () => { let task; beforeEach(() => { - // generate task - // task = generatedTask; + return api.post('/tasks', { + text: 'test habit', + type: 'habit', + }).then((createdTask) => { + task = createdTask; + }); }); - it('deletes a user\'s task'); + it('deletes a user\'s task', () => { + return api.del('/tasks/' + task._id) + .then(() => { + return expect(api.get('/tasks/' + task._id)).to.eventually.be.rejected.and.eql({ + code: 404, + error: 'NotFound', + message: t('taskNotFound'), + }); + }); + }); }); context('task cannot be deleted', () => { - it('cannot delete a non-existant task'); + it('cannot delete a non-existant task', () => { + return expect(api.del('/tasks/550e8400-e29b-41d4-a716-446655440000')).to.eventually.be.rejected.and.eql({ + code: 404, + error: 'NotFound', + message: t('taskNotFound'), + }); + }); - it('cannot delete a task owned by someone else'); + it('cannot delete a task owned by someone else', () => { + return generateUser() + .then((user2) => { + return requester(user2).post('/tasks', { + text: 'test habit', + type: 'habit', + }) + }) + .then((task2) => { + return expect(api.del('/tasks/' + task2._id)).to.eventually.be.rejected.and.eql({ + code: 404, + error: 'NotFound', + message: t('taskNotFound'), + }); + }); + }); - it('cannot delete active challenge tasks'); + it('cannot delete active challenge tasks'); // TODO after challenges are implemented }); }); diff --git a/test/api/v3/integration/tasks/GET-tasks.test.js b/test/api/v3/integration/tasks/GET-tasks.test.js index 3faf65c771..2ef56ff1fe 100644 --- a/test/api/v3/integration/tasks/GET-tasks.test.js +++ b/test/api/v3/integration/tasks/GET-tasks.test.js @@ -3,6 +3,7 @@ import { requester, translate as t, } from '../../../../helpers/api-integration.helper'; +import Q from 'q'; describe('GET /tasks', () => { let user, api; @@ -14,5 +15,33 @@ describe('GET /tasks', () => { }); }); - it('returns all user\'s tasks'); + it('returns all user\'s tasks', () => { + let length; + return Q.all([ + api.post('/tasks', {text: 'test habit', type: 'habit'}), + ]) + .then((createdTasks) => { + length = createdTasks.length; + return api.get('/tasks'); + }) + .then((tasks) => { + expect(tasks.length).to.equal(length + 1); // + 1 because 1 is a default task + }); + }); + + it('returns only a type of user\'s tasks if req.query.type is specified', () => { + let habitId; + api.post('/tasks', {text: 'test habit', type: 'habit'}) + .then((task) => { + habitId = task._id; + return api.get('/tasks?type=habit'); + }) + .then((tasks) => { + expect(tasks.length).to.equal(1); + expect(tasks[0]._id).to.equal(habitId); + }); + }); + + // TODO complete after task scoring is done + it('returns completed todos sorted by creation date if req.query.includeCompletedTodos is specified') }); diff --git a/website/src/controllers/api-v3/tasks.js b/website/src/controllers/api-v3/tasks.js index 065e8a9f7b..509aafbe02 100644 --- a/website/src/controllers/api-v3/tasks.js +++ b/website/src/controllers/api-v3/tasks.js @@ -18,6 +18,8 @@ let api = {}; * * @apiSuccess {Object} task The newly created task */ +// TODO should allow to create multiple tasks at once +// TODO gives problems when creating tasks concurrently because of how mongoose treats arrays (VersionErrors - treated as 500s) api.createTask = { method: 'POST', url: '/tasks', @@ -61,7 +63,7 @@ api.getTasks = { url: '/tasks', middlewares: [authWithHeaders()], handler (req, res, next) { - req.checkQuery('type', res.t('invalidTaskType')).isIn(Tasks.tasksTypes); + req.checkQuery('type', res.t('invalidTaskType')).optional().isIn(Tasks.tasksTypes); let validationErrors = req.validationErrors(); if (validationErrors) return next(validationErrors); @@ -74,7 +76,7 @@ api.getTasks = { query.type = type; if (type === 'todo') query.completed = false; // Exclude completed todos } else { - query.$and = [ // Exclude completed todos + query.$or = [ // Exclude completed todos {type: 'todo', completed: false}, {type: {$in: ['habit', 'daily', 'reward']}}, ]; @@ -532,7 +534,7 @@ api.removeTagFromTask = { function _removeTaskTasksOrder (user, taskId) { // Loop through all lists and when the task is found, remove it and return for (let i = 0; i < Tasks.tasksTypes.length; i++) { - let list = user.tasksOrder[Tasks.tasksTypes[i]]; + let list = user.tasksOrder[`${Tasks.tasksTypes[i]}s`]; let index = list.indexOf(taskId); if (index !== -1) { @@ -555,7 +557,7 @@ function _removeTaskTasksOrder (user, taskId) { * @apiSuccess {object} empty An empty object */ api.deleteTask = { - method: 'GET', + method: 'DELETE', url: '/tasks/:taskId', middlewares: [authWithHeaders()], handler (req, res, next) { diff --git a/website/src/models/tag.js b/website/src/models/tag.js index a7cc1ca243..78c1b7884e 100644 --- a/website/src/models/tag.js +++ b/website/src/models/tag.js @@ -15,4 +15,4 @@ schema.plugin(baseModel, { noSet: ['_id', 'challenge'], }); -export let model = mongoose.model('Tag', TagSchema); +export let model = mongoose.model('Tag', schema);