const sinon = require('sinon');
const MentionEmailReportJob = require('../');
class MockMentionReportRecipientRepository {
#recipients = [{
email: 'fake@email.address',
slug: 'user-slug'
}];
constructor(recipients) {
if (recipients) {
this.#recipients = recipients;
}
}
async getMentionReportRecipients() {
return this.#recipients;
}
}
class MockMentionReportEmailView {
async renderSubject() {
return 'Mention Report';
}
async renderHTML() {
return '
Mention Report
';
}
async renderText() {
return 'Mention Report';
}
}
class MockEmailService {
async send() {
return;
}
}
class MockMentionReportHistoryService {
#date = null;
constructor(date) {
if (!date) {
throw new Error('Missing date');
}
this.#date = date;
}
async getLatestReportDate() {
return this.#date;
}
async setLatestReportDate(date) {
this.#date = date;
}
}
class MockMentionReportGenerator {
#mentions = null;
constructor(mentions) {
if (!mentions) {
throw new Error('Missing mentions');
}
this.#mentions = mentions;
}
async getMentionReport(startDate, endDate) {
return {
startDate,
endDate,
mentions: this.#mentions
};
}
}
describe('MentionEmailReportJob', function () {
describe('sendLatestReport', function () {
it('Does not send an email if the report has no mentions', async function () {
const emailService = new MockEmailService();
const mock = sinon.mock(emailService);
mock.expects('send').never();
const job = new MentionEmailReportJob({
mentionReportGenerator: new MockMentionReportGenerator([]),
mentionReportRecipientRepository: new MockMentionReportRecipientRepository(),
mentionReportEmailView: new MockMentionReportEmailView(),
mentionReportHistoryService: new MockMentionReportHistoryService(new Date(0)),
emailService: emailService
});
await job.sendLatestReport();
mock.verify();
});
it('Does not send an email if the last email was sent within 24 hours', async function () {
const emailService = new MockEmailService();
const mock = sinon.mock(emailService);
mock.expects('send').never();
const job = new MentionEmailReportJob({
mentionReportGenerator: new MockMentionReportGenerator([{
target: new URL('https://target.com'),
source: new URL('https://source.com'),
sourceTitle: 'Source Title',
sourceExcerpt: 'Source Excerpt',
sourceSiteTitle: 'Source Site Title',
sourceFavicon: new URL('https://source.com/favicon.ico'),
sourceAuthor: 'Source Author',
sourceFeaturedImage: new URL('https://source.com/featured-image.jpg')
}]),
mentionReportRecipientRepository: new MockMentionReportRecipientRepository(),
mentionReportEmailView: new MockMentionReportEmailView(),
mentionReportHistoryService: new MockMentionReportHistoryService(new Date()),
emailService: emailService
});
await job.sendLatestReport();
mock.verify();
});
it('Sends an email if the last email was sent more than 24 hours ago', async function () {
const emailService = new MockEmailService();
const mock = sinon.mock(emailService);
mock.expects('send').once().alwaysCalledWith(
'fake@email.address',
'Mention Report',
'Mention Report
',
'Mention Report'
);
const job = new MentionEmailReportJob({
mentionReportGenerator: new MockMentionReportGenerator([{
target: new URL('https://target.com'),
source: new URL('https://source.com'),
sourceTitle: 'Source Title',
sourceExcerpt: 'Source Excerpt',
sourceSiteTitle: 'Source Site Title',
sourceFavicon: new URL('https://source.com/favicon.ico'),
sourceAuthor: 'Source Author',
sourceFeaturedImage: new URL('https://source.com/featured-image.jpg')
}]),
mentionReportRecipientRepository: new MockMentionReportRecipientRepository(),
mentionReportEmailView: new MockMentionReportEmailView(),
mentionReportHistoryService: new MockMentionReportHistoryService(new Date(0)),
emailService
});
await job.sendLatestReport();
mock.verify();
});
});
});