Removed bluebird from fixture-utils.js (#15626)

refs: https://github.com/TryGhost/Ghost/issues/14882

- Opted to use the in-house `sequence` function when refactoring Bluebird's `Promise.each` to avoid deadlock issues (see 734ef66e6c). 
-It's hard to know without tonnes of context if any `Promise.each` are safe to refactor to `Promise.all`.
This commit is contained in:
Halldor Thorhallsson 2022-10-21 15:56:21 -04:00 committed by GitHub
parent 9720459f55
commit dbad621b91
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,5 +1,4 @@
// Utility Packages // Utility Packages
const Promise = require('bluebird');
const _ = require('lodash'); const _ = require('lodash');
const path = require('path'); const path = require('path');
const fs = require('fs-extra'); const fs = require('fs-extra');
@ -35,11 +34,11 @@ const fixtures = {
}, },
insertPostsAndTags: function insertPostsAndTags() { insertPostsAndTags: function insertPostsAndTags() {
return Promise.map(DataGenerator.forKnex.tags, function (tag) { return Promise.all(DataGenerator.forKnex.tags.map((tag) => {
return models.Tag.add(tag, context.internal); return models.Tag.add(tag, context.internal);
}) }))
.then(function () { .then(function () {
return Promise.each(_.cloneDeep(DataGenerator.forKnex.posts), function (post) { return sequence(_.cloneDeep(DataGenerator.forKnex.posts).map(post => () => {
let postTagRelations = _.filter(DataGenerator.forKnex.posts_tags, {post_id: post.id}); let postTagRelations = _.filter(DataGenerator.forKnex.posts_tags, {post_id: post.id});
let postAuthorsRelations = _.filter(DataGenerator.forKnex.posts_authors, {post_id: post.id}); let postAuthorsRelations = _.filter(DataGenerator.forKnex.posts_authors, {post_id: post.id});
@ -55,12 +54,12 @@ const fixtures = {
post.authors = postAuthorsRelations; post.authors = postAuthorsRelations;
return models.Post.add(post, context.internal); return models.Post.add(post, context.internal);
}); }));
}) })
.then(function () { .then(function () {
return Promise.map(DataGenerator.forKnex.posts_meta, function (postMeta) { return Promise.all(DataGenerator.forKnex.posts_meta.map((postMeta) => {
return models.PostsMeta.add(postMeta, context.internal); return models.PostsMeta.add(postMeta, context.internal);
}); }));
}); });
}, },
@ -75,9 +74,9 @@ const fixtures = {
// insert users of different roles // insert users of different roles
return Promise.resolve(fixtures.createUsersWithRoles()).then(function () { return Promise.resolve(fixtures.createUsersWithRoles()).then(function () {
return Promise.map(DataGenerator.forKnex.tags, function (tag) { return Promise.all(DataGenerator.forKnex.tags.map((tag) => {
return models.Tag.add(tag, context.internal); return models.Tag.add(tag, context.internal);
}); }));
}).then(function () { }).then(function () {
return Promise.all([ return Promise.all([
models.User.fetchAll(_.merge({columns: ['id']}, context.internal)), models.User.fetchAll(_.merge({columns: ['id']}, context.internal)),
@ -99,11 +98,11 @@ const fixtures = {
k = k + 1; k = k + 1;
} }
return Promise.map(posts, function (post, index) { return Promise.all(posts.map((post, index) => {
posts[index].authors = [{id: posts[index].authors[0].id}]; posts[index].authors = [{id: posts[index].authors[0].id}];
posts[index].tags = [tags[Math.floor(Math.random() * (tags.length - 1))]]; posts[index].tags = [tags[Math.floor(Math.random() * (tags.length - 1))]];
return models.Post.add(posts[index], context.internal); return models.Post.add(posts[index], context.internal);
}); }));
}); });
}, },
@ -142,17 +141,17 @@ const fixtures = {
return models.User.getOwnerUser(context.internal) return models.User.getOwnerUser(context.internal)
.then(function (ownerUser) { .then(function (ownerUser) {
return Promise.map(posts, function (post, index) { return Promise.all(posts.map((post, index) => {
posts[index].authors = [ownerUser.toJSON()]; posts[index].authors = [ownerUser.toJSON()];
return models.Post.add(posts[index], context.internal); return models.Post.add(posts[index], context.internal);
}); }));
}); });
}, },
insertTags: function insertTags() { insertTags: function insertTags() {
return Promise.map(DataGenerator.forKnex.tags, function (tag) { return Promise.all(DataGenerator.forKnex.tags.map((tag) => {
return models.Tag.add(tag, context.internal); return models.Tag.add(tag, context.internal);
}); }));
}, },
insertExtraTags: function insertExtraTags(max) { insertExtraTags: function insertExtraTags(max) {
@ -166,9 +165,9 @@ const fixtures = {
tags.push(DataGenerator.forKnex.createBasic({name: tagName, slug: tagName})); tags.push(DataGenerator.forKnex.createBasic({name: tagName, slug: tagName}));
} }
return Promise.map(tags, function (tag, index) { return Promise.all(tags.map((tag, index) => {
return models.Tag.add(tags[index], context.internal); return models.Tag.add(tags[index], context.internal);
}); }));
}, },
insertExtraPostsTags: function insertExtraPostsTags(max) { insertExtraPostsTags: function insertExtraPostsTags(max) {
@ -190,20 +189,20 @@ const fixtures = {
throw new Error('Trying to add more posts_tags than the number of posts.'); throw new Error('Trying to add more posts_tags than the number of posts.');
} }
return Promise.map(posts.slice(0, max), function (post) { return Promise.all(posts.slice(0, max).map((post) => {
post.tags = post.tags ? post.tags : []; post.tags = post.tags ? post.tags : [];
return models.Post.edit({ return models.Post.edit({
tags: post.tags.concat([_.find(DataGenerator.Content.tags, {id: injectionTagId})]) tags: post.tags.concat([_.find(DataGenerator.Content.tags, {id: injectionTagId})])
}, _.merge({id: post.id}, context.internal)); }, _.merge({id: post.id}, context.internal));
}); }));
}); });
}, },
insertRoles: function insertRoles() { insertRoles: function insertRoles() {
return Promise.map(DataGenerator.forKnex.roles, function (role) { return Promise.all(DataGenerator.forKnex.roles.map((role) => {
return models.Role.add(role, context.internal); return models.Role.add(role, context.internal);
}); }));
}, },
initOwnerUser: function initOwnerUser() { initOwnerUser: function initOwnerUser() {
@ -212,9 +211,9 @@ const fixtures = {
user = DataGenerator.forKnex.createBasic(user); user = DataGenerator.forKnex.createBasic(user);
user = _.extend({}, user, {status: 'inactive'}); user = _.extend({}, user, {status: 'inactive'});
return Promise.map(DataGenerator.forKnex.roles, function (role) { return Promise.all(DataGenerator.forKnex.roles.map((role) => {
return models.Role.add(role, context.internal); return models.Role.add(role, context.internal);
}).then(function () { })).then(function () {
const userRolesRelation = _.cloneDeep(DataGenerator.forKnex.roles_users[0]); const userRolesRelation = _.cloneDeep(DataGenerator.forKnex.roles_users[0]);
user.roles = _.filter(DataGenerator.forKnex.roles, {id: userRolesRelation.role_id}); user.roles = _.filter(DataGenerator.forKnex.roles, {id: userRolesRelation.role_id});
return models.User.add(user, context.internal); return models.User.add(user, context.internal);
@ -248,10 +247,10 @@ const fixtures = {
}, },
createUsersWithRoles: function createUsersWithRoles() { createUsersWithRoles: function createUsersWithRoles() {
return Promise.map(DataGenerator.forKnex.roles, function (role) { return Promise.all(DataGenerator.forKnex.roles.map((role) => {
return models.Role.add(role, context.internal); return models.Role.add(role, context.internal);
}).then(function () { })).then(function () {
return Promise.map(_.cloneDeep(DataGenerator.forKnex.users), function (user) { return Promise.all(_.cloneDeep(DataGenerator.forKnex.users).map((user) => {
let userRolesRelations = _.filter(DataGenerator.forKnex.roles_users, {user_id: user.id}); let userRolesRelations = _.filter(DataGenerator.forKnex.roles_users, {user_id: user.id});
userRolesRelations = _.map(userRolesRelations, function (userRolesRelation) { userRolesRelations = _.map(userRolesRelations, function (userRolesRelation) {
@ -260,7 +259,7 @@ const fixtures = {
user.roles = userRolesRelations; user.roles = userRolesRelations;
return models.User.add(user, context.internal); return models.User.add(user, context.internal);
}); }));
}); });
}, },
@ -270,7 +269,7 @@ const fixtures = {
let roles = await models.Role.fetchAll(); let roles = await models.Role.fetchAll();
roles = roles.toJSON(); roles = roles.toJSON();
return Promise.map(usersWithoutOwner, function (user) { return Promise.all(usersWithoutOwner.map((user) => {
let userRolesRelations = _.filter(DataGenerator.forKnex.roles_users, {user_id: user.id}); let userRolesRelations = _.filter(DataGenerator.forKnex.roles_users, {user_id: user.id});
userRolesRelations = _.map(userRolesRelations, function (userRolesRelation) { userRolesRelations = _.map(userRolesRelations, function (userRolesRelation) {
@ -280,7 +279,7 @@ const fixtures = {
user.roles = userRolesRelations; user.roles = userRolesRelations;
return models.User.add(user, context.internal); return models.User.add(user, context.internal);
}); }));
}, },
createInactiveUser() { createInactiveUser() {
@ -315,10 +314,10 @@ const fixtures = {
// replacement for admin2, editor2 etc // replacement for admin2, editor2 etc
DataGenerator.Content.extraUsers = extraUsers; DataGenerator.Content.extraUsers = extraUsers;
return Promise.map(extraUsers, function (user) { return Promise.all(extraUsers.map((user) => {
user.roles = roles[user.id]; user.roles = roles[user.id];
return models.User.add(user, context.internal); return models.User.add(user, context.internal);
}); }));
}, },
insertOneUser: function insertOneUser(options) { insertOneUser: function insertOneUser(options) {
@ -412,19 +411,19 @@ const fixtures = {
} }
}); });
return Promise.map(permsToInsert, function (perm) { return Promise.all(permsToInsert.map((perm) => {
if (!_.isEmpty(permissionsRoles)) { if (!_.isEmpty(permissionsRoles)) {
perm.roles = permissionsRoles[perm.id]; perm.roles = permissionsRoles[perm.id];
} }
return models.Permission.add(perm, context.internal); return models.Permission.add(perm, context.internal);
}); }));
}, },
insertInvites: function insertInvites() { insertInvites: function insertInvites() {
return Promise.map(DataGenerator.forKnex.invites, function (invite) { return Promise.all(DataGenerator.forKnex.invites.map((invite) => {
return models.Invite.add(invite, context.internal); return models.Invite.add(invite, context.internal);
}); }));
}, },
insertWebhook: function (attributes) { insertWebhook: function (attributes) {
@ -438,33 +437,33 @@ const fixtures = {
}, },
insertWebhooks: function insertWebhooks() { insertWebhooks: function insertWebhooks() {
return Promise.map(DataGenerator.forKnex.webhooks, function (webhook) { return Promise.all(DataGenerator.forKnex.webhooks.map((webhook) => {
return models.Webhook.add(webhook, context.internal); return models.Webhook.add(webhook, context.internal);
}); }));
}, },
insertIntegrations: function insertIntegrations() { insertIntegrations: function insertIntegrations() {
return Promise.map(DataGenerator.forKnex.integrations, function (integration) { return Promise.all(DataGenerator.forKnex.integrations.map((integration) => {
return models.Integration.add(integration, context.internal); return models.Integration.add(integration, context.internal);
}); }));
}, },
insertApiKeys: function insertApiKeys() { insertApiKeys: function insertApiKeys() {
return Promise.map(DataGenerator.forKnex.api_keys, function (api_key) { return Promise.all(DataGenerator.forKnex.api_keys.map((api_key) => {
return models.ApiKey.add(api_key, context.internal); return models.ApiKey.add(api_key, context.internal);
}); }));
}, },
insertLinks: function insertLinks() { insertLinks: function insertLinks() {
return Promise.map(DataGenerator.forKnex.links, function (link) { return Promise.all(DataGenerator.forKnex.links.map((link) => {
return models.Redirect.add(link, context.internal); return models.Redirect.add(link, context.internal);
}); }));
}, },
insertEmails: function insertEmails() { insertEmails: function insertEmails() {
return Promise.map(DataGenerator.forKnex.emails, function (email) { return Promise.all(DataGenerator.forKnex.emails.map((email) => {
return models.Email.add(email, context.internal); return models.Email.add(email, context.internal);
}); }));
}, },
insertArchivedTiers: function insertArchivedTiers() { insertArchivedTiers: function insertArchivedTiers() {
@ -477,36 +476,36 @@ const fixtures = {
insertProducts: async function insertProducts() { insertProducts: async function insertProducts() {
let coreProductFixtures = fixtureManager.findModelFixtures('Product').entries; let coreProductFixtures = fixtureManager.findModelFixtures('Product').entries;
await Promise.map(coreProductFixtures, async (product) => { await Promise.all(coreProductFixtures.map(async (product) => {
const found = await models.Product.findOne(product, context.internal); const found = await models.Product.findOne(product, context.internal);
if (!found) { if (!found) {
await models.Product.add(product, context.internal); await models.Product.add(product, context.internal);
} }
}); }));
const product = await models.Product.findOne({type: 'paid'}, context.internal); const product = await models.Product.findOne({type: 'paid'}, context.internal);
await Promise.each(_.cloneDeep(DataGenerator.forKnex.stripe_products), function (stripeProduct) { await sequence(_.cloneDeep(DataGenerator.forKnex.stripe_products).map(stripeProduct => () => {
stripeProduct.product_id = product.id; stripeProduct.product_id = product.id;
return models.StripeProduct.add(stripeProduct, context.internal); return models.StripeProduct.add(stripeProduct, context.internal);
}); }));
await Promise.each(_.cloneDeep(DataGenerator.forKnex.stripe_prices), function (stripePrice) { await sequence(_.cloneDeep(DataGenerator.forKnex.stripe_prices).map(stripePrice => () => {
return models.StripePrice.add(stripePrice, context.internal); return models.StripePrice.add(stripePrice, context.internal);
}); }));
}, },
insertMembersAndLabelsAndProducts: function insertMembersAndLabelsAndProducts(newsletters = false) { insertMembersAndLabelsAndProducts: function insertMembersAndLabelsAndProducts(newsletters = false) {
return Promise.map(DataGenerator.forKnex.labels, function (label) { return Promise.all(DataGenerator.forKnex.labels.map((label) => {
return models.Label.add(label, context.internal); return models.Label.add(label, context.internal);
}).then(function () { })).then(function () {
let coreProductFixtures = fixtureManager.findModelFixtures('Product').entries; let coreProductFixtures = fixtureManager.findModelFixtures('Product').entries;
return Promise.map(coreProductFixtures, async (product) => { return Promise.all(coreProductFixtures.map(async (product) => {
const found = await models.Product.findOne(product, context.internal); const found = await models.Product.findOne(product, context.internal);
if (!found) { if (!found) {
await models.Product.add(product, context.internal); await models.Product.add(product, context.internal);
} }
}); }));
}).then(async function () { }).then(async function () {
let testProductFixtures = DataGenerator.forKnex.products; let testProductFixtures = DataGenerator.forKnex.products;
for (const productFixture of testProductFixtures) { for (const productFixture of testProductFixtures) {
@ -521,12 +520,12 @@ const fixtures = {
}).then(function () { }).then(function () {
return models.Product.findOne({type: 'paid'}, context.internal); return models.Product.findOne({type: 'paid'}, context.internal);
}).then(function (product) { }).then(function (product) {
return Promise.props({ return Promise.all([
stripeProducts: Promise.each(_.cloneDeep(DataGenerator.forKnex.stripe_products), function (stripeProduct) { sequence(_.cloneDeep(DataGenerator.forKnex.stripe_products).map(stripeProduct => () => {
stripeProduct.product_id = product.id; stripeProduct.product_id = product.id;
return models.StripeProduct.add(stripeProduct, context.internal); return models.StripeProduct.add(stripeProduct, context.internal);
}), })),
members: Promise.each(_.cloneDeep(DataGenerator.forKnex.members), function (member) { sequence(_.cloneDeep(DataGenerator.forKnex.members).map(member => () => {
let memberLabelRelations = _.filter(DataGenerator.forKnex.members_labels, {member_id: member.id}); let memberLabelRelations = _.filter(DataGenerator.forKnex.members_labels, {member_id: member.id});
memberLabelRelations = _.map(memberLabelRelations, function (memberLabelRelation) { memberLabelRelations = _.map(memberLabelRelations, function (memberLabelRelation) {
@ -550,16 +549,16 @@ const fixtures = {
} }
return models.Member.add(member, context.internal); return models.Member.add(member, context.internal);
}) }))
}); ]);
}).then(function () { }).then(function () {
return Promise.each(_.cloneDeep(DataGenerator.forKnex.members_stripe_customers), function (customer) { return sequence(_.cloneDeep(DataGenerator.forKnex.members_stripe_customers).map(customer => () => {
return models.MemberStripeCustomer.add(customer, context.internal); return models.MemberStripeCustomer.add(customer, context.internal);
}); }));
}).then(function () { }).then(function () {
return Promise.each(_.cloneDeep(DataGenerator.forKnex.stripe_prices), function (stripePrice) { return sequence(_.cloneDeep(DataGenerator.forKnex.stripe_prices).map(stripePrice => () => {
return models.StripePrice.add(stripePrice, context.internal); return models.StripePrice.add(stripePrice, context.internal);
}); }));
}).then(async function () { }).then(async function () {
// Add monthly/yearly prices to default product for testing // Add monthly/yearly prices to default product for testing
const defaultProduct = await models.Product.findOne({slug: 'default-product'}, context.internal); const defaultProduct = await models.Product.findOne({slug: 'default-product'}, context.internal);
@ -569,9 +568,9 @@ const fixtures = {
yearly_price_id: DataGenerator.forKnex.stripe_prices[2].id yearly_price_id: DataGenerator.forKnex.stripe_prices[2].id
}, _.merge({id: defaultProduct.id}, context.internal)); }, _.merge({id: defaultProduct.id}, context.internal));
}).then(function () { }).then(function () {
return Promise.each(_.cloneDeep(DataGenerator.forKnex.stripe_customer_subscriptions), function (subscription) { return sequence(_.cloneDeep(DataGenerator.forKnex.stripe_customer_subscriptions).map(subscription => () => {
return models.StripeCustomerSubscription.add(subscription, context.internal); return models.StripeCustomerSubscription.add(subscription, context.internal);
}); }));
}).then(async function () { }).then(async function () {
const members = (await models.Member.findAll({ const members = (await models.Member.findAll({
withRelated: [ withRelated: [
@ -609,16 +608,16 @@ const fixtures = {
}, },
insertEmailsAndRecipients: function insertEmailsAndRecipients() { insertEmailsAndRecipients: function insertEmailsAndRecipients() {
return Promise.each(_.cloneDeep(DataGenerator.forKnex.emails), function (email) { return sequence(_.cloneDeep(DataGenerator.forKnex.emails).map(email => () => {
return models.Email.add(email, context.internal); return models.Email.add(email, context.internal);
}).then(function () { })).then(function () {
return Promise.each(_.cloneDeep(DataGenerator.forKnex.email_batches), function (emailBatch) { return sequence(_.cloneDeep(DataGenerator.forKnex.email_batches).map(emailBatch => () => {
return models.EmailBatch.add(emailBatch, context.internal); return models.EmailBatch.add(emailBatch, context.internal);
}); }));
}).then(function () { }).then(function () {
return Promise.each(_.cloneDeep(DataGenerator.forKnex.email_recipients), (emailRecipient) => { return sequence(_.cloneDeep(DataGenerator.forKnex.email_recipients).map(emailRecipient => () => {
return models.EmailRecipient.add(emailRecipient, context.internal); return models.EmailRecipient.add(emailRecipient, context.internal);
}); }));
}).then(function () { }).then(function () {
const toAggregate = { const toAggregate = {
emailIds: DataGenerator.forKnex.emails.map(email => email.id), emailIds: DataGenerator.forKnex.emails.map(email => email.id),
@ -630,9 +629,9 @@ const fixtures = {
}, },
insertNewsletters: async function insertNewsletters() { insertNewsletters: async function insertNewsletters() {
return Promise.map(DataGenerator.forKnex.newsletters, function (newsletter) { return Promise.all(DataGenerator.forKnex.newsletters.map((newsletter) => {
return models.Newsletter.add(newsletter, context.internal); return models.Newsletter.add(newsletter, context.internal);
}); }));
}, },
insertComments: async function insertComments() { insertComments: async function insertComments() {
@ -668,15 +667,15 @@ const fixtures = {
}, },
insertSnippets: function insertSnippets() { insertSnippets: function insertSnippets() {
return Promise.map(DataGenerator.forKnex.snippets, function (snippet) { return Promise.all(DataGenerator.forKnex.snippets.map((snippet) => {
return models.Snippet.add(snippet, context.internal); return models.Snippet.add(snippet, context.internal);
}); }));
}, },
insertCustomThemeSettings: function insertCustomThemeSettings() { insertCustomThemeSettings: function insertCustomThemeSettings() {
return Promise.map(DataGenerator.forKnex.custom_theme_settings, function (setting) { return Promise.all(DataGenerator.forKnex.custom_theme_settings.map((setting) => {
return models.CustomThemeSetting.add(setting, context.internal); return models.CustomThemeSetting.add(setting, context.internal);
}); }));
}, },
async enableAllLabsFeatures() { async enableAllLabsFeatures() {