diff --git a/src/routes/milestones/update.js b/src/routes/milestones/update.js index 4b68e72d..fd72c263 100644 --- a/src/routes/milestones/update.js +++ b/src/routes/milestones/update.js @@ -10,7 +10,7 @@ import Sequelize from 'sequelize'; import { middleware as tcMiddleware } from 'tc-core-library-js'; import util from '../../util'; import validateTimeline from '../../middlewares/validateTimeline'; -import { EVENT, MILESTONE_STATUS } from '../../constants'; +import { EVENT, MILESTONE_STATUS, ADMIN_ROLES } from '../../constants'; import models from '../../models'; const permissions = tcMiddleware.permissions; @@ -185,6 +185,14 @@ module.exports = [ } } + if (entityToUpdate.completionDate || entityToUpdate.actualStartDate) { + if (!util.hasPermission({ topcoderRoles: ADMIN_ROLES }, req.authUser)) { + const apiErr = new Error('You are not authorised to perform this action'); + apiErr.status = 403; + return Promise.reject(apiErr); + } + } + if (entityToUpdate.completionDate && entityToUpdate.completionDate < milestone.startDate) { const apiErr = new Error('The milestone completionDate should be greater or equal than the startDate.'); apiErr.status = 422; diff --git a/src/routes/milestones/update.spec.js b/src/routes/milestones/update.spec.js index 382d2eab..253107a7 100644 --- a/src/routes/milestones/update.spec.js +++ b/src/routes/milestones/update.spec.js @@ -264,7 +264,6 @@ describe('UPDATE Milestone', () => { param: { name: 'Milestone 1-updated', duration: 3, - completionDate: '2018-05-16T00:00:00.000Z', description: 'description-updated', status: 'draft', type: 'type1-updated', @@ -302,6 +301,30 @@ describe('UPDATE Milestone', () => { .expect(403, done); }); + it('should return 403 for non-admin member updating the completionDate', (done) => { + const newBody = _.cloneDeep(body); + newBody.param.completionDate = '2019-01-16T00:00:00.000Z'; + request(server) + .patch('/v4/timelines/1/milestones/1') + .set({ + Authorization: `Bearer ${testUtil.jwts.manager}`, + }) + .send(newBody) + .expect(403, done); + }); + + it('should return 403 for non-admin member updating the actualStartDate', (done) => { + const newBody = _.cloneDeep(body); + newBody.param.actualStartDate = '2018-05-15T00:00:00.000Z'; + request(server) + .patch('/v4/timelines/1/milestones/1') + .set({ + Authorization: `Bearer ${testUtil.jwts.manager}`, + }) + .send(newBody) + .expect(403, done); + }); + it('should return 404 for non-existed timeline', (done) => { request(server) .patch('/v4/timelines/1234/milestones/1') @@ -490,12 +513,14 @@ describe('UPDATE Milestone', () => { }); it('should return 200 for admin', (done) => { + const newBody = _.cloneDeep(body); + newBody.param.completionDate = '2018-05-15T00:00:00.000Z'; request(server) .patch('/v4/timelines/1/milestones/1') .set({ Authorization: `Bearer ${testUtil.jwts.admin}`, }) - .send(body) + .send(newBody) .expect(200) .end((err, res) => { const resJson = res.body.result.content; @@ -503,7 +528,7 @@ describe('UPDATE Milestone', () => { resJson.name.should.be.eql(body.param.name); resJson.description.should.be.eql(body.param.description); resJson.duration.should.be.eql(body.param.duration); - resJson.completionDate.should.be.eql(body.param.completionDate); + resJson.completionDate.should.be.eql(newBody.param.completionDate); resJson.status.should.be.eql(body.param.status); resJson.type.should.be.eql(body.param.type); resJson.details.should.be.eql({ @@ -1061,6 +1086,30 @@ describe('UPDATE Milestone', () => { .end(done); }); + it('should return 200 for admin updating the completionDate', (done) => { + const newBody = _.cloneDeep(body); + newBody.param.completionDate = '2018-05-16T00:00:00.000Z'; + request(server) + .patch('/v4/timelines/1/milestones/1') + .set({ + Authorization: `Bearer ${testUtil.jwts.admin}`, + }) + .send(newBody) + .expect(200, done); + }); + + it('should return 200 for admin updating the actualStartDate', (done) => { + const newBody = _.cloneDeep(body); + newBody.param.actualStartDate = '2018-05-15T00:00:00.000Z'; + request(server) + .patch('/v4/timelines/1/milestones/1') + .set({ + Authorization: `Bearer ${testUtil.jwts.admin}`, + }) + .send(newBody) + .expect(200, done); + }); + it('should return 200 for connect manager', (done) => { request(server) .patch('/v4/timelines/1/milestones/1')