Skip to content

Commit 220e533

Browse files
committed
1. Refactored query parameter based functions to services/users file for reusability.
2. Updated the integration tests after refactoring of code. Signed-off-by: Prakhar Kumar <[email protected]>
1 parent cf511b3 commit 220e533

File tree

3 files changed

+236
-233
lines changed

3 files changed

+236
-233
lines changed

controllers/users.js

Lines changed: 78 additions & 231 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
import { isLastPRMergedWithinDays } from "../services/githubService";
2-
import { getUserStatus } from "../models/userStatus";
3-
import userService from "../services/users";
4-
import { getOverdueTasks } from "../models/tasks";
5-
61
const chaincodeQuery = require("../models/chaincodes");
72
const userQuery = require("../models/users");
83
const profileDiffsQuery = require("../models/profileDiffs");
@@ -39,6 +34,7 @@ const { generateUniqueUsername } = require("../services/users");
3934
const { NotFound, BadRequest } = require("http-errors");
4035
const discordDeveloperRoleId = config.get("discordDeveloperRoleId");
4136
const usersCollection = firestore.collection("users");
37+
const userService = require("../services/users");
4238

4339
const verifyUser = async (req, res) => {
4440
const userId = req.userData.id;
@@ -91,7 +87,6 @@ const getUserById = async (req, res) => {
9187

9288
const getUsers = async (req, res) => {
9389
try {
94-
// getting user details by id if present.
9590
const reqQueryObject = req.query;
9691
const { q, dev: devParam, query, departed, id, profile: profileParam, discordId } = reqQueryObject;
9792
const userData = req.userData || {};
@@ -108,107 +103,102 @@ const getUsers = async (req, res) => {
108103
return res.boom.notFound("Route not found");
109104
}
110105

111-
try {
112-
if (id) {
113-
const user = await findUserById(id);
114-
return res.json({
115-
message: "User returned successfully!",
116-
user: user,
117-
});
118-
}
119-
120-
if (profile) {
121-
return res.send(await getUserByProfileData(userData));
122-
}
106+
if (id) {
107+
const user = await userService.findUserById(id);
108+
return res.json({
109+
message: "User returned successfully!",
110+
user: user,
111+
});
112+
}
123113

124-
if (!transformedQuery?.days && transformedQuery?.filterBy === "unmerged_prs") {
125-
return res.boom.badRequest(`Days is required for filterBy ${transformedQuery?.filterBy}`);
126-
}
114+
if (profile) {
115+
return res.send(await userService.getUserByProfileData(userData));
116+
}
127117

128-
if (filterBy === "unmerged_prs" && days) {
129-
const users = await getUsersByUnmergedPrs(days);
130-
return res.json({
131-
message: "Inactive users returned successfully!",
132-
count: users.length,
133-
users: users,
134-
});
135-
}
118+
if (!transformedQuery?.days && transformedQuery?.filterBy === "unmerged_prs") {
119+
return res.boom.badRequest(`Days is required for filterBy ${transformedQuery?.filterBy}`);
120+
}
136121

137-
if (discordId) {
138-
if (dev) {
139-
const user = await getUserByDiscordId(discordId);
140-
return res.json({
141-
message: user ? "User returned successfully!" : "User not found",
142-
user: user,
143-
});
144-
} else {
145-
return res.boom.notFound("Route not found");
146-
}
147-
}
122+
if (filterBy === "unmerged_prs" && days) {
123+
const users = await userService.getUsersByUnmergedPrs(days);
124+
return res.json({
125+
message: "Inactive users returned successfully!",
126+
count: users.length,
127+
users: users,
128+
});
129+
}
148130

149-
if (isDeparted) {
150-
if (!dev) {
151-
return res.boom.notFound("Route not found");
152-
}
153-
const { result, departedUsers } = await getDepartedUsers(reqQueryObject);
154-
if (departedUsers.length === 0) return res.status(204).send();
131+
if (discordId) {
132+
if (dev) {
133+
const user = await userService.getUserByDiscordId(discordId);
155134
return res.json({
156-
message: "Users with abandoned tasks fetched successfully",
157-
users: departedUsers,
158-
links: {
159-
next: result.nextId ? getPaginationLink(reqQueryObject, "next", result.nextId) : "",
160-
prev: result.prevId ? getPaginationLink(reqQueryObject, "prev", result.prevId) : "",
161-
},
135+
message: user ? "User returned successfully!" : "User not found",
136+
user: user,
162137
});
138+
} else {
139+
return res.boom.notFound("Route not found");
163140
}
141+
}
164142

165-
if (filterBy === OVERDUE_TASKS) {
166-
const users = await getUsersByOverDueTasks(days, dev);
167-
if (!users || users.length === 0) {
168-
return res.json({
169-
message: "No users found",
170-
users: [],
171-
});
172-
}
173-
return res.json({
174-
message: "Users returned successfully!",
175-
count: users.length,
176-
users: users,
177-
});
143+
if (isDeparted) {
144+
if (!dev) {
145+
return res.boom.notFound("Route not found");
178146
}
147+
const { result, departedUsers } = await userService.getDepartedUsers(reqQueryObject);
148+
if (departedUsers.length === 0) return res.status(204).send();
149+
return res.json({
150+
message: "Users with abandoned tasks fetched successfully",
151+
users: departedUsers,
152+
links: {
153+
next: result.nextId ? getPaginationLink(reqQueryObject, "next", result.nextId) : "",
154+
prev: result.prevId ? getPaginationLink(reqQueryObject, "prev", result.prevId) : "",
155+
},
156+
});
157+
}
179158

180-
if (qualifiers?.filterBy) {
181-
const allPRs = await getFilteredPRsOrIssues(qualifiers);
182-
const usernames = getUsernamesFromPRs(allPRs);
183-
const users = await dataAccess.retrieveUsers({ usernames: usernames });
159+
if (filterBy === OVERDUE_TASKS) {
160+
const users = await userService.getUsersByOverDueTasks(days, dev);
161+
if (!users || users.length === 0) {
184162
return res.json({
185-
message: "Users returned successfully!",
186-
users,
163+
message: "No users found",
164+
users: [],
187165
});
188166
}
167+
return res.json({
168+
message: "Users returned successfully!",
169+
count: users.length,
170+
users: users,
171+
});
172+
}
189173

190-
const data = await dataAccess.retrieveUsers({ query: reqQueryObject });
191-
174+
if (qualifiers?.filterBy) {
175+
const allPRs = await getFilteredPRsOrIssues(qualifiers);
176+
const usernames = getUsernamesFromPRs(allPRs);
177+
const users = await dataAccess.retrieveUsers({ usernames: usernames });
192178
return res.json({
193179
message: "Users returned successfully!",
194-
users: data.users,
195-
links: {
196-
next: data.nextId ? getPaginationLink(reqQueryObject, "next", data.nextId) : "",
197-
prev: data.prevId ? getPaginationLink(reqQueryObject, "prev", data.prevId) : "",
198-
},
180+
users,
199181
});
200-
} catch (e) {
201-
if (e instanceof NotFound) {
202-
return res.boom.notFound(e.message);
203-
}
204-
if (e instanceof BadRequest) {
205-
return res.boom.BadRequest(e.message);
206-
}
182+
}
183+
184+
const data = await dataAccess.retrieveUsers({ query: reqQueryObject });
207185

208-
return res.boom.serverUnavailable(SOMETHING_WENT_WRONG);
186+
return res.json({
187+
message: "Users returned successfully!",
188+
users: data.users,
189+
links: {
190+
next: data.nextId ? getPaginationLink(reqQueryObject, "next", data.nextId) : "",
191+
prev: data.prevId ? getPaginationLink(reqQueryObject, "prev", data.prevId) : "",
192+
},
193+
});
194+
} catch (e) {
195+
if (e instanceof NotFound) {
196+
return res.boom.notFound(e.message);
209197
}
210-
} catch (error) {
211-
logger.error(`Error while fetching all users: ${error}`);
198+
if (e instanceof BadRequest) {
199+
return res.boom.BadRequest(e.message);
200+
}
201+
212202
return res.boom.serverUnavailable(SOMETHING_WENT_WRONG);
213203
}
214204
};
@@ -1042,149 +1032,6 @@ const updateProfile = async (req, res) => {
10421032
}
10431033
};
10441034

1045-
/**
1046-
* @param userId { string }: Id of the User
1047-
* @returns Promise<object>
1048-
*/
1049-
const findUserById = async (userId) => {
1050-
let result;
1051-
try {
1052-
result = await dataAccess.retrieveUsers({ id: userId });
1053-
if (!result.userExists) {
1054-
throw NotFound("User doesn't exist");
1055-
}
1056-
return result.user;
1057-
} catch (error) {
1058-
logger.error(`Error while fetching user: ${error}`);
1059-
throw error;
1060-
}
1061-
};
1062-
1063-
/**
1064-
* @param userData { Object }: req.userData
1065-
* @returns Promise<object>
1066-
*/
1067-
const getUserByProfileData = async (userData) => {
1068-
if (!userData.id) {
1069-
throw BadRequest("User ID not provided.");
1070-
}
1071-
1072-
try {
1073-
const result = await dataAccess.retrieveUsers({ id: userData.id });
1074-
return result.user;
1075-
} catch (error) {
1076-
logger.error(`Error while fetching user: ${error}`);
1077-
throw error;
1078-
}
1079-
};
1080-
1081-
/**
1082-
* @param days {number}: days since last unmerged pr.
1083-
* @returns Promise<object[]>
1084-
*/
1085-
const getUsersByUnmergedPrs = async (days) => {
1086-
try {
1087-
const inDiscordUser = await dataAccess.retrieveUsersWithRole(ROLES.INDISCORD);
1088-
const users = [];
1089-
1090-
for (const user of inDiscordUser) {
1091-
const username = user.github_id;
1092-
const isMerged = await isLastPRMergedWithinDays(username, days);
1093-
if (!isMerged) {
1094-
users.push(user.id);
1095-
}
1096-
}
1097-
1098-
return users;
1099-
} catch (error) {
1100-
logger.error(`Error while fetching all users: ${error}`);
1101-
throw error;
1102-
}
1103-
};
1104-
1105-
/**
1106-
* @param discordId { string }: discordId of the user
1107-
* @returns Promise<object>
1108-
*/
1109-
const getUserByDiscordId = async (discordId) => {
1110-
let result, user;
1111-
try {
1112-
result = await dataAccess.retrieveUsers({ discordId });
1113-
user = result.user;
1114-
if (!result.userExists) {
1115-
return null;
1116-
}
1117-
1118-
const userStatusResult = await getUserStatus(user.id);
1119-
if (userStatusResult.userStatusExists) {
1120-
user.state = userStatusResult.data.currentStatus.state;
1121-
}
1122-
} catch (error) {
1123-
logger.error(`Error while fetching user: ${error}`);
1124-
throw error;
1125-
}
1126-
return user;
1127-
};
1128-
1129-
/**
1130-
* @param queryObject { Object }: request query object
1131-
* @returns Promise<object>
1132-
*/
1133-
const getDepartedUsers = async (queryObject) => {
1134-
try {
1135-
const result = await dataAccess.retrieveUsers({ query: queryObject });
1136-
const departedUsers = await userService.getUsersWithIncompleteTasks(result.users);
1137-
if (!departedUsers || departedUsers.length === 0) return { departedUsers: [] };
1138-
return { result, departedUsers };
1139-
} catch (error) {
1140-
logger.error("Error when fetching users who abandoned tasks:", error);
1141-
throw error;
1142-
}
1143-
};
1144-
1145-
/**
1146-
* @param days { number }: overdue days
1147-
* @param dev {boolean}: dev feature flag
1148-
* @returns Promise<object[]>
1149-
*/
1150-
const getUsersByOverDueTasks = async (days, dev) => {
1151-
try {
1152-
const tasksData = await getOverdueTasks(days);
1153-
if (!tasksData.length) {
1154-
return [];
1155-
}
1156-
const userIds = new Set();
1157-
const usersData = [];
1158-
1159-
tasksData.forEach((task) => {
1160-
if (task.assignee) {
1161-
userIds.add(task.assignee);
1162-
}
1163-
});
1164-
1165-
const userInfo = await dataAccess.retrieveUsers({ userIds: Array.from(userIds) });
1166-
userInfo.forEach((user) => {
1167-
if (!user.roles.archived) {
1168-
const userTasks = tasksData.filter((task) => task.assignee === user.id);
1169-
const userData = {
1170-
id: user.id,
1171-
discordId: user.discordId,
1172-
username: user.username,
1173-
};
1174-
if (dev) {
1175-
userData.tasks = userTasks;
1176-
}
1177-
usersData.push(userData);
1178-
}
1179-
});
1180-
1181-
return usersData;
1182-
} catch (error) {
1183-
logger.error(`Error while fetching users and tasks: ${error}`);
1184-
throw error;
1185-
}
1186-
};
1187-
11881035
module.exports = {
11891036
verifyUser,
11901037
generateChaincode,

0 commit comments

Comments
 (0)