Skip to content

Commit

Permalink
Added ability to pass minThreshold for Milestone Slack notifications
Browse files Browse the repository at this point in the history
closes ENG-632

- This listens to a new property in the `milestones` config to set a minimum value of Milestones we wanna use the Slack notification service for
  • Loading branch information
aileen committed Mar 14, 2024
1 parent 60d81b2 commit 22d298f
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ class SlackNotificationsServiceWrapper {
* @param {string} deps.siteUrl
* @param {boolean} deps.isEnabled
* @param {URL} deps.webhookUrl
* @param {number} deps.minThreshold
*
* @returns {import('@tryghost/slack-notifications/lib/SlackNotificationsService')}
*/
static create({siteUrl, isEnabled, webhookUrl}) {
static create({siteUrl, isEnabled, webhookUrl, minThreshold}) {
const {
SlackNotificationsService,
SlackNotifications
Expand All @@ -32,7 +33,8 @@ class SlackNotificationsServiceWrapper {
logging,
config: {
isEnabled,
webhookUrl
webhookUrl,
minThreshold
},
slackNotifications
});
Expand All @@ -49,8 +51,9 @@ class SlackNotificationsServiceWrapper {
const siteUrl = urlUtils.getSiteUrl();
const isEnabled = !!(hostSettings?.milestones?.enabled && hostSettings?.milestones?.url);
const webhookUrl = hostSettings?.milestones?.url;
const minThreshold = hostSettings?.milestones?.minThreshold ? parseInt(hostSettings.milestones.minThreshold) : 0;

this.#api = SlackNotificationsServiceWrapper.create({siteUrl, isEnabled, webhookUrl});
this.#api = SlackNotificationsServiceWrapper.create({siteUrl, isEnabled, webhookUrl, minThreshold});

this.#api.subscribeEvents();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ describe('Slack Notifications Service', function () {
let scope;

beforeEach(function () {
configUtils.set('hostSettings', {milestones: {enabled: true, url: 'https://testhooks.slack.com/'}});
configUtils.set('hostSettings', {milestones: {enabled: true, url: 'https://testhooks.slack.com/', minThreshold: '100'}});

scope = nock('https://testhooks.slack.com/')
.post('/')
Expand All @@ -28,13 +28,13 @@ describe('Slack Notifications Service', function () {
milestone: {
type: 'arr',
currency: 'usd',
name: 'arr-100-usd',
value: 100,
name: 'arr-1000-usd',
value: 1000,
createdAt: new Date(),
emailSentAt: new Date()
},
meta: {
currentValue: 105
currentValue: 1005
}
}));

Expand Down
2 changes: 2 additions & 0 deletions ghost/slack-notifications/lib/SlackNotificationsService.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const {MilestoneCreatedEvent} = require('@tryghost/milestones');
* @typedef {object} config
* @prop {boolean} isEnabled
* @prop {URL} webhookUrl
* @prop {number} minThreshold
*/

module.exports = class SlackNotificationsService {
Expand Down Expand Up @@ -71,6 +72,7 @@ module.exports = class SlackNotificationsService {
&& event.data.milestone
&& this.#config.isEnabled
&& this.#config.webhookUrl
&& this.#config.minThreshold < event.data.milestone.value
) {
try {
await this.#slackNotifications.notifyMilestoneReceived(event.data);
Expand Down
50 changes: 45 additions & 5 deletions ghost/slack-notifications/test/SlackNotificationsService.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ describe('SlackNotificationsService', function () {

const config = {
isEnabled: true,
webhookUrl: 'https://slack-webhook.example'
webhookUrl: 'https://slack-webhook.example',
minThreshold: 1000
};

beforeEach(function () {
Expand Down Expand Up @@ -75,13 +76,13 @@ describe('SlackNotificationsService', function () {
milestone: {
id: new ObjectId().toHexString(),
type: 'arr',
value: 1000,
value: 10000,
currency: 'usd',
createdAt: new Date(),
emailSentAt: new Date()
},
meta: {
currentValue: 1398
currentValue: 13980
}
}));

Expand Down Expand Up @@ -118,6 +119,45 @@ describe('SlackNotificationsService', function () {
assert(slackNotificationStub.callCount === 0);
});

it('does not send notification when milestone value below notification threshold', async function () {
service = new SlackNotificationsService({
logging: {
warn: () => {},
error: loggingSpy
},
DomainEvents,
siteUrl: 'https://ghost.example',
config: {
isEnabled: false,
webhookUrl: 'https://slack-webhook.example'
},
slackNotifications: {
notifyMilestoneReceived: slackNotificationStub
}
});

service.subscribeEvents();

DomainEvents.dispatch(MilestoneCreatedEvent.create({
milestone: {
id: new ObjectId().toHexString(),
type: 'arr',
value: 1000,
currency: 'usd',
createdAt: new Date(),
emailSentAt: new Date()
},
meta: {
currentValue: 1398
}
}));

await DomainEvents.allSettled();

assert(loggingSpy.callCount === 0);
assert(slackNotificationStub.callCount === 0);
});

it('does not send notification when no url in hostSettings provided', async function () {
service = new SlackNotificationsService({
logging: {
Expand Down Expand Up @@ -166,8 +206,8 @@ describe('SlackNotificationsService', function () {
DomainEvents.dispatch(MilestoneCreatedEvent.create({
milestone: {
type: 'members',
name: 'members-100',
value: 100,
name: 'members-10000',
value: 10000,
createdAt: new Date()
}
}));
Expand Down

0 comments on commit 22d298f

Please sign in to comment.