Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit 54a5ba8

Browse files
author
Parth Shah
committed
fixes #69 & #70
1 parent 4567d52 commit 54a5ba8

File tree

11 files changed

+171
-155
lines changed

11 files changed

+171
-155
lines changed

.eslintignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
config/local.js
2+
coverage
3+
local/

.eslintrc.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
{
22
"extends": "airbnb-base",
3+
"env": {
4+
"browser": false,
5+
"node": true,
6+
"es6": true,
7+
"mocha": true
8+
},
9+
"import/no-extraneous-dependencies": ["error", {"devDependencies": ["**/*.test.js", "**/*.spec.js", "**/serviceMocks.js"]}],
10+
"max-len": ["error", { "ignoreComments": true, "code": 120 }],
11+
"valid-jsdoc": ["error", {
12+
"requireReturn": true,
13+
"requireReturnType": true,
14+
"requireParamDescription": true,
15+
"requireReturnDescription": true
16+
}],
317
"parserOptions": {
418
"ecmaVersion": 6
519
}

config/default.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ module.exports = {
1818

1919
// Target RabbitMQ that receive notifications from tc-connect-notifications
2020
NOTIFICATIONS_EXCHANGE_NAME: 'notifications',
21-
21+
2222
DELAYED_NOTIFICATIONS_EXCHANGE_NAME: 'connect-notifications-reminders',
2323
// The number of times reminders are sent
2424
DELAYED_NOTIFICATIONS_TTL: 3,

package.json

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77
"node": "6.9.2"
88
},
99
"scripts": {
10-
"dev": "NODE_ENV=local ./node_modules/.bin/nodemon -w src -w config src/app.js | ./node_modules/.bin/bunyan",
10+
"lint": "./node_modules/.bin/eslint .",
11+
"lint:fix": "./node_modules/.bin/eslint . --fix || true",
1112
"start": "./node_modules/.bin/node src/app.js",
12-
"lint": "./node_modules/.bin/eslint config src",
13-
"dev-test": "NODE_ENV=test ./node_modules/.bin/mocha -w --timeout 30000 src/**/*.test.js | ./node_modules/.bin/bunyan",
14-
"test": "NODE_ENV=test ./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha -- --timeout 3000 src/**/*.test.js"
13+
"start:dev": "NODE_ENV=local ./node_modules/.bin/nodemon -w src -w config src/app.js | ./node_modules/.bin/bunyan",
14+
"test": "npm run lint && NODE_ENV=test ./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha -- --timeout 3000 src/**/*.test.js",
15+
"test:watch": "NODE_ENV=test ./node_modules/.bin/mocha -w --timeout 30000 src/**/*.test.js | ./node_modules/.bin/bunyan"
1516
},
1617
"author": "TCSCODER",
1718
"dependencies": {
@@ -26,8 +27,13 @@
2627
"request": "^2.78.0"
2728
},
2829
"devDependencies": {
29-
"eslint": "^3.9.1",
30-
"eslint-config-airbnb-base": "^10.0.1",
30+
"babel-cli": "^6.9.0",
31+
"babel-core": "^6.11.4",
32+
"babel-eslint": "^7.1.1",
33+
"babel-plugin-add-module-exports": "^0.2.1",
34+
"babel-preset-es2015": "^6.9.0",
35+
"eslint": "^3.16.1",
36+
"eslint-config-airbnb-base": "^11.1.0",
3137
"eslint-plugin-import": "^2.2.0",
3238
"istanbul": "^0.4.5",
3339
"mocha": "^3.1.2",

src/app.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const delayService = require('./rabbitmq')(logger);
1919
const connectNotificationsqueueOptions = {
2020
url: config.get('RABBITMQ.URL'),
2121
exchangeName: config.get('RABBITMQ.NOTIFICATIONS_EXCHANGE_NAME'),
22-
queues: []
22+
queues: [],
2323
};
2424

2525
const delayQueueOptions = {

src/common/constants.js

Lines changed: 59 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,22 @@ const config = require('config');
1313
const projectTypes = {
1414
app_dev: {
1515
label: 'Full App',
16-
color: '#96d957'
16+
color: '#96d957',
1717
},
1818
generic: {
1919
label: 'Work Project',
20-
color: '#b47dd6'
20+
color: '#b47dd6',
2121
},
2222
visual_prototype: {
2323
label: 'Design & Prototype',
24-
color: '#67c5ef'
24+
color: '#67c5ef',
2525
},
2626
visual_design: {
2727
label: 'Design',
28-
color: '#67c5ef'
29-
}
28+
color: '#67c5ef',
29+
},
3030
};
31+
3132
const icons = {
3233
slack: {
3334
CoderBotIcon: 'https://emoji.slack-edge.com/T03R80JP7/coder-the-bot/85ae574c0c7063ef.png',
@@ -49,7 +50,7 @@ module.exports = {
4950
notifications: {
5051
slack: {
5152
projectInReview: (data) => {
52-
return {
53+
const obj = {
5354
channel: `${config.get('SLACK_CHANNEL_MANAGERS')}`,
5455
color: projectTypes[data.project.type].color,
5556
pretext: 'A project is ready to be reviewed.',
@@ -58,29 +59,27 @@ module.exports = {
5859
title_link: `https://connect.${config.get('AUTH_DOMAIN')}/projects/${data.project.id}/`,
5960
text: _.truncate(_.get(data, 'project.description', ''), {
6061
length: 200,
61-
separator: /,? +.,/
62+
separator: /,? +.,/,
6263
}),
6364
ts: (new Date(_.get(data, 'project.updatedAt', null))).getTime() / 1000,
6465
fields: [{
65-
title: 'Ref Code',
66-
value: _.get(data, 'project.details.utm.code', ''),
67-
short: false,
68-
},
69-
{
70-
title: 'Owner',
71-
value: `${_.get(data, 'owner.firstName', '')} ${_.get(data, 'owner.lastName', '')}`,
72-
short: false,
73-
},
74-
{
75-
title: 'Project Type',
76-
value: projectTypes[data.project.type].label,
77-
short: false,
78-
},
79-
],
66+
title: 'Ref Code',
67+
value: _.get(data, 'project.details.utm.code', ''),
68+
short: false,
69+
}, {
70+
title: 'Owner',
71+
value: `${_.get(data, 'owner.firstName', '')} ${_.get(data, 'owner.lastName', '')}`,
72+
short: false,
73+
}, {
74+
title: 'Project Type',
75+
value: projectTypes[data.project.type].label,
76+
short: false,
77+
}],
8078
};
79+
return obj;
8180
},
8281
projectUnclaimed: (data) => {
83-
return {
82+
const obj = {
8483
icon_url: icons.slack.CoderBotIcon,
8584
color: projectTypes[data.project.type].color,
8685
channel: `${config.get('SLACK_CHANNEL_COPILOTS')}`,
@@ -90,18 +89,19 @@ module.exports = {
9089
title_link: `https://connect.${config.get('AUTH_DOMAIN')}/projects/${data.project.id}/`,
9190
text: _.truncate(_.get(data, 'project.description', ''), {
9291
length: 200,
93-
separator: /,? +.,/
92+
separator: /,? +.,/,
9493
}),
9594
ts: (new Date(_.get(data, 'project.updatedAt', null))).getTime() / 1000,
9695
fields: [{
9796
title: 'Project Type',
9897
value: projectTypes[data.project.type].label,
9998
short: false,
100-
}, ]
101-
}
99+
}],
100+
};
101+
return obj;
102102
},
103103
projectUnclaimedReposted: (data) => {
104-
return {
104+
const obj = {
105105
icon_url: icons.slack.CoderErrorIcon,
106106
color: projectTypes[data.project.type].color,
107107
channel: `${config.get('SLACK_CHANNEL_COPILOTS')}`,
@@ -111,18 +111,19 @@ module.exports = {
111111
title_link: `https://connect.${config.get('AUTH_DOMAIN')}/projects/${data.project.id}/`,
112112
text: _.truncate(_.get(data, 'project.description', ''), {
113113
length: 200,
114-
separator: /,? +.,/
114+
separator: /,? +.,/,
115115
}),
116116
ts: (new Date(_.get(data, 'project.updatedAt', null))).getTime() / 1000,
117117
fields: [{
118118
title: 'Project Type',
119119
value: projectTypes[data.project.type].label,
120120
short: false,
121-
}, ]
122-
}
121+
}],
122+
};
123+
return obj;
123124
},
124125
projectClaimed: (data) => {
125-
return {
126+
const obj = {
126127
icon_url: icons.slack.CoderGrinningIcon,
127128
color: projectTypes[data.project.type].color,
128129
channel: `${config.get('SLACK_CHANNEL_COPILOTS')}`,
@@ -132,117 +133,118 @@ module.exports = {
132133
title_link: `https://connect.${config.get('AUTH_DOMAIN')}/projects/${data.project.id}/`,
133134
text: _.truncate(_.get(data, 'project.description', ''), {
134135
length: 200,
135-
separator: /,? +.,/
136+
separator: /,? +.,/,
136137
}),
137138
ts: (new Date(_.get(data, 'project.updatedAt', null))).getTime() / 1000,
138139
fields: [{
139140
title: 'Project Type',
140141
value: projectTypes[data.project.type].label,
141142
short: false,
142-
}, ]
143-
}
143+
}],
144+
};
145+
return obj;
144146
},
145147
},
146148
discourse: {
147149
project: {
148150
created: {
149151
title: 'Your project has been created, and we\'re ready for your specification',
150-
content: (data) => `Hello, Coder here! Your project '${data.projectName}' has been created successfully. For your next step, please head over to the <a href="${data.projectUrl}specification/" rel="nofollow">Specification</a> section and answer all of the required questions. If you already have a document with your requirements, just verify it against our checklist and then upload it. Once you're done, hit the "Submit for Review" button on the Specification. Get stuck or need help? Email us at <a href="mailto:support@topcoder.com?subject=Question%20Regarding%20My%20New%20Topcoder%20Connect%20Project" rel="nofollow">support@topcoder.com</a>.`,
152+
content: data => `Hello, Coder here! Your project '${data.projectName}' has been created successfully. For your next step, please head over to the <a href="${data.projectUrl}specification/" rel="nofollow">Specification</a> section and answer all of the required questions. If you already have a document with your requirements, just verify it against our checklist and then upload it. Once you're done, hit the "Submit for Review" button on the Specification. Get stuck or need help? Email us at <a href="mailto:support@topcoder.com?subject=Question%20Regarding%20My%20New%20Topcoder%20Connect%20Project" rel="nofollow">support@topcoder.com</a>.`,
151153
},
152154
submittedForReview: {
153155
title: 'Your project has been submitted for review',
154-
content: (data) => `Hello, it's Coder again. Thanks for submitting your project <a href="${data.projectUrl}" rel="nofollow">${data.projectName}</a>! I've used my super computational powers to route it to one of our trusty humans. They'll get back to you in 1-2 business days.`,
156+
content: data => `Hello, it's Coder again. Thanks for submitting your project <a href="${data.projectUrl}" rel="nofollow">${data.projectName}</a>! I've used my super computational powers to route it to one of our trusty humans. They'll get back to you in 1-2 business days.`,
155157
},
156158
activated: {
157159
title: 'Work on your project has begun',
158-
content: (data) => `Good news, everyone! Work on project ${data.projectName} has kicked off. Please keep an eye on the <a href="${data.projectUrl}" rel="nofollow">Dashboard</a> section (or your email inbox) for the latest status updates.`,
160+
content: data => `Good news, everyone! Work on project ${data.projectName} has kicked off. Please keep an eye on the <a href="${data.projectUrl}" rel="nofollow">Dashboard</a> section (or your email inbox) for the latest status updates.`,
159161
},
160162
canceled: {
161163
title: 'Your project has been canceled',
162-
content: (data) => `Project <a href="${data.projectUrl}" rel="nofollow">${data.projectName}</a> has been canceled. If you think this may have been a mistake, please reply to this message immediately. Otherwise, looking forward to your next project. Coder signing off....`,
164+
content: data => `Project <a href="${data.projectUrl}" rel="nofollow">${data.projectName}</a> has been canceled. If you think this may have been a mistake, please reply to this message immediately. Otherwise, looking forward to your next project. Coder signing off....`,
163165
},
164166
completed: {
165167
title: 'Your project has been completed',
166-
content: (data) => `Project <a href="${data.projectUrl}" rel="nofollow">${data.projectName}</a> is finished! Well done, team. Looking forward to seeing your next project soon. Coder signing off....`,
168+
content: data => `Project <a href="${data.projectUrl}" rel="nofollow">${data.projectName}</a> is finished! Well done, team. Looking forward to seeing your next project soon. Coder signing off....`,
167169
},
168170
},
169171
teamMembers: {
170172
added: {
171173
title: 'A new team member has joined your project',
172-
content: (data) => `${data.firstName} ${data.lastName} has joined project <a href="${data.projectUrl}" rel="nofollow">${data.projectName}</a>. Welcome ${data.firstName}! Looking forward to working with you.`,
174+
content: data => `${data.firstName} ${data.lastName} has joined project <a href="${data.projectUrl}" rel="nofollow">${data.projectName}</a>. Welcome ${data.firstName}! Looking forward to working with you.`,
173175
},
174176
managerJoined: {
175177
title: 'A Topcoder project manager has joined your project',
176-
content: (data) => `${data.firstName} ${data.lastName} has joined your project <a href="${data.projectUrl}" rel="nofollow">${data.projectName}</a> as a project manager.`,
178+
content: data => `${data.firstName} ${data.lastName} has joined your project <a href="${data.projectUrl}" rel="nofollow">${data.projectName}</a> as a project manager.`,
177179
},
178180
copilotJoined: {
179181
title: 'A Topcoder copilot has joined your project',
180-
content: (data) => `${data.firstName} ${data.lastName} has joined your project <a href="${data.projectUrl}" rel="nofollow">${data.projectName}</a> as a copilot.`,
182+
content: data => `${data.firstName} ${data.lastName} has joined your project <a href="${data.projectUrl}" rel="nofollow">${data.projectName}</a> as a copilot.`,
181183
},
182184
left: {
183185
title: 'A team member has left your project',
184-
content: (data) => `${data.firstName} ${data.lastName} has left project <a href="${data.projectUrl}" rel="nofollow">${data.projectName}</a>. Thanks for all your work ${data.firstName}.`,
186+
content: data => `${data.firstName} ${data.lastName} has left project <a href="${data.projectUrl}" rel="nofollow">${data.projectName}</a>. Thanks for all your work ${data.firstName}.`,
185187
},
186188
removed: {
187189
title: 'A team member has left your project',
188-
content: (data) => `${data.firstName} ${data.lastName} has left project <a href="${data.projectUrl}" rel="nofollow">${data.projectName}</a>. Thanks for all your work ${data.firstName}.`,
190+
content: data => `${data.firstName} ${data.lastName} has left project <a href="${data.projectUrl}" rel="nofollow">${data.projectName}</a>. Thanks for all your work ${data.firstName}.`,
189191
},
190192
ownerChanged: {
191193
title: 'Your project has a new owner',
192-
content: (data) => `${data.firstName} ${data.lastName} is now responsible for project <a href="${data.projectUrl}" rel="nofollow">${data.projectName}</a>. Good luck ${data.firstName}.`,
194+
content: data => `${data.firstName} ${data.lastName} is now responsible for project <a href="${data.projectUrl}" rel="nofollow">${data.projectName}</a>. Good luck ${data.firstName}.`,
193195
},
194196
ownerAdded: {
195197
title: 'Ownership changed',
196-
content: (data) => `Your project has a new owner ${data.firstName} ${data.lastName} is now responsible for project Project title. Good luck ${data.firstName}!`,
198+
content: data => `Your project has a new owner. ${data.firstName} ${data.lastName} is now responsible for project <a href="${data.projectUrl}" rel="nofollow">${data.projectName}</a>. Good luck ${data.firstName}!`,
197199
},
198200
},
199201
},
200202
project: {
201203
created: {
202204
notificationType: 'Project.Created',
203-
subject: 'Created'
205+
subject: 'Created',
204206
},
205207
submittedForReview: {
206208
notificationType: 'Project.SubmittedForReview',
207-
subject: 'Submitted for review'
209+
subject: 'Submitted for review',
208210
},
209211
availableForReview: {
210212
notificationType: 'Project.AvailableForReview',
211-
subject: 'Available for review'
213+
subject: 'Available for review',
212214
},
213215
reviewed: {
214216
notificationType: 'Project.Reviewed',
215-
subject: 'Reviewed'
217+
subject: 'Reviewed',
216218
},
217219
availableToClaim: {
218220
notificationType: 'Project.AvailableToClaim',
219-
subject: 'Reviewed - Available to claim'
221+
subject: 'Reviewed - Available to claim',
220222
},
221223
},
222224
teamMember: {
223225
added: {
224226
notificationType: 'Project.Member.Added',
225-
subject: 'Member added'
227+
subject: 'Member added',
226228
},
227229
managerJoined: {
228230
notificationType: 'Project.Member.ManagerJoined',
229-
subject: 'Manager joined'
231+
subject: 'Manager joined',
230232
},
231233
copilotJoined: {
232234
notificationType: 'Project.Member.CopilotJoined',
233-
subject: 'Copilot joined'
235+
subject: 'Copilot joined',
234236
},
235237
removed: {
236238
notificationType: 'Project.Member.Removed',
237-
subject: 'Member removed'
239+
subject: 'Member removed',
238240
},
239241
left: {
240242
notificationType: 'Project.Member.Left',
241-
subject: 'Member left'
243+
subject: 'Member left',
242244
},
243245
ownerChanged: {
244246
notificationType: 'Project.Member.OwnerChanged',
245-
subject: 'Ownership changed'
247+
subject: 'Ownership changed',
246248
},
247249
},
248250
},

src/handlers/index.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ const util = require('./util');
2323
* @param {Object} message the message
2424
*/
2525
module.exports = (logger, message, channel, publish) => {
26-
2726
const eventType = message.fields.routingKey;
2827
const correlationId = message.properties.correlationId;
2928
// create a child logger so we can trace with original request id
@@ -52,7 +51,7 @@ module.exports = (logger, message, channel, publish) => {
5251
return [];
5352
}
5453
}).then((notifications) => {
55-
logger.debug('Notifications: ', notifications)
54+
logger.debug('Notifications: ', notifications);
5655
_.each(notifications.discourse, (n) => {
5756
const { projectId, title, content } = n;
5857
util.createProjectDiscourseNotification(childLogger, projectId, title, content);
@@ -63,7 +62,9 @@ module.exports = (logger, message, channel, publish) => {
6362
// In the future, we can read custom slack integration urls per project.
6463
const webhookUrl = config.get('TC_SLACK_WEBHOOK_URL');
6564
if (!_.isEmpty(webhookUrl)) {
66-
const slackNotifications = _.union(notifications.slack.manager, notifications.slack.copilot);
65+
const slackNotifications = _.union(
66+
notifications.slack.manager,
67+
notifications.slack.copilot);
6768
_.each(slackNotifications, (n) => {
6869
notifyPromises.push(util.sendSlackNotification(webhookUrl, n, logger));
6970
});

0 commit comments

Comments
 (0)