Skip to content

Commit 72d8f08

Browse files
authored
Merge pull request #2061 from Real-Dev-Squad/dashboard/I-758/identity-stats
Added an API for identity stats
2 parents f73f04e + 1352dc1 commit 72d8f08

File tree

4 files changed

+98
-0
lines changed

4 files changed

+98
-0
lines changed

controllers/users.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,41 @@ async function usersPatchHandler(req, res) {
919919
}
920920
}
921921

922+
const getIdentityStats = async (req, res) => {
923+
const verifiedUsers = await userQuery.fetchUserForKeyValue("profileStatus", "VERIFIED");
924+
const blockedUsers = await userQuery.fetchUserForKeyValue("profileStatus", "BLOCKED");
925+
let developers = [];
926+
const membersInDiscord = await getDiscordMembers();
927+
if (membersInDiscord) {
928+
const developersInDiscord = membersInDiscord.filter(
929+
(discordMember) => discordMember && discordMember.roles && discordMember.roles.includes(discordDeveloperRoleId)
930+
);
931+
developers = developersInDiscord;
932+
}
933+
934+
const findUserByDiscordId = (usersArray, discordId) => usersArray.find((user) => user.discordId === discordId);
935+
936+
const verifiedDeveloperCount = developers.filter((developer) =>
937+
findUserByDiscordId(verifiedUsers, developer.user.id)
938+
).length;
939+
const blockedDeveloperCount = developers.filter((developer) =>
940+
findUserByDiscordId(blockedUsers, developer.user.id)
941+
).length;
942+
const developersLeftToVerifyCount = developers.filter(
943+
(developer) =>
944+
!findUserByDiscordId(verifiedUsers, developer.user.id) && !findUserByDiscordId(blockedUsers, developer.user.id)
945+
).length;
946+
947+
return res.status(200).json({
948+
verifiedUsersCount: verifiedUsers.length,
949+
blockedUsersCount: blockedUsers.length,
950+
verifiedDeveloperCount,
951+
blockedDeveloperCount,
952+
developersLeftToVerifyCount,
953+
developersCount: developers.length,
954+
});
955+
};
956+
922957
module.exports = {
923958
verifyUser,
924959
generateChaincode,
@@ -949,4 +984,5 @@ module.exports = {
949984
archiveUserIfNotInDiscord,
950985
usersPatchHandler,
951986
isDeveloper,
987+
getIdentityStats,
952988
};

routes/users.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ router.get("/isUsernameAvailable/:username", authenticate, users.getUsernameAvai
2424
router.get("/username", authenticate, userValidator.validateGenerateUsernameQuery, users.generateUsername);
2525
router.get("/chaincode", authenticate, users.generateChaincode);
2626
router.get("/search", userValidator.validateUserQueryParams, users.filterUsers);
27+
router.get("/identity-stats", authenticate, authorizeRoles([SUPERUSER]), users.getIdentityStats);
2728
router.patch(
2829
"/:userId/update-nickname",
2930
authenticate,

test/fixtures/user/user.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ module.exports = () => {
3434
},
3535
status: "active",
3636
profileURL: "https://abcde.com",
37+
profileStatus: "BLOCKED",
3738
picture: {
3839
publicId: "profile/mtS4DhUvNYsKqI7oCWVB/aenklfhtjldc5ytei3ar",
3940
url: "https://res.cloudinary.com/realdevsquad/image/upload/v1667685133/profile/mtS4DhUvNYsKqI7oCWVB/aenklfhtjldc5ytei3ar.jpg",
@@ -59,6 +60,7 @@ module.exports = () => {
5960
url: "https://res.cloudinary.com/realdevsquad/image/upload/v1667685133/profile/mtS4DhUvNYsKqI7oCWVB/aenklfhtjldc5ytei3ar.jpg",
6061
},
6162
nickname_synced: false,
63+
profileStatus: "BLOCKED",
6264
},
6365
{
6466
username: "pranavg",
@@ -81,6 +83,7 @@ module.exports = () => {
8183
url: "https://res.cloudinary.com/realdevsquad/image/upload/v1667685133/profile/mtS4DhUvNYsKqI7oCWVB/aenklfhtjldc5ytei3ar.jpg",
8284
},
8385
nickname_synced: false,
86+
profileStatus: "VERIFIED",
8487
},
8588
{
8689
username: "sagar",

test/integration/users.test.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,64 @@ describe("Users", function () {
6565
await cleanDb();
6666
});
6767

68+
describe("GET /users/identity-stats", function () {
69+
beforeEach(function () {
70+
fetchStub = Sinon.stub(global, "fetch");
71+
fetchStub.returns(
72+
Promise.resolve({
73+
status: 200,
74+
json: () => Promise.resolve(getDiscordMembers),
75+
})
76+
);
77+
});
78+
79+
afterEach(function () {
80+
Sinon.restore();
81+
});
82+
83+
it("Should return when only one user", function (done) {
84+
chai
85+
.request(app)
86+
.get("/users/identity-stats")
87+
.set("cookie", `${cookieName}=${superUserAuthToken}`)
88+
.end((err, res) => {
89+
if (err) {
90+
return done(err);
91+
}
92+
93+
expect(res).to.have.status(200);
94+
expect(res.body.blockedDeveloperCount).to.equal(0);
95+
expect(res.body.blockedUsersCount).to.equal(1);
96+
expect(res.body.developersCount).to.equal(0);
97+
expect(res.body.developersLeftToVerifyCount).to.equal(0);
98+
expect(res.body.verifiedDeveloperCount).to.equal(0);
99+
expect(res.body.verifiedUsersCount).to.equal(0);
100+
101+
return done();
102+
});
103+
});
104+
105+
it("Should return verified and blocked users", async function () {
106+
await addOrUpdate(userData[0]);
107+
await addOrUpdate(userData[1]);
108+
await addOrUpdate(userData[2]);
109+
await addOrUpdate(userData[3]);
110+
111+
const res = await chai
112+
.request(app)
113+
.get("/users/identity-stats")
114+
.set("cookie", `${cookieName}=${superUserAuthToken}`);
115+
116+
expect(res).to.have.status(200);
117+
expect(res.body.blockedDeveloperCount).to.equal(0);
118+
expect(res.body.blockedUsersCount).to.equal(2);
119+
expect(res.body.developersCount).to.equal(0);
120+
expect(res.body.developersLeftToVerifyCount).to.equal(0);
121+
expect(res.body.verifiedDeveloperCount).to.equal(0);
122+
expect(res.body.verifiedUsersCount).to.equal(1);
123+
});
124+
});
125+
68126
describe("PATCH /users/self", function () {
69127
beforeEach(function () {
70128
fetchStub = Sinon.stub(global, "fetch");

0 commit comments

Comments
 (0)