Refactored staff-service
This moves the shared data between all templates into a method so that it's calculated in a single place, as well as exposing separate render methods for HTML and Text. We've also added some new custom helpers for use in the handlebars templates
This commit is contained in:
parent
04efb6c177
commit
3cf3f633aa
@ -162,6 +162,23 @@ class StaffServiceEmails {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {object} recipient
|
||||
* @param {string} recipient.email
|
||||
* @param {string} recipient.slug
|
||||
*/
|
||||
async getSharedData(recipient) {
|
||||
return {
|
||||
siteTitle: this.settingsCache.get('title'),
|
||||
siteUrl: this.urlUtils.getSiteUrl(),
|
||||
siteDomain: this.siteDomain,
|
||||
accentColor: this.settingsCache.get('accent_color'),
|
||||
fromEmail: this.fromEmailAddress,
|
||||
toEmail: recipient.email,
|
||||
staffUrl: this.urlUtils.urlJoin(this.urlUtils.urlFor('admin', true), '#', `/settings/staff/${recipient.slug}`)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {object} eventData
|
||||
@ -322,13 +339,53 @@ class StaffServiceEmails {
|
||||
});
|
||||
}
|
||||
|
||||
async renderEmailTemplate(templateName, data) {
|
||||
async renderHTML(templateName, data) {
|
||||
const htmlTemplateSource = await fs.readFile(path.join(__dirname, './email-templates/', `${templateName}.hbs`), 'utf8');
|
||||
const htmlTemplate = this.Handlebars.compile(Buffer.from(htmlTemplateSource).toString());
|
||||
|
||||
this.Handlebars.registerHelper('eq', function (arg, value, options) {
|
||||
if (arg === value) {
|
||||
return options.fn(this);
|
||||
} else {
|
||||
return options.inverse(this);
|
||||
}
|
||||
});
|
||||
|
||||
this.Handlebars.registerHelper('limit', function (array, limit) {
|
||||
if (!Array.isArray(array)) {
|
||||
return [];
|
||||
}
|
||||
return array.slice(0,limit);
|
||||
});
|
||||
|
||||
let sharedData = {};
|
||||
if (data.recipient) {
|
||||
sharedData = await this.getSharedData(data.recipient);
|
||||
}
|
||||
|
||||
return htmlTemplate({
|
||||
...data,
|
||||
...sharedData
|
||||
});
|
||||
}
|
||||
|
||||
async renderText(templateName, data) {
|
||||
const textTemplate = require(`./email-templates/${templateName}.txt.js`);
|
||||
|
||||
const html = htmlTemplate(data);
|
||||
const text = textTemplate(data);
|
||||
let sharedData = {};
|
||||
if (data.recipient) {
|
||||
sharedData = await this.getSharedData(data.recipient);
|
||||
}
|
||||
|
||||
return textTemplate({
|
||||
...data,
|
||||
...sharedData
|
||||
});
|
||||
}
|
||||
|
||||
async renderEmailTemplate(templateName, data) {
|
||||
const html = await this.renderHTML(templateName, data);
|
||||
const text = await this.renderText(templateName, data);
|
||||
|
||||
return {html, text};
|
||||
}
|
||||
|
@ -4,6 +4,9 @@ const sinon = require('sinon');
|
||||
const {MemberCreatedEvent, SubscriptionCancelledEvent, SubscriptionActivatedEvent} = require('@tryghost/member-events');
|
||||
const {MilestoneCreatedEvent} = require('@tryghost/milestones');
|
||||
|
||||
// Stuff we are testing
|
||||
const DomainEvents = require('@tryghost/domain-events');
|
||||
|
||||
require('./utils');
|
||||
const StaffService = require('../index');
|
||||
|
||||
@ -191,6 +194,65 @@ describe('StaffService', function () {
|
||||
subscribeStub.calledWith(MemberCreatedEvent).should.be.true();
|
||||
subscribeStub.calledWith(MilestoneCreatedEvent).should.be.true();
|
||||
});
|
||||
|
||||
it('listens to events', async function () {
|
||||
service = new StaffService({
|
||||
logging: {
|
||||
info: loggingInfoStub,
|
||||
warn: () => {},
|
||||
error: () => {}
|
||||
},
|
||||
models: {
|
||||
User: {
|
||||
getEmailAlertUsers: getEmailAlertUsersStub
|
||||
}
|
||||
},
|
||||
mailer: {
|
||||
send: mailStub
|
||||
},
|
||||
DomainEvents,
|
||||
settingsCache,
|
||||
urlUtils,
|
||||
settingsHelpers
|
||||
});
|
||||
service.subscribeEvents();
|
||||
sinon.spy(service, 'handleEvent');
|
||||
DomainEvents.dispatch(MemberCreatedEvent.create({
|
||||
source: 'member',
|
||||
memberId: 'member-2'
|
||||
}));
|
||||
await DomainEvents.allSettled();
|
||||
service.handleEvent.calledWith(MemberCreatedEvent).should.be.true();
|
||||
|
||||
DomainEvents.dispatch(SubscriptionActivatedEvent.create({
|
||||
source: 'member',
|
||||
memberId: 'member-1',
|
||||
subscriptionId: 'sub-1',
|
||||
offerId: 'offer-1',
|
||||
tierId: 'tier-1'
|
||||
}));
|
||||
await DomainEvents.allSettled();
|
||||
service.handleEvent.calledWith(SubscriptionActivatedEvent).should.be.true();
|
||||
|
||||
DomainEvents.dispatch(SubscriptionCancelledEvent.create({
|
||||
source: 'member',
|
||||
memberId: 'member-1',
|
||||
subscriptionId: 'sub-1',
|
||||
tierId: 'tier-1'
|
||||
}));
|
||||
await DomainEvents.allSettled();
|
||||
service.handleEvent.calledWith(SubscriptionCancelledEvent).should.be.true();
|
||||
|
||||
DomainEvents.dispatch(MilestoneCreatedEvent.create({
|
||||
milestone: {
|
||||
type: 'arr',
|
||||
value: '100',
|
||||
currency: 'usd'
|
||||
}
|
||||
}));
|
||||
await DomainEvents.allSettled();
|
||||
service.handleEvent.calledWith(MilestoneCreatedEvent).should.be.true();
|
||||
});
|
||||
});
|
||||
|
||||
describe('handleEvent', function () {
|
||||
|
Loading…
Reference in New Issue
Block a user