diff --git a/controllers/extensionRequests.js b/controllers/extensionRequests.js index 06bbcca76..7ecab94c6 100644 --- a/controllers/extensionRequests.js +++ b/controllers/extensionRequests.js @@ -16,156 +16,84 @@ const { getFullName } = require("../utils/users"); * @param res {Object} - Express response object */ const createTaskExtensionRequest = async (req, res) => { - const dev = req.query.dev === "true"; - if (dev) { - try { - let extensionBody = req.body; - - let assigneeUsername = await getUsernameElseUndefined(extensionBody.assignee); - let assigneeId = extensionBody.assignee; - if (!assigneeUsername) { - assigneeId = await getUserIdElseUndefined(extensionBody.assignee); - assigneeUsername = extensionBody.assignee; - extensionBody.assignee = assigneeId; - } + try { + let extensionBody = req.body; + + let assigneeUsername = await getUsernameElseUndefined(extensionBody.assignee); + let assigneeId = extensionBody.assignee; + if (!assigneeUsername) { + assigneeId = await getUserIdElseUndefined(extensionBody.assignee); + assigneeUsername = extensionBody.assignee; + extensionBody.assignee = assigneeId; + } - if (!assigneeId) { - return res.boom.badRequest("User Not Found"); - } + if (!assigneeId) { + return res.boom.badRequest("User Not Found"); + } - if (req.userData.id !== extensionBody.assignee && !req.userData.roles?.super_user) { - return res.boom.forbidden("Only assigned user and super user can create an extension request for this task."); - } + if (req.userData.id !== extensionBody.assignee && !req.userData.roles?.super_user) { + return res.boom.forbidden("Only assigned user and super user can create an extension request for this task."); + } - const { taskData: task } = await tasks.fetchTask(extensionBody.taskId); - if (!task) { - return res.boom.badRequest("Task Not Found"); - } - if (task.assignee !== assigneeUsername) { - return res.boom.badRequest("This task is assigned to some different user."); - } - if (task.endsOn >= extensionBody.newEndsOn) { - return res.boom.badRequest("New ETA must be greater than Old ETA"); - } - if (extensionBody.oldEndsOn !== task.endsOn) { - extensionBody.oldEndsOn = task.endsOn; - } + const { taskData: task } = await tasks.fetchTask(extensionBody.taskId); + if (!task) { + return res.boom.badRequest("Task Not Found"); + } + if (task.assignee !== assigneeUsername) { + return res.boom.badRequest("This task is assigned to some different user."); + } + if (task.endsOn >= extensionBody.newEndsOn) { + return res.boom.badRequest("New ETA must be greater than Old ETA"); + } + if (extensionBody.oldEndsOn !== task.endsOn) { + extensionBody.oldEndsOn = task.endsOn; + } - const latestExtensionRequest = await extensionRequestsQuery.fetchLatestExtensionRequest({ - taskId: extensionBody.taskId, - }); + const latestExtensionRequest = await extensionRequestsQuery.fetchLatestExtensionRequest({ + taskId: extensionBody.taskId, + }); - if (latestExtensionRequest && latestExtensionRequest.status === EXTENSION_REQUEST_STATUS.PENDING) { - return res.boom.badRequest("An extension request for this task already exists."); - } + if (latestExtensionRequest && latestExtensionRequest.status === EXTENSION_REQUEST_STATUS.PENDING) { + return res.boom.badRequest("An extension request for this task already exists."); + } - let requestNumber; - if (latestExtensionRequest && latestExtensionRequest.assigneeId === assigneeId) { - if (latestExtensionRequest.requestNumber && latestExtensionRequest.requestNumber > 0) { - requestNumber = latestExtensionRequest.requestNumber + 1; - extensionBody = { ...extensionBody, requestNumber }; - } else { - extensionBody = { ...extensionBody, requestNumber: 2 }; - } + let requestNumber; + if (latestExtensionRequest && latestExtensionRequest.assigneeId === assigneeId) { + if (latestExtensionRequest.requestNumber && latestExtensionRequest.requestNumber > 0) { + requestNumber = latestExtensionRequest.requestNumber + 1; + extensionBody = { ...extensionBody, requestNumber }; } else { - extensionBody = { ...extensionBody, requestNumber: 1 }; + extensionBody = { ...extensionBody, requestNumber: 2 }; } - - const extensionRequest = await extensionRequestsQuery.createExtensionRequest(extensionBody); - const extensionLog = { - type: "extensionRequests", - meta: { - taskId: extensionBody.taskId, - createdBy: req.userData.id, - }, - body: { - extensionRequestId: extensionRequest.id, - oldEndsOn: task.endsOn, - newEndsOn: extensionBody.newEndsOn, - assignee: extensionBody.assignee, - status: EXTENSION_REQUEST_STATUS.PENDING, - }, - }; - - await addLog(extensionLog.type, extensionLog.meta, extensionLog.body); - - return res.json({ - message: "Extension Request created successfully!", - extensionRequest: { ...extensionBody, id: extensionRequest.id }, - }); - } catch (err) { - logger.error(`Error while creating new extension request: ${err}`); - return res.boom.badImplementation(INTERNAL_SERVER_ERROR); + } else { + extensionBody = { ...extensionBody, requestNumber: 1 }; } - } else { - try { - const extensionBody = req.body; - - let assigneeUsername = await getUsernameElseUndefined(extensionBody.assignee); - let assigneeId = extensionBody.assignee; - if (!assigneeUsername) { - assigneeId = await getUserIdElseUndefined(extensionBody.assignee); - assigneeUsername = extensionBody.assignee; - extensionBody.assignee = assigneeId; - } - - if (!assigneeId) { - return res.boom.badRequest("User with this id or username doesn't exist."); - } - - if (req.userData.id !== extensionBody.assignee && !req.userData.roles?.super_user) { - return res.boom.forbidden("Only assigned user and super user can create an extension request for this task."); - } - const { taskData: task } = await tasks.fetchTask(extensionBody.taskId); - if (!task) { - return res.boom.badRequest("Task with this id or taskid doesn't exist."); - } - if (task.assignee !== assigneeUsername) { - return res.boom.badRequest("This task is assigned to some different user"); - } - if (task.endsOn >= extensionBody.newEndsOn) { - return res.boom.badRequest("The value for newEndsOn should be greater than the previous ETA"); - } - if (extensionBody.oldEndsOn !== task.endsOn) { - extensionBody.oldEndsOn = task.endsOn; - } - - const prevExtensionRequest = await extensionRequestsQuery.fetchExtensionRequests({ + const extensionRequest = await extensionRequestsQuery.createExtensionRequest(extensionBody); + const extensionLog = { + type: "extensionRequests", + meta: { taskId: extensionBody.taskId, + createdBy: req.userData.id, + }, + body: { + extensionRequestId: extensionRequest.id, + oldEndsOn: task.endsOn, + newEndsOn: extensionBody.newEndsOn, assignee: extensionBody.assignee, - }); - if (prevExtensionRequest.length) { - return res.boom.forbidden("An extension request for this task already exists."); - } - - const extensionRequest = await extensionRequestsQuery.createExtensionRequest(extensionBody); - - const extensionLog = { - type: "extensionRequests", - meta: { - taskId: extensionBody.taskId, - createdBy: req.userData.id, - }, - body: { - extensionRequestId: extensionRequest.id, - oldEndsOn: task.endsOn, - newEndsOn: extensionBody.newEndsOn, - assignee: extensionBody.assignee, - status: EXTENSION_REQUEST_STATUS.PENDING, - }, - }; + status: EXTENSION_REQUEST_STATUS.PENDING, + }, + }; - await addLog(extensionLog.type, extensionLog.meta, extensionLog.body); + await addLog(extensionLog.type, extensionLog.meta, extensionLog.body); - return res.json({ - message: "Extension Request created successfully!", - extensionRequest: { ...extensionBody, id: extensionRequest.id }, - }); - } catch (err) { - logger.error(`Error while creating new extension request: ${err}`); - return res.boom.badImplementation(INTERNAL_SERVER_ERROR); - } + return res.json({ + message: "Extension Request created successfully!", + extensionRequest: { ...extensionBody, id: extensionRequest.id }, + }); + } catch (err) { + logger.error(`Error while creating new extension request: ${err}`); + return res.boom.badImplementation(INTERNAL_SERVER_ERROR); } }; diff --git a/test/integration/extensionRequests.test.js b/test/integration/extensionRequests.test.js index 9a1915299..3f0d70580 100644 --- a/test/integration/extensionRequests.test.js +++ b/test/integration/extensionRequests.test.js @@ -30,6 +30,8 @@ describe("Extension Requests", function () { taskId2, taskId3, taskId4, + taskId5, + taskId6, extensionRequestId1, extensionRequestId2, extensionRequestId3, @@ -115,6 +117,30 @@ describe("Extension Requests", function () { completionAward: { [DINERO]: 3, [NEELAM]: 300 }, lossRate: { [DINERO]: 1 }, }, + { + title: "Task with multiple requests", + type: "feature", + endsOn: 1234, + startedOn: 4567, + status: "active", + percentCompleted: 10, + assignee: appOwner.username, + isNoteworthy: true, + completionAward: { [DINERO]: 3, [NEELAM]: 300 }, + lossRate: { [DINERO]: 1 }, + }, + { + title: "Task with pending request", + type: "feature", + endsOn: 1234, + startedOn: 4567, + status: "active", + percentCompleted: 10, + assignee: appOwner.username, + isNoteworthy: true, + completionAward: { [DINERO]: 3, [NEELAM]: 300 }, + lossRate: { [DINERO]: 1 }, + }, ]; // Add the active task @@ -127,6 +153,8 @@ describe("Extension Requests", function () { // Add the completed task taskId3 = (await tasks.updateTask(taskData[3])).taskId; taskId4 = (await tasks.updateTask(taskData[4])).taskId; + taskId5 = (await tasks.updateTask(taskData[5])).taskId; + taskId6 = (await tasks.updateTask(taskData[6])).taskId; const extensionRequest = { taskId: taskId3, @@ -176,11 +204,21 @@ describe("Extension Requests", function () { reason: "family event", status: "PENDING", }; + const extensionRequest6 = { + taskId: taskId6, + title: "change ETA", + assignee: user.id, + oldEndsOn: 1234, + newEndsOn: 1235, + reason: "family event", + status: "PENDING", + }; extensionRequestId1 = (await extensionRequests.createExtensionRequest(extensionRequest)).id; extensionRequestId2 = (await extensionRequests.createExtensionRequest(extensionRequest1)).id; extensionRequestId3 = (await extensionRequests.createExtensionRequest(extensionRequest2)).id; extensionRequestId4 = (await extensionRequests.createExtensionRequest(extensionRequest3)).id; extensionRequestId5 = (await extensionRequests.createExtensionRequest(extensionRequest4)).id; + await extensionRequests.createExtensionRequest(extensionRequest6); }); after(async function () { @@ -333,7 +371,7 @@ describe("Extension Requests", function () { return done(err); } expect(res).to.have.status(400); - expect(res.body.message).to.equal("User with this id or username doesn't exist."); + expect(res.body.message).to.equal("User Not Found"); return done(); }); }); @@ -387,7 +425,7 @@ describe("Extension Requests", function () { expect(res).to.have.status(400); expect(res.body).to.be.a("object"); - expect(res.body.message).to.equal("Task with this id or taskid doesn't exist."); + expect(res.body.message).to.equal("Task Not Found"); return done(); }); }); @@ -413,7 +451,7 @@ describe("Extension Requests", function () { expect(res).to.have.status(400); expect(res.body).to.be.a("object"); - expect(res.body.message).to.equal("This task is assigned to some different user"); + expect(res.body.message).to.equal("This task is assigned to some different user."); return done(); }); }); @@ -438,34 +476,54 @@ describe("Extension Requests", function () { } expect(res).to.have.status(400); expect(res.body).to.be.a("object"); - expect(res.body.message).to.equal("The value for newEndsOn should be greater than the previous ETA"); + expect(res.body.message).to.equal("New ETA must be greater than Old ETA"); return done(); }); }); - it("Should return fail response if extension request for a task already exists", function (done) { - chai + it("should create a new extension request when no previous extension request exists and make the requestNumber to 1", async function () { + const requestData = { + taskId: taskId5, + title: "change ETA", + assignee: appOwner.id, + oldEndsOn: 1234, + newEndsOn: 1235, + reason: "family event", + status: "PENDING", + }; + + const res = await chai .request(app) .post("/extension-requests") .set("cookie", `${cookieName}=${appOwnerjwt}`) - .send({ - taskId: taskId3, - title: "change ETA", - assignee: appOwner.id, - oldEndsOn: 1234, - newEndsOn: 1235, - reason: "family event", - status: "PENDING", - }) - .end((err, res) => { - if (err) { - return done(err); - } - expect(res).to.have.status(403); - expect(res.body).to.be.a("object"); - expect(res.body.message).to.equal("An extension request for this task already exists."); - return done(); - }); + .send(requestData); + + expect(res).to.have.status(200); + expect(res.body.message).to.equal("Extension Request created successfully!"); + + expect(res.body.extensionRequest.requestNumber).to.be.equal(1); + expect(res.body.extensionRequest).to.be.an("object"); + }); + + it("should handle the case when a previous extension request is pending so api should not allow and throw a proper message", async function () { + const requestData = { + taskId: taskId6, + title: "change ETA", + assignee: appOwner.id, + oldEndsOn: 1235, + newEndsOn: 1236, + reason: "family event", + status: "PENDING", + }; + + const res = await chai + .request(app) + .post("/extension-requests") + .set("cookie", `${cookieName}=${appOwnerjwt}`) + .send(requestData); + + expect(res).to.have.status(400); + expect(res.body.message).to.equal("An extension request for this task already exists."); }); it("Should return success response after adding the extension request and also there should be a log for the same", function (done) { diff --git a/test/integration/multilpleExtensionRequest.test.js b/test/integration/multilpleExtensionRequest.test.js index 75a08996e..2a8e6dff4 100644 --- a/test/integration/multilpleExtensionRequest.test.js +++ b/test/integration/multilpleExtensionRequest.test.js @@ -12,7 +12,6 @@ const config = require("config"); const cookieName = config.get("userToken.cookieName"); const userData = require("../fixtures/user/user")(); const cleanDb = require("../utils/cleanDb"); -const { EXTENSION_REQUEST_STATUS } = require("../../constants/extensionRequests"); const taskData = require("../fixtures/tasks/multiple-extension-requests-tasks")(); chai.use(chaiHttp); @@ -20,7 +19,7 @@ const user = userData[5]; const appOwner = userData[3]; let userJWT; describe("Multiple Extension Requests", function () { - let taskId0, taskId1, taskId2, taskId3; + let taskId1; before(async function () { const userId = await addUser(user); @@ -29,10 +28,7 @@ describe("Multiple Extension Requests", function () { appOwner.id = appOwnerUserId; userJWT = authService.generateAuthToken({ userId: userId }); // Add the active task - taskId0 = (await tasks.updateTask(taskData[0])).taskId; - taskId1 = (await tasks.updateTask(taskData[1])).taskId; - taskId2 = (await tasks.updateTask(taskData[2])).taskId; - taskId3 = (await tasks.updateTask(taskData[3])).taskId; + taskId1 = (await tasks.updateTask(taskData[2])).taskId; }); after(async function () { @@ -43,244 +39,6 @@ describe("Multiple Extension Requests", function () { sinon.restore(); }); - describe("POST /extension-requests - allows the creation of extension request", function () { - // Stub the extensionRequestsQuery.fetchLatestExtensionRequest method - let fetchLatestExtensionRequestStub; - - beforeEach(function () { - // Create a Sinon sandbox - fetchLatestExtensionRequestStub = sinon.stub(extensionRequests, "fetchLatestExtensionRequest"); - }); - - afterEach(function () { - // Restore the stub after each test - fetchLatestExtensionRequestStub.restore(); - }); - - it("Should return success response after adding the extension request (sending assignee username)", function (done) { - fetchLatestExtensionRequestStub.returns([]); - chai - .request(app) - .post("/extension-requests/?dev=true") - .set("cookie", `${cookieName}=${userJWT}`) - .send({ - taskId: taskId0, - title: "change ETA", - assignee: user.username, - oldEndsOn: 1234, - newEndsOn: 1235, - reason: "family event", - status: "PENDING", - }) - .end((err, res) => { - if (err) { - return done(err); - } - expect(res).to.have.status(200); - expect(res.body).to.be.a("object"); - expect(res.body.message).to.equal("Extension Request created successfully!"); - expect(res.body.extensionRequest).to.be.a("object"); - expect(res.body.extensionRequest.assignee).to.equal(user.id); - expect(res.body.extensionRequest.status).to.equal(EXTENSION_REQUEST_STATUS.PENDING); - return done(); - }); - }); - - it("Should return failure response after adding the extension request (sending wrong assignee info)", function (done) { - chai - .request(app) - .post("/extension-requests/?dev=true") - .set("cookie", `${cookieName}=${userJWT}`) - .send({ - taskId: taskId0, - title: "change ETA", - assignee: "hello", - oldEndsOn: 1234, - newEndsOn: 1235, - reason: "family event", - status: "PENDING", - }) - .end((err, res) => { - if (err) { - return done(err); - } - expect(res).to.have.status(400); - expect(res.body.message).to.equal("User Not Found"); - return done(); - }); - }); - - it("Should return fail response if someone try to create an extension request for someone else and is not a super user", function (done) { - chai - .request(app) - .post("/extension-requests/?dev=true") - .set("cookie", `${cookieName}=${userJWT}`) - .send({ - taskId: taskId3, - title: "change ETA", - assignee: appOwner.id, - oldEndsOn: 1234, - newEndsOn: 1235, - reason: "family event", - status: "PENDING", - }) - .end((err, res) => { - if (err) { - return done(err); - } - - expect(res).to.have.status(403); - expect(res.body).to.be.a("object"); - expect(res.body.message).to.equal( - "Only assigned user and super user can create an extension request for this task." - ); - return done(); - }); - }); - - it("Should return fail response if task with the taskId doesn't exists", function (done) { - chai - .request(app) - .post("/extension-requests/?dev=true") - .set("cookie", `${cookieName}=${userJWT}`) - .send({ - taskId: "12345678", - title: "change ETA", - assignee: user.id, - oldEndsOn: 1234, - newEndsOn: 1235, - reason: "family event", - status: "PENDING", - }) - .end((err, res) => { - if (err) { - return done(err); - } - - expect(res).to.have.status(400); - expect(res.body).to.be.a("object"); - expect(res.body.message).to.equal("Task Not Found"); - return done(); - }); - }); - - it("Should return fail response if task belongs to someone else", function (done) { - chai - .request(app) - .post("/extension-requests?dev=true") - .set("cookie", `${cookieName}=${userJWT}`) - .send({ - taskId: taskId2, - title: "change ETA", - assignee: user.id, // sending wrong assignee as task is assigned to appOwner - oldEndsOn: 1234, - newEndsOn: 1235, - reason: "family event", - status: "PENDING", - }) - .end((err, res) => { - if (err) { - return done(err); - } - - expect(res).to.have.status(400); - expect(res.body).to.be.a("object"); - expect(res.body.message).to.equal("This task is assigned to some different user."); - return done(); - }); - }); - - it("should create a new extension request when dev flag is true and no previous extension request exists and make the requestNumber to 1", async function () { - fetchLatestExtensionRequestStub.returns([]); - - const requestData = { - taskId: taskId1, - title: "change ETA", - assignee: user.id, - oldEndsOn: 1234, - newEndsOn: 1235, - reason: "family event", - status: "PENDING", - }; - - const res = await chai - .request(app) - .post("/extension-requests?dev=true") - .set("cookie", `${cookieName}=${userJWT}`) - .send(requestData); - - expect(res).to.have.status(200); - expect(res.body.message).to.equal("Extension Request created successfully!"); - - expect(res.body.extensionRequest.requestNumber).to.be.equal(1); - expect(res.body.extensionRequest).to.be.an("object"); - }); - - it("should handle the case when a previous extension request is pending so api should not allow and throw a proper message", async function () { - fetchLatestExtensionRequestStub.returns({ - taskId: taskId1, - title: "change ETA", - assignee: user.id, - oldEndsOn: 1234, - newEndsOn: 1235, - reason: "family event", - status: "PENDING", - }); - - const requestData = { - taskId: taskId1, - title: "change ETA", - assignee: user.id, - oldEndsOn: 1235, - newEndsOn: 1236, - reason: "family event", - status: "PENDING", - }; - - const res = await chai - .request(app) - .post("/extension-requests?dev=true") - .set("cookie", `${cookieName}=${userJWT}`) - .send(requestData); - - expect(res).to.have.status(400); - expect(res.body.message).to.equal("An extension request for this task already exists."); - sinon.assert.calledOnce(fetchLatestExtensionRequestStub); - }); - - it("should return fail response if newETAshould return success response and an empty array of extensionRequest if assignee is not same as latest one", function (done) { fetchLatestExtensionRequestStub.returns({ - taskId: taskId2, + taskId: taskId1, title: "change ETA", assignee: "mayur", oldEndsOn: 1234, @@ -307,7 +65,7 @@ describe("Multiple Extension Requests", function () { chai .request(app) .get(`/extension-requests/self`) - .query({ taskId: taskId2, dev: "true" }) + .query({ taskId: taskId1, dev: "true" }) .set("cookie", `${cookieName}=${userJWT}`) .end((err, res) => { if (err) { @@ -324,7 +82,7 @@ describe("Multiple Extension Requests", function () { it("Dev-flag true->should return success response and a single latestExtensionRequest if assignee same as latest one", function (done) { fetchLatestExtensionRequestStub.returns({ - taskId: taskId2, + taskId: taskId1, title: "change ETA", assigneeId: user.id, assignee: "mayur", @@ -339,7 +97,7 @@ describe("Multiple Extension Requests", function () { chai .request(app) .get(`/extension-requests/self`) - .query({ taskId: taskId2, dev: "true" }) + .query({ taskId: taskId1, dev: "true" }) .set("cookie", `${cookieName}=${userJWT}`) .end((err, res) => { if (err) {