From c0a99eec8b039a45dccfbebcad076e62a96a4dff Mon Sep 17 00:00:00 2001 From: Matteo Pagliazzi Date: Thu, 3 Dec 2015 18:15:22 +0100 Subject: [PATCH] fix user model, sanitize some fields on task creation, add some tests and comments --- .../tasks/POST-create_task.test.js | 23 ++++++++++++++++++- website/src/controllers/api-v3/tasks.js | 8 +++---- website/src/models/task.js | 10 ++++++-- website/src/models/user.js | 2 ++ 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/test/api/v3/integration/tasks/POST-create_task.test.js b/test/api/v3/integration/tasks/POST-create_task.test.js index ebf3936ad3..90234d06a3 100644 --- a/test/api/v3/integration/tasks/POST-create_task.test.js +++ b/test/api/v3/integration/tasks/POST-create_task.test.js @@ -17,7 +17,7 @@ describe('POST /tasks', () => { }); }); - context('checks "type" is present and a valid value', () => { + context('checks "req.body.type"', () => { it('returns an error if req.body.type is absent', () => { expect(api.post('/tasks', { notType: 'habit', @@ -27,5 +27,26 @@ describe('POST /tasks', () => { message: t('invalidReqParams'), }); }); + + it('returns an error if req.body.type is not valid', () => { + expect(api.post('/tasks', { + type: 'habitF', + })).to.eventually.be.rejected.and.eql({ + code: 400, + error: 'BadRequest', + message: t('invalidReqParams'), + }); + }); + }); + + context('checks "task.userId"', () => { + it('sets "task.userId" to valid value', () => { + return api.post('/tasks', { + text: 'test habit', + type: 'habit', + }).then((task) => { + expect(task.userId).to.equal(user._id); + }); + }); }); }); diff --git a/website/src/controllers/api-v3/tasks.js b/website/src/controllers/api-v3/tasks.js index 41177e3ad0..1431e3c0a2 100644 --- a/website/src/controllers/api-v3/tasks.js +++ b/website/src/controllers/api-v3/tasks.js @@ -31,16 +31,16 @@ api.createTask = { let user = res.locals.user; let taskType = req.body.type; - let newTask = new Tasks[taskType](Tasks.Task.sanitize(req.body)); + let newTask = new Tasks[taskType](Tasks.Task.sanitizeCreate(req.body)); newTask.userId = user._id; - user.tasksOrder[taskType].unshift(newTask._id); + user.tasksOrder[taskType + 's'].unshift(newTask._id); Q.all([ newTask.save(), user.save(), ]) - .then(([task]) => res.respond(201, task)) + .then((results) => res.respond(201, results[0])) .catch(next); }, }; @@ -478,7 +478,7 @@ api.deleteTask = { let validationErrors = req.validationErrors(); if (validationErrors) return next(validationErrors); - + Tasks.Task.findOne({ _id: req.params.taskId, userId: user._id, diff --git a/website/src/models/task.js b/website/src/models/task.js index d697bac622..c7c368c059 100644 --- a/website/src/models/task.js +++ b/website/src/models/task.js @@ -18,7 +18,7 @@ export let TaskSchema = new Schema({ text: {type: String, required: true}, notes: {type: String, default: ''}, tags: {type: Schema.Types.Mixed, default: {}}, // TODO dictionary? { "4ddf03d9-54bd-41a3-b011-ca1f1d2e9371" : true }, validate - value: {type: Number, default: 0}, // redness + value: {type: Number, default: 0}, // redness or cost for rewards priority: {type: Number, default: 1, required: true}, attribute: {type: String, default: 'str', enum: ['str', 'con', 'int', 'per']}, userId: {type: String, ref: 'User'}, // When null it belongs to a challenge @@ -40,8 +40,14 @@ TaskSchema.plugin(baseModel, { timestamps: true, }); +// A list of additional fields that cannot be set on creation (but can be set on updare) +let noCreate = ['completed']; +TaskSchema.statics.sanitizeCreate = function sanitizeCreate (createObj) { + return Task.sanitize(createObj, noCreate); // eslint-disable-line no-use-before-define +}; + // A list of additional fields that cannot be updated (but can be set on creation) -let noUpdate = ['_id', 'type']; +let noUpdate = ['_id', 'type']; // TODO should prevent changes to checlist.*.id TaskSchema.statics.sanitizeUpdate = function sanitizeUpdate (updateObj) { return Task.sanitize(updateObj, noUpdate); // eslint-disable-line no-use-before-define }; diff --git a/website/src/models/user.js b/website/src/models/user.js index 3607dcc1b2..0febc4cab0 100644 --- a/website/src/models/user.js +++ b/website/src/models/user.js @@ -628,6 +628,8 @@ schema.pre('save', true, function preSaveUser (next, done) { _populateDefaultsForNewUser(this) .then(() => done()) .catch(done); + } else { + done(); } });