Skip to content

Commit 3a1473a

Browse files
committed
- moved the function which returns the required data to service layer and the corresponding queries to model.
- removed test cases from integration testing and moved it to unit testing. - moved updateTaskStatusToDone to tasks model as it was causing circular dependency. - created a separate fixture file for mock data required to test the feature. - reverted the test case changes done for other test cases due to mock data changes.
1 parent e0d7dbb commit 3a1473a

File tree

12 files changed

+374
-272
lines changed

12 files changed

+374
-272
lines changed

controllers/tasks.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const { getPaginatedLink } = require("../utils/helper");
1212
const { updateUserStatusOnTaskUpdate, updateStatusOnTaskCompletion } = require("../models/userStatus");
1313
const dataAccess = require("../services/dataAccessLayer");
1414
const { parseSearchQuery } = require("../utils/tasks");
15-
const { addTaskCreatedAtAndUpdatedAtFields } = require("../services/tasks");
15+
const { addTaskCreatedAtAndUpdatedAtFields, fetchOrphanedTasks } = require("../services/tasks");
1616
const { RQLQueryParser } = require("../utils/RQLParser");
1717
const { getMissedProgressUpdatesUsers } = require("../models/discordactions");
1818
const { logType } = require("../constants/logs");
@@ -534,7 +534,7 @@ const getUsersHandler = async (req, res) => {
534534

535535
const getOrphanedTasks = async (req, res) => {
536536
try {
537-
const data = await tasks.fetchOrphanedTasks();
537+
const data = await fetchOrphanedTasks();
538538

539539
return res.status(200).json({ message: "Orphan tasks fetched successfully", data });
540540
} catch (error) {

models/tasks.js

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ const userModel = firestore.collection("users");
44
const ItemModel = firestore.collection("itemTags");
55
const dependencyModel = firestore.collection("taskDependencies");
66
const userUtils = require("../utils/users");
7-
const { updateTaskStatusToDone } = require("../services/tasks");
87
const { chunks } = require("../utils/array");
98
const { DOCUMENT_WRITE_SIZE } = require("../constants/constants");
109
const { fromFirestoreData, toFirestoreData, buildTasks } = require("../utils/tasks");
@@ -24,6 +23,33 @@ const {
2423
const { OLD_ACTIVE, OLD_BLOCKED, OLD_PENDING, OLD_COMPLETED } = TASK_STATUS_OLD;
2524
const { INTERNAL_SERVER_ERROR } = require("../constants/errorMessages");
2625

26+
const updateTaskStatusToDone = async (tasksData) => {
27+
const batch = firestore.batch();
28+
const tasksBatch = [];
29+
const summary = {
30+
totalUpdatedStatus: 0,
31+
totalOperationsFailed: 0,
32+
updatedTaskDetails: [],
33+
failedTaskDetails: [],
34+
};
35+
tasksData.forEach((task) => {
36+
const updateTaskData = { ...task, status: "DONE" };
37+
batch.update(tasksModel.doc(task.id), updateTaskData);
38+
tasksBatch.push(task.id);
39+
});
40+
try {
41+
await batch.commit();
42+
summary.totalUpdatedStatus += tasksData.length;
43+
summary.updatedTaskDetails = [...tasksBatch];
44+
return { ...summary };
45+
} catch (err) {
46+
logger.error("Firebase batch Operation Failed!");
47+
summary.totalOperationsFailed += tasksData.length;
48+
summary.failedTaskDetails = [...tasksBatch];
49+
return { ...summary };
50+
}
51+
};
52+
2753
/**
2854
* Adds and Updates tasks
2955
*
@@ -701,31 +727,16 @@ const markUnDoneTasksOfArchivedUsersBacklog = async (users) => {
701727
}
702728
};
703729

704-
const fetchOrphanedTasks = async () => {
730+
const fetchIncompleteTaskForUser = async (user) => {
731+
const COMPLETED_STATUSES = [DONE, COMPLETED];
705732
try {
706-
const COMPLETED_STATUSES = [DONE, COMPLETED];
707-
const abandonedTasks = [];
708-
709-
const userSnapshot = await userModel
710-
.where("roles.archived", "==", true)
711-
.where("roles.in_discord", "==", false)
733+
const incompleteTaskForUser = await tasksModel
734+
.where("assigneeId", "==", user.id)
735+
.where("status", "not-in", COMPLETED_STATUSES)
712736
.get();
713-
714-
for (const userDoc of userSnapshot.docs) {
715-
const user = userDoc.data();
716-
const abandonedTasksQuerySnapshot = await tasksModel
717-
.where("assigneeId", "==", user.id || "")
718-
.where("status", "not-in", COMPLETED_STATUSES)
719-
.get();
720-
721-
// Check if the user has any tasks with status not in [Done, Complete]
722-
if (!abandonedTasksQuerySnapshot.empty) {
723-
abandonedTasks.push(...abandonedTasksQuerySnapshot.docs.map((doc) => doc.data()));
724-
}
725-
}
726-
return abandonedTasks;
737+
return incompleteTaskForUser;
727738
} catch (error) {
728-
logger.error(`Error in getting tasks abandoned by users: ${error}`);
739+
logger.error("Error when fetching incomplete tasks:", error);
729740
throw error;
730741
}
731742
};
@@ -749,5 +760,6 @@ module.exports = {
749760
updateTaskStatus,
750761
updateOrphanTasksStatus,
751762
markUnDoneTasksOfArchivedUsersBacklog,
752-
fetchOrphanedTasks,
763+
fetchIncompleteTaskForUser,
764+
updateTaskStatusToDone,
753765
};

models/users.js

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,12 @@ const firestore = require("../utils/firestore");
88
const { fetchWallet, createWallet } = require("../models/wallets");
99
const { updateUserStatus } = require("../models/userStatus");
1010
const { arraysHaveCommonItem, chunks } = require("../utils/array");
11-
const { archiveUsers } = require("../services/users");
12-
const { ALLOWED_FILTER_PARAMS, FIRESTORE_IN_CLAUSE_SIZE } = require("../constants/users");
11+
const {
12+
ALLOWED_FILTER_PARAMS,
13+
FIRESTORE_IN_CLAUSE_SIZE,
14+
USERS_PATCH_HANDLER_SUCCESS_MESSAGES,
15+
USERS_PATCH_HANDLER_ERROR_MESSAGES,
16+
} = require("../constants/users");
1317
const { DOCUMENT_WRITE_SIZE } = require("../constants/constants");
1418
const { userState } = require("../constants/userStatus");
1519
const { BATCH_SIZE_IN_CLAUSE } = require("../constants/firebase");
@@ -27,6 +31,46 @@ const { formatUsername } = require("../utils/username");
2731
const { logType } = require("../constants/logs");
2832
const { addLog } = require("../services/logService");
2933

34+
const archiveUsers = async (usersData) => {
35+
const batch = firestore.batch();
36+
const usersBatch = [];
37+
const summary = {
38+
totalUsersArchived: 0,
39+
totalOperationsFailed: 0,
40+
updatedUserDetails: [],
41+
failedUserDetails: [],
42+
};
43+
44+
usersData.forEach((user) => {
45+
const { id, first_name: firstName, last_name: lastName } = user;
46+
const updatedUserData = {
47+
...user,
48+
roles: {
49+
...user.roles,
50+
archived: true,
51+
},
52+
updated_at: Date.now(),
53+
};
54+
batch.update(userModel.doc(id), updatedUserData);
55+
usersBatch.push({ id, firstName, lastName });
56+
});
57+
58+
try {
59+
await batch.commit();
60+
summary.totalUsersArchived += usersData.length;
61+
summary.updatedUserDetails = [...usersBatch];
62+
return {
63+
message: USERS_PATCH_HANDLER_SUCCESS_MESSAGES.ARCHIVE_USERS.SUCCESSFULLY_COMPLETED_BATCH_UPDATES,
64+
...summary,
65+
};
66+
} catch (err) {
67+
logger.error("Firebase batch Operation Failed!");
68+
summary.totalOperationsFailed += usersData.length;
69+
summary.failedUserDetails = [...usersBatch];
70+
return { message: USERS_PATCH_HANDLER_ERROR_MESSAGES.ARCHIVE_USERS.BATCH_DATA_UPDATED_FAILED, ...summary };
71+
}
72+
};
73+
3074
/**
3175
* Adds or updates the user data
3276
*
@@ -1030,7 +1074,21 @@ const updateUsersWithNewUsernames = async () => {
10301074
}
10311075
};
10321076

1077+
const fetchUsersNotInDiscordServer = async () => {
1078+
try {
1079+
const usersNotInDiscordServer = await userModel
1080+
.where("roles.archived", "==", true)
1081+
.where("roles.in_discord", "==", false)
1082+
.get();
1083+
return usersNotInDiscordServer;
1084+
} catch (error) {
1085+
logger.error(`Error in getting users who are not in discord server: ${error}`);
1086+
throw error;
1087+
}
1088+
};
1089+
10331090
module.exports = {
1091+
archiveUsers,
10341092
addOrUpdate,
10351093
fetchPaginatedUsers,
10361094
fetchUser,
@@ -1059,4 +1117,5 @@ module.exports = {
10591117
fetchUserForKeyValue,
10601118
getNonNickNameSyncedUsers,
10611119
updateUsersWithNewUsernames,
1120+
fetchUsersNotInDiscordServer,
10621121
};

services/tasks.js

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,8 @@ const firestore = require("../utils/firestore");
22
const tasksModel = firestore.collection("tasks");
33
const { chunks } = require("../utils/array");
44
const { DOCUMENT_WRITE_SIZE: FIRESTORE_BATCH_OPERATIONS_LIMIT } = require("../constants/constants");
5-
6-
const updateTaskStatusToDone = async (tasksData) => {
7-
const batch = firestore.batch();
8-
const tasksBatch = [];
9-
const summary = {
10-
totalUpdatedStatus: 0,
11-
totalOperationsFailed: 0,
12-
updatedTaskDetails: [],
13-
failedTaskDetails: [],
14-
};
15-
tasksData.forEach((task) => {
16-
const updateTaskData = { ...task, status: "DONE" };
17-
batch.update(tasksModel.doc(task.id), updateTaskData);
18-
tasksBatch.push(task.id);
19-
});
20-
try {
21-
await batch.commit();
22-
summary.totalUpdatedStatus += tasksData.length;
23-
summary.updatedTaskDetails = [...tasksBatch];
24-
return { ...summary };
25-
} catch (err) {
26-
logger.error("Firebase batch Operation Failed!");
27-
summary.totalOperationsFailed += tasksData.length;
28-
summary.failedTaskDetails = [...tasksBatch];
29-
return { ...summary };
30-
}
31-
};
5+
const { fetchUsersNotInDiscordServer } = require("../models/users");
6+
const { fetchIncompleteTaskForUser } = require("../models/tasks");
327

338
const addTaskCreatedAtAndUpdatedAtFields = async () => {
349
const operationStats = {
@@ -83,7 +58,29 @@ const addTaskCreatedAtAndUpdatedAtFields = async () => {
8358
return operationStats;
8459
};
8560

61+
const fetchOrphanedTasks = async () => {
62+
try {
63+
const abandonedTasks = [];
64+
65+
const userSnapshot = await fetchUsersNotInDiscordServer();
66+
67+
for (const userDoc of userSnapshot.docs) {
68+
const user = userDoc.data();
69+
const abandonedTasksQuerySnapshot = await fetchIncompleteTaskForUser(user);
70+
71+
// Check if the user has any tasks with status not in [Done, Complete]
72+
if (!abandonedTasksQuerySnapshot.empty) {
73+
abandonedTasks.push(...abandonedTasksQuerySnapshot.docs.map((doc) => doc.data()));
74+
}
75+
}
76+
return abandonedTasks;
77+
} catch (error) {
78+
logger.error(`Error in getting tasks abandoned by users: ${error}`);
79+
throw error;
80+
}
81+
};
82+
8683
module.exports = {
87-
updateTaskStatusToDone,
8884
addTaskCreatedAtAndUpdatedAtFields,
85+
fetchOrphanedTasks,
8986
};

0 commit comments

Comments
 (0)