🏗 Flattened members subscriptions data in API (#12581)

no refs

- Updates member model serializer to directly set subscriptions on member object instead of `stripe.subscriptions`
- Updates all references to members subscriptions from nested `stripe.subscriptions` to `subscriptions`
- Updates v3 API serializer to still use `stripe.subscriptions`
- Updates tests
This commit is contained in:
Rishabh Garg 2021-01-28 22:55:38 +05:30 committed by Daniel Lockyer
parent 6af2706f10
commit 26ee648397
No known key found for this signature in database
GPG Key ID: FFBC6FA2A6F6ABC1
9 changed files with 40 additions and 39 deletions

View File

@ -132,7 +132,7 @@ function updateLocalTemplateOptions(req, res, next) {
name: req.member.name,
firstname: req.member.name && req.member.name.split(' ')[0],
avatar_image: req.member.avatar_image,
subscriptions: req.member.stripe.subscriptions,
subscriptions: req.member.subscriptions,
paid: req.member.status === 'paid'
} : null;

View File

@ -73,8 +73,8 @@ function serializeMember(member, options) {
const json = member.toJSON(options);
let comped = false;
if (json.stripe && json.stripe.subscriptions) {
const hasCompedSubscription = !!json.stripe.subscriptions.find(
if (json.subscriptions) {
const hasCompedSubscription = !!json.subscriptions.find(
/**
* @param {SerializedMemberStripeSubscription} sub
*/
@ -86,6 +86,7 @@ function serializeMember(member, options) {
comped = true;
}
}
const subscriptions = json.subscriptions || [];
return {
id: json.id,
@ -98,7 +99,7 @@ function serializeMember(member, options) {
created_at: json.created_at,
updated_at: json.updated_at,
labels: json.labels,
stripe: json.stripe,
subscriptions: subscriptions,
avatar_image: json.avatar_image,
comped: comped,
email_count: json.email_count,
@ -146,7 +147,7 @@ function createSerializer(debugString, serialize) {
* @prop {string} created_at
* @prop {string} updated_at
* @prop {string[]} labels
* @prop {null|SerializedMemberStripeData} stripe
* @prop {SerializedMemberStripeSubscription[]} subscriptions
* @prop {string} avatar_image
* @prop {boolean} comped
* @prop {number} email_count

View File

@ -73,8 +73,12 @@ function serializeMember(member, options) {
const json = member.toJSON(options);
let comped = false;
if (json.stripe && json.stripe.subscriptions) {
const hasCompedSubscription = !!json.stripe.subscriptions.find(
let stripe = null;
if (json.subscriptions) {
stripe = {
subscriptions: json.subscriptions
};
const hasCompedSubscription = !!json.subscriptions.find(
/**
* @param {SerializedMemberStripeSubscription} sub
*/
@ -98,7 +102,7 @@ function serializeMember(member, options) {
created_at: json.created_at,
updated_at: json.updated_at,
labels: json.labels,
stripe: json.stripe,
stripe: stripe,
avatar_image: json.avatar_image,
comped: comped,
email_count: json.email_count,

View File

@ -67,9 +67,7 @@ const Member = ghostBookshelf.Model.extend({
const defaultSerializedObject = ghostBookshelf.Model.prototype.serialize.call(this, options);
if (defaultSerializedObject.stripeSubscriptions) {
defaultSerializedObject.stripe = {
subscriptions: defaultSerializedObject.stripeSubscriptions
};
defaultSerializedObject.subscriptions = defaultSerializedObject.stripeSubscriptions;
delete defaultSerializedObject.stripeSubscriptions;
}

View File

@ -136,7 +136,7 @@ const createSessionFromMagicLink = async function (req, res, next) {
try {
const member = await membersService.ssr.exchangeTokenForSession(req, res);
const subscriptions = member && member.stripe && member.stripe.subscriptions || [];
const subscriptions = member && member.subscriptions || [];
const action = req.query.action;

View File

@ -9,7 +9,7 @@ module.exports.formattedMemberResponse = function formattedMemberResponse(member
firstname: member.name && member.name.split(' ')[0],
avatar_image: member.avatar_image,
subscribed: !!member.subscribed,
subscriptions: member.stripe ? member.stripe.subscriptions : [],
subscriptions: member.subscriptions || [],
paid: member.status === 'paid'
};
};

View File

@ -37,7 +37,7 @@ describe('Members API', function () {
should.exist(jsonResponse);
should.exist(jsonResponse.members);
jsonResponse.members.should.have.length(4);
localUtils.API.checkResponse(jsonResponse.members[0], 'member', 'stripe');
localUtils.API.checkResponse(jsonResponse.members[0], 'member', 'subscriptions');
testUtils.API.isISO8601(jsonResponse.members[0].created_at).should.be.true();
jsonResponse.members[0].created_at.should.be.an.instanceof(String);
@ -64,7 +64,7 @@ describe('Members API', function () {
should.exist(jsonResponse.members);
jsonResponse.members.should.have.length(1);
localUtils.API.checkResponse(jsonResponse, 'members');
localUtils.API.checkResponse(jsonResponse.members[0], 'member', 'stripe');
localUtils.API.checkResponse(jsonResponse.members[0], 'member', 'subscriptions');
localUtils.API.checkResponse(jsonResponse.meta.pagination, 'pagination');
});
@ -83,7 +83,7 @@ describe('Members API', function () {
jsonResponse.members.should.have.length(1);
jsonResponse.members[0].email.should.equal('member1@test.com');
localUtils.API.checkResponse(jsonResponse, 'members');
localUtils.API.checkResponse(jsonResponse.members[0], 'member', 'stripe');
localUtils.API.checkResponse(jsonResponse.members[0], 'member', 'subscriptions');
localUtils.API.checkResponse(jsonResponse.meta.pagination, 'pagination');
});
@ -103,7 +103,7 @@ describe('Members API', function () {
jsonResponse.members[0].email.should.equal('paid@test.com');
jsonResponse.members[1].email.should.equal('trialing@test.com');
localUtils.API.checkResponse(jsonResponse, 'members');
localUtils.API.checkResponse(jsonResponse.members[0], 'member', 'stripe');
localUtils.API.checkResponse(jsonResponse.members[0], 'member', 'subscriptions');
localUtils.API.checkResponse(jsonResponse.meta.pagination, 'pagination');
});
@ -120,7 +120,7 @@ describe('Members API', function () {
should.exist(jsonResponse);
should.exist(jsonResponse.members);
jsonResponse.members.should.have.length(1);
localUtils.API.checkResponse(jsonResponse.members[0], 'member', 'stripe');
localUtils.API.checkResponse(jsonResponse.members[0], 'member', 'subscriptions');
});
it('Can read and include email_recipients', async function () {
@ -136,7 +136,7 @@ describe('Members API', function () {
should.exist(jsonResponse);
should.exist(jsonResponse.members);
jsonResponse.members.should.have.length(1);
localUtils.API.checkResponse(jsonResponse.members[0], 'member', ['stripe', 'email_recipients']);
localUtils.API.checkResponse(jsonResponse.members[0], 'member', ['subscriptions', 'email_recipients']);
jsonResponse.members[0].email_recipients.length.should.equal(1);
localUtils.API.checkResponse(jsonResponse.members[0].email_recipients[0], 'email_recipient', ['email']);
localUtils.API.checkResponse(jsonResponse.members[0].email_recipients[0].email, 'email');
@ -235,7 +235,7 @@ describe('Members API', function () {
should.exist(jsonResponse2);
should.exist(jsonResponse2.members);
jsonResponse2.members.should.have.length(1);
localUtils.API.checkResponse(jsonResponse2.members[0], 'member', 'stripe');
localUtils.API.checkResponse(jsonResponse2.members[0], 'member', 'subscriptions');
jsonResponse2.members[0].name.should.equal(memberChanged.name);
jsonResponse2.members[0].email.should.equal(memberChanged.email);
jsonResponse2.members[0].email.should.not.equal(memberToChange.email);
@ -360,8 +360,8 @@ describe('Members API', function () {
importedMember1.labels.length.should.equal(1);
testUtils.API.isISO8601(importedMember1.created_at).should.be.true();
importedMember1.comped.should.equal(false);
importedMember1.stripe.should.not.be.undefined();
importedMember1.stripe.subscriptions.length.should.equal(0);
importedMember1.subscriptions.should.not.be.undefined();
importedMember1.subscriptions.length.should.equal(0);
const importedMember2 = jsonResponse2.members.find(m => m.email === 'test@example.com');
should.exist(importedMember2);
@ -372,8 +372,8 @@ describe('Members API', function () {
testUtils.API.isISO8601(importedMember2.created_at).should.be.true();
importedMember2.created_at.should.equal('1991-10-02T20:30:31.000Z');
importedMember2.comped.should.equal(false);
importedMember2.stripe.should.not.be.undefined();
importedMember2.stripe.subscriptions.length.should.equal(0);
importedMember2.subscriptions.should.not.be.undefined();
importedMember2.subscriptions.length.should.equal(0);
});
async function fetchStats() {

View File

@ -91,7 +91,7 @@ describe('Members API', function () {
jsonResponse.members.should.have.length(1);
jsonResponse.members[0].email.should.equal('member1@test.com');
localUtils.API.checkResponse(jsonResponse, 'members');
localUtils.API.checkResponse(jsonResponse.members[0], 'member', 'stripe');
localUtils.API.checkResponse(jsonResponse.members[0], 'member', 'subscriptions');
localUtils.API.checkResponse(jsonResponse.meta.pagination, 'pagination');
});
});
@ -111,7 +111,7 @@ describe('Members API', function () {
jsonResponse.members.should.have.length(1);
jsonResponse.members[0].email.should.equal('member2@test.com');
localUtils.API.checkResponse(jsonResponse, 'members');
localUtils.API.checkResponse(jsonResponse.members[0], 'member', 'stripe');
localUtils.API.checkResponse(jsonResponse.members[0], 'member', 'subscriptions');
localUtils.API.checkResponse(jsonResponse.meta.pagination, 'pagination');
});
});
@ -131,7 +131,7 @@ describe('Members API', function () {
jsonResponse.members.should.have.length(1);
jsonResponse.members[0].email.should.equal('paid@test.com');
localUtils.API.checkResponse(jsonResponse, 'members');
localUtils.API.checkResponse(jsonResponse.members[0], 'member', 'stripe');
localUtils.API.checkResponse(jsonResponse.members[0], 'member', 'subscriptions');
localUtils.API.checkResponse(jsonResponse.meta.pagination, 'pagination');
});
});
@ -234,7 +234,7 @@ describe('Members API', function () {
should.exist(jsonResponse);
should.exist(jsonResponse.members);
jsonResponse.members.should.have.length(1);
localUtils.API.checkResponse(jsonResponse.members[0], 'member', 'stripe');
localUtils.API.checkResponse(jsonResponse.members[0], 'member', 'subscriptions');
jsonResponse.members[0].name.should.equal(memberToChange.name);
jsonResponse.members[0].email.should.equal(memberToChange.email);
jsonResponse.members[0].comped.should.equal(memberToChange.comped);
@ -397,8 +397,8 @@ describe('Members API', function () {
should(importedMember1.note).equal(null);
importedMember1.subscribed.should.equal(true);
importedMember1.comped.should.equal(false);
importedMember1.stripe.should.not.be.undefined();
importedMember1.stripe.subscriptions.length.should.equal(0);
importedMember1.subscriptions.should.not.be.undefined();
importedMember1.subscriptions.length.should.equal(0);
// check label order
// 1 unique global + 1 record labels + 1 auto generated label
@ -464,8 +464,8 @@ describe('Members API', function () {
should(importedMember1.note).equal('no need to map me');
importedMember1.subscribed.should.equal(true);
importedMember1.comped.should.equal(false);
importedMember1.stripe.should.not.be.undefined();
importedMember1.stripe.subscriptions.length.should.equal(0);
importedMember1.subscriptions.should.not.be.undefined();
importedMember1.subscriptions.length.should.equal(0);
importedMember1.labels.length.should.equal(1); // auto-generated import label
});
});
@ -509,8 +509,8 @@ describe('Members API', function () {
should(defaultMember1.note).equal(null);
defaultMember1.subscribed.should.equal(true);
defaultMember1.comped.should.equal(false);
defaultMember1.stripe.should.not.be.undefined();
defaultMember1.stripe.subscriptions.length.should.equal(0);
defaultMember1.subscriptions.should.not.be.undefined();
defaultMember1.subscriptions.length.should.equal(0);
defaultMember1.labels.length.should.equal(1); // auto-generated import label
const defaultMember2 = jsonResponse.members.find(member => (member.email === 'member+defaults_2@example.com'));

View File

@ -104,11 +104,9 @@ describe('Members Service Middleware', function () {
// Fake token handling failure
membersService.ssr.exchangeTokenForSession.resolves({
stripe: {
subscriptions: [{
status: 'active'
}]
}
subscriptions: [{
status: 'active'
}]
});
// Call the middleware