Skip to content

Commit

Permalink
Add OOO request approved data to user future status (#2001)
Browse files Browse the repository at this point in the history
* added all changes

* create new status if user not have any status

* refactor: result schema

* test: add test for user future status model functions

* test: add test for add futire staus to user status model.

* refactor addFutureStatus user status model function

---------

Co-authored-by: Amit Prakash <34869115+iamitprakash@users.noreply.github.com>
  • Loading branch information
sahsisunny and iamitprakash authored Apr 10, 2024
1 parent 1969a37 commit 7fb0e0e
Show file tree
Hide file tree
Showing 11 changed files with 191 additions and 15 deletions.
10 changes: 7 additions & 3 deletions constants/userStatus.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
const userState = {
export const userState = {
ACTIVE: "ACTIVE",
IDLE: "IDLE",
OOO: "OOO",
ONBOARDING: "ONBOARDING",
};

const CANCEL_OOO = "cancelOoo";
export const statusState = {
UPCOMING: "UPCOMING",
APPLIED: "APPLIED",
NOT_APPLIED: "NOT_APPLIED",
};

module.exports = { userState, CANCEL_OOO };
export const CANCEL_OOO = "cancelOoo";
22 changes: 22 additions & 0 deletions controllers/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ import {
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 { createRequest, getRequests, updateRequest } from "../models/requests";
import { addLog } from "../models/logs";
import { getPaginatedLink } from "../utils/helper";
Expand Down Expand Up @@ -94,6 +98,24 @@ export const updateRequestController = async (req: any, res: any) => {
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: {
Expand Down
8 changes: 2 additions & 6 deletions models/requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,8 @@ export const getRequests = async (query: any) => {
return null;
}
return {
allRequests: [
{
id: requestDoc.id,
...requestDoc.data(),
},
],
id: requestDoc.id,
...requestDoc.data(),
};
}

Expand Down
56 changes: 56 additions & 0 deletions models/userFutureStatus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import firestore from "../utils/firestore";
const userFutureStatusModel = firestore.collection("userFutureStatus");
import { UserFutureStatusType } from "../types/userFutureStatus";
import * as admin from "firebase-admin";

/**
* Function to create user future status
* @param body: UserFutureStatusType
* @returns UserFutureStatusType
*/
export const createUserFutureStatus = async (body: UserFutureStatusType) => {
try {
const statusBody: UserFutureStatusType = {
createdAt: Date.now(),
...body,
};
const resultDoc = await userFutureStatusModel.add(statusBody);
return {
id: resultDoc.id,
...body,
};
} catch (error) {
logger.error("Error while creating user future status", error);
throw error;
}
};

/**
* Function to get user future status
* @param: id: string, status: string, state: string
* @returns Array of user future status
**/
export const getUserFutureStatus = async (userId: string, status: string, state: string) => {
try {
let resultArray = [];
let query: admin.firestore.Query = userFutureStatusModel;

if (userId) {
query = query.where("userId", "==", userId);
}
if (status) {
query = query.where("status", "==", status);
}
if (state) {
query = query.where("state", "==", state);
}
const resultDoc = await query.get();
resultDoc.forEach((doc) => {
resultArray.push({ id: doc.id, ...doc.data() });
});
return resultArray;
} catch (error) {
logger.error("Error while fetching user future status", error);
throw error;
}
};
32 changes: 32 additions & 0 deletions models/userStatus.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-console */
const { Forbidden, NotFound } = require("http-errors");
const admin = require("firebase-admin");
const firestore = require("../utils/firestore");
Expand Down Expand Up @@ -673,6 +674,36 @@ const cancelOooStatus = async (userId) => {
}
};

const addFutureStatus = async (futureStatusData) => {
try {
const userStatusDocs = await userStatusModel.where("userId", "==", futureStatusData.userId).limit(1).get();
const [userStatusDoc] = userStatusDocs.docs;
let docId;
let userStatusData;

if (userStatusDoc) {
docId = userStatusDoc.id;
userStatusData = userStatusDoc.data();
} else {
const newUserStatusRef = userStatusModel.doc();
await newUserStatusRef.set({ userId: futureStatusData.userId });
docId = newUserStatusRef.id;
userStatusData = { userId: futureStatusData.userId };
}

delete futureStatusData.userId;
const newStatusData = {
...userStatusData,
futureStatus: futureStatusData,
};
await userStatusModel.doc(docId).update(newStatusData);
return { id: docId, userStatusExists: true, data: newStatusData };
} catch (error) {
logger.error(`error in updating User Status Document ${error}`);
throw error;
}
};

module.exports = {
deleteUserStatus,
getUserStatus,
Expand All @@ -686,4 +717,5 @@ module.exports = {
getTaskBasedUsersStatus,
cancelOooStatus,
getGroupRole,
addFutureStatus,
};
12 changes: 12 additions & 0 deletions test/fixtures/userFutureStatus/userFutureStatusData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { REQUEST_TYPE } from "../../../constants/requests";
import { statusState } from "../../../constants/userStatus";

export const userFutureStatusData = {
requestId: "randomId",
status: REQUEST_TYPE.OOO,
state: statusState.UPCOMING,
from: 1712277700000,
endsOn: 1712277700000,
userId: "randomUserId",
message: "I am out of office",
};
4 changes: 1 addition & 3 deletions test/unit/models/requests.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,7 @@ describe("models/oooRequests", () => {
const oooRequest = await createRequest(createOooRequests2);
const query = { id: oooRequest.id, dev: "true" };
const oooRequestData: any = await getRequests(query);
expect(oooRequestData).to.have.property("allRequests");
expect(oooRequestData.allRequests[0].id).to.be.equal(oooRequest.id);
expect(oooRequestData.allRequests).to.have.lengthOf(1);
expect(oooRequestData.id).to.be.equal(oooRequest.id);
});

it("Should return null if the request with the specified ID does not exist", async () => {
Expand Down
34 changes: 34 additions & 0 deletions test/unit/models/userFutureStatus.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { createUserFutureStatus, getUserFutureStatus } from "../../../models/userFutureStatus";
import { expect } from "chai";
import cleanDb from "../../utils/cleanDb";
import { UserFutureStatusType } from "../../../types/userFutureStatus";
import { userFutureStatusData } from "../../fixtures/userFutureStatus/userFutureStatusData";

describe("models/userFutureStatus", () => {
afterEach(async () => {
await cleanDb();
});

describe("createUserFutureStatus ", () => {
it("should successfully create a new user future status", async () => {
const userFutureStatus = await createUserFutureStatus(userFutureStatusData as UserFutureStatusType);
expect(userFutureStatus).to.not.be.null;
expect(userFutureStatus).to.have.property("id");
expect(userFutureStatus).to.have.property("userId");
});
});

describe("getUserFutureStatus", () => {
it("should successfully get user future status", async () => {
await createUserFutureStatus(userFutureStatusData as UserFutureStatusType);
const userFutureStatus = await getUserFutureStatus(
userFutureStatusData.userId,
userFutureStatusData.status,
userFutureStatusData.state
);
expect(userFutureStatus).to.not.be.null;
expect(userFutureStatus).to.be.an("array");
expect(userFutureStatus).to.have.length(1);
});
});
});
9 changes: 8 additions & 1 deletion test/unit/models/userStatus.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { userFutureStatusData } from "../../fixtures/userFutureStatus/userFutureStatusData";
const chai = require("chai");
const sinon = require("sinon");
const { NotFound, Forbidden } = require("http-errors");
const { expect } = chai;
const firestore = require("../../../utils/firestore");
const userStatusModel = firestore.collection("usersStatus");
const tasksModel = firestore.collection("tasks");
const { cancelOooStatus } = require("../../../models/userStatus");
const { cancelOooStatus, addFutureStatus } = require("../../../models/userStatus");
const cleanDb = require("../../utils/cleanDb");
const addUser = require("../../utils/addUser");
const { userState } = require("../../../constants/userStatus");
Expand Down Expand Up @@ -79,4 +80,10 @@ describe("tasks", function () {
expect(err.message).to.be.equal("Task not found");
});
});

it("Should add future status to the User", async function () {
const response = await addFutureStatus(userFutureStatusData);
expect(response.userStatusExists).to.equal(true);
expect(response.data.futureStatus.state).to.equal("UPCOMING");
});
});
6 changes: 4 additions & 2 deletions types/oooRequest.d.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import { Request, Response } from "express";
import { REQUEST_STATE, REQUEST_TYPE } from "../constants/request";
import { REQUEST_STATE, REQUEST_TYPE } from "../constants/requests";
import { userState } from "../constants/userStatus";
import { Boom } from "express-boom";

export type OooStatusRequest = {
id: string;
type: REQUEST_TYPE.OOO;
from: number;
until?: number;
message?: string;
status: userState;
state?: REQUEST_STATE;
lastModifiedBy?: string;
requestedBy?: string;
createdAt?: Timestamp;
updatedAt?: Timestamp;
reason?: string;
Expand Down Expand Up @@ -40,7 +42,7 @@ export type userData= {
};

export type RequestQuery = {
dev: string;
dev?: string;
type?: string;
requestedBy?: string;
state?: REQUEST_STATE.APPROVED | REQUEST_STATE.PENDING | REQUEST_STATE.REJECTED;
Expand Down
13 changes: 13 additions & 0 deletions types/userFutureStatus.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { userState, statusState } from "../constants/userStatus";

export type UserFutureStatusType = {
id?: string;
requestId?: string;
status: userState.OOO | userState.IDLE | userState.ACTIVE;
state: statusState.UPCOMING | statusState.APPLIED | statusState.NOT_APPLIED;
from: number;
endsOn?: number;
userId: string;
message?: string;
createdAt?: number;
};

0 comments on commit 7fb0e0e

Please sign in to comment.