diff --git a/apps/admin-x-settings/src/components/settings/general/users/email-notifications-tab.tsx b/apps/admin-x-settings/src/components/settings/general/users/email-notifications-tab.tsx index 4a038fe84c9..d50dfc0bf8a 100644 --- a/apps/admin-x-settings/src/components/settings/general/users/email-notifications-tab.tsx +++ b/apps/admin-x-settings/src/components/settings/general/users/email-notifications-tab.tsx @@ -1,4 +1,3 @@ -import useFeatureFlag from '../../../../hooks/use-feature-flag'; import {SettingGroup, SettingGroupContent, Toggle} from '@tryghost/admin-x-design-system'; import {type User, hasAdminAccess} from '@tryghost/admin-x-framework/api/users'; import {checkStripeEnabled} from '@tryghost/admin-x-framework/api/settings'; @@ -6,7 +5,6 @@ import {useGlobalData} from '../../../providers/global-data-provider'; const EmailNotificationsInputs: React.FC<{ user: User; setUserData: (user: User) => void; }> = ({user, setUserData}) => { const {config, settings} = useGlobalData(); - const hasWebmentions = useFeatureFlag('webmentions'); const hasStripeEnabled = checkStripeEnabled(settings || [], config || {}); return ( @@ -21,15 +19,6 @@ const EmailNotificationsInputs: React.FC<{ user: User; setUserData: (user: User) }} /> {hasAdminAccess(user) && <> - {hasWebmentions && { - setUserData?.({...user, mention_notifications: e.target.checked}); - }} - />} 0) { - filter = `source:[${sources.map(s => `'${s}'`).join(',')}]`; - } - - const sourceMentions = await this.store.query('mention', {filter}); - mentions.forEach((mention) => { - mention.set('mentions', sourceMentions.filterBy('source', mention.source)); - }); - return mentions; - } -} diff --git a/ghost/admin/app/templates/mentions.hbs b/ghost/admin/app/templates/mentions.hbs deleted file mode 100644 index 1187684fb85..00000000000 --- a/ghost/admin/app/templates/mentions.hbs +++ /dev/null @@ -1,120 +0,0 @@ -
- -
- {{#if this.post }} -
- - Posts - - {{svg-jar "arrow-right-small"}} - - Analytics - - {{svg-jar "arrow-right-small"}}Mentions -
- {{else}} -
- - Dashboard - - {{svg-jar "arrow-right-small"}}Mentions -
- {{/if}} -

- {{#if this.post }} - {{this.post.title}} - {{else}} - Mentions - {{/if}} -

- - {{#if (and this.post this.mentionsInfinityModel)}} -
-
- This post was mentioned in: -
-
- {{/if}} -
-
-
- - {{#if this.mentionsInfinityModel}} -
-
- -

Introducing Mentions

-

Whenever another person or site links to you, you’ll receive a notification in your dashboard to show you who’s talking about your content — and, when you link to someone else’s work, they’ll be notified, too.

-
-
- {{/if}} -
-
diff --git a/ghost/admin/mirage/config/mentions.js b/ghost/admin/mirage/config/mentions.js deleted file mode 100644 index 831740f2c12..00000000000 --- a/ghost/admin/mirage/config/mentions.js +++ /dev/null @@ -1,5 +0,0 @@ -import {paginatedResponse} from '../utils'; - -export default function mockMentions(server) { - server.get('/mentions/', paginatedResponse('mentions')); -} diff --git a/ghost/admin/mirage/routes-test.js b/ghost/admin/mirage/routes-test.js index f39ccc538fd..0f812bf9a4b 100644 --- a/ghost/admin/mirage/routes-test.js +++ b/ghost/admin/mirage/routes-test.js @@ -9,7 +9,6 @@ import mockIntegrations from './config/integrations'; import mockInvites from './config/invites'; import mockLabels from './config/labels'; import mockMembers from './config/members'; -import mockMentions from './config/mentions'; import mockNewsletters from './config/newsletters'; import mockOffers from './config/offers'; import mockPages from './config/pages'; @@ -60,7 +59,6 @@ export default function () { mockSnippets(this); mockNewsletters(this); mockStats(this); - mockMentions(this); /* Notifications -------------------------------------------------------- */ diff --git a/ghost/admin/tests/acceptance/mentions-test.js b/ghost/admin/tests/acceptance/mentions-test.js deleted file mode 100644 index 6fe618f7962..00000000000 --- a/ghost/admin/tests/acceptance/mentions-test.js +++ /dev/null @@ -1,35 +0,0 @@ -import {authenticateSession, invalidateSession} from 'ember-simple-auth/test-support'; -import {currentURL, visit} from '@ember/test-helpers'; -import {describe, it} from 'mocha'; -import {enableLabsFlag} from '../helpers/labs-flag'; -import {expect} from 'chai'; -import {setupApplicationTest} from 'ember-mocha'; -import {setupMirage} from 'ember-cli-mirage/test-support'; - -describe('Acceptance: Mentions', function () { - const hooks = setupApplicationTest(); - setupMirage(hooks); - - it('redirects to signin when not authenticated', async function () { - await invalidateSession(); - await visit('/mentions'); - expect(currentURL()).to.equal('/signin'); - }); - - describe('as admin', function () { - beforeEach(async function () { - this.server.loadFixtures('configs'); - this.server.loadFixtures('settings'); - - let role = this.server.create('role', {name: 'Administrator'}); - this.server.create('user', {roles: [role]}); - enableLabsFlag(this.server, 'webmentions'); - await authenticateSession(); - }); - it('can render mentions page', async function () { - await visit('/mentions'); - expect(currentURL(), 'currentURL').to.equal('/mentions'); - }); - }); -}); - diff --git a/ghost/core/core/boot.js b/ghost/core/core/boot.js index cdc14528ac0..05f610cdfe9 100644 --- a/ghost/core/core/boot.js +++ b/ghost/core/core/boot.js @@ -329,7 +329,6 @@ async function initServices() { const emailService = require('./server/services/email-service'); const emailAnalytics = require('./server/services/email-analytics'); const mentionsService = require('./server/services/mentions'); - const mentionsEmailReport = require('./server/services/mentions-email-report'); const tagsPublic = require('./server/services/tags-public'); const postsPublic = require('./server/services/posts-public'); const slackNotifications = require('./server/services/slack-notifications'); @@ -353,7 +352,6 @@ async function initServices() { identityTokens.init(), memberAttribution.init(), mentionsService.init(), - mentionsEmailReport.init(), staffService.init(), members.init(), tiers.init(), diff --git a/ghost/core/core/server/services/mentions-email-report/index.js b/ghost/core/core/server/services/mentions-email-report/index.js deleted file mode 100644 index 102ef66d4fe..00000000000 --- a/ghost/core/core/server/services/mentions-email-report/index.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('./service'); diff --git a/ghost/core/core/server/services/mentions-email-report/job.js b/ghost/core/core/server/services/mentions-email-report/job.js deleted file mode 100644 index 10849b0fb82..00000000000 --- a/ghost/core/core/server/services/mentions-email-report/job.js +++ /dev/null @@ -1,11 +0,0 @@ -const {parentPort} = require('worker_threads'); -const StartMentionEmailReportJob = require('./start-mention-email-report-job'); - -if (parentPort) { - parentPort.postMessage({ - event: { - type: StartMentionEmailReportJob.name - } - }); - parentPort.postMessage('done'); -} diff --git a/ghost/core/core/server/services/mentions-email-report/mention-email-report-job.js b/ghost/core/core/server/services/mentions-email-report/mention-email-report-job.js deleted file mode 100644 index 96629a1115b..00000000000 --- a/ghost/core/core/server/services/mentions-email-report/mention-email-report-job.js +++ /dev/null @@ -1,117 +0,0 @@ -module.exports = class MentionEmailReportJob { - /** @type {IMentionReportGenerator} */ - #mentionReportGenerator; - - /** @type {IMentionReportRecipientRepository} */ - #mentionReportRecipientRepository; - - /** @type {IMentionReportEmailView} */ - #mentionReportEmailView; - - /** @type {IMentionReportHistoryService} */ - #mentionReportHistoryService; - - /** @type {IEmailService} */ - #emailService; - - /** - * @param {object} deps - * @param {IMentionReportGenerator} deps.mentionReportGenerator - * @param {IMentionReportRecipientRepository} deps.mentionReportRecipientRepository - * @param {IMentionReportEmailView} deps.mentionReportEmailView - * @param {IMentionReportHistoryService} deps.mentionReportHistoryService - * @param {IEmailService} deps.emailService - */ - constructor(deps) { - this.#mentionReportGenerator = deps.mentionReportGenerator; - this.#mentionReportRecipientRepository = deps.mentionReportRecipientRepository; - this.#mentionReportEmailView = deps.mentionReportEmailView; - this.#mentionReportHistoryService = deps.mentionReportHistoryService; - this.#emailService = deps.emailService; - } - - /** - * Checks for new mentions since the last report and sends an email to the recipients. - * - * @returns {Promise} - A promise that resolves with the number of mentions found. - */ - async sendLatestReport() { - const lastReport = await this.#mentionReportHistoryService.getLatestReportDate(); - const now = new Date(); - - if (now.valueOf() - lastReport.valueOf() < 24 * 60 * 60 * 1000) { - return 0; - } - - const report = await this.#mentionReportGenerator.getMentionReport(lastReport, now); - - report.mentions = report.mentions.map((mention) => { - return { - targetUrl: mention.target, - sourceUrl: mention.source, - sourceTitle: mention.sourceTitle, - sourceExcerpt: mention.sourceExcerpt, - sourceSiteTitle: mention.sourceSiteTitle, - sourceFavicon: mention.sourceFavicon, - sourceAuthor: mention.sourceAuthor, - sourceFeaturedImage: mention.sourceFeaturedImage - }; - }); - - if (!report?.mentions?.length) { - return 0; - } - - const recipients = await this.#mentionReportRecipientRepository.getMentionReportRecipients(); - - for (const recipient of recipients) { - const subject = await this.#mentionReportEmailView.renderSubject(report, recipient); - const html = await this.#mentionReportEmailView.renderHTML(report, recipient); - const text = await this.#mentionReportEmailView.renderText(report, recipient); - - await this.#emailService.send(recipient.email, subject, html, text); - } - - await this.#mentionReportHistoryService.setLatestReportDate(now); - - return report.mentions.length; - } -}; - -/** - * @typedef {object} MentionReportRecipient - * @prop {string} email - * @prop {string} slug - */ - -/** - * @typedef {object} IMentionReportRecipientRepository - * @prop {() => Promise} getMentionReportRecipients - */ - -/** - * @typedef {import('../mentions/mentions-api').MentionReport} MentionReport - */ - -/** - * @typedef {object} IMentionReportGenerator - * @prop {(startDate: Date, endDate: Date) => Promise} getMentionReport - */ - -/** - * @typedef {object} IMentionReportEmailView - * @prop {(report: MentionReport, recipient: MentionReportRecipient) => Promise} renderHTML - * @prop {(report: MentionReport, recipient: MentionReportRecipient) => Promise} renderText - * @prop {(report: MentionReport, recipient: MentionReportRecipient) => Promise} renderSubject - */ - -/** - * @typedef {object} IEmailService - * @prop {(to: string, subject: string, html: string, text: string) => Promise} send - */ - -/** - * @typedef {object} IMentionReportHistoryService - * @prop {() => Promise} getLatestReportDate - * @prop {(date: Date) => Promise} setLatestReportDate - */ diff --git a/ghost/core/core/server/services/mentions-email-report/service.js b/ghost/core/core/server/services/mentions-email-report/service.js deleted file mode 100644 index d8eb8091554..00000000000 --- a/ghost/core/core/server/services/mentions-email-report/service.js +++ /dev/null @@ -1,167 +0,0 @@ -const MentionEmailReportJob = require('./mention-email-report-job'); - -/** - * @typedef {MentionEmailReportJob.MentionReport} MentionReport - * @typedef {MentionEmailReportJob.MentionReportRecipient} MentionReportRecipient - */ - -let initialised = false; - -module.exports = { - async init() { - if (initialised) { - return; - } - - const mentions = require('../mentions'); - const mentionReportGenerator = { - getMentionReport(startDate, endDate) { - return mentions.api.getMentionReport(startDate, endDate); - } - }; - - const models = require('../../models'); - const mentionReportRecipientRepository = { - async getMentionReportRecipients() { - const users = await models.User.getEmailAlertUsers('mention-received'); - return users.map((model) => { - return { - email: model.email, - slug: model.slug - }; - }); - } - }; - - const staffService = require('../staff'); - const mentionReportEmailView = { - /** - * @returns {Promise} - */ - async renderSubject(report) { - const sourceSiteTitles = report?.mentions?.map(mention => mention.sourceSiteTitle); - const uniqueSourceSiteTitles = [...new Set(sourceSiteTitles)]; - const totalSiteMentions = uniqueSourceSiteTitles.length; - const firstMentionSite = uniqueSourceSiteTitles[0]; - - let subject = 'Mention Report'; - - if (totalSiteMentions === 1) { - subject = `${firstMentionSite} mentioned you`; - } else if (totalSiteMentions === 2) { - subject = `${firstMentionSite} & 1 other mentioned you`; - } else if (totalSiteMentions > 2) { - subject = `${firstMentionSite} & ${totalSiteMentions - 1} others mentioned you`; - } - - return subject; - }, - - /** - * @param {MentionReport} report - * @param {MentionReportRecipient} recipient - * @returns {Promise} - */ - async renderHTML(report, recipient) { - // Filter out mentions with duplicate source url from the report - const uniqueMentions = report.mentions.filter((mention, index, self) => { - return self.findIndex(m => m.sourceUrl.href === mention.sourceUrl.href) === index; - }); - - return staffService.api.emails.renderHTML('mention-report', { - mentions: uniqueMentions, - recipient: recipient, - hasMoreMentions: report.mentions.length > 5 - }); - }, - - /** - * @param {MentionReport} report - * @param {MentionReportRecipient} recipient - * @returns {Promise} - */ - async renderText(report, recipient) { - // Filter out mentions with duplicate source url from the report - const uniqueMentions = report.mentions.filter((mention, index, self) => { - return self.findIndex(m => m.sourceUrl.href === mention.sourceUrl.href) === index; - }); - - return staffService.api.emails.renderText('mention-report', { - mentions: uniqueMentions, - recipient: recipient - }); - } - }; - - const settingsCache = require('../../../shared/settings-cache'); - const mentionReportHistoryService = { - async getLatestReportDate() { - const setting = settingsCache.get('last_mentions_report_email_timestamp'); - const parsedInt = parseInt(setting); - - // Protect against missing/bad data - if (Number.isNaN(parsedInt) || !parsedInt) { - const date = new Date(); - date.setDate(date.getDate() - 1); - return date; - } - - return new Date(parsedInt); - }, - async setLatestReportDate(date) { - await models.Settings.edit({ - key: 'last_mentions_report_email_timestamp', - value: date.getTime() - }); - } - }; - - const mail = require('../mail'); - const mailer = new mail.GhostMailer(); - const emailService = { - async send(to, subject, html, text) { - return mailer.send({ - to, - subject, - html, - text - }); - } - }; - - const job = new MentionEmailReportJob({ - mentionReportGenerator, - mentionReportRecipientRepository, - mentionReportEmailView, - mentionReportHistoryService, - emailService - }); - - const mentionsJobs = require('../mentions-jobs'); - - const DomainEvents = require('@tryghost/domain-events'); - const StartMentionEmailReportJob = require('./start-mention-email-report-job'); - - const labs = require('../../../shared/labs'); - DomainEvents.subscribe(StartMentionEmailReportJob, () => { - if (labs.isSet('webmentions')) { - job.sendLatestReport(); - } - }); - - // Kick off the job on boot, this will make sure that we send a missing report if needed - DomainEvents.dispatch(StartMentionEmailReportJob.create()); - - const s = Math.floor(Math.random() * 60); // 0-59 - const m = Math.floor(Math.random() * 60); // 0-59 - - // Schedules a job every hour at a random minute and second to send the latest report - mentionsJobs.addJob({ - name: 'mentions-email-report', - job: require('path').resolve(__dirname, './job.js'), - at: `${s} ${m} * * * *` - }); - - initialised = true; - } -}; diff --git a/ghost/core/core/server/services/mentions-email-report/start-mention-email-report-job.js b/ghost/core/core/server/services/mentions-email-report/start-mention-email-report-job.js deleted file mode 100644 index a13e74ea14c..00000000000 --- a/ghost/core/core/server/services/mentions-email-report/start-mention-email-report-job.js +++ /dev/null @@ -1,16 +0,0 @@ -module.exports = class StartMentionEmailReportJob { - /** - * @param {Date} timestamp - */ - constructor(timestamp) { - this.data = null; - this.timestamp = timestamp; - } - - /** - * @param {Date} [timestamp] - */ - static create(data, timestamp) { - return new StartMentionEmailReportJob(timestamp ?? new Date); - } -}; diff --git a/ghost/core/core/server/services/staff/email-templates/mention-report.hbs b/ghost/core/core/server/services/staff/email-templates/mention-report.hbs deleted file mode 100644 index e2f1f4d3081..00000000000 --- a/ghost/core/core/server/services/staff/email-templates/mention-report.hbs +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - 💌 New mention{{#eq mentions.length 1}}{{else}}{{mentions.length}}s{{/eq}} - {{> styles}} - - - - - - - - - -
  -
- - - - - - - - - - -
- - - - - - - - - - - - - - -
-

Hey there,

-

{{siteTitle}} was mentioned{{#eq mentions.length 1}} in:{{else}} {{mentions.length}} times recently. Here's where:{{/eq}}

- - {{#each (limit mentions 5) as |mention|}} - -
- -
-
{{mention.sourceTitle}}
-
{{mention.sourceExcerpt}}
-
- {{#if mention.sourceFavicon}}{{/if}} - {{#if mention.sourceSiteTitle}}{{mention.sourceSiteTitle}}{{/if}} -
-
- {{#if mention.sourceFeaturedImage}} -
- -
- {{/if}} -
-
- - - - - {{/each}} - - - - - - - -
- - - - - - -
View all {{#if hasMoreMentions}}{{mentions.length}}{{/if}} mentions
-
-
-

You can also copy & paste this URL into your browser:

- -
-

This message was sent from {{siteDomain}} to {{toEmail}}

-
-

Don’t want to receive these emails? Manage your preferences here.

-
-
- - - -
-
 
- - diff --git a/ghost/core/core/server/services/staff/email-templates/mention-report.txt.js b/ghost/core/core/server/services/staff/email-templates/mention-report.txt.js deleted file mode 100644 index c67946b3ef0..00000000000 --- a/ghost/core/core/server/services/staff/email-templates/mention-report.txt.js +++ /dev/null @@ -1,19 +0,0 @@ -module.exports = function (data) { - const {mentions} = data; - // Create a list of new mentions with a link to the source - const mentionsList = mentions.map((mention) => { - return `- ${mention.sourceSiteTitle} (${mention.sourceUrl})`; - }).join('\n'); - - // Be careful when you indent the email, because whitespaces are visible in emails! - return ` -You have been mentioned recently. Here's where: - -${mentionsList} - ---- - -Sent to ${data.toEmail} from ${data.siteDomain}. -If you would no longer like to receive these notifications you can adjust your settings at ${data.staffUrl}. - `; -}; diff --git a/ghost/core/core/shared/labs.js b/ghost/core/core/shared/labs.js index 78be710e6b6..9b8515c7071 100644 --- a/ghost/core/core/shared/labs.js +++ b/ghost/core/core/shared/labs.js @@ -41,7 +41,6 @@ const PUBLIC_BETA_FEATURES = [ // Which is only visible if the developer experiments flag is enabled const PRIVATE_FEATURES = [ 'stripeAutomaticTax', - 'webmentions', 'importMemberTier', 'urlCache', 'lexicalIndicators', diff --git a/ghost/core/test/e2e-api/admin/__snapshots__/config.test.js.snap b/ghost/core/test/e2e-api/admin/__snapshots__/config.test.js.snap index 42657aeee84..d0d0f3090e0 100644 --- a/ghost/core/test/e2e-api/admin/__snapshots__/config.test.js.snap +++ b/ghost/core/test/e2e-api/admin/__snapshots__/config.test.js.snap @@ -31,7 +31,6 @@ Object { "themeTranslation": true, "transistor": true, "urlCache": true, - "webmentions": true, "welcomeEmailEditor": true, "welcomeEmails": true, }, diff --git a/ghost/core/test/e2e-api/webmentions/__snapshots__/webmentions.test.js.snap b/ghost/core/test/e2e-api/webmentions/__snapshots__/webmentions.test.js.snap deleted file mode 100644 index aa4555c1a25..00000000000 --- a/ghost/core/test/e2e-api/webmentions/__snapshots__/webmentions.test.js.snap +++ /dev/null @@ -1,2491 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Webmentions (receiving) can display page title in notification email 1: [html 1] 1`] = ` -" - - - - - 💌 New mention from:http://testpage.com/external-article-12345-email-test/ - - - - - - - - - - -
  -
- - - - - - - - - - -
- - - - - - - - - - - - - - -
-

Hey there,

-

Your page About this site was mentioned in:

- - -
- -
-
Test Page
-
Test description
-
- - -  • John Doe -
-
-
-
- - - - - - - - - - -
- - - - - - -
View mentions
-
-
-

You can also copy & paste this URL into your browser:

-

http://127.0.0.1:2369/ghost/#/mentions

-
-

This message was sent from 127.0.0.1 to jbloggs@example.com

-
-

Don’t want to receive these emails? Manage your preferences here.

-
-
- - - -
-
 
- - -" -`; - -exports[`Webmentions (receiving) can display post title in notification email 1: [html 1] 1`] = ` -" - - - - - 💌 New mention from:http://testpage.com/external-article-1234-email-test/ - - - - - - - - - - -
  -
- - - - - - - - - - -
- - - - - - - - - - - - - - -
-

Hey there,

-

Your post Setting up apps and custom integrations was mentioned in:

- - -
- -
-
Test Page
-
Test description
-
- - -  • John Doe -
-
-
-
- - - - - - - - - - -
- - - - - - -
View mentions
-
-
-

You can also copy & paste this URL into your browser:

-

http://127.0.0.1:2369/ghost/#/mentions

-
-

This message was sent from 127.0.0.1 to jbloggs@example.com

-
-

Don’t want to receive these emails? Manage your preferences here.

-
-
- - - -
-
 
- - -" -`; diff --git a/ghost/core/test/e2e-api/webmentions/webmentions.test.js b/ghost/core/test/e2e-api/webmentions/webmentions.test.js index 4865199edfc..9fde406a5f3 100644 --- a/ghost/core/test/e2e-api/webmentions/webmentions.test.js +++ b/ghost/core/test/e2e-api/webmentions/webmentions.test.js @@ -28,7 +28,6 @@ describe('Webmentions (receiving)', function () { beforeEach(async function () { await allSettled(); mockManager.disableNetwork(); - mockManager.mockLabsEnabled('webmentions'); }); afterEach(async function () { diff --git a/ghost/core/test/unit/server/services/mentions-email-report/mention-email-report-job.test.js b/ghost/core/test/unit/server/services/mentions-email-report/mention-email-report-job.test.js deleted file mode 100644 index bd76c288244..00000000000 --- a/ghost/core/test/unit/server/services/mentions-email-report/mention-email-report-job.test.js +++ /dev/null @@ -1,164 +0,0 @@ -const sinon = require('sinon'); -const MentionEmailReportJob = require('../../../../../core/server/services/mentions-email-report/mention-email-report-job'); - -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(); - }); - }); -}); diff --git a/ghost/core/test/unit/server/services/staff/staff-service.test.js b/ghost/core/test/unit/server/services/staff/staff-service.test.js index 87fb834158a..f2394b236d8 100644 --- a/ghost/core/test/unit/server/services/staff/staff-service.test.js +++ b/ghost/core/test/unit/server/services/staff/staff-service.test.js @@ -1120,28 +1120,5 @@ describe('StaffService', function () { ), true); }); }); - - describe('renderText for webmentions', function () { - it('renders plaintext report for mentions', async function () { - const textTemplate = await service.emails.renderText('mention-report', { - toEmail: 'jamie@example.com', - siteDomain: 'ghost.org', - staffUrl: 'https://admin.example.com/blog/ghost/#/settings/staff/jane.', - mentions: [ - { - sourceSiteTitle: 'Webmentions', - sourceUrl: 'https://webmention.io/' - }, - { - sourceSiteTitle: 'Ghost Demo', - sourceUrl: 'https://demo.ghost.io/' - } - ] - }); - assert.match(textTemplate, /- Webmentions \(https:\/\/webmention.io\/\)/); - assert.match(textTemplate, /Ghost Demo \(https:\/\/demo.ghost.io\/\)/); - assert.match(textTemplate, /Sent to jamie@example.com from ghost.org/); - }); - }); }); });