mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-03 23:00:14 -05:00
Added awaiting jobs and events by default to all tests (#16505)
no issue This change waits for domain events and jobs before continuing with the next test. This prevents issues where background tasks in tests are executed when the next test is running and the configurations have changed, causing random error logs and test failures. It also includes a change in Stripe mocking in one E2E test to make use of the new StripeMocker instead of custom mocking in each test (also to reduce error logs).
This commit is contained in:
parent
16c625a630
commit
ba8f082d41
3 changed files with 110 additions and 101 deletions
|
@ -1,71 +1,26 @@
|
|||
const statsService = require('../../../../core/server/services/stats');
|
||||
const {agentProvider, fixtureManager, mockManager} = require('../../../utils/e2e-framework');
|
||||
const moment = require('moment');
|
||||
require('should');
|
||||
const nock = require('nock');
|
||||
const {stripeMocker} = require('../../../utils/e2e-framework-mock-manager');
|
||||
const moment = require('moment');
|
||||
|
||||
let agent;
|
||||
let counter = 0;
|
||||
|
||||
async function createMemberWithSubscription(interval, amount, currency, date) {
|
||||
counter += 1;
|
||||
|
||||
const fakePrice = {
|
||||
id: 'price_' + counter,
|
||||
product: '',
|
||||
active: true,
|
||||
nickname: 'Paid',
|
||||
unit_amount: amount,
|
||||
const tier = await stripeMocker.createTier({
|
||||
currency,
|
||||
type: 'recurring',
|
||||
recurring: {
|
||||
interval
|
||||
}
|
||||
};
|
||||
|
||||
const fakeSubscription = {
|
||||
id: 'sub_' + counter,
|
||||
customer: 'cus_' + counter,
|
||||
status: 'active',
|
||||
cancel_at_period_end: false,
|
||||
metadata: {},
|
||||
current_period_end: Date.now() / 1000 + 1000,
|
||||
start_date: moment(date).unix(),
|
||||
plan: fakePrice,
|
||||
items: {
|
||||
data: [{
|
||||
price: fakePrice
|
||||
}]
|
||||
}
|
||||
};
|
||||
|
||||
const fakeCustomer = {
|
||||
id: 'cus_' + counter,
|
||||
name: 'Test Member',
|
||||
email: 'create-member-subscription-' + counter + '@email.com',
|
||||
subscriptions: {
|
||||
type: 'list',
|
||||
data: [fakeSubscription]
|
||||
}
|
||||
};
|
||||
nock('https://api.stripe.com')
|
||||
.persist()
|
||||
.get(/v1\/.*/)
|
||||
.reply((uri) => {
|
||||
const [match, resource] = uri.match(/\/?v1\/(\w+)\/?(\w+)/) || [null];
|
||||
|
||||
if (!match) {
|
||||
return [500];
|
||||
}
|
||||
|
||||
if (resource === 'customers') {
|
||||
return [200, fakeCustomer];
|
||||
}
|
||||
|
||||
if (resource === 'subscriptions') {
|
||||
return [200, fakeSubscription];
|
||||
}
|
||||
});
|
||||
monthly_price: amount,
|
||||
yearly_price: amount
|
||||
});
|
||||
const price = await stripeMocker.getPriceForTier(tier.get('slug'), interval);
|
||||
const fakeCustomer = stripeMocker.createCustomer({});
|
||||
await stripeMocker.createSubscription({
|
||||
customer: fakeCustomer,
|
||||
price,
|
||||
start_date: moment(date).unix()
|
||||
}, {
|
||||
sendWebhook: false
|
||||
});
|
||||
|
||||
const initialMember = {
|
||||
name: fakeCustomer.name,
|
||||
|
@ -78,8 +33,6 @@ async function createMemberWithSubscription(interval, amount, currency, date) {
|
|||
.post(`/members/`)
|
||||
.body({members: [initialMember]})
|
||||
.expectStatus(201);
|
||||
|
||||
nock.cleanAll();
|
||||
}
|
||||
|
||||
describe('MRR Stats Service', function () {
|
||||
|
@ -87,15 +40,15 @@ describe('MRR Stats Service', function () {
|
|||
agent = await agentProvider.getAdminAPIAgent();
|
||||
await fixtureManager.init();
|
||||
await agent.loginAsOwner();
|
||||
mockManager.mockMail();
|
||||
});
|
||||
|
||||
after(async function () {
|
||||
mockManager.restore();
|
||||
beforeEach(function () {
|
||||
mockManager.mockMail();
|
||||
mockManager.mockStripe();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
nock.cleanAll();
|
||||
mockManager.restore();
|
||||
});
|
||||
|
||||
describe('getCurrentMrr', function () {
|
||||
|
@ -103,7 +56,7 @@ describe('MRR Stats Service', function () {
|
|||
const result = await statsService.mrr.getCurrentMrr();
|
||||
result.should.eql([
|
||||
{
|
||||
currency: 'usd',
|
||||
currency: 'usd', // need to check capital usage here!
|
||||
mrr: 0
|
||||
}
|
||||
]);
|
||||
|
@ -114,7 +67,7 @@ describe('MRR Stats Service', function () {
|
|||
const result = await statsService.mrr.getCurrentMrr();
|
||||
result.should.eql([
|
||||
{
|
||||
currency: 'eur',
|
||||
currency: 'EUR',
|
||||
mrr: 500
|
||||
}
|
||||
]);
|
||||
|
@ -125,11 +78,11 @@ describe('MRR Stats Service', function () {
|
|||
const result = await statsService.mrr.getCurrentMrr();
|
||||
result.should.eql([
|
||||
{
|
||||
currency: 'eur',
|
||||
currency: 'EUR',
|
||||
mrr: 500
|
||||
},
|
||||
{
|
||||
currency: 'usd',
|
||||
currency: 'USD',
|
||||
mrr: 1
|
||||
}
|
||||
]);
|
||||
|
@ -140,11 +93,11 @@ describe('MRR Stats Service', function () {
|
|||
const result = await statsService.mrr.getCurrentMrr();
|
||||
result.should.eql([
|
||||
{
|
||||
currency: 'eur',
|
||||
currency: 'EUR',
|
||||
mrr: 500
|
||||
},
|
||||
{
|
||||
currency: 'usd',
|
||||
currency: 'USD',
|
||||
mrr: 2
|
||||
}
|
||||
]);
|
||||
|
@ -155,11 +108,11 @@ describe('MRR Stats Service', function () {
|
|||
let result = await statsService.mrr.getCurrentMrr();
|
||||
result.should.eql([
|
||||
{
|
||||
currency: 'eur',
|
||||
currency: 'EUR',
|
||||
mrr: 500
|
||||
},
|
||||
{
|
||||
currency: 'usd',
|
||||
currency: 'USD',
|
||||
mrr: 3
|
||||
}
|
||||
]);
|
||||
|
@ -169,11 +122,11 @@ describe('MRR Stats Service', function () {
|
|||
result = await statsService.mrr.getCurrentMrr();
|
||||
result.should.eql([
|
||||
{
|
||||
currency: 'eur',
|
||||
currency: 'EUR',
|
||||
mrr: 500
|
||||
},
|
||||
{
|
||||
currency: 'usd',
|
||||
currency: 'USD',
|
||||
mrr: 3
|
||||
}
|
||||
]);
|
||||
|
@ -183,11 +136,11 @@ describe('MRR Stats Service', function () {
|
|||
result = await statsService.mrr.getCurrentMrr();
|
||||
result.should.eql([
|
||||
{
|
||||
currency: 'eur',
|
||||
currency: 'EUR',
|
||||
mrr: 500
|
||||
},
|
||||
{
|
||||
currency: 'usd',
|
||||
currency: 'USD',
|
||||
mrr: 3
|
||||
}
|
||||
]);
|
||||
|
@ -197,11 +150,11 @@ describe('MRR Stats Service', function () {
|
|||
result = await statsService.mrr.getCurrentMrr();
|
||||
result.should.eql([
|
||||
{
|
||||
currency: 'eur',
|
||||
currency: 'EUR',
|
||||
mrr: 500
|
||||
},
|
||||
{
|
||||
currency: 'usd',
|
||||
currency: 'USD',
|
||||
mrr: 4
|
||||
}
|
||||
]);
|
||||
|
@ -216,22 +169,22 @@ describe('MRR Stats Service', function () {
|
|||
{
|
||||
date: '2000-01-10',
|
||||
delta: 500,
|
||||
currency: 'eur'
|
||||
currency: 'EUR'
|
||||
},
|
||||
{
|
||||
date: '2000-01-10',
|
||||
delta: 1,
|
||||
currency: 'usd'
|
||||
currency: 'USD'
|
||||
},
|
||||
{
|
||||
date: '2000-01-11',
|
||||
delta: 1,
|
||||
currency: 'usd'
|
||||
currency: 'USD'
|
||||
},
|
||||
{
|
||||
date: '2000-01-12',
|
||||
delta: 2,
|
||||
currency: 'usd'
|
||||
currency: 'USD'
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
|
|
@ -17,3 +17,21 @@ mochaHooks.beforeAll = async function () {
|
|||
// Disable network in tests to prevent any accidental requests
|
||||
mockManager.disableNetwork();
|
||||
};
|
||||
|
||||
const originalAfterEach = mochaHooks.afterEach;
|
||||
mochaHooks.afterEach = async function () {
|
||||
const domainEvents = require('@tryghost/domain-events');
|
||||
const mentionsJobsService = require('../../core/server/services/mentions-jobs');
|
||||
const jobsService = require('../../core/server/services/jobs');
|
||||
|
||||
await domainEvents.allSettled();
|
||||
await mentionsJobsService.allSettled();
|
||||
await jobsService.allSettled();
|
||||
|
||||
// Last time for events emitted during jobs
|
||||
await domainEvents.allSettled();
|
||||
|
||||
if (originalAfterEach) {
|
||||
await originalAfterEach();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -19,6 +19,8 @@ class StripeMocker {
|
|||
prices = [];
|
||||
products = [];
|
||||
|
||||
nockInterceptors = [];
|
||||
|
||||
constructor(data = {}) {
|
||||
this.customers = data.customers ?? [];
|
||||
this.subscriptions = data.subscriptions ?? [];
|
||||
|
@ -80,6 +82,25 @@ class StripeMocker {
|
|||
return this.#getData(this.prices, id)[1];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {object} data
|
||||
* @param {string} [data.name]
|
||||
* @param {string} data.currency
|
||||
* @param {number} data.monthly_price
|
||||
* @param {number} data.yearly_price
|
||||
* @returns
|
||||
*/
|
||||
async createTier({name, currency, monthly_price, yearly_price}) {
|
||||
return await models.Product.add({
|
||||
name: name ?? ('Tier ' + this.#generateRandomId()),
|
||||
type: 'paid',
|
||||
currency: currency.toUpperCase(),
|
||||
monthly_price,
|
||||
yearly_price
|
||||
});
|
||||
}
|
||||
|
||||
async createTrialSubscription({customer, price, ...overrides}) {
|
||||
return await this.createSubscription({
|
||||
customer,
|
||||
|
@ -113,7 +134,7 @@ class StripeMocker {
|
|||
await DomainEvents.allSettled();
|
||||
}
|
||||
|
||||
async createSubscription({customer, price, ...overrides}) {
|
||||
async createSubscription({customer, price, ...overrides}, options = {sendWebhook: true}) {
|
||||
const subscriptionId = `sub_${this.#generateRandomId()}`;
|
||||
|
||||
const subscription = {
|
||||
|
@ -140,18 +161,20 @@ class StripeMocker {
|
|||
customer.subscriptions.data.push(subscription);
|
||||
|
||||
// Announce
|
||||
await this.sendWebhook({
|
||||
type: 'checkout.session.completed',
|
||||
data: {
|
||||
object: {
|
||||
mode: 'subscription',
|
||||
customer: customer.id,
|
||||
metadata: {
|
||||
checkoutType: 'signup'
|
||||
if (options.sendWebhook) {
|
||||
await this.sendWebhook({
|
||||
type: 'checkout.session.completed',
|
||||
data: {
|
||||
object: {
|
||||
mode: 'subscription',
|
||||
customer: customer.id,
|
||||
metadata: {
|
||||
checkoutType: 'signup'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return subscription;
|
||||
}
|
||||
|
@ -266,10 +289,21 @@ class StripeMocker {
|
|||
return [200, subscription];
|
||||
}
|
||||
|
||||
remove() {
|
||||
for (const interceptor of this.nockInterceptors) {
|
||||
nock.removeInterceptor(interceptor);
|
||||
}
|
||||
this.nockInterceptors = [];
|
||||
}
|
||||
|
||||
stub() {
|
||||
nock('https://api.stripe.com')
|
||||
this.remove();
|
||||
|
||||
let interceptor = nock('https://api.stripe.com')
|
||||
.persist()
|
||||
.get(/v1\/.*/)
|
||||
.get(/v1\/.*/);
|
||||
this.nockInterceptors.push(interceptor);
|
||||
interceptor
|
||||
.reply((uri) => {
|
||||
const [match, resource, id] = uri.match(/\/?v1\/(\w+)\/?(\w+)/) || [null];
|
||||
|
||||
|
@ -308,9 +342,11 @@ class StripeMocker {
|
|||
return [500];
|
||||
});
|
||||
|
||||
nock('https://api.stripe.com')
|
||||
interceptor = nock('https://api.stripe.com')
|
||||
.persist()
|
||||
.post(/v1\/.*/)
|
||||
.post(/v1\/.*/);
|
||||
this.nockInterceptors.push(interceptor);
|
||||
interceptor
|
||||
.reply((uri, body) => {
|
||||
const [match, resource, id] = uri.match(/\/?v1\/(\w+)(?:\/?(\w+)){0,2}/) || [null];
|
||||
|
||||
|
@ -345,9 +381,11 @@ class StripeMocker {
|
|||
return [500];
|
||||
});
|
||||
|
||||
nock('https://api.stripe.com')
|
||||
interceptor = nock('https://api.stripe.com')
|
||||
.persist()
|
||||
.delete(/v1\/.*/)
|
||||
.delete(/v1\/.*/);
|
||||
this.nockInterceptors.push(interceptor);
|
||||
interceptor
|
||||
.reply((uri) => {
|
||||
const [match, resource, id] = uri.match(/\/?v1\/(\w+)(?:\/?(\w+)){0,2}/) || [null];
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue