Skip to content

Commit 398d1f9

Browse files
committed
feat: acknowledge OOO request
1 parent f171027 commit 398d1f9

File tree

9 files changed

+153
-155
lines changed

9 files changed

+153
-155
lines changed

constants/requests.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ export const REQUEST_ALREADY_PENDING = "Request already exists please wait for a
4848
export const UNAUTHORIZED_TO_CREATE_OOO_REQUEST = "Unauthorized to create OOO request";
4949
export const USER_STATUS_NOT_FOUND = "User status not found";
5050
export const OOO_STATUS_ALREADY_EXIST = "Your status is already OOO. Please cancel OOO to raise new one";
51-
export const UNAUTHORIZED_TO_ACKNOWLEDGE_OOO_REQUEST = "Only super users are allowed to acknowledge OOO requests";
5251

5352
export const TASK_REQUEST_MESSAGES = {
5453
NOT_AUTHORIZED_TO_CREATE_REQUEST: "Not authorized to create the request",

controllers/oooRequests.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {
1212
REQUEST_ALREADY_PENDING,
1313
USER_STATUS_NOT_FOUND,
1414
OOO_STATUS_ALREADY_EXIST,
15-
UNAUTHORIZED_TO_ACKNOWLEDGE_OOO_REQUEST,
15+
UNAUTHORIZED_TO_UPDATE_REQUEST,
1616
ERROR_WHILE_ACKNOWLEDGING_REQUEST,
1717
REQUEST_DOES_NOT_EXIST,
1818
INVALID_REQUEST_TYPE,
@@ -172,15 +172,16 @@ export const acknowledgeOooRequestController = async (
172172

173173
if(!dev) return res.boom.notImplemented("Feature not implemented");
174174

175-
const requestBody = req.body;
176-
const superUserId = req.userData.id;
177-
const requestId = req.params.id;
178175
const isSuperuser = req.userData.roles?.super_user;
179176

180177
if (!isSuperuser) {
181-
return res.boom.forbidden(UNAUTHORIZED_TO_ACKNOWLEDGE_OOO_REQUEST);
178+
return res.boom.forbidden(UNAUTHORIZED_TO_UPDATE_REQUEST);
182179
}
183180

181+
const requestBody = req.body;
182+
const superUserId = req.userData.id;
183+
const requestId = req.params.id;
184+
184185
try {
185186

186187
const response = await acknowledgeOooRequest(requestId, requestBody, superUserId);

middlewares/validators/oooRequests.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,20 +39,7 @@ export const createOooStatusRequestValidator = async (
3939
await schema.validateAsync(req.body, { abortEarly: false });
4040
};
4141

42-
/**
43-
* Middleware to validate the acknowledge Out-Of-Office (OOO) request payload.
44-
*
45-
* @param {AcknowledgeOooRequest} req - The request object containing the body to be validated.
46-
* @param {OooRequestResponse} res - The response object used to send error responses if validation fails.
47-
* @param {NextFunction} next - The next middleware function to call if validation succeeds.
48-
* @returns {Promise<void>} Resolves or sends errors.
49-
*/
50-
export const acknowledgeOooRequestsValidator = async (
51-
req: AcknowledgeOooRequest,
52-
res: OooRequestResponse,
53-
next: NextFunction
54-
): Promise<void> => {
55-
const schema = joi
42+
const schema = joi
5643
.object()
5744
.strict()
5845
.keys({
@@ -72,6 +59,19 @@ export const acknowledgeOooRequestsValidator = async (
7259
})
7360
});
7461

62+
/**
63+
* Middleware to validate the acknowledge Out-Of-Office (OOO) request payload.
64+
*
65+
* @param {AcknowledgeOooRequest} req - The request object containing the body to be validated.
66+
* @param {OooRequestResponse} res - The response object used to send error responses if validation fails.
67+
* @param {NextFunction} next - The next middleware function to call if validation succeeds.
68+
* @returns {Promise<void>} Resolves or sends errors.
69+
*/
70+
export const acknowledgeOooRequestsValidator = async (
71+
req: AcknowledgeOooRequest,
72+
res: OooRequestResponse,
73+
next: NextFunction
74+
): Promise<void> => {
7575
try {
7676
await schema.validateAsync(req.body, { abortEarly: false });
7777
next();

models/requests.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,23 @@ export const updateRequest = async (id: string, body: any, lastModifiedBy: strin
6969
}
7070
};
7171

72+
export const getRequestById = async (id: string) => {
73+
try {
74+
const requestDoc = await requestModel.doc(id).get();
75+
76+
if (!requestDoc.exists) {
77+
return {
78+
error: REQUEST_DOES_NOT_EXIST,
79+
};
80+
}
81+
82+
return requestDoc.data();
83+
} catch (error) {
84+
logger.error(ERROR_WHILE_FETCHING_REQUEST, error);
85+
throw error;
86+
}
87+
};
88+
7289
export const getRequests = async (query: any) => {
7390
let { id, type, requestedBy, state, prev, next, page, size = SIZE } = query;
7491
const dev = query.dev === "true";

services/oooRequest.ts

Lines changed: 9 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,14 @@ import {
1414
INVALID_REQUEST_TYPE,
1515
} from "../constants/requests";
1616
import { userState } from "../constants/userStatus";
17-
import { createRequest } from "../models/requests";
17+
import { createRequest, getRequestById } from "../models/requests";
1818
import { OooStatusRequest, OooStatusRequestBody } from "../types/oooRequest";
1919
import { UserStatus } from "../types/userStatus";
2020
import { addLog } from "./logService";
21-
import firestore from "../utils/firestore";
2221
import { BadRequest } from "http-errors";
2322
import { updateRequest } from "../models/requests";
2423
import { AcknowledgeOooRequestBody } from "../types/oooRequest";
2524
import { addFutureStatus } from "../models/userStatus";
26-
const requestModel = firestore.collection("requests");
2725

2826
/**
2927
* Validates the user status.
@@ -124,30 +122,18 @@ export const validateOooAcknowledgeRequest = async (
124122
try {
125123

126124
if (requestType !== REQUEST_TYPE.OOO) {
127-
await addLog(logType.INVALID_REQUEST_TYPE,
128-
{ requestId, type: requestType },
129-
{ message: INVALID_REQUEST_TYPE }
130-
);
131125
return {
132126
error: INVALID_REQUEST_TYPE
133127
};
134128
}
135129

136130
if (requestStatus === REQUEST_STATE.APPROVED) {
137-
await addLog(logType.REQUEST_ALREADY_APPROVED,
138-
{ oooRequestId: requestId },
139-
{ message: REQUEST_ALREADY_APPROVED }
140-
);
141131
return {
142132
error: REQUEST_ALREADY_APPROVED
143133
};
144134
}
145135

146136
if (requestStatus === REQUEST_STATE.REJECTED) {
147-
await addLog(logType.REQUEST_ALREADY_REJECTED,
148-
{ oooRequestId: requestId },
149-
{ message: REQUEST_ALREADY_REJECTED }
150-
);
151137
return {
152138
error: REQUEST_ALREADY_REJECTED
153139
};
@@ -173,25 +159,21 @@ export const acknowledgeOooRequest = async (
173159
superUserId: string,
174160
) => {
175161
try {
176-
const request = await requestModel.doc(requestId).get();
162+
const requestData = await getRequestById(requestId);
177163

178-
if (!request.exists) {
179-
await addLog(logType.REQUEST_DOES_NOT_EXIST,
180-
{ oooRequestId: requestId },
181-
{ message: REQUEST_DOES_NOT_EXIST }
182-
);
164+
if (requestData.error) {
165+
logger.error("Error while acknowledging OOO request", { requestId, reason: REQUEST_DOES_NOT_EXIST });
183166
return {
184167
error: REQUEST_DOES_NOT_EXIST
185168
};
186169
}
187170

188-
const requestData = request.data();
171+
const validationError = await validateOooAcknowledgeRequest(requestId, requestData.type, requestData.status);
189172

190-
const validationResponse = await validateOooAcknowledgeRequest(requestId, requestData.type, requestData.status);
191-
192-
if (validationResponse) {
173+
if (validationError) {
174+
logger.error(`Error while validating OOO acknowledge request`, { requestId, reason: validationError.error });
193175
return {
194-
error: validationResponse.error
176+
error: validationError.error
195177
};
196178
}
197179

@@ -209,10 +191,9 @@ export const acknowledgeOooRequest = async (
209191
const requestLog = {
210192
type: acknowledgeLogType,
211193
meta: {
212-
requestId: requestId,
194+
requestId,
213195
action: LOG_ACTION.UPDATE,
214196
userId: superUserId,
215-
createdAt: Date.now(),
216197
},
217198
body: requestResult,
218199
};

test/fixtures/oooRequest/oooRequest.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ export const createOooRequests3 = {
168168
status: REQUEST_STATE.PENDING
169169
};
170170

171-
export const acknowledgeOooRequest = {
171+
export const testAcknowledgeOooRequest = {
172172
type: REQUEST_TYPE.OOO,
173173
status: REQUEST_STATE.APPROVED,
174174
comment: "OOO request approved as it's emergency."

test/integration/requests.test.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
validOooStatusRequests,
1616
validOooStatusUpdate,
1717
createOooRequests2,
18-
acknowledgeOooRequest,
18+
testAcknowledgeOooRequest,
1919
createOooRequests3,
2020
} from "../fixtures/oooRequest/oooRequest";
2121
import { createRequest, updateRequest } from "../../models/requests";
@@ -30,7 +30,7 @@ import {
3030
REQUEST_REJECTED_SUCCESSFULLY,
3131
REQUEST_ALREADY_REJECTED,
3232
INVALID_REQUEST_TYPE,
33-
// UNAUTHORIZED_TO_ACKNOWLEDGE_OOO_REQUEST,
33+
UNAUTHORIZED_TO_UPDATE_REQUEST,
3434
UNAUTHORIZED_TO_CREATE_OOO_REQUEST,
3535
USER_STATUS_NOT_FOUND,
3636
OOO_STATUS_ALREADY_EXIST,
@@ -323,7 +323,7 @@ describe("/requests OOO", function () {
323323
});
324324
});
325325

326-
describe.skip("PATCH /requests/:id", function () {
326+
describe("PATCH /requests/:id", function () {
327327
let testOooRequest;
328328
let onboardingRequest;
329329
let approvedOooRequest;
@@ -352,7 +352,7 @@ describe("/requests OOO", function () {
352352
chai
353353
.request(app)
354354
.patch(`/requests/${testOooRequest.id}?dev=true`)
355-
.send(acknowledgeOooRequest)
355+
.send(testAcknowledgeOooRequest)
356356
.end(function (err, res) {
357357
expect(res).to.have.status(401);
358358
expect(res.body.error).to.equal("Unauthorized");
@@ -366,7 +366,7 @@ describe("/requests OOO", function () {
366366
.request(app)
367367
.patch(`/requests/${testOooRequest.id}?dev=false`)
368368
.set("cookie", `${cookieName}=${superUserToken}`)
369-
.send(acknowledgeOooRequest)
369+
.send(testAcknowledgeOooRequest)
370370
.end(function (err, res) {
371371
if (err) {
372372
return done(err);
@@ -382,7 +382,7 @@ describe("/requests OOO", function () {
382382
.request(app)
383383
.patch(`/requests/11111111111111?dev=true`)
384384
.set("cookie", `${cookieName}=${superUserToken}`)
385-
.send(acknowledgeOooRequest)
385+
.send(testAcknowledgeOooRequest)
386386
.end(function (err, res) {
387387
if (err) {
388388
return done(err);
@@ -398,13 +398,13 @@ describe("/requests OOO", function () {
398398
.request(app)
399399
.patch(`/requests/${testOooRequest.id}?dev=true`)
400400
.set("cookie", `${cookieName}=${authToken}`)
401-
.send(acknowledgeOooRequest)
401+
.send(testAcknowledgeOooRequest)
402402
.end(function (err, res) {
403403
if (err) {
404404
return done(err);
405405
}
406406
expect(res.statusCode).to.equal(403);
407-
// expect(res.body.message).to.equal(UNAUTHORIZED_TO_ACKNOWLEDGE_OOO_REQUEST);
407+
expect(res.body.message).to.equal(UNAUTHORIZED_TO_UPDATE_REQUEST);
408408
done();
409409
});
410410
});
@@ -414,7 +414,7 @@ describe("/requests OOO", function () {
414414
.request(app)
415415
.patch(`/requests/${approvedOooRequest.id}?dev=true`)
416416
.set("cookie", `${cookieName}=${superUserToken}`)
417-
.send(acknowledgeOooRequest)
417+
.send(testAcknowledgeOooRequest)
418418
.end(function (err, res) {
419419
if (err) {
420420
return done(err);
@@ -430,7 +430,7 @@ describe("/requests OOO", function () {
430430
.request(app)
431431
.patch(`/requests/${rejectedOooRequest.id}?dev=true`)
432432
.set("cookie", `${cookieName}=${superUserToken}`)
433-
.send(acknowledgeOooRequest)
433+
.send(testAcknowledgeOooRequest)
434434
.end(function (err, res) {
435435
if (err) {
436436
return done(err);
@@ -446,7 +446,7 @@ describe("/requests OOO", function () {
446446
.request(app)
447447
.patch(`/requests/${onboardingRequest.id}?dev=true`)
448448
.set("cookie", `${cookieName}=${superUserToken}`)
449-
.send(acknowledgeOooRequest)
449+
.send(testAcknowledgeOooRequest)
450450
.end(function (err, res) {
451451
if (err) {
452452
return done(err);
@@ -462,7 +462,7 @@ describe("/requests OOO", function () {
462462
.request(app)
463463
.patch(`/requests/${testOooRequest.id}?dev=true`)
464464
.set("cookie", `${cookieName}=${superUserToken}`)
465-
.send(acknowledgeOooRequest)
465+
.send(testAcknowledgeOooRequest)
466466
.end(function (err, res) {
467467
if (err) {
468468
return done(err);
@@ -478,7 +478,7 @@ describe("/requests OOO", function () {
478478
.request(app)
479479
.patch(`/requests/${testOooRequest.id}?dev=true`)
480480
.set("cookie", `${cookieName}=${superUserToken}`)
481-
.send({...acknowledgeOooRequest, status: REQUEST_STATE.REJECTED})
481+
.send({...testAcknowledgeOooRequest, status: REQUEST_STATE.REJECTED})
482482
.end(function (err, res) {
483483
if (err) {
484484
return done(err);
@@ -495,7 +495,7 @@ describe("/requests OOO", function () {
495495
.request(app)
496496
.patch(`/requests/${testOooRequest.id}?dev=true`)
497497
.set("cookie", `${cookieName}=${superUserToken}`)
498-
.send(acknowledgeOooRequest)
498+
.send(testAcknowledgeOooRequest)
499499
.end(function (err, res) {
500500
if (err) return done(err);
501501
expect(res.statusCode).to.equal(500);

test/unit/middlewares/oooRequests.test.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ const { expect } = chai;
44

55
import {
66
createOooStatusRequestValidator,
7-
// acknowledgeOOORequestsValidator,
7+
acknowledgeOooRequestsValidator,
88
} from "./../../../middlewares/validators/oooRequests";
9-
import { acknowledgeOooRequest, validOooStatusRequests, validOooStatusUpdate } from "../../fixtures/oooRequest/oooRequest";
9+
import { testAcknowledgeOooRequest, validOooStatusRequests, validOooStatusUpdate } from "../../fixtures/oooRequest/oooRequest";
1010
import _ from "lodash";
1111

1212
describe("OOO Status Request Validators", function () {
@@ -91,40 +91,40 @@ describe("OOO Status Request Validators", function () {
9191
});
9292
});
9393

94-
describe.skip("acknowledgeOOORequestsValidator", function () {
94+
describe("acknowledgeOooRequestsValidator", function () {
9595
it("should not validate for an invalid request for invalid request type", async function () {
9696
req = {
97-
body: { ...acknowledgeOooRequest, type: "XYZ"}
97+
body: { ...testAcknowledgeOooRequest, type: "XYZ"}
9898
};
9999

100-
// await acknowledgeOOORequestsValidator(req, res, nextSpy);
100+
await acknowledgeOooRequestsValidator(req, res, nextSpy);
101101
expect(nextSpy.notCalled).to.be.true;
102102
});
103103

104104
it("should not validate for an invalid request if status is incorrect", async function () {
105105
req = {
106-
body: { ...acknowledgeOooRequest, status: "PENDING"}
106+
body: { ...testAcknowledgeOooRequest, status: "PENDING"}
107107
};
108108

109-
// await acknowledgeOOORequestsValidator(req, res, nextSpy);
109+
await acknowledgeOooRequestsValidator(req, res, nextSpy);
110110
expect(nextSpy.notCalled).to.be.true;
111111
});
112112

113113
it("should validate for a valid acknowledge OOO request if comment not provided by superusers", async function() {
114114
req = {
115-
body: _.omit(acknowledgeOooRequest, "comment")
115+
body: _.omit(testAcknowledgeOooRequest, "comment")
116116
};
117117
res = {};
118-
// await acknowledgeOOORequestsValidator(req, res, nextSpy);
118+
await acknowledgeOooRequestsValidator(req, res, nextSpy);
119119
expect(nextSpy.calledOnce).to.be.true;
120120
});
121121

122122
it("should validate for a valid acknowledge OOO request", async function() {
123123
req = {
124-
body: acknowledgeOooRequest
124+
body: testAcknowledgeOooRequest
125125
};
126126
res = {};
127-
// await acknowledgeOOORequestsValidator(req, res, nextSpy);
127+
await acknowledgeOooRequestsValidator(req, res, nextSpy);
128128
expect(nextSpy.calledOnce).to.be.true;
129129
});
130130
});

0 commit comments

Comments
 (0)