Skip to content

Commit 7d0449b

Browse files
authored
Updated UsersStatus /:userId PATCH Endpoint (#2313)
* Updated the userId Patch endpoint to allow authenticated User patch * added one test case for unauthorized user and superuser
1 parent afee8e6 commit 7d0449b

File tree

3 files changed

+81
-14
lines changed

3 files changed

+81
-14
lines changed

controllers/userStatus.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ const { INTERNAL_SERVER_ERROR } = require("../constants/errorMessages");
44
const dataAccess = require("../services/dataAccessLayer");
55
const userStatusModel = require("../models/userStatus");
66
const { userState, CANCEL_OOO } = require("../constants/userStatus");
7+
const ROLES = require("../constants/roles");
8+
const firestore = require("../utils/firestore");
9+
const usersCollection = firestore.collection("users");
710

811
/**
912
* Deletes a new User Status
@@ -107,6 +110,11 @@ const getAllUserStatus = async (req, res) => {
107110
const updateUserStatus = async (req, res) => {
108111
try {
109112
const userId = getUserIdBasedOnRoute(req);
113+
const userDoc = await usersCollection.doc(userId).get();
114+
if (!userDoc.exists) {
115+
return res.boom.notFound("The User doesn't exist.");
116+
}
117+
110118
if (userId) {
111119
const dataToUpdate = req.body;
112120
const updateStatus = await userStatusModel.updateUserStatus(userId, dataToUpdate);
@@ -240,6 +248,26 @@ const updateUserStatusController = async (req, res, next) => {
240248
}
241249
};
242250

251+
const updateUserStatuses = async (req, res, next) => {
252+
try {
253+
const { id: currentUserId, roles = {} } = req.userData;
254+
const isSelf = req.params.userId === currentUserId;
255+
const isSuperUser = roles[ROLES.SUPERUSER];
256+
257+
if (isSelf || isSuperUser) {
258+
if (isSelf && Object.keys(req.body).includes(CANCEL_OOO)) {
259+
return await cancelOOOStatus(req, res, next);
260+
}
261+
return await updateUserStatus(req, res, next);
262+
}
263+
264+
return res.boom.unauthorized("You are not authorized to perform this action.");
265+
} catch (err) {
266+
logger.error(`Error in updateUserStatusController: ${err}`);
267+
return res.boom.badImplementation("An unexpected error occurred.");
268+
}
269+
};
270+
243271
module.exports = {
244272
deleteUserStatus,
245273
getUserStatus,
@@ -250,4 +278,5 @@ module.exports = {
250278
getUserStatusControllers,
251279
batchUpdateUsersStatus,
252280
updateUserStatusController,
281+
updateUserStatuses,
253282
};

routes/userStatus.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ const express = require("express");
22
const {
33
deleteUserStatus,
44
getUserStatus,
5-
updateUserStatus,
5+
updateUserStatuses,
66
updateAllUserStatus,
77
batchUpdateUsersStatus,
88
getUserStatusControllers,
@@ -24,15 +24,15 @@ const { Services } = require("../constants/bot");
2424
router.get("/", validateGetQueryParams, getUserStatusControllers);
2525
router.get("/self", authenticate, getUserStatus);
2626
router.get("/:userId", getUserStatus);
27-
router.patch("/self", authenticate, validateUserStatus, updateUserStatusController);
27+
router.patch("/self", authenticate, validateUserStatus, updateUserStatusController); // this route is being deprecated, please use /users/status/:userId PATCH endpoint instead.
2828
router.patch("/update", authorizeAndAuthenticate([ROLES.SUPERUSER], [Services.CRON_JOB_HANDLER]), updateAllUserStatus);
2929
router.patch(
3030
"/batch",
3131
authorizeAndAuthenticate([ROLES.SUPERUSER], [Services.CRON_JOB_HANDLER]),
3232
validateMassUpdate,
3333
batchUpdateUsersStatus
3434
);
35-
router.patch("/:userId", authenticate, authorizeRoles([SUPERUSER]), validateUserStatus, updateUserStatus);
35+
router.patch("/:userId", authenticate, validateUserStatus, updateUserStatuses);
3636
router.delete("/:userId", authenticate, authorizeRoles([SUPERUSER]), deleteUserStatus);
3737

3838
module.exports = router;

test/integration/userStatus.test.js

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ describe("UserStatus", function () {
296296
it("Should store the User Status in the collection", function (done) {
297297
chai
298298
.request(app)
299-
.patch(`/users/status/self`)
299+
.patch(`/users/status/${testUserId}`)
300300
.set("Cookie", `${cookieName}=${testUserJwt}`)
301301
.send(userStatusDataForOooState)
302302
.end((err, res) => {
@@ -329,6 +329,24 @@ describe("UserStatus", function () {
329329
});
330330
});
331331

332+
it("Should store the User Status in the collection when requested by User", function (done) {
333+
chai
334+
.request(app)
335+
.patch(`/users/status/${testUserId}`)
336+
.set("Cookie", `${cookieName}=${testUserJwt}`)
337+
.send(userStatusDataForOooState)
338+
.end((err, res) => {
339+
if (err) {
340+
return done(err);
341+
}
342+
expect(res).to.have.status(201);
343+
expect(res.body).to.be.a("object");
344+
expect(res.body.message).to.equal("User Status created successfully.");
345+
expect(res.body.data.currentStatus.state).to.equal("OOO");
346+
return done();
347+
});
348+
});
349+
332350
// Skipping this as the users are not allowed to mark them as active or idle. Will remove the test while removing the feature flag.
333351
// eslint-disable-next-line mocha/no-skipped-tests
334352
it.skip("Should update the User Status", function (done) {
@@ -350,7 +368,7 @@ describe("UserStatus", function () {
350368
it("Should update the User Status without reason for short duration", function (done) {
351369
chai
352370
.request(app)
353-
.patch(`/users/status/self`)
371+
.patch(`/users/status/${userId}`)
354372
.set("cookie", `${cookieName}=${jwt}`)
355373
.send(oooStatusDataForShortDuration)
356374
.end((err, res) => {
@@ -398,10 +416,27 @@ describe("UserStatus", function () {
398416
});
399417
});
400418

419+
it("Should return 401 for unauthorized request for user and superuser", function (done) {
420+
chai
421+
.request(app)
422+
.patch(`/users/status/${testUserId}`)
423+
.set("cookie", `${cookieName}=${jwt}`)
424+
.send(userStatusDataForOooState)
425+
.end((err, res) => {
426+
if (err) {
427+
return done(err);
428+
}
429+
expect(res).to.have.status(401);
430+
expect(res.body).to.be.a("object");
431+
expect(res.body.message).to.equal("You are not authorized to perform this action.");
432+
return done();
433+
});
434+
});
435+
401436
it("Should return 400 for incorrect state value", function (done) {
402437
chai
403438
.request(app)
404-
.patch(`/users/status/self`)
439+
.patch(`/users/status/${testUserId}`)
405440
.set("cookie", `${cookieName}=${testUserJwt}`)
406441
.send(generateUserStatusData("IN_OFFICE", Date.now(), Date.now()))
407442
.end((err, res) => {
@@ -421,7 +456,7 @@ describe("UserStatus", function () {
421456
const untilDate = Date.now() + 4 * 24 * 60 * 60 * 1000;
422457
chai
423458
.request(app)
424-
.patch(`/users/status/self`)
459+
.patch(`/users/status/${testUserId}`)
425460
.set("cookie", `${cookieName}=${testUserJwt}`)
426461
.send(generateUserStatusData("OOO", Date.now(), Date.now(), untilDate, ""))
427462
.end((err, res) => {
@@ -442,7 +477,7 @@ describe("UserStatus", function () {
442477
const fromDate = Date.now() - 4 * 24 * 60 * 60 * 1000;
443478
chai
444479
.request(app)
445-
.patch(`/users/status/self`)
480+
.patch(`/users/status/${testUserId}`)
446481
.set("cookie", `${cookieName}=${testUserJwt}`)
447482
.send(generateUserStatusData("OOO", Date.now(), fromDate, "", ""))
448483
.end((err, res) => {
@@ -464,7 +499,7 @@ describe("UserStatus", function () {
464499
const untilDate = Date.now() + 5 * 24 * 60 * 60 * 1000;
465500
chai
466501
.request(app)
467-
.patch(`/users/status/self`)
502+
.patch(`/users/status/${testUserId}`)
468503
.set("cookie", `${cookieName}=${testUserJwt}`)
469504
.send(generateUserStatusData("OOO", Date.now(), fromDate, untilDate, "Semester Exams"))
470505
.end((err, res) => {
@@ -493,7 +528,7 @@ describe("UserStatus", function () {
493528
let untilDateInUTC = convertTimestampToUTCStartOrEndOfDay(untilDate, true);
494529
const response2 = await chai
495530
.request(app)
496-
.patch(`/users/status/self`)
531+
.patch(`/users/status/${testUserId}`)
497532
.set("Cookie", `${cookieName}=${testUserJwt}`)
498533
.send(generateUserStatusData("OOO", Date.now(), fromDate, untilDate, "Vacation Trip"));
499534
expect(response2).to.have.status(200);
@@ -510,7 +545,7 @@ describe("UserStatus", function () {
510545
untilDateInUTC = convertTimestampToUTCStartOrEndOfDay(untilDate, true);
511546
const response3 = await chai
512547
.request(app)
513-
.patch(`/users/status/self`)
548+
.patch(`/users/status/${testUserId}`)
514549
.set("Cookie", `${cookieName}=${testUserJwt}`)
515550
.send(generateUserStatusData("OOO", Date.now(), fromDate, untilDate, "New plan for vacation Trip"));
516551
expect(response3).to.have.status(200);
@@ -521,7 +556,10 @@ describe("UserStatus", function () {
521556
expect(response3.body.data.futureStatus.until).to.equal(untilDateInUTC); // 5th Dec 2022
522557

523558
// Checking the current status
524-
const response4 = await chai.request(app).get(`/users/status/self`).set("Cookie", `${cookieName}=${testUserJwt}`);
559+
const response4 = await chai
560+
.request(app)
561+
.get(`/users/status/${testUserId}`)
562+
.set("Cookie", `${cookieName}=${testUserJwt}`);
525563
expect(response4).to.have.status(200);
526564
expect(response4.body).to.be.a("object");
527565
expect(response4.body.message).to.equal("User Status found successfully.");
@@ -541,7 +579,7 @@ describe("UserStatus", function () {
541579
let untilDateInUTC = convertTimestampToUTCStartOrEndOfDay(untilDate, true);
542580
const response1 = await chai
543581
.request(app)
544-
.patch(`/users/status/self`)
582+
.patch(`/users/status/${testUserId}`)
545583
.set("Cookie", `${cookieName}=${testUserJwt}`)
546584
.send(generateUserStatusData("OOO", Date.now(), fromDate, untilDate, "Vacation Trip"));
547585
expect(response1).to.have.status(201);
@@ -558,7 +596,7 @@ describe("UserStatus", function () {
558596
untilDateInUTC = convertTimestampToUTCStartOrEndOfDay(untilDate, true);
559597
const response2 = await chai
560598
.request(app)
561-
.patch(`/users/status/self`)
599+
.patch(`/users/status/${testUserId}`)
562600
.set("Cookie", `${cookieName}=${testUserJwt}`)
563601
.send(generateUserStatusData("OOO", Date.now(), fromDate, untilDate, "Changed plan for vacation Trip"));
564602
expect(response2).to.have.status(200);

0 commit comments

Comments
 (0)