diff --git a/controllers/discordactions.js b/controllers/discordactions.js index 7c71c885e..ed8b4604d 100644 --- a/controllers/discordactions.js +++ b/controllers/discordactions.js @@ -124,8 +124,20 @@ const deleteGroupRole = async (req, res) => { * @param res {Object} - Express response object */ -const getAllGroupRoles = async (req, res) => { +const getPaginatedGroupRoles = async (req, res) => { try { + const isDevMode = req.query?.dev === "true"; + if (isDevMode) { + const latestDoc = req.query?.latestDoc; + const { groups, newLatestDoc } = await discordRolesModel.getPaginatedGroupRoles(latestDoc); + const discordId = req.userData?.discordId; + const groupsWithMembershipInfo = await discordRolesModel.enrichGroupDataWithMembershipInfo(discordId, groups); + return res.json({ + message: "Roles fetched successfully!", + newLatestDoc: newLatestDoc, + groups: groupsWithMembershipInfo, + }); + } const { groups } = await discordRolesModel.getAllGroupRoles(); const discordId = req.userData?.discordId; const groupsWithMembershipInfo = await discordRolesModel.enrichGroupDataWithMembershipInfo(discordId, groups); @@ -431,7 +443,7 @@ const syncDiscordGroupRolesInFirestore = async (req, res) => { }); await Promise.all(batch); - const allRolesInFirestore = await discordRolesModel.getAllGroupRoles(); + const allRolesInFirestore = await discordRolesModel.getPaginatedGroupRoles(); return res.json({ response: allRolesInFirestore.groups, @@ -534,7 +546,7 @@ const getUserDiscordInvite = async (req, res) => { module.exports = { getGroupsRoleId, createGroupRole, - getAllGroupRoles, + getPaginatedGroupRoles, addGroupRoleToMember, deleteRole, updateDiscordImageForVerification, diff --git a/models/discordactions.js b/models/discordactions.js index bfe728cb8..2a2b27f75 100644 --- a/models/discordactions.js +++ b/models/discordactions.js @@ -107,6 +107,7 @@ const deleteRoleFromDatabase = async (roleId, discordId) => { * @param roleData { Object }: Data of the new role * @returns {Promise} */ + const getAllGroupRoles = async () => { try { const data = await discordRoleModel.get(); @@ -125,6 +126,28 @@ const getAllGroupRoles = async () => { } }; +const getPaginatedGroupRoles = async (latestDoc) => { + try { + const data = await discordRoleModel + .orderBy("roleid") + .startAfter(latestDoc || 0) + .limit(18) + .get(); + const groups = []; + data.forEach((doc) => { + const group = { + id: doc.id, + ...doc.data(), + }; + groups.push(group); + }); + return { groups, newLatestDoc: data.docs[data.docs.length - 1]?.data().roleid }; + } catch (err) { + logger.error("Error in getting all group-roles", err); + throw err; + } +}; + /** * * @param groupRoleName String : name of the role @@ -1086,6 +1109,7 @@ module.exports = { removeMemberGroup, getGroupRolesForUser, getAllGroupRoles, + getPaginatedGroupRoles, getGroupRoleByName, updateGroupRole, addGroupRoleToMember, diff --git a/routes/discordactions.js b/routes/discordactions.js index 3869eca58..9f8eb7d6a 100644 --- a/routes/discordactions.js +++ b/routes/discordactions.js @@ -3,7 +3,7 @@ const authenticate = require("../middlewares/authenticate"); const { createGroupRole, getGroupsRoleId, - getAllGroupRoles, + getPaginatedGroupRoles, addGroupRoleToMember, deleteRole, updateDiscordImageForVerification, @@ -33,7 +33,7 @@ const { authorizeAndAuthenticate } = require("../middlewares/authorizeUsersAndSe const router = express.Router(); router.post("/groups", authenticate, checkIsVerifiedDiscord, validateGroupRoleBody, createGroupRole); -router.get("/groups", authenticate, checkIsVerifiedDiscord, getAllGroupRoles); +router.get("/groups", authenticate, checkIsVerifiedDiscord, getPaginatedGroupRoles); router.delete("/groups/:groupId", authenticate, checkIsVerifiedDiscord, authorizeRoles([SUPERUSER]), deleteGroupRole); router.post("/roles", authenticate, checkIsVerifiedDiscord, validateMemberRoleBody, addGroupRoleToMember); router.get("/invite", authenticate, getUserDiscordInvite); diff --git a/test/unit/models/discordactions.test.js b/test/unit/models/discordactions.test.js index 249e70601..73e04bb2f 100644 --- a/test/unit/models/discordactions.test.js +++ b/test/unit/models/discordactions.test.js @@ -19,7 +19,7 @@ const tasksModel = firestore.collection("tasks"); const { createNewRole, - getAllGroupRoles, + getPaginatedGroupRoles, isGroupRoleExists, addGroupRoleToMember, deleteRoleFromDatabase, @@ -93,27 +93,42 @@ describe("discordactions", function () { }); }); - describe("getAllGroupRoles", function () { - let getStub; + describe("getPaginatedGroupRoles", function () { + let orderByStub, startAfterStub, limitStub, getStub; beforeEach(function () { - getStub = sinon.stub(discordRoleModel, "get").resolves({ - forEach: (callback) => groupData.forEach(callback), + orderByStub = sinon.stub(); + startAfterStub = sinon.stub(); + limitStub = sinon.stub(); + getStub = sinon.stub(); + + orderByStub.returns({ startAfter: startAfterStub }); + startAfterStub.returns({ limit: limitStub }); + limitStub.returns({ get: getStub }); + getStub.resolves({ + docs: groupData.map((group) => ({ + id: group.id, + data: () => group, + })), }); + + sinon.stub(discordRoleModel, "orderBy").returns(orderByStub); }); afterEach(function () { - getStub.restore(); + sinon.restore(); }); - it("should return all group-roles from the database", async function () { - const result = await getAllGroupRoles(); - expect(result.groups).to.be.an("array"); + it("should return paginated group-roles from the database", async function () { + const result = await getPaginatedGroupRoles(); + expect(result).to.have.property("groups").that.is.an("array"); + expect(result).to.have.property("newLatestDoc"); + expect(result.groups.length).to.be.at.most(18); // Assuming the limit is 18 as per the function }); it("should throw an error if getting group-roles fails", async function () { getStub.rejects(new Error("Database error")); - return getAllGroupRoles().catch((err) => { + return getPaginatedGroupRoles().catch((err) => { expect(err).to.be.an.instanceOf(Error); expect(err.message).to.equal("Database error"); });