Ghost/ghost/slack-notifications/test/SlackNotificationsService.test.js
Aileen Booker f16d9802d0 Added ability to pass minThreshold for Milestone Slack notifications
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
2024-03-14 12:06:43 -04:00

223 lines
7.7 KiB
JavaScript

const assert = require('assert/strict');
const sinon = require('sinon');
const {SlackNotificationsService} = require('../index');
const ObjectId = require('bson-objectid').default;
const {MilestoneCreatedEvent} = require('@tryghost/milestones');
const DomainEvents = require('@tryghost/domain-events');
describe('SlackNotificationsService', function () {
describe('Constructor', function () {
it('doesn\'t throw', function () {
new SlackNotificationsService({});
});
});
describe('Slack notifications service', function () {
let service;
let slackNotificationStub;
let loggingSpy;
const config = {
isEnabled: true,
webhookUrl: 'https://slack-webhook.example',
minThreshold: 1000
};
beforeEach(function () {
slackNotificationStub = sinon.stub().resolves();
loggingSpy = sinon.spy();
});
afterEach(function () {
sinon.restore();
});
describe('subscribeEvents', function () {
it('subscribes to events', async function () {
const subscribeStub = sinon.stub().resolves();
service = new SlackNotificationsService({
logging: {
warn: () => {},
error: loggingSpy
},
DomainEvents: {
subscribe: subscribeStub
},
siteUrl: 'https://ghost.example',
config,
slackNotifications: {
notifyMilestoneReceived: slackNotificationStub
}
});
service.subscribeEvents();
assert(subscribeStub.callCount === 1);
assert(subscribeStub.calledWith(MilestoneCreatedEvent) === true);
});
it('handles milestone created event', async function () {
service = new SlackNotificationsService({
logging: {
warn: () => {},
error: loggingSpy
},
DomainEvents,
siteUrl: 'https://ghost.example',
config,
slackNotifications: {
notifyMilestoneReceived: slackNotificationStub
}
});
service.subscribeEvents();
DomainEvents.dispatch(MilestoneCreatedEvent.create({
milestone: {
id: new ObjectId().toHexString(),
type: 'arr',
value: 10000,
currency: 'usd',
createdAt: new Date(),
emailSentAt: new Date()
},
meta: {
currentValue: 13980
}
}));
await DomainEvents.allSettled();
assert(loggingSpy.callCount === 0);
assert(slackNotificationStub.calledOnce);
});
it('does not send notification when milestones is disabled in hostSettings', 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: {}}));
await DomainEvents.allSettled();
assert(loggingSpy.callCount === 0);
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: {
warn: () => {},
error: loggingSpy
},
DomainEvents,
siteUrl: 'https://ghost.example',
config: {
isEnabled: true,
webhookUrl: null
},
slackNotifications: {
notifyMilestoneReceived: slackNotificationStub
}
});
service.subscribeEvents();
DomainEvents.dispatch(MilestoneCreatedEvent.create({milestone: {}}));
await DomainEvents.allSettled();
assert(loggingSpy.callCount === 0);
assert(slackNotificationStub.callCount === 0);
});
it('logs error when event handling fails', async function () {
service = new SlackNotificationsService({
logging: {
warn: () => {},
error: loggingSpy
},
DomainEvents,
siteUrl: 'https://ghost.example',
config,
slackNotifications: {
async notifyMilestoneReceived() {
throw new Error('test');
}
}
});
service.subscribeEvents();
DomainEvents.dispatch(MilestoneCreatedEvent.create({
milestone: {
type: 'members',
name: 'members-10000',
value: 10000,
createdAt: new Date()
}
}));
await DomainEvents.allSettled();
const loggingSpyCall = loggingSpy.getCall(0).args[0];
assert(loggingSpy.calledOnce);
assert(loggingSpyCall instanceof Error);
});
});
});
});