Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: skip users having approved onboarding extension when applying groupOnboarding31d+ role #2330

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 51 additions & 1 deletion models/discordactions.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
const discordService = require("../services/discordService");
const { buildTasksQueryForMissedUpdates } = require("../utils/tasks");
const { buildProgressQueryForMissedUpdates } = require("../utils/progresses");
const { getRequestByKeyValues } = require("./requests");
const { REQUEST_TYPE, REQUEST_STATE } = require("../constants/requests");
const allMavens = [];

/**
Expand Down Expand Up @@ -550,7 +552,7 @@

for (let i = 0; i < nicknameUpdateBatches.length; i++) {
const promises = [];
const usersStatusDocsBatch = nicknameUpdateBatches[i];

Check warning on line 555 in models/discordactions.js

View workflow job for this annotation

GitHub Actions / build (20.11.x)

Variable Assigned to Object Injection Sink
usersStatusDocsBatch.forEach((document) => {
const doc = document.data();
const userId = doc.userId;
Expand Down Expand Up @@ -753,12 +755,59 @@
};
};

/**
* Filters out onboarding users who have an approved onboarding extension request that is still valid.
*
* This function iterates through the given list of onboarding users and checks if each user has a valid
* approved onboarding extension request. If a valid extension request exists with a `newEndsOn`
* date greater than the current date, the user is skipped. Otherwise, the user is added to the
* returned list.
*
* @async
* @function skipOnboardingUsersHavingApprovedExtensionRequest
* @param {Array<Object>} [users=[]] - An array of user objects to be filtered. Each user object
* must have an `id` property.
* @returns {Promise<Array<Object>>} A promise that resolves to an array of users who do not have
* a valid approved onboarding extension request.
*/
const skipOnboardingUsersHavingApprovedExtensionRequest = async (users = []) => {
pankajjs marked this conversation as resolved.
Show resolved Hide resolved
const currentTime = Date.now();

const results = await Promise.all(
users.map(async (user) => {
try {
const latestApprovedExtension = await getRequestByKeyValues({
type: REQUEST_TYPE.ONBOARDING,
state: REQUEST_STATE.APPROVED,
userId: user.id,
});

if (latestApprovedExtension && latestApprovedExtension.newEndsOn > currentTime) {
return null;
}

return user;
} catch (error) {
logger.error(`Error while fetching latest approved extension for user ${user.id}:`, error);
return null;
}
})
);

return results.filter(Boolean);
};

const updateUsersWith31DaysPlusOnboarding = async () => {
try {
const allOnboardingUsers31DaysCompleted = await getUsersBasedOnFilter({
let allOnboardingUsers31DaysCompleted = await getUsersBasedOnFilter({
state: userState.ONBOARDING,
time: "31d",
});

allOnboardingUsers31DaysCompleted = await skipOnboardingUsersHavingApprovedExtensionRequest(
allOnboardingUsers31DaysCompleted
);

const discordMembers = await getDiscordMembers();
const groupOnboardingRole = await getGroupRole("group-onboarding-31d+");
const groupOnboardingRoleId = groupOnboardingRole.role.roleid;
Expand Down Expand Up @@ -1131,4 +1180,5 @@
addInviteToInviteModel,
groupUpdateLastJoinDate,
deleteGroupRole,
skipOnboardingUsersHavingApprovedExtensionRequest,
};
28 changes: 28 additions & 0 deletions test/integration/discordactions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ chai.use(chaiHttp);
const { userStatusDataForOooState } = require("../fixtures/userStatus/userStatus");
const { generateCronJobToken } = require("../utils/generateBotToken");
const { CRON_JOB_HANDLER } = require("../../constants/bot");
const { createRequest } = require("../../models/requests");
const { REQUEST_TYPE, REQUEST_STATE } = require("../../constants/requests");
const { convertDaysToMilliseconds } = require("../../utils/time");

describe("Discord actions", function () {
let superUserId;
Expand Down Expand Up @@ -853,6 +856,8 @@ describe("Discord actions", function () {
});

describe("PUT /discord-actions/group-onboarding-31d-plus", function () {
let userId;

beforeEach(async function () {
userData[0] = {
...userData[0],
Expand Down Expand Up @@ -884,6 +889,7 @@ describe("Discord actions", function () {
const addUsersPromises = allUsers.map((user) => addUser(user));
const userIds = await Promise.all(addUsersPromises);

userId = userIds[0];
const updateUserStatusPromises = userIds.map((userId, index) => {
if (index === 3) return updateUserStatus(userId, generateUserStatusData("IDLE", new Date(), new Date()));
return updateUserStatus(userId, generateUserStatusData("ONBOARDING", new Date(), new Date()));
Expand All @@ -905,6 +911,28 @@ describe("Discord actions", function () {
await cleanDb();
});

it("should filter users who have approved extension request and update groupOnboarding31d+ role", function (done) {
createRequest({
type: REQUEST_TYPE.ONBOARDING,
state: REQUEST_STATE.APPROVED,
userId: userId,
newEndsOn: Date.now() + convertDaysToMilliseconds(2),
});
chai
.request(app)
.put(`/discord-actions/group-onboarding-31d-plus`)
.set("Cookie", `${cookieName}=${superUserAuthToken}`)
.end((err, res) => {
if (err) return done(err);
expect(res).to.have.status(201);
expect(res.body.message).to.be.equal("All Users with 31 Days Plus Onboarding are updated successfully.");
expect(res.body.totalOnboardingUsers31DaysCompleted.count).to.be.equal(2);
expect(res.body.totalOnboarding31dPlusRoleApplied.count).to.be.equal(2);
expect(res.body.totalOnboarding31dPlusRoleRemoved.count).to.be.equal(1);
return done();
});
});

it("should update role for onboarding users with 31 days completed", function (done) {
chai
.request(app)
Expand Down
77 changes: 76 additions & 1 deletion test/unit/models/discordactions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const {
removeMemberGroup,
getGroupRoleByName,
getGroupRolesForUser,
skipOnboardingUsersHavingApprovedExtensionRequest,
} = require("../../../models/discordactions");
const {
groupData,
Expand All @@ -63,6 +64,8 @@ const { stubbedModelTaskProgressData } = require("../../fixtures/progress/progre
const { convertDaysToMilliseconds } = require("../../../utils/time");
const { generateUserStatusData } = require("../../fixtures/userStatus/userStatus");
const { userState } = require("../../../constants/userStatus");
const { REQUEST_TYPE, REQUEST_STATE } = require("../../../constants/requests");
const { createRequest } = require("../../../models/requests");

chai.should();

Expand Down Expand Up @@ -1064,6 +1067,7 @@ describe("discordactions", function () {

describe("updateUsersWith31DaysPlusOnboarding", function () {
let fetchStub;
let userId0;

beforeEach(async function () {
fetchStub = sinon.stub(global, "fetch");
Expand All @@ -1087,7 +1091,7 @@ describe("discordactions", function () {
roles: { archived: false, in_discord: true },
};

const userId0 = await addUser(userData[0]);
userId0 = await addUser(userData[0]);
const userId1 = await addUser(userData[1]);
const userId2 = await addUser(userData[2]);

Expand Down Expand Up @@ -1133,6 +1137,48 @@ describe("discordactions", function () {
await cleanDb();
});

it("should add grouponboarding31D when user has an approved extension request but dealine has been passed", async function () {
await createRequest({
type: REQUEST_TYPE.ONBOARDING,
state: REQUEST_STATE.APPROVED,
newEndsOn: Date.now() - convertDaysToMilliseconds(2),
userId: userId0,
});

const res = await updateUsersWith31DaysPlusOnboarding();
expect(res.totalOnboardingUsers31DaysCompleted.count).to.equal(2);
expect(res.totalOnboarding31dPlusRoleApplied.count).to.equal(1);
expect(res.totalOnboarding31dPlusRoleRemoved.count).to.equal(1);
});

it("should add grouponboarding31D when user does not have approved extension request", async function () {
await createRequest({
type: REQUEST_TYPE.ONBOARDING,
state: REQUEST_STATE.PENDING,
newEndsOn: Date.now() + convertDaysToMilliseconds(2),
userId: userId0,
});

const res = await updateUsersWith31DaysPlusOnboarding();
expect(res.totalOnboardingUsers31DaysCompleted.count).to.equal(2);
expect(res.totalOnboarding31dPlusRoleApplied.count).to.equal(1);
expect(res.totalOnboarding31dPlusRoleRemoved.count).to.equal(1);
});

it("should not add grouponboarding31D when user has approved extension request", async function () {
await createRequest({
type: REQUEST_TYPE.ONBOARDING,
state: REQUEST_STATE.APPROVED,
newEndsOn: Date.now() + convertDaysToMilliseconds(2),
userId: userId0,
});

const res = await updateUsersWith31DaysPlusOnboarding();
expect(res.totalOnboardingUsers31DaysCompleted.count).to.equal(1);
expect(res.totalOnboarding31dPlusRoleApplied.count).to.equal(1);
expect(res.totalOnboarding31dPlusRoleRemoved.count).to.equal(1);
});

it("apply, or remove grouponboarding31D", async function () {
const res = await updateUsersWith31DaysPlusOnboarding();

Expand Down Expand Up @@ -1343,4 +1389,33 @@ describe("discordactions", function () {
}
});
});

describe("skipOnboardingUsersHavingApprovedExtensionRequest", function () {
const userId0 = "11111";
const userId1 = "12345";

afterEach(async function () {
sinon.restore();
await cleanDb();
});

it("should return filtered users", async function () {
await createRequest({
state: REQUEST_STATE.APPROVED,
type: REQUEST_TYPE.ONBOARDING,
newEndsOn: Date.now() + convertDaysToMilliseconds(2),
userId: userId0,
});
const users = await skipOnboardingUsersHavingApprovedExtensionRequest([{ id: userId0 }, { id: userId1 }]);
expect(users.length).to.equal(1);
expect(users[0].id).to.equal(userId1);
});

it("should not return filtered users", async function () {
const users = await skipOnboardingUsersHavingApprovedExtensionRequest([{ id: userId0 }, { id: userId1 }]);
expect(users.length).to.equal(2);
expect(users[0].id).to.equal(userId0);
expect(users[1].id).to.equal(userId1);
});
});
});
Loading