Skip to content

Commit b04c97b

Browse files
authored
Merge pull request #37 from topcoder-platform/issues-99
Issues-94: Updating group category
2 parents 47d5c96 + f441ffc commit b04c97b

File tree

5 files changed

+107
-86
lines changed

5 files changed

+107
-86
lines changed

src/constants.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ module.exports = {
4040
KICK: 'kick'
4141
},
4242
TOPCODER: {
43-
ROLE_COPILOT : 'copilot'
43+
ROLE_COPILOT: 'copilot'
4444
},
4545
VANILLA: {
4646
CHALLENGES_FORUM: 'Challenges Forums',

src/modules/update_challenge/helpers.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
const config = require('config')
2-
const _ = require('lodash')
32

43
/**
54
* Processes a payload from the topic, to be consumed by the handler

src/services/vanilla.js

Lines changed: 51 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -35,24 +35,24 @@ async function manageVanillaUser (data) {
3535
}
3636
const topcoderProfile = JSON.parse(topcoderProfileResponseStr).result.content[0]
3737

38-
const {text: topcoderRolesResponseStr} = await topcoderApi.getRoles(topcoderProfile.id)
38+
const { text: topcoderRolesResponseStr } = await topcoderApi.getRoles(topcoderProfile.id)
3939
const topcoderRolesResponse = JSON.parse(topcoderRolesResponseStr).result.content
4040
const topcoderRoleNames = _.map(topcoderRolesResponse, 'roleName')
4141

42-
const{ body: allVanillaRoles } = await vanillaClient.getAllRoles()
42+
const { body: allVanillaRoles } = await vanillaClient.getAllRoles()
4343

4444
// Add all missing Topcoder roles
4545
await addTopcoderRoles(allVanillaRoles, topcoderRoleNames)
4646

4747
const { body: allNewVanillaRoles } = await vanillaClient.getAllRoles()
4848

49-
let allTopcoderRoles = _.filter(allNewVanillaRoles, { type: 'topcoder' })
49+
const allTopcoderRoles = _.filter(allNewVanillaRoles, { type: 'topcoder' })
5050

51-
let nonTopcoderRoles = _.filter(allNewVanillaRoles, role => role['type'] != 'topcoder')
52-
let nonTopcoderRoleIDs = _.map(nonTopcoderRoles, 'roleID')
51+
const nonTopcoderRoles = _.filter(allNewVanillaRoles, role => role.type !== 'topcoder')
52+
const nonTopcoderRoleIDs = _.map(nonTopcoderRoles, 'roleID')
5353

54-
let userTopcoderRoles = _.filter(allTopcoderRoles, role => topcoderRoleNames.includes(role['name']))
55-
let userTopcoderRoleIDs = _.map(userTopcoderRoles, 'roleID')
54+
const userTopcoderRoles = _.filter(allTopcoderRoles, role => topcoderRoleNames.includes(role.name))
55+
const userTopcoderRoleIDs = _.map(userTopcoderRoles, 'roleID')
5656

5757
if (!vanillaUser) {
5858
logger.info(`The '${username}' user wasn't found in Vanilla`)
@@ -79,7 +79,7 @@ async function manageVanillaUser (data) {
7979
vanillaUser = user
8080

8181
// Sync Topcoder roles
82-
const allCurrentUserRoleIDs = _.map(vanillaUser.roles, 'roleID');
82+
const allCurrentUserRoleIDs = _.map(vanillaUser.roles, 'roleID')
8383
const currentVanillaRoleIDs = _.intersection(allCurrentUserRoleIDs, nonTopcoderRoleIDs)
8484
const userData = {
8585
roleID: [...currentVanillaRoleIDs, ...userTopcoderRoleIDs]
@@ -119,15 +119,15 @@ async function manageVanillaUser (data) {
119119
}
120120
}
121121

122-
async function addTopcoderRoles(allVanillaRoles, topcoderRoleNames) {
122+
async function addTopcoderRoles (allVanillaRoles, topcoderRoleNames) {
123123
const allTopcoderRoles = _.filter(allVanillaRoles, { type: 'topcoder' })
124-
const userTopcoderRoles = _.filter(allTopcoderRoles, role => topcoderRoleNames.includes(role['name']))
124+
const userTopcoderRoles = _.filter(allTopcoderRoles, role => topcoderRoleNames.includes(role.name))
125125
const userTopcoderRoleIDs = _.map(userTopcoderRoles, 'roleID')
126126

127-
if(topcoderRoleNames.length != userTopcoderRoleIDs.length) {
128-
const missingRoles = _.difference(topcoderRoleNames, _.map(userTopcoderRoles, 'name'))
127+
if (topcoderRoleNames.length !== userTopcoderRoleIDs.length) {
128+
const missingRoles = _.difference(topcoderRoleNames, _.map(userTopcoderRoles, 'name'))
129129
logger.info('Missing roles:' + JSON.stringify(missingRoles))
130-
for(const missingRole of missingRoles) {
130+
for (const missingRole of missingRoles) {
131131
await vanillaClient.createRole({
132132
canSession: 1,
133133
description: 'Added by Challenge Forum Processor',
@@ -168,7 +168,7 @@ async function createVanillaGroup (challenge) {
168168
throw new Error('Multiple discussions with type=\'challenge\' and provider=\'vanilla\' are not supported.')
169169
}
170170

171-
const {body: project} = await topcoderApi.getProject(challenge.projectId)
171+
const { body: project } = await topcoderApi.getProject(challenge.projectId)
172172
const copilots = _.filter(project.members, { role: constants.TOPCODER.ROLE_COPILOT })
173173
const challengesForums = _.filter(template.categories, ['name', constants.VANILLA.CHALLENGES_FORUM])
174174
if (!challengesForums) {
@@ -228,15 +228,15 @@ async function createVanillaGroup (challenge) {
228228

229229
// Create the root challenge category
230230
const { body: challengeCategory } = await vanillaClient.createCategory({
231-
name: challengeDetailsDiscussion.name,
231+
name: challenge.name,
232232
urlcode: `${challenge.id}`,
233233
parentCategoryID: parentCategory[0].categoryID,
234234
displayAs: groupTemplate.categories ? constants.VANILLA.CATEGORY_DISPLAY_STYLE.CATEGORIES : constants.VANILLA.CATEGORY_DISPLAY_STYLE.DISCUSSIONS
235235
})
236236

237237
logger.info(`The '${challengeCategory.name}' category was created`)
238238

239-
if(groupTemplate.categories) {
239+
if (groupTemplate.categories) {
240240
for (const item of groupTemplate.categories) {
241241
const urlCodeTemplate = _.template(item.urlcode)
242242
const { body: childCategory } = await vanillaClient.createCategory({
@@ -245,16 +245,16 @@ async function createVanillaGroup (challenge) {
245245
parentCategoryID: challengeCategory.categoryID
246246
})
247247
logger.info(`The '${item.name}' category was created`)
248-
await createDiscussions(group, challenge, item.discussions, childCategory);
248+
await createDiscussions(group, challenge, item.discussions, childCategory)
249249
}
250250
}
251251

252-
if(groupTemplate.discussions){
253-
await createDiscussions(group, challenge, groupTemplate.discussions, challengeCategory);
252+
if (groupTemplate.discussions) {
253+
await createDiscussions(group, challenge, groupTemplate.discussions, challengeCategory)
254254
}
255255

256256
for (const copilot of copilots) {
257-
await manageVanillaUser({challengeId: challenge.id, action: constants.USER_ACTIONS.INVITE, handle: copilot.handle})
257+
await manageVanillaUser({ challengeId: challenge.id, action: constants.USER_ACTIONS.INVITE, handle: copilot.handle })
258258
}
259259

260260
challengeDetailsDiscussion.url = `${challengeCategory.url}`
@@ -274,34 +274,47 @@ async function updateVanillaGroup (challenge) {
274274
logger.info(`The challenge with challengeID=${challenge.id}:`)
275275

276276
const { body: groups } = await vanillaClient.searchGroups(challenge.id)
277-
if (groups.length == 0) {
278-
throw new Error('The group wasn\'t found for this challenge')
277+
if (groups.length === 0) {
278+
throw new Error('The group wasn\'t found for this challenge')
279279
}
280280

281281
if (groups.length > 1) {
282282
throw new Error('Multiple groups were found for this challenge')
283283
}
284284

285-
const {body: updatedGroup} = await vanillaClient.updateGroup(groups[0].groupID, {name: challenge.name})
286-
285+
const { body: updatedGroup } = await vanillaClient.updateGroup(groups[0].groupID, { name: challenge.name })
287286
logger.info(`The group was updated: ${JSON.stringify(updatedGroup)}`)
287+
288+
const { body: groupCategory } = await vanillaClient.getCategoryByUrlcode(`${challenge.id}`)
289+
if (!groupCategory) {
290+
throw new Error('Group category wasn\'t found for this challenge')
291+
}
292+
293+
const { body: groupCategoryForEdit } = await vanillaClient.getCategoryForEdit(groupCategory.categoryID)
294+
if (!groupCategoryForEdit) {
295+
throw new Error('Group category wasn\'t found for this challenge')
296+
}
297+
groupCategoryForEdit.name = challenge.name
298+
299+
const { body: updatedGroupCategory } = await vanillaClient.updateCategory(groupCategoryForEdit.categoryID, groupCategoryForEdit)
300+
logger.info(`The group category was updated: ${JSON.stringify(updatedGroupCategory)}`)
288301
}
289302

290303
async function createDiscussions (group, challenge, templateDiscussions, vanillaCategory) {
291-
for (const discussion of templateDiscussions) {
292-
// create a discussion
293-
const bodyTemplate = _.template(discussion.body)
294-
await vanillaClient.createDiscussion({
295-
body: bodyTemplate({ challenge: challenge }),
296-
name: discussion.title,
297-
groupID: group.groupID,
298-
categoryID: vanillaCategory.categoryID,
299-
format: constants.VANILLA.DISCUSSION_FORMAT.WYSIWYG,
300-
closed: discussion.closed,
301-
pinned: discussion.announce
302-
})
303-
logger.info(`The '${discussion.title}' discussion/announcement was created`)
304-
}
304+
for (const discussion of templateDiscussions) {
305+
// create a discussion
306+
const bodyTemplate = _.template(discussion.body)
307+
await vanillaClient.createDiscussion({
308+
body: bodyTemplate({ challenge: challenge }),
309+
name: discussion.title,
310+
groupID: group.groupID,
311+
categoryID: vanillaCategory.categoryID,
312+
format: constants.VANILLA.DISCUSSION_FORMAT.WYSIWYG,
313+
closed: discussion.closed,
314+
pinned: discussion.announce
315+
})
316+
logger.info(`The '${discussion.title}' discussion/announcement was created`)
317+
}
305318
}
306319

307320
module.exports = {

src/utils/topcoder-api.util.js

Lines changed: 43 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,33 @@
1-
const config = require("config");
2-
const _ = require("lodash");
3-
const m2mAuth = require("tc-core-library-js").auth.m2m;
4-
const request = require("superagent");
5-
const logger = require("./logger.util");
1+
const config = require('config')
2+
const _ = require('lodash')
3+
const m2mAuth = require('tc-core-library-js').auth.m2m
4+
const request = require('superagent')
5+
const logger = require('./logger.util')
66

7-
let m2m = null;
7+
let m2m = null
88

99
/**
1010
* Function to get M2M token
1111
*/
12-
async function getM2MToken() {
12+
async function getM2MToken () {
1313
if (_.isNull(m2m)) {
1414
m2m = m2mAuth(
1515
_.pick(config.TOPCODER, [
16-
"AUTH0_URL",
17-
"AUTH0_AUDIENCE",
18-
"TOKEN_CACHE_TIME",
19-
"AUTH0_PROXY_SERVER_URL",
16+
'AUTH0_URL',
17+
'AUTH0_AUDIENCE',
18+
'TOKEN_CACHE_TIME',
19+
'AUTH0_PROXY_SERVER_URL'
2020
])
21-
);
21+
)
2222
}
2323
logger.info(
2424
`Getting M2M token for client ID=${config.TOPCODER.AUTH0_CLIENT_ID}`
25-
);
25+
)
2626

2727
return m2m.getMachineToken(
2828
config.TOPCODER.AUTH0_CLIENT_ID,
2929
config.TOPCODER.AUTH0_CLIENT_SECRET
30-
);
30+
)
3131
}
3232

3333
/**
@@ -36,90 +36,89 @@ async function getM2MToken() {
3636
* @param {String} path Complete path of the API URL
3737
* @param {Object} reqBody Body of the request
3838
*/
39-
async function reqToAPI(reqType, path, reqBody) {
40-
const token = await getM2MToken();
41-
const authHeader = token ? { Authorization: `Bearer ${token}` } : {};
39+
async function reqToAPI (reqType, path, reqBody) {
40+
const token = await getM2MToken()
41+
const authHeader = token ? { Authorization: `Bearer ${token}` } : {}
4242

43-
const validReqTypes = ["GET", "HEAD", "POST", "PUT", "PATCH", "DELETE"];
44-
const hasBody = ["POST", "PUT", "PATCH"];
43+
const validReqTypes = ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE']
44+
const hasBody = ['POST', 'PUT', 'PATCH']
4545

4646
if (_.indexOf(validReqTypes, _.upperCase(reqType)) === -1) {
47-
throw new Error("Invalid request type");
47+
throw new Error('Invalid request type')
4848
}
49-
const reqMethod = request[_.lowerCase(reqType)];
49+
const reqMethod = request[_.lowerCase(reqType)]
5050

5151
if (_.indexOf(hasBody, _.upperCase(reqType)) === -1) {
5252
return reqMethod(path)
5353
.set(authHeader)
54-
.set("Content-Type", "application/json");
54+
.set('Content-Type', 'application/json')
5555
} else {
5656
return reqMethod(path)
5757
.set(authHeader)
58-
.set("Content-Type", "application/json")
59-
.send(reqBody);
58+
.set('Content-Type', 'application/json')
59+
.send(reqBody)
6060
}
6161
}
6262

6363
/**
6464
* Gets the user's handle given the user's ID
6565
* @param {String} userId User's ID (6-digit numeric)
6666
*/
67-
async function getUserDetailsById(userId) {
68-
const path = `${config.TOPCODER.API_URL}/v3/users?filter=id%3D${userId}`;
69-
return reqToAPI("GET", path);
67+
async function getUserDetailsById (userId) {
68+
const path = `${config.TOPCODER.API_URL}/v3/users?filter=id%3D${userId}`
69+
return reqToAPI('GET', path)
7070
}
7171

7272
/**
7373
* Gets the user by Topcoder's handle
7474
* @param {String} handle
7575
*/
76-
async function getUserDetailsByHandle(handle) {
77-
const path = `${config.TOPCODER.API_URL}/v3/users?filter=handle%3D${handle}`;
78-
return reqToAPI("GET", path);
76+
async function getUserDetailsByHandle (handle) {
77+
const path = `${config.TOPCODER.API_URL}/v3/users?filter=handle%3D${handle}`
78+
return reqToAPI('GET', path)
7979
}
8080

8181
/**
8282
* Gets the challenge
8383
* @param {String} challengeId Challenge's ID (uuid)
8484
*/
85-
async function getChallenge(challengeId) {
86-
const path = `${config.TOPCODER.API_URL}/v5/challenges/${challengeId}`;
87-
return reqToAPI("GET", path);
85+
async function getChallenge (challengeId) {
86+
const path = `${config.TOPCODER.API_URL}/v5/challenges/${challengeId}`
87+
return reqToAPI('GET', path)
8888
}
8989

9090
/**
9191
* Update the challenge
9292
* @param {String} challengeId Challenge's ID (uuid)
9393
*/
94-
async function updateChallenge(challengeId, data) {
95-
const path = `${config.TOPCODER.API_URL}/v5/challenges/${challengeId}`;
96-
return reqToAPI("PATCH", path, data);
94+
async function updateChallenge (challengeId, data) {
95+
const path = `${config.TOPCODER.API_URL}/v5/challenges/${challengeId}`
96+
return reqToAPI('PATCH', path, data)
9797
}
9898

9999
/**
100100
* Gets the roles for an user
101101
* @param {int} userId User's ID
102102
*/
103-
async function getRoles(userId) {
104-
const path = `${config.TOPCODER.API_URL}/v3/roles?filter=subjectID%3D${userId}`;
105-
return reqToAPI("GET", path);
103+
async function getRoles (userId) {
104+
const path = `${config.TOPCODER.API_URL}/v3/roles?filter=subjectID%3D${userId}`
105+
return reqToAPI('GET', path)
106106
}
107107

108108
/**
109109
* Gets the project
110110
* @param {int} projectId Project's Id (int)
111111
*/
112-
async function getProject(projectId) {
113-
const path = `${config.TOPCODER.API_URL}/v5/projects/${projectId}`;
114-
return reqToAPI("GET", path);
112+
async function getProject (projectId) {
113+
const path = `${config.TOPCODER.API_URL}/v5/projects/${projectId}`
114+
return reqToAPI('GET', path)
115115
}
116116

117-
118117
module.exports = {
119118
getUserDetailsById,
120119
getUserDetailsByHandle,
121120
getChallenge,
122121
updateChallenge,
123122
getRoles,
124123
getProject
125-
};
124+
}

src/utils/vanilla-client.util.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ function getVanillaClient () {
2424
throw err
2525
})
2626
},
27+
updateCategory: (categoryId, data) => {
28+
return request.patch(`${config.VANILLA.API_URL}/categories/${categoryId}`)
29+
.query({ access_token: config.VANILLA.ADMIN_ACCESS_TOKEN })
30+
.send(data)
31+
},
2732
getCategories: (parentCategoryID) => {
2833
const queryParams = { access_token: config.VANILLA.ADMIN_ACCESS_TOKEN }
2934
if (_.isNumber(parentCategoryID)) {
@@ -39,9 +44,14 @@ function getVanillaClient () {
3944
return request.get(`${config.VANILLA.API_URL}/categories`)
4045
.query(queryParams)
4146
},
42-
getGroupCategory: () => {
47+
getCategoryByUrlcode: (urlcode) => {
48+
const queryParams = { access_token: config.VANILLA.ADMIN_ACCESS_TOKEN }
49+
return request.get(`${config.VANILLA.API_URL}/categories/urlcode/${urlcode}`)
50+
.query(queryParams)
51+
},
52+
getCategoryForEdit: (categoryId) => {
4353
const queryParams = { access_token: config.VANILLA.ADMIN_ACCESS_TOKEN }
44-
return request.get(`${config.VANILLA.API_URL}/groups/category`)
54+
return request.get(`${config.VANILLA.API_URL}/categories/${categoryId}/edit`)
4555
.query(queryParams)
4656
},
4757
watchCategory: (categoryId, userId, data) => {

0 commit comments

Comments
 (0)