diff --git a/ghost/data-generator/lib/data-generator.js b/ghost/data-generator/lib/data-generator.js index b3811e127d..512e0d85ce 100644 --- a/ghost/data-generator/lib/data-generator.js +++ b/ghost/data-generator/lib/data-generator.js @@ -24,7 +24,8 @@ const { MembersPaidSubscriptionEventsImporter, MembersSubscriptionCreatedEventsImporter, MembersSubscribeEventsImporter, - MentionsImporter + MentionsImporter, + EmailsImporter } = tables; const path = require('path'); const fs = require('fs/promises'); @@ -182,7 +183,7 @@ class DataGenerator { this.logger.info('No base data pack specified, starting random base data generation'); const newslettersImporter = new NewslettersImporter(transaction); // First newsletter is free, second is paid - newsletters = await newslettersImporter.import({amount: 2, rows: ['sort_order']}); + newsletters = await newslettersImporter.import({amount: 2, rows: ['name', 'sort_order']}); newsletters.sort((a, b) => a.sort_order - b.sort_order); const postsImporter = new PostsImporter(transaction, { @@ -308,7 +309,7 @@ class DataGenerator { const membersSubscribeEventsImporter = new MembersSubscribeEventsImporter(transaction, {newsletters, subscriptions}); const membersSubscribeEvents = await membersSubscribeEventsImporter.importForEach(members, { amount: 2, - rows: ['member_id', 'newsletter_id'] + rows: ['member_id', 'newsletter_id', 'created_at'] }); const membersNewslettersImporter = new MembersNewslettersImporter(transaction); @@ -326,7 +327,8 @@ class DataGenerator { // Generate up to 4 webmentions per post await mentionsImporter.importForEach(posts, {amount: 4}); - // TODO: Emails! (relies on posts & newsletters) + const emailsImporter = new EmailsImporter(transaction, {newsletters, members, membersSubscribeEvents}); + await emailsImporter.importForEach(posts, {amount: 1}); // TODO: Email clicks - redirect, members_click_events (relies on emails) diff --git a/ghost/data-generator/lib/tables/emails.js b/ghost/data-generator/lib/tables/emails.js new file mode 100644 index 0000000000..6bc0f951cc --- /dev/null +++ b/ghost/data-generator/lib/tables/emails.js @@ -0,0 +1,80 @@ +const TableImporter = require('./base'); +const {faker} = require('@faker-js/faker'); +const generateEvents = require('../utils/event-generator'); +const {luck} = require('../utils/random'); +const dateToDatabaseString = require('../utils/database-date'); + +class EmailsImporter extends TableImporter { + constructor(knex, {newsletters, members, membersSubscribeEvents}) { + super('emails', knex); + this.newsletters = newsletters; + this.members = members; + this.membersSubscribeEvents = membersSubscribeEvents; + } + + setImportOptions({model}) { + this.model = model; + } + + generate() { + const id = faker.database.mongodbObjectId(); + + const newsletter = luck(90) + ? this.newsletters.find(nl => nl.name === 'Regular premium') + : this.newsletters.find(nl => nl.name !== 'Regular premium'); + + const timestamp = luck(60) + ? new Date(this.model.published_at) + : generateEvents({ + shape: 'ease-out', + trend: 'negative', + total: 1, + startTime: new Date(this.model.published_at), + endTime: new Date() + })[0]; + + const recipientCount = this.membersSubscribeEvents + .filter(entry => entry.newsletter_id === newsletter.id) + .filter(entry => new Date(entry.created_at) < timestamp).length; + const deliveredCount = Math.ceil(recipientCount * faker.datatype.float({ + max: 1, + min: 0.9, + precision: 0.001 + })); + const openedCount = Math.ceil(deliveredCount * faker.datatype.float({ + max: 0.95, + min: 0.6, + precision: 0.001 + })); + const failedCount = Math.floor((recipientCount - deliveredCount) * faker.datatype.float({ + max: 0.05, + min: 0, + precision: 0.001 + })); + + return { + id, + uuid: faker.datatype.uuid(), + post_id: this.model.id, + status: 'submitted', + recipient_filter: '', // TODO: Add recipient filter? + email_count: recipientCount, + delivered_count: deliveredCount, + opened_count: openedCount, + failed_count: failedCount, + subject: this.model.title, + source_type: 'html', + track_opens: true, + track_clicks: true, + feedback_enabled: true, + submitted_at: dateToDatabaseString(timestamp), + newsletter_id: newsletter.id, + created_at: dateToDatabaseString(timestamp), + created_by: 'unused', + updated_at: dateToDatabaseString(timestamp), + updated_by: 'unused' + }; + } +} + +module.exports = EmailsImporter; diff --git a/ghost/data-generator/lib/tables/index.js b/ghost/data-generator/lib/tables/index.js index e58476b5c9..05d1422572 100644 --- a/ghost/data-generator/lib/tables/index.js +++ b/ghost/data-generator/lib/tables/index.js @@ -23,5 +23,6 @@ module.exports = { MembersPaidSubscriptionEventsImporter: require('./members-paid-subscription-events'), MembersSubscriptionCreatedEventsImporter: require('./members-subscription-created-events'), MembersSubscribeEventsImporter: require('./members-subscribe-events'), - MentionsImporter: require('./mentions') + MentionsImporter: require('./mentions'), + EmailsImporter: require('./emails') };