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(); }); }); });