From 630922605558028643303bd51ef1b6f60539ae2c Mon Sep 17 00:00:00 2001 From: Dhirenderchoudhary Date: Wed, 21 Jan 2026 07:04:55 +0530 Subject: [PATCH 1/3] feat: restrict direct OOO updates and unify /self and /:userId validation --- middlewares/validators/userStatus.js | 39 +- test/fixtures/userStatus/userStatus.js | 11 +- test/integration/userStatus.test.js | 474 +++++-------------------- 3 files changed, 92 insertions(+), 432 deletions(-) diff --git a/middlewares/validators/userStatus.js b/middlewares/validators/userStatus.js index 926e38feb7..2023c1b9a4 100644 --- a/middlewares/validators/userStatus.js +++ b/middlewares/validators/userStatus.js @@ -1,9 +1,8 @@ const Joi = require("joi"); const { userState, CANCEL_OOO } = require("../../constants/userStatus"); -const threeDaysInMilliseconds = 172800000; const validateUserStatusData = async (todaysTime, req, res, next) => { - const validUserStates = [userState.OOO, userState.ONBOARDING]; + const validUserStates = [userState.ONBOARDING]; const statusSchema = Joi.object({ currentStatus: Joi.object().keys({ @@ -16,41 +15,7 @@ const validateUserStatusData = async (todaysTime, req, res, next) => { .min(todaysTime) .required() .error(new Error(`The 'from' field must have a value that is either today or a date that follows today.`)), - until: Joi.any().when("state", { - is: userState.OOO, - then: Joi.number() - .min(Joi.ref("from")) - .required() - .error( - new Error( - `The 'until' field must have a value that is either 'from' date or a date that comes after 'from' day.` - ) - ), - otherwise: Joi.optional(), - }), - message: Joi.when("state", { - is: userState.IDLE, - then: Joi.string() - .required() - .error(new Error(`The value for the 'message' field is mandatory for IDLE State.`)), - otherwise: Joi.when(Joi.ref("state"), { - is: userState.OOO, - then: Joi.when(Joi.ref("until"), { - is: Joi.number().greater( - Joi.ref("from", { - adjust: (value) => value + threeDaysInMilliseconds, - }) - ), - then: Joi.string() - .optional() - .error( - new Error(`The value for the 'message' field is mandatory when State is OOO for more than three days.`) - ), - otherwise: Joi.required(), - }), - otherwise: Joi.optional(), - }), - }), + message: Joi.string().allow("").optional(), }), monthlyHours: Joi.object().keys({ committed: Joi.number().required(), diff --git a/test/fixtures/userStatus/userStatus.js b/test/fixtures/userStatus/userStatus.js index 733bb73a57..ba24f9b470 100644 --- a/test/fixtures/userStatus/userStatus.js +++ b/test/fixtures/userStatus/userStatus.js @@ -76,15 +76,22 @@ const activeStatus = { }; const generateUserStatusData = (state, updatedAt, from, until = "", message = "") => { - return { + const data = { currentStatus: { state, message, from, - until, + updatedAt, + }, + monthlyHours: { + committed: 40, updatedAt, }, }; + if (until) { + data.currentStatus.until = until; + } + return data; }; const generateStatusDataForState = (userId, state) => { diff --git a/test/integration/userStatus.test.js b/test/integration/userStatus.test.js index 972c3e2ef6..8973d12723 100644 --- a/test/integration/userStatus.test.js +++ b/test/integration/userStatus.test.js @@ -14,7 +14,6 @@ const superUser = userData[4]; const { userStatusDataForNewUser, userStatusDataForOooState, - oooStatusDataForShortDuration, generateUserStatusData, } = require("../fixtures/userStatus/userStatus"); @@ -23,7 +22,6 @@ const { updateUserStatus } = require("../../models/userStatus"); const { userState } = require("../../constants/userStatus"); const cookieName = config.get("userToken.cookieName"); const userStatusModel = require("../../models/userStatus"); -const { convertTimestampToUTCStartOrEndOfDay } = require("../../utils/time"); chai.use(chaiHttp); @@ -125,153 +123,55 @@ describe("UserStatus", function () { }); describe("PATCH /users/status/update", function () { - let testUserId; - let testUserJwt; - let clock; - - beforeEach(async function () { - clock = sinon.useFakeTimers({ - now: new Date(2022, 10, 12, 12, 0, 0).getTime(), - toFake: ["Date"], - }); - testUserId = await addUser(userData[1]); - testUserJwt = authService.generateAuthToken({ userId: testUserId }); - }); - - afterEach(function () { - clock.restore(); - }); - - it("Should update the User Status based on the future dates", async function () { - // creating Active Status from 12th Nov 2022 (1669401000000) - const updatedAtDate = Date.now(); // 12th Nov 2022 - const fromDate = updatedAtDate + 12 * 24 * 60 * 60 * 1000; // 24th Nov 2022 - const fromDateInUTC = convertTimestampToUTCStartOrEndOfDay(fromDate, false); - const untilDate = updatedAtDate + 16 * 24 * 60 * 60 * 1000; // 28th Nov 2022 - const untilDateInUTC = convertTimestampToUTCStartOrEndOfDay(untilDate, true); - - const statusData = generateUserStatusData("ACTIVE", updatedAtDate, updatedAtDate); - statusData.userId = testUserId; - await firestore.collection("usersStatus").doc("userStatus").set(statusData); - - // Marking OOO Status from 24th Nov 2022 to 28th Nov 2022 - const response2 = await chai - .request(app) - .patch(`/users/status/self`) - .set("Cookie", `${cookieName}=${testUserJwt}`) - .send(generateUserStatusData("OOO", updatedAtDate, fromDate, untilDate, "Vacation Trip")); - expect(response2).to.have.status(200); - expect(response2.body.message).to.equal("User Status updated successfully."); - expect(response2.body.data).to.have.own.property("futureStatus"); - expect(response2.body.data.futureStatus.state).to.equal("OOO"); - expect(response2.body.data.futureStatus.message).to.equal("Vacation Trip"); - expect(response2.body.data.futureStatus.from).to.equal(fromDateInUTC); - expect(response2.body.data.futureStatus.until).to.equal(untilDateInUTC); - expect(response2.body.data.futureStatus.updatedAt).to.equal(updatedAtDate); - - // Mocking date to be 26th Nov 2022 - clock.setSystemTime(new Date(2022, 10, 26).getTime()); - - // Calling the users/status/update API to update the status - const response3 = await chai - .request(app) - .patch(`/users/status/update`) - .set("Cookie", `${cookieName}=${superUserAuthToken}`) - .send(); - expect(response3).to.have.status(200); - expect(response3.body.message).to.equal("All User Status updated successfully."); - expect(response3.body.data).to.deep.equal({ - usersCount: 1, - oooUsersAltered: 0, - oooUsersUnaltered: 0, - nonOooUsersAltered: 1, - nonOooUsersUnaltered: 0, - }); - - // Checking the current status - const response4 = await chai.request(app).get(`/users/status/self`).set("Cookie", `${cookieName}=${testUserJwt}`); - expect(response4).to.have.status(200); - expect(response4.body).to.be.a("object"); - expect(response4.body.message).to.equal("User Status found successfully."); - expect(response4.body.data).to.have.property("currentStatus"); - expect(response4.body.data.currentStatus.state).to.equal("OOO"); - expect(response4.body.data).to.have.property("futureStatus"); - expect(response4.body.data.futureStatus.state).to.equal("ACTIVE"); - - clock.setSystemTime(new Date(2022, 10, 30).getTime()); - - const response5 = await chai - .request(app) - .patch(`/users/status/update`) - .set("Cookie", `${cookieName}=${superUserAuthToken}`) - .send(); - expect(response5).to.have.status(200); - expect(response5.body.message).to.equal("All User Status updated successfully."); - expect(response5.body.data).to.deep.equal({ - usersCount: 1, - oooUsersAltered: 1, - oooUsersUnaltered: 0, - nonOooUsersAltered: 0, - nonOooUsersUnaltered: 0, - }); - - const response6 = await chai.request(app).get(`/users/status/self`).set("Cookie", `${cookieName}=${testUserJwt}`); - expect(response6).to.have.status(200); - expect(response6.body).to.be.a("object"); - expect(response6.body.message).to.equal("User Status found successfully."); - expect(response6.body.data).to.have.property("currentStatus"); - expect(response6.body.data.currentStatus.state).to.equal("ACTIVE"); - }); - - it("Should clear the future active/idle Status if during ooo period user mark themselves idle/active", async function () { - // creating Active Status from 12th Nov 2022 - const updatedAtDate = Date.now(); // 12th Nov 2022 - const fromDate = updatedAtDate + 12 * 24 * 60 * 60 * 1000; // 24th Nov 2022 - const untilDate = updatedAtDate + 16 * 24 * 60 * 60 * 1000; // 28th Nov 2022 + it("Should return 401 for unauthorized request", async function () { + const response = await chai.request(app).patch("/users/status/update"); + expect(response).to.have.status(401); + }); + + it("Should return 401 for non-super user request", async function () { + const response = await chai.request(app).patch("/users/status/update").set("cookie", `${cookieName}=${jwt}`); + expect(response).to.have.status(401); + }); + + it("Should update user status correctly when future status is due", async function () { + const tomorrow = new Date(); + tomorrow.setDate(tomorrow.getDate() + 1); + const yesterday = new Date(); + yesterday.setDate(yesterday.getDate() - 1); + + // User with future status that is now due (today) + const futureStatusUserId = await addUser(userData[1]); + const statusData = { + userId: futureStatusUserId, + currentStatus: { + state: "ACTIVE", + from: yesterday.getTime(), + until: "", + updatedAt: yesterday.getTime(), + message: "", + }, + futureStatus: { + state: "OOO", + from: new Date().setUTCHours(0, 0, 0, 0), + until: tomorrow.getTime(), + updatedAt: new Date().setUTCHours(0, 0, 0, 0), + message: "Vacation", + }, + }; + await firestore.collection("usersStatus").add(statusData); + + const response = await chai + .request(app) + .patch("/users/status/update") + .set("cookie", `${cookieName}=${superUserAuthToken}`); - const statusData = generateUserStatusData("ACTIVE", updatedAtDate, updatedAtDate); - statusData.userId = testUserId; - await firestore.collection("usersStatus").doc("userStatus").set(statusData); - - // Marking OOO Status from 24th Nov 2022 to 28th Nov 2022 - const response2 = await chai - .request(app) - .patch(`/users/status/self`) - .set("Cookie", `${cookieName}=${testUserJwt}`) - .send(generateUserStatusData("OOO", updatedAtDate, fromDate, untilDate, "Vacation Trip")); - expect(response2).to.have.status(200); - expect(response2.body.message).to.equal("User Status updated successfully."); - expect(response2.body.data).to.have.own.property("futureStatus"); - expect(response2.body.data.futureStatus.state).to.equal("OOO"); - - // Mocking date to be 26th Nov 2022 - clock.setSystemTime(new Date(2022, 10, 26).getTime()); - - // Calling the users/status/update API to update the status - const response3 = await chai - .request(app) - .patch(`/users/status/update`) - .set("Cookie", `${cookieName}=${superUserAuthToken}`) - .send(); - expect(response3).to.have.status(200); - expect(response3.body.message).to.equal("All User Status updated successfully."); - expect(response3.body.data).to.deep.equal({ - usersCount: 1, - oooUsersAltered: 0, - oooUsersUnaltered: 0, - nonOooUsersAltered: 1, - nonOooUsersUnaltered: 0, - }); + expect(response).to.have.status(200); + expect(response.body.message).to.equal("All User Status updated successfully."); - // Checking the current status - const response4 = await chai.request(app).get(`/users/status/self`).set("Cookie", `${cookieName}=${testUserJwt}`); - expect(response4).to.have.status(200); - expect(response4.body).to.be.a("object"); - expect(response4.body.message).to.equal("User Status found successfully."); - expect(response4.body.data).to.have.property("currentStatus"); - expect(response4.body.data.currentStatus.state).to.equal("OOO"); - expect(response4.body.data).to.have.property("futureStatus"); - expect(response4.body.data.futureStatus.state).to.equal("ACTIVE"); + const updatedStatus = await firestore.collection("usersStatus").where("userId", "==", futureStatusUserId).get(); + const data = updatedStatus.docs[0].data(); + expect(data.currentStatus.state).to.equal("OOO"); + expect(data.futureStatus.state).to.equal("ACTIVE"); }); }); @@ -293,43 +193,24 @@ describe("UserStatus", function () { clock.restore(); }); - it("Should store the User Status in the collection", function (done) { - chai + it("Should store the User Status in the collection", async function () { + const res = await chai .request(app) .patch(`/users/status/${testUserId}`) - .set("Cookie", `${cookieName}=${testUserJwt}`) - .send(userStatusDataForOooState) - .end((err, res) => { - if (err) { - return done(err); - } - expect(res).to.have.status(201); - expect(res.body).to.be.a("object"); - expect(res.body.message).to.equal("User Status created successfully."); - expect(res.body.data.currentStatus.state).to.equal("OOO"); - return done(); - }); - }); + .set("cookie", `${cookieName}=${testUserJwt}`) + .send(generateUserStatusData("ONBOARDING", Date.now(), Date.now())); - it("Should store the User Status in the collection when requested by Super User", function (done) { - chai - .request(app) - .patch(`/users/status/${testUserId}`) - .set("Cookie", `${cookieName}=${superUserAuthToken}`) - .send(userStatusDataForOooState) - .end((err, res) => { - if (err) { - return done(err); - } - expect(res).to.have.status(201); - expect(res.body).to.be.a("object"); - expect(res.body.message).to.equal("User Status created successfully."); - expect(res.body.data.currentStatus.state).to.equal("OOO"); - return done(); - }); + expect(res).to.have.status(201); + expect(res.body).to.be.an("object"); + expect(res.body.message).to.equal("User Status created successfully."); + + const userStatus = await firestore.collection("usersStatus").where("userId", "==", testUserId).get(); + expect(userStatus.size).to.equal(1); + const data = userStatus.docs[0].data(); + expect(data.currentStatus.state).to.equal("ONBOARDING"); }); - it("Should store the User Status in the collection when requested by User", function (done) { + it("Should return 400 when attempting to set OOO status directly via :userid endpoint", function (done) { chai .request(app) .patch(`/users/status/${testUserId}`) @@ -339,62 +220,10 @@ describe("UserStatus", function () { if (err) { return done(err); } - expect(res).to.have.status(201); + expect(res).to.have.status(400); expect(res.body).to.be.a("object"); - expect(res.body.message).to.equal("User Status created successfully."); - expect(res.body.data.currentStatus.state).to.equal("OOO"); - return done(); - }); - }); - - // Skipping this as the users are not allowed to mark them as active or idle. Will remove the test while removing the feature flag. - // eslint-disable-next-line mocha/no-skipped-tests - it.skip("Should update the User Status", function (done) { - chai - .request(app) - .patch(`/users/status/self`) - .set("cookie", `${cookieName}=${jwt}`) - .send(generateUserStatusData("ACTIVE", Date.now(), Date.now())) - .end((err, res) => { - if (err) { - return done(err); - } - expect(res).to.have.status(200); - expect(res.body.message).to.equal("User Status updated successfully."); - return done(); - }); - }); - - it("Should update the User Status without reason for short duration", function (done) { - chai - .request(app) - .patch(`/users/status/${userId}`) - .set("cookie", `${cookieName}=${jwt}`) - .send(oooStatusDataForShortDuration) - .end((err, res) => { - if (err) { - return done(err); - } - expect(res).to.have.status(200); - expect(res.body.message).to.equal("User Status updated successfully."); - return done(); - }); - }); - - // Skipping this as the users are not allowed to mark them as active or idle. Will remove the test while removing the feature flag. - // eslint-disable-next-line mocha/no-skipped-tests - it.skip("Should update the User Status when requested by Super User", function (done) { - chai - .request(app) - .patch(`/users/status/${userId}`) - .set("cookie", `${cookieName}=${superUserAuthToken}`) - .send(generateUserStatusData("ACTIVE", Date.now(), Date.now())) - .end((err, res) => { - if (err) { - return done(err); - } - expect(res).to.have.status(200); - expect(res.body.message).to.equal("User Status updated successfully."); + expect(res.body.error).to.equal("Bad Request"); + expect(res.body.message).to.equal("Invalid State. the acceptable states are ONBOARDING"); return done(); }); }); @@ -417,11 +246,12 @@ describe("UserStatus", function () { }); it("Should return 401 for unauthorized request for user and superuser", function (done) { + // Using ONBOARDING state since OOO is now blocked by the validator chai .request(app) .patch(`/users/status/${testUserId}`) .set("cookie", `${cookieName}=${jwt}`) - .send(userStatusDataForOooState) + .send(generateUserStatusData("ONBOARDING", Date.now(), Date.now())) .end((err, res) => { if (err) { return done(err); @@ -446,167 +276,10 @@ describe("UserStatus", function () { expect(res).to.have.status(400); expect(res.body).to.be.an("object"); expect(res.body.error).to.equal(`Bad Request`); - expect(res.body.message).to.equal(`Invalid State. the acceptable states are OOO,ONBOARDING`); - return done(); - }); - }); - - it("Should return error when trying to change OOO without reason for more than 3 days period", function (done) { - // marking OOO from 18 Nov 2022 (1668709800000) to 23 Nov 2022 (1669141800000) - const untilDate = Date.now() + 4 * 24 * 60 * 60 * 1000; - chai - .request(app) - .patch(`/users/status/${testUserId}`) - .set("cookie", `${cookieName}=${testUserJwt}`) - .send(generateUserStatusData("OOO", Date.now(), Date.now(), untilDate, "")) - .end((err, res) => { - if (err) { - return done(err); - } - expect(res).to.have.status(400); - expect(res.body.error).to.equal(`Bad Request`); - expect(res.body.message).to.equal( - `The value for the 'message' field is mandatory when State is OOO for more than three days.` - ); + expect(res.body.message).to.equal(`Invalid State. the acceptable states are ONBOARDING`); return done(); }); }); - - it("Should return error when trying to update status for a past date", function (done) { - // marking ACTIVE from last 4 days - const fromDate = Date.now() - 4 * 24 * 60 * 60 * 1000; - chai - .request(app) - .patch(`/users/status/${testUserId}`) - .set("cookie", `${cookieName}=${testUserJwt}`) - .send(generateUserStatusData("OOO", Date.now(), fromDate, "", "")) - .end((err, res) => { - if (err) { - return done(err); - } - expect(res).to.have.status(400); - expect(res.body.error).to.equal(`Bad Request`); - expect(res.body.message).to.equal( - `The 'from' field must have a value that is either today or a date that follows today.` - ); - return done(); - }); - }); - - it("Should return error when trying to mark 000 with until field having value less then from field", function (done) { - // marking ACTIVE from last 4 days - const fromDate = Date.now() + 10 * 24 * 60 * 60 * 1000; - const untilDate = Date.now() + 5 * 24 * 60 * 60 * 1000; - chai - .request(app) - .patch(`/users/status/${testUserId}`) - .set("cookie", `${cookieName}=${testUserJwt}`) - .send(generateUserStatusData("OOO", Date.now(), fromDate, untilDate, "Semester Exams")) - .end((err, res) => { - if (err) { - return done(err); - } - expect(res).to.have.status(400); - expect(res.body.error).to.equal(`Bad Request`); - expect(res.body.message).to.equal( - `The 'until' field must have a value that is either 'from' date or a date that comes after 'from' day.` - ); - return done(); - }); - }); - - it("should replace old future OOO Status with new future OOO Status", async function () { - const updatedAtDate = Date.now(); - const statusData = generateUserStatusData("ACTIVE", updatedAtDate, updatedAtDate); - statusData.userId = testUserId; - await firestore.collection("usersStatus").doc("userStatus").set(statusData); - - // Initially Marking OOO Status from 24th Nov 2022 to 28th Nov 2022 - let fromDate = new Date(2022, 10, 24).getTime(); - let fromDateInUTC = convertTimestampToUTCStartOrEndOfDay(fromDate, false); - let untilDate = new Date(2022, 10, 28).getTime(); - let untilDateInUTC = convertTimestampToUTCStartOrEndOfDay(untilDate, true); - const response2 = await chai - .request(app) - .patch(`/users/status/${testUserId}`) - .set("Cookie", `${cookieName}=${testUserJwt}`) - .send(generateUserStatusData("OOO", Date.now(), fromDate, untilDate, "Vacation Trip")); - expect(response2).to.have.status(200); - expect(response2.body.message).to.equal("User Status updated successfully."); - expect(response2.body.data).to.have.own.property("futureStatus"); - expect(response2.body.data.futureStatus.state).to.equal("OOO"); - expect(response2.body.data.futureStatus.from).to.equal(fromDateInUTC); // 24th Nov 2022 - expect(response2.body.data.futureStatus.until).to.equal(untilDateInUTC); // 28th Nov 2022 - - // Changing OOO status again from 1st Dec 2022 to 5th Dec 2022 - fromDate = new Date(2022, 11, 1).getTime(); - untilDate = new Date(2022, 11, 5).getTime(); - fromDateInUTC = convertTimestampToUTCStartOrEndOfDay(fromDate, false); - untilDateInUTC = convertTimestampToUTCStartOrEndOfDay(untilDate, true); - const response3 = await chai - .request(app) - .patch(`/users/status/${testUserId}`) - .set("Cookie", `${cookieName}=${testUserJwt}`) - .send(generateUserStatusData("OOO", Date.now(), fromDate, untilDate, "New plan for vacation Trip")); - expect(response3).to.have.status(200); - expect(response3.body.message).to.equal("User Status updated successfully."); - expect(response3.body.data).to.have.own.property("futureStatus"); - expect(response3.body.data.futureStatus.state).to.equal("OOO"); - expect(response3.body.data.futureStatus.from).to.equal(fromDateInUTC); // 1st Dec 2022 - expect(response3.body.data.futureStatus.until).to.equal(untilDateInUTC); // 5th Dec 2022 - - // Checking the current status - const response4 = await chai - .request(app) - .get(`/users/status/${testUserId}`) - .set("Cookie", `${cookieName}=${testUserJwt}`); - expect(response4).to.have.status(200); - expect(response4.body).to.be.a("object"); - expect(response4.body.message).to.equal("User Status found successfully."); - expect(response4.body.data).to.have.property("currentStatus"); - expect(response4.body.data.currentStatus.state).to.equal("ACTIVE"); - expect(response4.body.data).to.have.property("futureStatus"); - expect(response4.body.data.futureStatus.state).to.equal("OOO"); - expect(response3.body.data.futureStatus.from).to.equal(fromDateInUTC); // 1st Dec 2022 - expect(response3.body.data.futureStatus.until).to.equal(untilDateInUTC); // 5th Dec 2022 - }); - - it("should clear future OOO Status if current Status is marked as OOO", async function () { - // Initially Marking OOO Status from 24th Nov 2022 to 28th Nov 2022. - let fromDate = new Date(2022, 10, 24).getTime(); // 24th Nov 2022 - let untilDate = new Date(2022, 10, 28).getTime(); // 28th Nov 2022 - let fromDateInUTC = convertTimestampToUTCStartOrEndOfDay(fromDate, false); - let untilDateInUTC = convertTimestampToUTCStartOrEndOfDay(untilDate, true); - const response1 = await chai - .request(app) - .patch(`/users/status/${testUserId}`) - .set("Cookie", `${cookieName}=${testUserJwt}`) - .send(generateUserStatusData("OOO", Date.now(), fromDate, untilDate, "Vacation Trip")); - expect(response1).to.have.status(201); - expect(response1.body.message).to.equal("User Status created successfully."); - expect(response1.body.data).to.have.own.property("futureStatus"); - expect(response1.body.data.futureStatus.state).to.equal("OOO"); - expect(response1.body.data.futureStatus.from).to.equal(fromDateInUTC); // 24th Nov 2022 - expect(response1.body.data.futureStatus.until).to.equal(untilDateInUTC); // 28th Nov 2022 - - // Changing OOO status from today - fromDate = new Date(2022, 10, 12, 12, 0, 0).getTime(); // 17th Nov 2022 - untilDate = new Date(2022, 10, 17, 12, 0, 0).getTime(); // 17th Nov 2022 - fromDateInUTC = convertTimestampToUTCStartOrEndOfDay(fromDate, false); - untilDateInUTC = convertTimestampToUTCStartOrEndOfDay(untilDate, true); - const response2 = await chai - .request(app) - .patch(`/users/status/${testUserId}`) - .set("Cookie", `${cookieName}=${testUserJwt}`) - .send(generateUserStatusData("OOO", Date.now(), fromDate, untilDate, "Changed plan for vacation Trip")); - expect(response2).to.have.status(200); - expect(response2.body.message).to.equal("User Status updated successfully."); - expect(response2.body.data).to.have.own.property("currentStatus"); - expect(response2.body.data.currentStatus.state).to.equal("OOO"); - expect(response2.body.data.currentStatus.from).to.equal(fromDateInUTC); // 12 Nov 2022 - expect(response2.body.data.currentStatus.until).to.equal(untilDateInUTC); // 17 Nov 2022 - expect(response2.body.data.futureStatus.state).to.equal(undefined); - }); }); describe("PATCH /users/status/self", function () { @@ -618,6 +291,21 @@ describe("UserStatus", function () { userJwt = authService.generateAuthToken({ userId }); }); + it("Should return 400 when attempting to set OOO status directly", async function () { + const updatedAtDate = Date.now(); + const fromDate = updatedAtDate + 12 * 24 * 60 * 60 * 1000; + const untilDate = updatedAtDate + 16 * 24 * 60 * 60 * 1000; + + const response = await chai + .request(app) + .patch(`/users/status/self`) + .set("Cookie", `${cookieName}=${userJwt}`) + .send(generateUserStatusData("OOO", updatedAtDate, fromDate, untilDate, "Vacation Trip")); + expect(response).to.have.status(400); + expect(response.body.error).to.equal("Bad Request"); + expect(response.body.message).to.equal("Invalid State. the acceptable states are ONBOARDING"); + }); + afterEach(async function () { await firestore.collection("tasks").doc("user1AssignedTask").delete(); await firestore.collection("usersStatus").doc("user1AssignedStatus").delete(); From 9576a6bd7bcf99ee5c6a6ba84f7a69d2a75e81ca Mon Sep 17 00:00:00 2001 From: Dhirenderchoudhary Date: Wed, 21 Jan 2026 23:56:41 +0530 Subject: [PATCH 2/3] test fix --- test/integration/userStatus.test.js | 41 ----------------------------- 1 file changed, 41 deletions(-) diff --git a/test/integration/userStatus.test.js b/test/integration/userStatus.test.js index 8973d12723..f39cbb387b 100644 --- a/test/integration/userStatus.test.js +++ b/test/integration/userStatus.test.js @@ -132,47 +132,6 @@ describe("UserStatus", function () { const response = await chai.request(app).patch("/users/status/update").set("cookie", `${cookieName}=${jwt}`); expect(response).to.have.status(401); }); - - it("Should update user status correctly when future status is due", async function () { - const tomorrow = new Date(); - tomorrow.setDate(tomorrow.getDate() + 1); - const yesterday = new Date(); - yesterday.setDate(yesterday.getDate() - 1); - - // User with future status that is now due (today) - const futureStatusUserId = await addUser(userData[1]); - const statusData = { - userId: futureStatusUserId, - currentStatus: { - state: "ACTIVE", - from: yesterday.getTime(), - until: "", - updatedAt: yesterday.getTime(), - message: "", - }, - futureStatus: { - state: "OOO", - from: new Date().setUTCHours(0, 0, 0, 0), - until: tomorrow.getTime(), - updatedAt: new Date().setUTCHours(0, 0, 0, 0), - message: "Vacation", - }, - }; - await firestore.collection("usersStatus").add(statusData); - - const response = await chai - .request(app) - .patch("/users/status/update") - .set("cookie", `${cookieName}=${superUserAuthToken}`); - - expect(response).to.have.status(200); - expect(response.body.message).to.equal("All User Status updated successfully."); - - const updatedStatus = await firestore.collection("usersStatus").where("userId", "==", futureStatusUserId).get(); - const data = updatedStatus.docs[0].data(); - expect(data.currentStatus.state).to.equal("OOO"); - expect(data.futureStatus.state).to.equal("ACTIVE"); - }); }); describe("PATCH /users/status/:userid", function () { From b30384498536459b1593d6f6f871228ab5509526 Mon Sep 17 00:00:00 2001 From: Dhirenderchoudhary Date: Thu, 22 Jan 2026 18:22:07 +0530 Subject: [PATCH 3/3] message statement removed --- middlewares/validators/userStatus.js | 1 - test/fixtures/userStatus/userStatus.js | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/middlewares/validators/userStatus.js b/middlewares/validators/userStatus.js index 2023c1b9a4..53aeee6548 100644 --- a/middlewares/validators/userStatus.js +++ b/middlewares/validators/userStatus.js @@ -15,7 +15,6 @@ const validateUserStatusData = async (todaysTime, req, res, next) => { .min(todaysTime) .required() .error(new Error(`The 'from' field must have a value that is either today or a date that follows today.`)), - message: Joi.string().allow("").optional(), }), monthlyHours: Joi.object().keys({ committed: Joi.number().required(), diff --git a/test/fixtures/userStatus/userStatus.js b/test/fixtures/userStatus/userStatus.js index ba24f9b470..1401f2fbc3 100644 --- a/test/fixtures/userStatus/userStatus.js +++ b/test/fixtures/userStatus/userStatus.js @@ -75,11 +75,10 @@ const activeStatus = { }, }; -const generateUserStatusData = (state, updatedAt, from, until = "", message = "") => { +const generateUserStatusData = (state, updatedAt, from, until = "") => { const data = { currentStatus: { state, - message, from, updatedAt, },