Skip to content

Commit 44dae99

Browse files
committed
Merge branch 'develop' into website-backend-368-2
2 parents 1a8564b + c63b90b commit 44dae99

File tree

13 files changed

+246
-40
lines changed

13 files changed

+246
-40
lines changed

CONTRIBUTING.md

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
# Contributing to Real Dev Squad API
32

43
- [Getting Started](#getting-started)
@@ -25,19 +24,22 @@ The script associated with `npm run test` will run all tests that ensures that y
2524
repository. This will run the lint, integration and unit tests.
2625

2726
##### `npm run lint`
27+
2828
Runs the lint checks in the project.
2929

3030
##### `npm run generate-api-schema`
31+
3132
Generates the API schema in the file `public/apiSchema.json`.
3233

3334
##### `npm run validate-setup`
34-
Runs the test for checking local development setup is working properly or not.
3535

36+
Runs the test for checking local development setup is working properly or not.
3637

3738
## Project Structure
39+
3840
The following project structure should be followed:
3941

40-
``` shell script
42+
```shell script
4143
|-- website-backend
4244
|-- config
4345
| |-- custom-environment-variables.js
@@ -89,6 +91,7 @@ The following project structure should be followed:
8991
```
9092
9193
## Generating Authentication Token
94+
9295
- Run the project locally, make sure the server is listening to requests
9396
- Navigate to `https://github.com/login/oauth/authorize?client_id=<GITHUB_CLIENT_ID>`
9497
- Authorize the application
@@ -97,8 +100,8 @@ The following project structure should be followed:
97100
- For non-production environments, authentication is also supported with the `Authorization` header.
98101
- Authorization header: `Authorization: Bearer <token>`
99102
100-
101103
## Testing Guidelines
104+
102105
- Libraries used in testing in the project:
103106
- [mocha](https://mochajs.org/): Test framework
104107
- [chai](https://www.chaijs.com/): Assertion library
@@ -110,6 +113,7 @@ The following project structure should be followed:
110113
- Java version 1.8 or higher.
111114
112115
## Using Firebase Emulator Locally
116+
113117
- [Firebase Local Emulator Suite](https://firebase.google.com/docs/emulator-suite) can be used locally as the DB for the project
114118
- Pre-requisites:
115119
- Node.js version 8.0 or higher.
@@ -119,15 +123,18 @@ The following project structure should be followed:
119123
- [Future] You can view the emulator UI at: `http://localhost:4000`
120124
121125
## Running test scripts on Windows
126+
122127
- Git Bash is recommended for running test scripts on Windows.
123128
- Run `npm run test-integration` for running integration tests.
124129
- Run `npm run test-unit` for running unit tests.
125-
- Make sure to close the emulator window after running the tests in order to avoid the blocking of the port for the next tests to run.
130+
- Make sure the server is not running.
131+
- Make sure to close the emulator window after running the tests in order to avoid the blocking of the port for the next tests to run.
126132
- For e.g - After running the integration tests, close the emulator window and then run the command for unit tests.
127133
128134
## Pull request guidelines
135+
129136
- Ensure that the tests pass locally before raising a PR.
130137
- All pull requests should have base as the develop branch.
131138
- Every pull request should have associated issue(s) on our [issue tracker](https://github.com/Real-Dev-Squad/website-backend/issues).
132139
- For any non-trivial fixes and features, unit and integration tests must be added. The PR reviewer should not approve/merge PR(s) that lack these.
133-
- The PR(s) should be merged only after the CI passes.
140+
- The PR(s) should be merged only after the CI passes.

constants/tasks.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ const TASK_STATUS = {
88
ACTIVE: 'active',
99
ASSIGNED: 'assigned',
1010
BLOCKED: 'blocked',
11-
COMPLETED: 'completed'
11+
COMPLETED: 'completed',
12+
UNASSIGNED: 'unAssigned'
1213
}
1314

1415
module.exports = { TASK_TYPE, TASK_STATUS }

controllers/members.js

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const memberQuery = require('../models/members')
1+
const { fetchMembers, migrateUsers, deleteIsMemberProperty } = require('../models/members')
22
const tasks = require('../models/tasks')
33

44
/**
@@ -10,7 +10,7 @@ const tasks = require('../models/tasks')
1010

1111
const getMembers = async (req, res) => {
1212
try {
13-
const allMembers = await memberQuery.fetchMembers()
13+
const allMembers = await fetchMembers()
1414

1515
return res.json({
1616
message: allMembers.length ? 'Members returned successfully!' : 'No member found',
@@ -31,7 +31,7 @@ const getMembers = async (req, res) => {
3131

3232
const getIdleMembers = async (req, res) => {
3333
try {
34-
const allMembers = await memberQuery.fetchMembers()
34+
const allMembers = await fetchMembers()
3535
const taskParticipants = await tasks.fetchActiveTaskMembers()
3636
const idleMembers = allMembers?.filter(({ id }) => !taskParticipants.has(id))
3737
const idleMemberUserNames = idleMembers?.map((member) => member.username)
@@ -46,7 +46,47 @@ const getIdleMembers = async (req, res) => {
4646
}
4747
}
4848

49+
/**
50+
* Returns the lists of usernames migrated
51+
*
52+
* @param req {Object} - Express request object
53+
* @param res {Object} - Express response object
54+
*/
55+
const migrateUserRoles = async (req, res) => {
56+
try {
57+
const migratedUserData = await migrateUsers()
58+
return res.json({
59+
message: 'Users migrated successfully',
60+
...migratedUserData
61+
})
62+
} catch (error) {
63+
logger.error(`Error while migrating user roles: ${error}`)
64+
return res.boom.badImplementation('Something went wrong. Please contact admin')
65+
}
66+
}
67+
68+
/**
69+
* Returns the lists of usernames whose isMember property was deleted
70+
*
71+
* @param req {Object} - Express request object
72+
* @param res {Object} - Express response object
73+
*/
74+
const deleteIsMember = async (req, res) => {
75+
try {
76+
const deletedIsMemberData = await deleteIsMemberProperty()
77+
return res.json({
78+
message: 'Users isMember deleted successfully',
79+
...deletedIsMemberData
80+
})
81+
} catch (error) {
82+
logger.error(`Error while deleting isMember: ${error}`)
83+
return res.boom.badImplementation('Something went wrong. Please contact admin')
84+
}
85+
}
86+
4987
module.exports = {
5088
getMembers,
51-
getIdleMembers
89+
getIdleMembers,
90+
migrateUserRoles,
91+
deleteIsMember
5292
}

controllers/tasks.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const tasks = require('../models/tasks')
2+
const { TASK_STATUS } = require('../constants/tasks')
23
/**
34
* Creates new task
45
*
@@ -52,8 +53,15 @@ const fetchTasks = async (req, res) => {
5253
*/
5354
const getUserTasks = async (req, res) => {
5455
try {
56+
const { status } = req.query
5557
const { username } = req.params
56-
const allTasks = await tasks.fetchUserTasks(username)
58+
let allTasks = []
59+
60+
if (!Object.values(TASK_STATUS).includes(status)) {
61+
return res.boom.notFound('Status not found!')
62+
}
63+
64+
allTasks = await tasks.fetchUserTasks(username, status ? [status] : [])
5765

5866
if (allTasks.userNotFound) {
5967
return res.boom.notFound('User doesn\'t exist')

docs/swaggerDefinition.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,17 @@ const swaggerOptions = {
398398
}
399399
}
400400
},
401+
migratedUsers: {
402+
type: 'object',
403+
properties: {
404+
count: {
405+
type: 'number'
406+
},
407+
users: {
408+
type: 'array'
409+
}
410+
}
411+
},
401412
users: {
402413
type: 'object',
403414
properties: {

models/members.js

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,23 @@ const userModel = firestore.collection('users')
1313

1414
const fetchMembers = async () => {
1515
try {
16-
const snapshot = await userModel.where('isMember', '==', true).get()
16+
const snapshot = await userModel.get()
1717

1818
const allMembers = []
1919

2020
if (!snapshot.empty) {
2121
snapshot.forEach((doc) => {
22-
allMembers.push({
22+
const memberData = doc.data()
23+
const curatedMemberData = {
2324
id: doc.id,
24-
...doc.data(),
25+
...memberData,
2526
tokens: undefined,
2627
phone: undefined,
2728
email: undefined
28-
})
29-
}
30-
)
29+
}
30+
curatedMemberData.isMember = !!(memberData.roles && memberData.roles.member)
31+
allMembers.push(curatedMemberData)
32+
})
3133
}
3234

3335
return allMembers
@@ -37,6 +39,67 @@ const fetchMembers = async () => {
3739
}
3840
}
3941

42+
/**
43+
* Migrate user roles
44+
* @return {Promise<usersMigrated|Object>}
45+
*/
46+
const migrateUsers = async () => {
47+
try {
48+
const userSnapShot = await userModel.where('isMember', '==', true).get()
49+
const migratedUsers = []
50+
51+
const usersArr = []
52+
53+
userSnapShot.forEach(doc => usersArr.push({ id: doc.id, ...doc.data() }))
54+
55+
for (const user of usersArr) {
56+
const roles = { ...user.roles, member: true }
57+
58+
await userModel.doc(user.id).set({
59+
...user,
60+
roles
61+
})
62+
63+
migratedUsers.push(user.username)
64+
}
65+
66+
return { count: migratedUsers.length, users: migratedUsers }
67+
} catch (err) {
68+
logger.error('Error migrating user roles', err)
69+
throw err
70+
}
71+
}
72+
73+
/**
74+
* Deletes isMember property from user object
75+
* @return {Promise<usersMigrated|Object>}
76+
*/
77+
const deleteIsMemberProperty = async () => {
78+
try {
79+
const userSnapShot = await userModel.where('roles', '!=', false).get()
80+
const migratedUsers = []
81+
82+
const usersArr = []
83+
84+
userSnapShot.forEach(doc => usersArr.push({ id: doc.id, ...doc.data() }))
85+
86+
for (const user of usersArr) {
87+
delete user.isMember
88+
89+
await userModel.doc(user.id).set({ ...user })
90+
91+
migratedUsers.push(user.username)
92+
}
93+
94+
return { count: migratedUsers.length, users: migratedUsers }
95+
} catch (err) {
96+
logger.error('Error deleting isMember property', err)
97+
throw err
98+
}
99+
}
100+
40101
module.exports = {
41-
fetchMembers
102+
fetchMembers,
103+
migrateUsers,
104+
deleteIsMemberProperty
42105
}

package-lock.json

Lines changed: 6 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/apiSchema.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)