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

Slack fixes #66

Merged
merged 7 commits into from
Feb 8, 2017
Merged
Show file tree
Hide file tree
Changes from 4 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
64 changes: 59 additions & 5 deletions src/common/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ module.exports = {
fallback: 'A project is ready to be reviewed.',
title: _.get(data, 'project.name', ''),
title_link: `https://connect.${config.get('AUTH_DOMAIN')}/projects/${data.project.id}/`,
text: _.truncate(_.get(data, 'project.description', ''), {length: 200, separator: /,? +.,/ }),
text: _.truncate(_.get(data, 'project.description', ''), { length: 200, separator: /,? +.,/ }),
ts: (new Date(_.get(data, 'project.updatedAt', null))).getTime() / 1000,
fields: [
{
Expand All @@ -40,24 +40,74 @@ module.exports = {
},
{
title: 'Owner',
value: `${_.get(data, 'owner.firstName', '')} ${_.get(data, 'owner.lastName', '')}` ,
value: `${_.get(data, 'owner.firstName', '')} ${_.get(data, 'owner.lastName', '')}`,
short: false,
},
{
title: 'Project Type',
value: data.project.type,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please map raw project types to the following -

  • app_dev --> Full App
  • generic --> Work Project
  • visual_prototype --> Design & Prototype
  • Visual Design --> Design

short: false,
},
],
};
},
projectUnclaimed: (data) => {
return {
icon_url: 'https://emoji.slack-edge.com/T03R80JP7/coder-the-bot/85ae574c0c7063ef.png',

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please move to constants file, 'CoderBotIcon'

channel: `${config.get('SLACK_CHANNEL_COPILOTS')}`,
pretext: 'A project has been reviewed and needs a copilot. Please check it out and claim it.',
fallback: 'A project has been reviewed and needs a copilot. Please check it out and claim it.',
title: _.get(data, 'project.name', ''),
title_link: `https://connect.${config.get('AUTH_DOMAIN')}/projects/${data.project.id}/`,
text: _.truncate(_.get(data, 'project.description', ''), {length: 200, separator: /,? +.,/ }),
text: _.truncate(_.get(data, 'project.description', ''), { length: 200, separator: /,? +.,/ }),
ts: (new Date(_.get(data, 'project.updatedAt', null))).getTime() / 1000,
fields: []
fields: [
{
title: 'Project Type',
value: data.project.type,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above, thanks!

short: false,
},
]
}
}
},
projectUnclaimedReposted: (data) => {
return {
icon_url: 'https://emoji.slack-edge.com/T03R80JP7/coder-error/cd2633216e7fd385.png',

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move to constants CoderErrorIcon

channel: `${config.get('SLACK_CHANNEL_COPILOTS')}`,
pretext: 'We\'re still looking for a copilot for a reviewed project. Please check it out and claim it.',
fallback: 'We\'re still looking for a copilot for a reviewed project. Please check it out and claim it.',
title: _.get(data, 'project.name', ''),
title_link: `https://connect.${config.get('AUTH_DOMAIN')}/projects/${data.project.id}/`,
text: _.truncate(_.get(data, 'project.description', ''), { length: 200, separator: /,? +.,/ }),
ts: (new Date(_.get(data, 'project.updatedAt', null))).getTime() / 1000,
fields: [
{
title: 'Project Type',
value: data.project.type,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

short: false,
},
]
}
},
projectClaimed: (data) => {
return {
icon_url: 'https://emoji.slack-edge.com/T03R80JP7/coder-grinning/a3b7f3fe9e838377.png',

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move to constants - CoderGrinningIcon

channel: `${config.get('SLACK_CHANNEL_COPILOTS')}`,
pretext: `${data.firstName} ${data.lastName} has claimed a project. Welcome to the team!`,
fallback: `${data.firstName} ${data.lastName} has claimed a project. Welcome to the team!`,
title: _.get(data, 'project.name', ''),
title_link: `https://connect.${config.get('AUTH_DOMAIN')}/projects/${data.project.id}/`,
text: _.truncate(_.get(data, 'project.description', ''), { length: 200, separator: /,? +.,/ }),
ts: (new Date(_.get(data, 'project.updatedAt', null))).getTime() / 1000,
fields: [
{
title: 'Project Type',
value: data.project.type,
short: false,
},
]
}
},
},
discourse: {
project: {
Expand Down Expand Up @@ -107,6 +157,10 @@ module.exports = {
title: 'Your project has a new owner',
content: (data) => `${data.firstName} ${data.lastName} is now responsible for project <a href="${data.projectUrl}" rel="nofollow">${data.projectName}</a>. Good luck ${data.firstName}.`,
},
ownerAdded: {
title: 'Ownership changed',
content: (data) => `Your project has a new owner ${data.firstName} ${data.lastName} is now responsible for project Project title. Good luck ${data.firstName}!`,
},
},
},
project: {
Expand Down
31 changes: 23 additions & 8 deletions src/handlers/memberEvents.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
const config = require('config');
const constants = require('../common/constants');
const util = require('./util');
const _ = require('lodash');

/**
* Create notifications from project.member.added events
Expand All @@ -23,12 +24,28 @@ function* memberAdded(logger, data) {
];

let topic;
if (data.role === constants.memberRoles.customer) {
const notifications = {
slack: {
copilot: [],
},
};
if (data.role === constants.memberRoles.customer && data.isPrimary) {
topic = constants.notifications.discourse.teamMembers.ownerAdded;
} else if (data.role === constants.memberRoles.customer) {
topic = constants.notifications.discourse.teamMembers.added;
} else if (data.role === constants.memberRoles.manager) {
topic = constants.notifications.discourse.teamMembers.managerJoined;
} else if (data.role === constants.memberRoles.copilot) {
topic = constants.notifications.discourse.teamMembers.copilotJoined;
// Notify project claimed
const slackNotification = util.buildSlackNotification(
{
project,
firstName: addedMember.firstName,
lastName: addedMember.lastName,
},
constants.notifications.slack.projectClaimed);
notifications.slack.copilot.push(slackNotification);
}

const topicData = {
Expand All @@ -38,13 +55,11 @@ function* memberAdded(logger, data) {
lastName: addedMember.lastName,
};

const notifications = {
discourse: [{
projectId: project.id,
title: topic.title,
content: topic.content(topicData),
}],
};
notifications.discourse = [{
projectId: project.id,
title: topic.title,
content: topic.content(topicData),
}];
return notifications;
}

Expand Down
6 changes: 3 additions & 3 deletions src/handlers/projectEvents.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,9 @@ function* projectUnclaimedNotifications(logger, data) {
projectCopilotIds.length === 0) {
notifications.delayed = data;
const slackNotification = util.buildSlackNotification(
{ project, },
constants.notifications.slack.projectUnclaimed
)
{ project },
constants.notifications.slack.projectUnclaimedReposted
);
notifications.slack.copilot.push(slackNotification);
}
return notifications;
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ function buildSlackNotification(data, slackDataGenerator) {
const slackData = slackDataGenerator(data);
return {
username: config.get('SLACK_USERNAME'),
icon_url: config.get('SLACK_ICON_URL'),
icon_url: slackData.url || config.get('SLACK_ICON_URL'),
channel: slackData.channel,
attachments: [{
color: "#36a64f",
Expand Down
46 changes: 43 additions & 3 deletions src/test/app.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const sampleEvents = {
updatedReviewedAnotherStatus: require('./data/events.updated.reviewed.anotherStatus.json'),
updatedReviewedSameStatus: require('./data/events.updated.reviewed.sameStatus.json'),
memberAddedTeamMember: require('./data/events.memberAdded.teamMember.json'),
memberAddedOwner: require('./data/events.memberAdded.owner.json'),
memberAddedManager: require('./data/events.memberAdded.manager.json'),
memberAddedCopilot: require('./data/events.memberAdded.copilot.json'),
memberRemovedLeft: require('./data/events.memberRemoved.left.json'),
Expand Down Expand Up @@ -55,7 +56,13 @@ const expectedSlackNotficationBase = {
title: "test",
title_link: "https://connect.topcoder-dev.com/projects/1/",
text: "test",
fields: [],
fields: [
{
short: false,
title: 'Project Type',
value: 'visual_design',
},
],
footer: "Topcoder",
footer_icon: "https://emoji.slack-edge.com/T03R80JP7/topcoder/7c68acd90a6b6d77.png",
ts: 1478304000,
Expand All @@ -66,7 +73,21 @@ const expectedSlackCopilotNotification = _.cloneDeep(expectedSlackNotficationBas
_.extend(expectedSlackCopilotNotification.attachments[0], {
pretext: 'A project has been reviewed and needs a copilot. Please check it out and claim it.',
fallback: 'A project has been reviewed and needs a copilot. Please check it out and claim it.',
})
});

const expectedRepostedSlackCopilotNotification = _.cloneDeep(expectedSlackNotficationBase);
_.extend(expectedRepostedSlackCopilotNotification.attachments[0], {
pretext: 'We\'re still looking for a copilot for a reviewed project. Please check it out and claim it.',
fallback: 'We\'re still looking for a copilot for a reviewed project. Please check it out and claim it.',
});
const expectedClaimedSlackCopilotNotification = _.cloneDeep(expectedSlackNotficationBase);
_.extend(expectedClaimedSlackCopilotNotification.attachments[0], {
pretext: 'F_user L_user has claimed a project. Welcome to the team!',
fallback: 'F_user L_user has claimed a project. Welcome to the team!',
text: 'Project description 1',
title: 'Project name 1',
ts: '1477671612',
});

const expectedManagerSlackNotification = _.cloneDeep(expectedSlackNotficationBase);
_.extend(expectedManagerSlackNotification.attachments[0], {
Expand All @@ -75,6 +96,11 @@ _.extend(expectedManagerSlackNotification.attachments[0], {
fields: [
{ title: 'Ref Code', value: '', short: false },
{ title: 'Owner', value: 'F_user L_user', short: false },
{
short: false,
title: 'Project Type',
value: 'visual_design',
},
]
})

Expand Down Expand Up @@ -278,7 +304,7 @@ describe('app', () => {
assertCount += 1;
sinon.assert.notCalled(spy);
const params = slackSpy.lastCall.args;
assert.deepEqual(params[1], expectedSlackCopilotNotification);
assert.deepEqual(params[1], expectedRepostedSlackCopilotNotification);
// console.log('assert#', assertCount)
// console.log('callbackCount#', callbackCount)
// checkAssert(assertCount, callbackCount, done);
Expand Down Expand Up @@ -316,6 +342,18 @@ describe('app', () => {
});

describe('`project.member.added` event', () => {
it('should create `Project.Member.ownerAdded` notification', (done) => {
sendTestEvent(sampleEvents.memberAddedOwner, 'project.member.added');
setTimeout(() => {
const expectedTitle = 'Ownership changed';
const expectedBody = 'Your project has a new owner F_user L_user is now responsible for project Project title. Good luck F_user!';
const params = spy.lastCall.args;
assert.equal(params[2], expectedTitle);
assert.equal(params[3], expectedBody);
done();
}, testTimeout);
});

it('should create `Project.Member.TeamMemberAdded` notification', (done) => {
sendTestEvent(sampleEvents.memberAddedTeamMember, 'project.member.added');
setTimeout(() => {
Expand Down Expand Up @@ -348,6 +386,8 @@ describe('app', () => {
const params = spy.lastCall.args;
assert.equal(params[2], expectedTitle);
assert.equal(params[3], expectedBody);
const slackParams = slackSpy.lastCall.args;
assert.deepEqual(slackParams[1], expectedClaimedSlackCopilotNotification);
done();
}, testTimeout);
});
Expand Down
11 changes: 11 additions & 0 deletions src/test/data/events.memberAdded.owner.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"id": 1185,
"userId": 40051331,
"role": "customer",
"isPrimary": true,
"createdAt": "2016-11-04T03:57:57.000Z",
"updatedAt": "2016-11-04T03:57:57.000Z",
"createdBy": 40152856,
"updatedBy": 40152856,
"projectId": 1
}
2 changes: 1 addition & 1 deletion src/test/data/events.memberAdded.teamMember.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"id": 1185,
"userId": 40051331,
"role": "customer",
"isPrimary": true,
"isPrimary": false,
"createdAt": "2016-11-04T03:57:57.000Z",
"updatedAt": "2016-11-04T03:57:57.000Z",
"createdBy": 40152856,
Expand Down