Ghost/test/regression/models/model_members_spec.js
Fabien 'egg' O'Carroll 1294e3f92c
Replaced all usage of member models with members-api (#12117)
no-issue

* Added stripeSubscriptions relation to member model

This allows us to fetch the subscriptions for a member via standard
model usage, e.g. `withRelated: ['stripeSubscriptions']` rather than
offloading to loops and `decorateWithSubscriptions` functions, this is
more performant and less non-standard than the existing method.

* Updated serialize methods to match existing format

The current usage of `decorateWithSubscriptions` and the usage of
members throughout the codebase has a subscriptions array on a stripe
object on the member, this ensures that when we serialize members to
JSON that we are using the same format.

There is definitely room to change this in future, but this is an
attempt to create as few breaking changes as possible.

* Installed @tryghost/members-api@0.26.0

This includes the required API changes so that everywhere can use
members-api directly rather than models and/or helper methods
2020-08-12 14:17:44 +01:00

211 lines
8.0 KiB
JavaScript

const should = require('should');
const BaseModel = require('../../../core/server/models/base');
const {Label} = require('../../../core/server/models/label');
const {Member} = require('../../../core/server/models/member');
const {MemberStripeCustomer} = require('../../../core/server/models/member-stripe-customer');
const {StripeCustomerSubscription} = require('../../../core/server/models/stripe-customer-subscription');
const testUtils = require('../../utils');
describe('Member Model', function run() {
before(testUtils.teardownDb);
beforeEach(testUtils.setup('roles'));
afterEach(testUtils.teardownDb);
describe('stripeSubscriptions', function () {
it('It is correctly mapped to all a members subscriptions, regardless of customer', async function () {
const context = testUtils.context.admin;
await Member.add({
email: 'test@test.member',
labels: []
}, context);
const member = await Member.findOne({
email: 'test@test.member'
}, context);
should.exist(member, 'Member should have been created');
await MemberStripeCustomer.add({
member_id: member.get('id'),
customer_id: 'fake_customer_id1'
}, context);
await MemberStripeCustomer.add({
member_id: member.get('id'),
customer_id: 'fake_customer_id2'
}, context);
await StripeCustomerSubscription.add({
customer_id: 'fake_customer_id1',
subscription_id: 'fake_subscription_id1',
plan_id: 'fake_plan_id',
plan_amount: 1337,
plan_nickname: 'e-LEET',
plan_interval: 'year',
plan_currency: 'btc',
status: 'active',
start_date: new Date(),
current_period_end: new Date(),
cancel_at_period_end: false
}, context);
await StripeCustomerSubscription.add({
customer_id: 'fake_customer_id2',
subscription_id: 'fake_subscription_id2',
plan_id: 'fake_plan_id',
plan_amount: 1337,
plan_nickname: 'e-LEET',
plan_interval: 'year',
plan_currency: 'btc',
status: 'active',
start_date: new Date(),
current_period_end: new Date(),
cancel_at_period_end: false
}, context);
const memberWithRelations = await Member.findOne({
email: 'test@test.member'
}, Object.assign({
withRelated: [
'stripeSubscriptions',
'stripeSubscriptions.customer'
]
}, context));
const subscriptions = memberWithRelations.related('stripeSubscriptions').toJSON();
const subscription1 = subscriptions.find(({id}) => id === 'fake_subscription_id1');
const subscription2 = subscriptions.find(({id}) => id === 'fake_subscription_id2');
should.exist(subscription1);
should.exist(subscription2);
});
});
describe('stripeCustomers', function () {
it('Is correctly mapped to the stripe customers', async function () {
const context = testUtils.context.admin;
await Member.add({
email: 'test@test.member',
stripeCustomers: [{
customer_id: 'fake_customer_id1'
}]
}, context);
const customer1 = await MemberStripeCustomer.findOne({
customer_id: 'fake_customer_id1'
}, context);
should.exist(customer1, 'MemberStripeCustomer should have been created');
await MemberStripeCustomer.add({
member_id: customer1.get('member_id'),
customer_id: 'fake_customer_id2'
}, context);
const member = await Member.findOne({
email: 'test@test.member'
}, Object.assign({}, context, {
withRelated: ['stripeCustomers']
}));
should.exist(member.related('stripeCustomers'), 'Member should have been fetched with stripeCustomers');
const stripeCustomers = member.related('stripeCustomers');
should.equal(stripeCustomers.length, 2, 'Should be two stripeCustomers');
should.equal(stripeCustomers.models[0].get('customer_id'), 'fake_customer_id1');
should.equal(stripeCustomers.models[1].get('customer_id'), 'fake_customer_id2');
});
});
describe('destroy', function () {
it('Cascades to members_labels, members_stripe_customers & members_stripe_customers_subscriptions', async function () {
const context = testUtils.context.admin;
await Member.add({
email: 'test@test.member',
labels: [{
name: 'A label',
slug: 'a-unique-slug-for-testing-members-model'
}]
}, context);
const member = await Member.findOne({
email: 'test@test.member'
}, context);
should.exist(member, 'Member should have been created');
const label = await Label.findOne({
slug: 'a-unique-slug-for-testing-members-model'
}, context);
should.exist(label, 'Label should have been created');
const memberLabel = await BaseModel.knex('members_labels').where({
label_id: label.get('id'),
member_id: member.get('id')
}).select().first();
should.exist(memberLabel, 'Label should have been attached to member');
await MemberStripeCustomer.add({
member_id: member.get('id'),
customer_id: 'fake_customer_id'
}, context);
const customer = await MemberStripeCustomer.findOne({
member_id: member.get('id')
}, context);
should.exist(customer, 'Customer should have been created');
await StripeCustomerSubscription.add({
customer_id: 'fake_customer_id',
subscription_id: 'fake_subscription_id',
plan_id: 'fake_plan_id',
plan_amount: 1337,
plan_nickname: 'e-LEET',
plan_interval: 'year',
plan_currency: 'btc',
status: 'active',
start_date: new Date(),
current_period_end: new Date(),
cancel_at_period_end: false
}, context);
const subscription = await StripeCustomerSubscription.findOne({
customer_id: customer.get('customer_id')
}, context);
should.exist(subscription, 'Subscription should have been created');
await Member.destroy(Object.assign({
id: member.get('id')
}, context));
const memberAfterDestroy = await Member.findOne({
email: 'test@test.member'
});
should.not.exist(memberAfterDestroy, 'Member should have been destroyed');
const memberLabelAfterDestroy = await BaseModel.knex('members_labels').where({
label_id: label.get('id'),
member_id: member.get('id')
}).select().first();
should.not.exist(memberLabelAfterDestroy, 'Label should have been removed from member');
const customerAfterDestroy = await MemberStripeCustomer.findOne({
member_id: member.get('id')
});
should.not.exist(customerAfterDestroy, 'MemberStripeCustomer should have been destroyed');
const subscriptionAfterDestroy = await StripeCustomerSubscription.findOne({
customer_id: customer.get('customer_id')
});
should.not.exist(subscriptionAfterDestroy, 'StripeCustomerSubscription should have been destroyed');
});
});
});