From c4fecf29a709653196f975681354f8ae30b49264 Mon Sep 17 00:00:00 2001 From: sailingsam Date: Wed, 25 Sep 2024 23:53:44 +0530 Subject: [PATCH 1/4] feat: lazyLoadDiscordGroupsPage | Tests are not yet written --- controllers/discordactions.js | 10 ++++++---- models/discordactions.js | 12 ++++++++---- routes/discordactions.js | 4 ++-- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/controllers/discordactions.js b/controllers/discordactions.js index c29a443ce..55981843d 100644 --- a/controllers/discordactions.js +++ b/controllers/discordactions.js @@ -69,13 +69,15 @@ const createGroupRole = async (req, res) => { * @param res {Object} - Express response object */ -const getAllGroupRoles = async (req, res) => { +const getPaginatedGroupRoles = async (req, res) => { try { - const { groups } = await discordRolesModel.getAllGroupRoles(); + 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, }); } catch (err) { @@ -381,7 +383,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, @@ -484,7 +486,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 b439ca4ff..d209b2c9e 100644 --- a/models/discordactions.js +++ b/models/discordactions.js @@ -82,9 +82,13 @@ const deleteRoleFromDatabase = async (roleId, discordId) => { * @param roleData { Object }: Data of the new role * @returns {Promise} */ -const getAllGroupRoles = async () => { +const getPaginatedGroupRoles = async (latestDoc) => { try { - const data = await discordRoleModel.get(); + const data = await discordRoleModel + .orderBy("roleid") + .startAfter(latestDoc || 0) + .limit(18) + .get(); const groups = []; data.forEach((doc) => { const group = { @@ -93,7 +97,7 @@ const getAllGroupRoles = async () => { }; groups.push(group); }); - return { groups }; + return { groups, newLatestDoc: data.docs[data.docs.length - 1]?.data().roleid }; } catch (err) { logger.error("Error in getting all group-roles", err); throw err; @@ -1058,7 +1062,7 @@ module.exports = { createNewRole, removeMemberGroup, getGroupRolesForUser, - getAllGroupRoles, + getPaginatedGroupRoles, getGroupRoleByName, updateGroupRole, addGroupRoleToMember, diff --git a/routes/discordactions.js b/routes/discordactions.js index 745a306df..55defae59 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.post("/roles", authenticate, checkIsVerifiedDiscord, validateMemberRoleBody, addGroupRoleToMember); router.get("/invite", authenticate, getUserDiscordInvite); router.post("/invite", authenticate, checkCanGenerateDiscordLink, generateInviteForUser); From bc9345ab268c065dafcead735c312c36d4142f27 Mon Sep 17 00:00:00 2001 From: sailingsam Date: Thu, 26 Sep 2024 04:06:03 +0530 Subject: [PATCH 2/4] add: updated testcases --- test/unit/models/discordactions.test.js | 43 +++++++++++++++++-------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/test/unit/models/discordactions.test.js b/test/unit/models/discordactions.test.js index 312a432eb..6cb7e5695 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, @@ -85,27 +85,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"); }); From 7492a86aa073d73d7cdbcae6c47472e43848979d Mon Sep 17 00:00:00 2001 From: sailingsam Date: Thu, 26 Sep 2024 04:07:23 +0530 Subject: [PATCH 3/4] Add: updated test cases --- test/unit/models/discordactions.test.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/unit/models/discordactions.test.js b/test/unit/models/discordactions.test.js index 6cb7e5695..5bb812914 100644 --- a/test/unit/models/discordactions.test.js +++ b/test/unit/models/discordactions.test.js @@ -87,37 +87,37 @@ describe("discordactions", function () { describe("getPaginatedGroupRoles", function () { let orderByStub, startAfterStub, limitStub, getStub; - + beforeEach(function () { 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 => ({ + docs: groupData.map((group) => ({ id: group.id, - data: () => group + data: () => group, })), }); - + sinon.stub(discordRoleModel, "orderBy").returns(orderByStub); }); - + afterEach(function () { sinon.restore(); }); - + 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).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 getPaginatedGroupRoles().catch((err) => { From a5e4fe79b049c513fa025657fe14a3676cfc0291 Mon Sep 17 00:00:00 2001 From: sailingsam Date: Fri, 27 Sep 2024 05:45:31 +0530 Subject: [PATCH 4/4] Added feature flag --- controllers/discordactions.js | 16 +++++++++++++--- models/discordactions.js | 20 ++++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/controllers/discordactions.js b/controllers/discordactions.js index 55981843d..a48925201 100644 --- a/controllers/discordactions.js +++ b/controllers/discordactions.js @@ -71,13 +71,23 @@ const createGroupRole = async (req, res) => { const getPaginatedGroupRoles = async (req, res) => { try { - const latestDoc = req.query?.latestDoc; - const { groups, newLatestDoc } = await discordRolesModel.getPaginatedGroupRoles(latestDoc); + 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); return res.json({ message: "Roles fetched successfully!", - newLatestDoc: newLatestDoc, groups: groupsWithMembershipInfo, }); } catch (err) { diff --git a/models/discordactions.js b/models/discordactions.js index d209b2c9e..090aa49ba 100644 --- a/models/discordactions.js +++ b/models/discordactions.js @@ -82,6 +82,25 @@ const deleteRoleFromDatabase = async (roleId, discordId) => { * @param roleData { Object }: Data of the new role * @returns {Promise} */ + +const getAllGroupRoles = async () => { + try { + const data = await discordRoleModel.get(); + const groups = []; + data.forEach((doc) => { + const group = { + id: doc.id, + ...doc.data(), + }; + groups.push(group); + }); + return { groups }; + } catch (err) { + logger.error("Error in getting all group-roles", err); + throw err; + } +}; + const getPaginatedGroupRoles = async (latestDoc) => { try { const data = await discordRoleModel @@ -1062,6 +1081,7 @@ module.exports = { createNewRole, removeMemberGroup, getGroupRolesForUser, + getAllGroupRoles, getPaginatedGroupRoles, getGroupRoleByName, updateGroupRole,