diff --git a/controllers/extensionRequestsv2.ts b/controllers/extensionRequestsv2.ts index 90bca33ae..df4bffae7 100644 --- a/controllers/extensionRequestsv2.ts +++ b/controllers/extensionRequestsv2.ts @@ -1,5 +1,14 @@ -import { getRequestByKeyValues } from "../models/requests"; -import { LOG_ACTION, REQUEST_LOG_TYPE, REQUEST_STATE, REQUEST_TYPE } from "../constants/requests"; +import { getRequestByKeyValues, updateRequest } from "../models/requests"; +import { + ERROR_WHILE_CREATING_REQUEST, + ERROR_WHILE_UPDATING_REQUEST, + LOG_ACTION, + REQUEST_APPROVED_SUCCESSFULLY, + REQUEST_LOG_TYPE, + REQUEST_REJECTED_SUCCESSFULLY, + REQUEST_STATE, + REQUEST_TYPE, +} from "../constants/requests"; import { addLog } from "../models/logs"; import { createRequest } from "../models/requests"; import { fetchTask } from "../models/tasks"; @@ -52,15 +61,16 @@ export const createTaskExtensionRequest = async (req: ExtensionRequestRequest, r const latestExtensionRequest: ExtensionRequest | undefined = await getRequestByKeyValues({ taskId, - state: REQUEST_STATE.PENDING, type: REQUEST_TYPE.EXTENSION, }); if (latestExtensionRequest && latestExtensionRequest.state === REQUEST_STATE.PENDING) { return res.boom.badRequest("An extension request for this task already exists."); } - - let requestNumber: number = latestExtensionRequest?.requestedBy === requestedBy && latestExtensionRequest.requestNumber ? latestExtensionRequest.requestNumber + 1 : 1; + const requestNumber: number = + latestExtensionRequest?.requestedBy === requestedBy && latestExtensionRequest.requestNumber + ? latestExtensionRequest.requestNumber + 1 + : 1; extensionBody = { ...extensionBody, requestNumber }; const extensionRequest = await createRequest(extensionBody); @@ -87,7 +97,51 @@ export const createTaskExtensionRequest = async (req: ExtensionRequestRequest, r extensionRequest: { ...extensionBody, id: extensionRequest.id }, }); } catch (err) { - logger.error(`Error while creating new extension request: ${err}`); - return res.boom.badImplementation('Internal Server Error'); + logger.error(ERROR_WHILE_CREATING_REQUEST, err); + return res.boom.badImplementation(ERROR_WHILE_CREATING_REQUEST); + } +}; + +export const updateTaskExtensionRequest = async (req: any, res: any) => { + const requestBody = req.body; + const userId = req?.userData?.id; + const requestId = req.params.id; + + if (!userId) { + return res.boom.unauthorized(); + } + + try { + const requestResult = await updateRequest(requestId, requestBody, userId,REQUEST_TYPE.EXTENSION) + if ("error" in requestResult) { + return res.boom.badRequest(requestResult.error); + } + const [logType, returnMessage] = + requestResult.state === REQUEST_STATE.APPROVED + ? [REQUEST_LOG_TYPE.REQUEST_APPROVED, REQUEST_APPROVED_SUCCESSFULLY] + : [REQUEST_LOG_TYPE.REQUEST_REJECTED, REQUEST_REJECTED_SUCCESSFULLY]; + + const requestLog = { + type: logType, + meta: { + requestId: requestId, + action: LOG_ACTION.UPDATE, + createdBy: userId, + createdAt: Date.now(), + }, + body: requestResult, + }; + await addLog(requestLog.type, requestLog.meta, requestLog.body); + + return res.status(201).json({ + message: returnMessage, + data: { + id: requestResult.id, + ...requestResult, + }, + }); + } catch (err) { + logger.error(ERROR_WHILE_UPDATING_REQUEST, err); + return res.boom.badImplementation(ERROR_WHILE_UPDATING_REQUEST); } }; diff --git a/controllers/oooRequests.ts b/controllers/oooRequests.ts index 825b04e69..5463db714 100644 --- a/controllers/oooRequests.ts +++ b/controllers/oooRequests.ts @@ -6,11 +6,18 @@ import { REQUEST_ALREADY_PENDING, REQUEST_STATE, REQUEST_TYPE, + ERROR_WHILE_UPDATING_REQUEST, + REQUEST_APPROVED_SUCCESSFULLY, + REQUEST_REJECTED_SUCCESSFULLY, } from "../constants/requests"; +import { statusState } from "../constants/userStatus"; import { addLog } from "../models/logs"; -import { createRequest, getRequestByKeyValues } from "../models/requests"; +import { createRequest, getRequestByKeyValues, getRequests, updateRequest } from "../models/requests"; +import { createUserFutureStatus } from "../models/userFutureStatus"; +import { addFutureStatus } from "../models/userStatus"; import { CustomResponse } from "../typeDefinitions/global"; import { OooRequestCreateRequest, OooStatusRequest } from "../types/oooRequest"; +import { UpdateRequest } from "../types/requests"; export const createOooRequestController = async (req: OooRequestCreateRequest, res: CustomResponse) => { const requestBody = req.body; @@ -53,3 +60,63 @@ export const createOooRequestController = async (req: OooRequestCreateRequest, r return res.boom.badImplementation(ERROR_WHILE_CREATING_REQUEST); } }; + +export const updateOooRequestController = async (req: UpdateRequest, res: CustomResponse) => { + const requestBody = req.body; + const userId = req?.userData?.id; + const requestId = req.params.id; + if (!userId) { + return res.boom.unauthorized(); + } + + try { + const requestResult = await updateRequest(requestId, requestBody, userId, REQUEST_TYPE.OOO); + if ("error" in requestResult) { + return res.boom.badRequest(requestResult.error); + } + const [logType, returnMessage] = + requestResult.state === REQUEST_STATE.APPROVED + ? [REQUEST_LOG_TYPE.REQUEST_APPROVED, REQUEST_APPROVED_SUCCESSFULLY] + : [REQUEST_LOG_TYPE.REQUEST_REJECTED, REQUEST_REJECTED_SUCCESSFULLY]; + + const requestLog = { + type: logType, + meta: { + requestId: requestId, + action: LOG_ACTION.UPDATE, + createdBy: userId, + createdAt: Date.now(), + }, + body: requestResult, + }; + await addLog(requestLog.type, requestLog.meta, requestLog.body); + if (requestResult.state === REQUEST_STATE.APPROVED) { + const requestData = await getRequests({ id: requestId }); + + if (requestData) { + const { from, until, requestedBy, message } = requestData as any; + const userFutureStatusData = { + requestId, + status: REQUEST_TYPE.OOO, + state: statusState.UPCOMING, + from, + endsOn: until, + userId: requestedBy, + message, + }; + await createUserFutureStatus(userFutureStatusData); + await addFutureStatus(userFutureStatusData); + } + } + return res.status(201).json({ + message: returnMessage, + data: { + id: requestResult.id, + ...requestResult, + }, + }); + } catch (err) { + logger.error(ERROR_WHILE_UPDATING_REQUEST, err); + return res.boom.badImplementation(ERROR_WHILE_UPDATING_REQUEST); + } +}; diff --git a/controllers/requests.ts b/controllers/requests.ts index be66c19bd..6e1d55d82 100644 --- a/controllers/requests.ts +++ b/controllers/requests.ts @@ -1,30 +1,21 @@ import { ERROR_WHILE_FETCHING_REQUEST, - ERROR_WHILE_UPDATING_REQUEST, - REQUEST_REJECTED_SUCCESSFULLY, - REQUEST_APPROVED_SUCCESSFULLY, REQUEST_FETCHED_SUCCESSFULLY, - REQUEST_STATE, - LOG_ACTION, - REQUEST_LOG_TYPE, REQUEST_TYPE, } from "../constants/requests"; -import { statusState } from "../constants/userStatus"; -import { addFutureStatus } from "../models/userStatus"; -import { createUserFutureStatus } from "../models/userFutureStatus"; -import { getRequests, updateRequest } from "../models/requests"; -import { addLog } from "../models/logs"; +import { getRequests } from "../models/requests"; import { getPaginatedLink } from "../utils/helper"; -import { createOooRequestController } from "./oooRequests"; +import { createOooRequestController, updateOooRequestController } from "./oooRequests"; import { OooRequestCreateRequest, OooRequestResponse } from "../types/oooRequest"; import { CustomResponse } from "../typeDefinitions/global"; import { ExtensionRequestRequest, ExtensionRequestResponse } from "../types/extensionRequests"; -import { createTaskExtensionRequest } from "./extensionRequestsv2"; +import { createTaskExtensionRequest, updateTaskExtensionRequest } from "./extensionRequestsv2"; +import { UpdateRequest } from "../types/requests"; export const createRequestController = async ( req: OooRequestCreateRequest | ExtensionRequestRequest, - res: CustomResponse) => { - + res: CustomResponse +) => { const type = req.body.type; switch (type) { case REQUEST_TYPE.OOO: @@ -36,63 +27,15 @@ export const createRequestController = async ( } }; -export const updateRequestController = async (req: any, res: any) => { - const requestBody = req.body; - const userId = req?.userData?.id; - const requestId = req.params.id; - if (!userId) { - return res.boom.unauthorized(); - } - - try { - const requestResult = await updateRequest(requestId, requestBody, userId); - if ("error" in requestResult) { - return res.boom.badRequest(requestResult.error); - } - const [logType, returnMessage] = - requestResult.state === REQUEST_STATE.APPROVED - ? [REQUEST_LOG_TYPE.REQUEST_APPROVED, REQUEST_APPROVED_SUCCESSFULLY] - : [REQUEST_LOG_TYPE.REQUEST_REJECTED, REQUEST_REJECTED_SUCCESSFULLY]; - - const requestLog = { - type: logType, - meta: { - requestId: requestId, - action: LOG_ACTION.UPDATE, - createdBy: userId, - createdAt: Date.now(), - }, - body: requestResult, - }; - await addLog(requestLog.type, requestLog.meta, requestLog.body); - if (requestResult.state === REQUEST_STATE.APPROVED) { - const requestData = await getRequests({ id: requestId }); - - if (requestData) { - const { from, until, requestedBy, message } = requestData as any; - const userFutureStatusData = { - requestId, - status: REQUEST_TYPE.OOO, - state: statusState.UPCOMING, - from, - endsOn: until, - userId: requestedBy, - message, - }; - await createUserFutureStatus(userFutureStatusData); - await addFutureStatus(userFutureStatusData); - } - } - return res.status(201).json({ - message: returnMessage, - data: { - id: requestResult.id, - ...requestResult, - }, - }); - } catch (err) { - logger.error(ERROR_WHILE_UPDATING_REQUEST, err); - return res.boom.badImplementation(ERROR_WHILE_UPDATING_REQUEST); +export const updateRequestController = async (req: UpdateRequest, res: CustomResponse) => { + const type = req.body.type; + switch (type) { + case REQUEST_TYPE.OOO: + return await updateOooRequestController(req as UpdateRequest, res as ExtensionRequestResponse); + case REQUEST_TYPE.EXTENSION: + return await updateTaskExtensionRequest(req as UpdateRequest, res as ExtensionRequestResponse); + default: + return res.boom.badRequest("Invalid request type"); } }; diff --git a/middlewares/validators/oooRequests.ts b/middlewares/validators/oooRequests.ts index 01aa2fd19..1a90aea6e 100644 --- a/middlewares/validators/oooRequests.ts +++ b/middlewares/validators/oooRequests.ts @@ -1,7 +1,7 @@ import joi from "joi"; import { NextFunction } from "express"; import { REQUEST_STATE, REQUEST_TYPE } from "../../constants/requests"; -import { OooRequestCreateRequest, OooRequestResponse,OooRequestUpdateRequest } from "../../types/oooRequest"; +import { OooRequestCreateRequest, OooRequestResponse } from "../../types/oooRequest"; export const createOooStatusRequestValidator = async ( req: OooRequestCreateRequest, @@ -38,26 +38,3 @@ export const createOooStatusRequestValidator = async ( await schema.validateAsync(req.body, { abortEarly: false }); }; - - -export const updateOooStatusRequestValidator = async ( - req: OooRequestUpdateRequest, - -) => { - const schema = joi - .object() - .strict() - .keys({ - reason: joi.string().optional(), - state: joi - .string() - .valid(REQUEST_STATE.APPROVED, REQUEST_STATE.REJECTED) - .required() - .messages({ - "any.only": "state must be APPROVED or REJECTED", - }), - type: joi.string().valid(REQUEST_TYPE.OOO).required(), - }); - - await schema.validateAsync(req.body, { abortEarly: false }); -}; diff --git a/middlewares/validators/requests.ts b/middlewares/validators/requests.ts index c434930e4..8b84b6dd2 100644 --- a/middlewares/validators/requests.ts +++ b/middlewares/validators/requests.ts @@ -1,11 +1,12 @@ import joi from "joi"; import { NextFunction } from "express"; import { REQUEST_STATE, REQUEST_TYPE } from "../../constants/requests"; -import { OooRequestCreateRequest, OooRequestResponse, OooRequestUpdateRequest } from "../../types/oooRequest"; -import { createOooStatusRequestValidator, updateOooStatusRequestValidator } from "./oooRequests"; +import { OooRequestCreateRequest, OooRequestResponse } from "../../types/oooRequest"; +import { createOooStatusRequestValidator } from "./oooRequests"; import { createExtensionRequestValidator } from "./extensionRequestsv2"; import { ExtensionRequestRequest, ExtensionRequestResponse } from "../../types/extensionRequests"; import { CustomResponse } from "../../typeDefinitions/global"; +import { UpdateRequest } from "../../types/requests"; export const createRequestsMiddleware = async ( req: OooRequestCreateRequest|ExtensionRequestRequest, @@ -39,29 +40,37 @@ export const createRequestsMiddleware = async ( }; export const updateRequestsMiddleware = async ( - req: OooRequestUpdateRequest, - res: OooRequestResponse, + req: UpdateRequest, + res: CustomResponse, next: NextFunction ) => { - const type = req.body.type; - // TODO: Remove this check once feature is tested and ready to be used if ( req.query.dev !== "true") { return res.boom.badRequest("Please use feature flag to make this requests"); } + const schema = joi + .object() + .strict() + .keys({ + reason: joi.string().optional() + .messages({ + "string.empty": "reason cannot be empty", + }), + state: joi + .string() + .valid(REQUEST_STATE.APPROVED, REQUEST_STATE.REJECTED) + .required() + .messages({ + "any.only": "state must be APPROVED or REJECTED", + }), + type: joi.string().valid(REQUEST_TYPE.OOO, REQUEST_TYPE.EXTENSION).required(), + }); try { - switch (type) { - case REQUEST_TYPE.OOO: - await updateOooStatusRequestValidator(req as OooRequestUpdateRequest); - break; - default: - res.boom.badRequest(`Invalid request type: ${type}`); - } - + await schema.validateAsync(req.body, { abortEarly: false }); next(); } catch (error) { - const errorMessages = error.details.map((detail) => detail.message); + const errorMessages = error.details.map((detail:any) => detail.message); logger.error(`Error while validating request payload : ${errorMessages}`); res.boom.badRequest(errorMessages); } diff --git a/models/requests.ts b/models/requests.ts index 5eabb0b40..9fda2fcbe 100644 --- a/models/requests.ts +++ b/models/requests.ts @@ -1,4 +1,3 @@ -import { RequestQuery } from "../types/oooRequest"; import firestore from "../utils/firestore"; const requestModel = firestore.collection("requests"); import { REQUEST_ALREADY_APPROVED, REQUEST_ALREADY_REJECTED, REQUEST_STATE } from "../constants/requests"; @@ -8,7 +7,6 @@ import { ERROR_WHILE_UPDATING_REQUEST, REQUEST_DOES_NOT_EXIST, } from "../constants/requests"; -import * as admin from "firebase-admin"; import { getUserId } from "../utils/users"; const SIZE = 5; @@ -31,7 +29,7 @@ export const createRequest = async (body: any) => { } }; -export const updateRequest = async (id: string, body: any, lastModifiedBy: string) => { +export const updateRequest = async (id: string, body: any, lastModifiedBy: string, type:string) => { try { const existingRequestDoc = await requestModel.doc(id).get(); if (!existingRequestDoc.exists) { @@ -49,6 +47,11 @@ export const updateRequest = async (id: string, body: any, lastModifiedBy: strin error: REQUEST_ALREADY_REJECTED, }; } + if (existingRequestDoc.data().type !== type) { + return { + error: REQUEST_DOES_NOT_EXIST, + }; + } const requestBody: any = { updatedAt: Date.now(), @@ -163,7 +166,7 @@ export const getRequestByKeyValues = async (keyValues: KeyValues) => { requestQuery = requestQuery.where(key, "==", value); }); - const requestQueryDoc = await requestQuery.get(); + const requestQueryDoc = await requestQuery.orderBy("createdAt", "desc").limit(1).get(); if (requestQueryDoc.empty) { return null; } @@ -181,3 +184,4 @@ export const getRequestByKeyValues = async (keyValues: KeyValues) => { throw error; } }; + diff --git a/test/integration/requests.test.ts b/test/integration/requests.test.ts index 650f3998b..0add1ee6e 100644 --- a/test/integration/requests.test.ts +++ b/test/integration/requests.test.ts @@ -24,6 +24,8 @@ import { REQUEST_CREATED_SUCCESSFULLY, REQUEST_DOES_NOT_EXIST, REQUEST_ALREADY_PENDING, + REQUEST_REJECTED_SUCCESSFULLY, + REQUEST_ALREADY_REJECTED, } from "../../constants/requests"; import { updateTask } from "../../models/tasks"; @@ -53,7 +55,7 @@ describe("/requests OOO", function () { const { id: pendingOooId }: any = await createRequest(oooRequestData2); pendingOooRequestId = pendingOooId; - const { id: approveOooId }: any = await updateRequest(oooRequestId, { state: "APPROVED" }, superUserId); + const { id: approveOooId }: any = await updateRequest(oooRequestId, { state: REQUEST_STATE.APPROVED }, superUserId, REQUEST_TYPE.OOO); approvedOooRequestId = approveOooId; authToken = authService.generateAuthToken({ userId }); @@ -247,7 +249,7 @@ describe("/requests OOO", function () { .end(function (err, res) { expect(res).to.have.status(400); expect(res.body).to.have.property("message"); - expect(res.body.message).to.equal("Invalid request type: ACTIVE"); + expect(res.body.message).to.equal('"type" must be one of [OOO, EXTENSION]'); done(); }); }); @@ -388,7 +390,6 @@ describe("/requests OOO", function () { }); }); - describe("/requests Extension", function () { let taskId1: string; let taskId2: string; @@ -569,7 +570,6 @@ describe("/requests Extension", function () { }); }); - // Should Return Bad Request for Existing Pending Extension Request it("should not create a new extension request if an extension request for this task already exists", function (done) { const extensionRequestObj = { taskId: taskId1, @@ -601,4 +601,161 @@ describe("/requests Extension", function () { }); }); }); + + describe("PUT /requests/:id", function () { + let approvedExtensionRequestId: string; + let rejectedExtensionRequestId: string; + let pendingExtensionRequestId: string; + + const approvedExtensionRequest = { + state: REQUEST_STATE.APPROVED, + type: REQUEST_TYPE.EXTENSION, + }; + + const rejectedExtensionRequest = { + state: REQUEST_STATE.REJECTED, + type: REQUEST_TYPE.EXTENSION, + }; + + const invalidExtensionRequest = { + state: "ACTIVE", + type: REQUEST_TYPE.EXTENSION, + }; + + beforeEach(async function () { + const extensionRequestObj = { + taskId: taskId1, + ...extensionRequest + }; + const { id: approvedId } = await createRequest({ ...extensionRequestObj, requestedBy: userId1 }); + approvedExtensionRequestId = await updateRequest(approvedId, approvedExtensionRequest, superUserId, REQUEST_TYPE.EXTENSION); + + const { id: rejectedId } = await createRequest({ ...extensionRequestObj, requestedBy: userId1 }); + rejectedExtensionRequestId = await updateRequest(rejectedId, rejectedExtensionRequest, superUserId, REQUEST_TYPE.EXTENSION); + + const { id: pendingId } = await createRequest({ ...extensionRequestObj, requestedBy: userId1 }); + pendingExtensionRequestId = pendingId; + + }); + + it("should return 401(Unauthorized) if user is not logged in", function (done) { + chai + .request(app) + .put(`/requests/${pendingExtensionRequestId}?dev=true`) + .send(approvedExtensionRequest) + .end(function (err, res) { + expect(res).to.have.status(401); + expect(res.body).to.have.property("message"); + expect(res.body.message).to.equal("Unauthenticated User"); + done(); + }); + }); + + it("should return 401 if user is not super user", function (done) { + chai + .request(app) + .put(`/requests/${pendingExtensionRequestId}?dev=true`) + .set("cookie", `${cookieName}=${userJwtToken1}`) + .send(approvedExtensionRequest) + .end(function (err, res) { + expect(res).to.have.status(401); + expect(res.body).to.have.property("message"); + expect(res.body.message).to.equal("You are not authorized for this action."); + done(); + }); + }); + + it("should return 400(Bad Request) if request is already approved", function (done) { + chai + .request(app) + .put(`/requests/${pendingExtensionRequestId}?dev=true`) + .set("cookie", `${cookieName}=${superUserJwtToken}`) + .send(approvedExtensionRequest) + .end(function (err, res) { + expect(res).to.have.status(201); + const id = res.body.data.id; + expect(res.body).to.have.property("message"); + expect(res.body.message).to.equal(REQUEST_APPROVED_SUCCESSFULLY); + + chai + .request(app) + .put(`/requests/${id}?dev=true`) + .set("cookie", `${cookieName}=${superUserJwtToken}`) + .send(approvedExtensionRequest) + .end(function (err, res) { + expect(res).to.have.status(400); + expect(res.body).to.have.property("message"); + expect(res.body.message).to.equal(REQUEST_ALREADY_APPROVED); + done(); + }); + }); + }); + + it("should return 400(Bad Request) if request is already rejected", function (done) { + chai + .request(app) + .put(`/requests/${pendingExtensionRequestId}?dev=true`) + .set("cookie", `${cookieName}=${superUserJwtToken}`) + .send(rejectedExtensionRequest) + .end(function (err, res) { + expect(res).to.have.status(201); + const id = res.body.data.id; + expect(res.body).to.have.property("message"); + expect(res.body.message).to.equal(REQUEST_REJECTED_SUCCESSFULLY); + + chai + .request(app) + .put(`/requests/${id}?dev=true`) + .set("cookie", `${cookieName}=${superUserJwtToken}`) + .send(rejectedExtensionRequest) + .end(function (err, res) { + expect(res).to.have.status(400); + expect(res.body).to.have.property("message"); + expect(res.body.message).to.equal(REQUEST_ALREADY_REJECTED); + done(); + }); + }); + }); + + it("should approve an extension request", function (done) { + chai + .request(app) + .put(`/requests/${pendingExtensionRequestId}?dev=true`) + .set("cookie", `${cookieName}=${superUserJwtToken}`) + .send(approvedExtensionRequest) + .end(function (err, res) { + expect(res).to.have.status(201); + done(); + }); + }); + + it("should return 400(Bad Request) if invalid state is passed", function (done) { + chai + .request(app) + .put(`/requests/${pendingExtensionRequestId}?dev=true`) + .set("cookie", `${cookieName}=${superUserJwtToken}`) + .send(invalidExtensionRequest) + .end(function (err, res) { + expect(res).to.have.status(400); + expect(res.body).to.have.property("message"); + expect(res.body.message).to.equal('state must be APPROVED or REJECTED'); + done(); + }); + }); + + it("should return 404(Not Found) if request does not exist", function (done) { + chai + .request(app) + .put(`/requests/randomId?dev=true`) + .set("cookie", `${cookieName}=${superUserJwtToken}`) + .send(approvedExtensionRequest) + .end(function (err, res) { + expect(res).to.have.status(400); + expect(res.body).to.have.property("message"); + expect(res.body.message).to.equal(REQUEST_DOES_NOT_EXIST); + done(); + }); + }); + }); + }); diff --git a/test/unit/middlewares/oooRequests.test.ts b/test/unit/middlewares/oooRequests.test.ts index 61f4744e6..719ccaaa3 100644 --- a/test/unit/middlewares/oooRequests.test.ts +++ b/test/unit/middlewares/oooRequests.test.ts @@ -4,7 +4,6 @@ const { expect } = chai; import { createOooStatusRequestValidator, - updateOooStatusRequestValidator, } from "./../../../middlewares/validators/oooRequests"; import { validOooStatusRequests, validOooStatusUpdate } from "../../fixtures/oooRequest/oooRequest"; @@ -90,17 +89,4 @@ describe("OOO Status Request Validators", function () { } }); }); - - describe("updateOooStatusRequestValidator", function () { - it("should validate for a valid update ooo request", async function () { - const req = { - body: validOooStatusUpdate, - }; - const res = {}; - const nextSpy = sinon.spy(); - - await updateOooStatusRequestValidator(req as any); - expect(nextSpy.calledOnce); - }); - }); }); diff --git a/test/unit/models/requests.test.ts b/test/unit/models/requests.test.ts index 6c1cb1df6..51107008f 100644 --- a/test/unit/models/requests.test.ts +++ b/test/unit/models/requests.test.ts @@ -51,6 +51,7 @@ describe("models/oooRequests", () => { oooRequest.id, updateOooApprovedRequests, updateOooApprovedRequests.lastModifiedBy + , REQUEST_TYPE.OOO ); expect(updatedOooRequest).to.not.be.null; expect(updatedOooRequest).to.have.property("state"); @@ -59,7 +60,7 @@ describe("models/oooRequests", () => { it("should throw an error if the OOO request does not exist", async () => { try { - await updateRequest("randomId", updateOooApprovedRequests, updateOooApprovedRequests.lastModifiedBy); + await updateRequest("randomId", updateOooApprovedRequests, updateOooApprovedRequests.lastModifiedBy, REQUEST_TYPE.OOO); expect.fail("OOO request does not exist"); } catch (error) { expect(error.message).to.equal("OOO request does not exist"); @@ -68,9 +69,9 @@ describe("models/oooRequests", () => { it("should throw an error if the OOO request is already approved", async () => { const oooRequest: any = await createRequest(createOooStatusRequests); - await updateRequest(oooRequest.id, updateOooApprovedRequests, updateOooApprovedRequests.lastModifiedBy); + await updateRequest(oooRequest.id, updateOooApprovedRequests, updateOooApprovedRequests.lastModifiedBy, REQUEST_TYPE.OOO); try { - await updateRequest(oooRequest.id, updateOooApprovedRequests, updateOooApprovedRequests.lastModifiedBy); + await updateRequest(oooRequest.id, updateOooApprovedRequests, updateOooApprovedRequests.lastModifiedBy, REQUEST_TYPE.OOO); expect.fail("OOO request is already approved"); } catch (error) { expect(error.message).to.equal("OOO request is already approved"); @@ -79,9 +80,9 @@ describe("models/oooRequests", () => { it("should throw an error if the OOO request is already rejected", async () => { const oooRequest: any = await createRequest(createOooStatusRequests); - await updateRequest(oooRequest.id, updateOooRejectedRequests, updateOooRejectedRequests.lastModifiedBy); + await updateRequest(oooRequest.id, updateOooRejectedRequests, updateOooRejectedRequests.lastModifiedBy, REQUEST_TYPE.OOO); try { - await updateRequest(oooRequest.id, updateOooApprovedRequests, updateOooApprovedRequests.lastModifiedBy); + await updateRequest(oooRequest.id, updateOooApprovedRequests, updateOooApprovedRequests.lastModifiedBy, REQUEST_TYPE.OOO); expect.fail("OOO request is already rejected"); } catch (error) { expect(error.message).to.equal("OOO request is already rejected"); @@ -113,7 +114,7 @@ describe("models/oooRequests", () => { it("Should return a list of all the requests with specified state - APPROVED", async () => { const oooRequest: any = await createRequest(createOooStatusRequests); - await updateRequest(oooRequest.id, updateOooApprovedRequests, updateOooApprovedRequests.lastModifiedBy); + await updateRequest(oooRequest.id, updateOooApprovedRequests, updateOooApprovedRequests.lastModifiedBy, REQUEST_TYPE.OOO) const query = { dev: "true", state: REQUEST_STATE.APPROVED }; const oooRequestData = await getRequests(query); expect(oooRequestData.allRequests[0].state).to.be.equal(REQUEST_STATE.APPROVED); diff --git a/types/oooRequest.d.ts b/types/oooRequest.d.ts index 46cf45c27..5655cee01 100644 --- a/types/oooRequest.d.ts +++ b/types/oooRequest.d.ts @@ -2,6 +2,8 @@ import { Request, Response } from "express"; import { REQUEST_STATE, REQUEST_TYPE } from "../constants/requests"; import { userState } from "../constants/userStatus"; import { Boom } from "express-boom"; +import { RequestParams, RequestQuery } from "./requests"; +import { userData } from "./global"; export type OooStatusRequest = { id: string; @@ -37,30 +39,6 @@ export type OooRequestUpdateBody = { updatedAt?: admin.firestore.Timestamp; }; -export type userData= { - id: string; -}; - -export type RequestQuery = { - dev?: string; - type?: string; - requestedBy?: string; - state?: REQUEST_STATE.APPROVED | REQUEST_STATE.PENDING | REQUEST_STATE.REJECTED; - id?: string; - prev?: string; - next?: string; - page?: number; - size?: number; -}; - -export type RequestParams = { - id: string; -}; - -export type RequestParams = { - id: string; -}; - export type OooRequestResponse = Response & { boom: Boom }; export type OooRequestCreateRequest = Request & { OooStatusRequestBody , userData: userData , query: RequestQuery }; diff --git a/types/requests.d.ts b/types/requests.d.ts new file mode 100644 index 000000000..808241a1b --- /dev/null +++ b/types/requests.d.ts @@ -0,0 +1,32 @@ +import { Request } from "express"; +import { REQUEST_STATE, REQUEST_TYPE } from "./../constants/requests"; +import { userData } from "./global"; + +export type UpdateRequestBody = { + type: REQUEST_TYPE.OOO | REQUEST_TYPE.EXTENSION; + reason: string; + state: REQUEST_STATE.APPROVED | REQUEST_STATE.REJECTED; +}; + +export type RequestQuery = { + dev?: string; + type?: string; + requestedBy?: string; + state?: REQUEST_STATE.APPROVED | REQUEST_STATE.PENDING | REQUEST_STATE.REJECTED; + id?: string; + prev?: string; + next?: string; + page?: number; + size?: number; +}; + +export type RequestParams = { + id: string; +}; + +export type UpdateRequest = Request & { + UpdateRequestBody; + userData: userData; + query: RequestQuery; + params: RequestParams; +};