diff --git a/core/server/data/schema/commands.js b/core/server/data/schema/commands.js index 5bedd2089a..aeb229ce61 100644 --- a/core/server/data/schema/commands.js +++ b/core/server/data/schema/commands.js @@ -40,6 +40,9 @@ function addTableColumn(tableName, table, columnName, columnSpec = schema[tableN // check if table exists? column.references(columnSpec.references); } + if (Object.prototype.hasOwnProperty.call(columnSpec, 'cascadeDelete') && columnSpec.cascadeDelete === true) { + column.onDelete('CASCADE'); + } if (Object.prototype.hasOwnProperty.call(columnSpec, 'defaultTo')) { column.defaultTo(columnSpec.defaultTo); } diff --git a/core/server/data/schema/schema.js b/core/server/data/schema/schema.js index e83a0a3d53..072cbf362c 100644 --- a/core/server/data/schema/schema.js +++ b/core/server/data/schema/schema.js @@ -387,15 +387,14 @@ module.exports = { }, members_labels: { id: {type: 'string', maxlength: 24, nullable: false, primary: true}, - member_id: {type: 'string', maxlength: 24, nullable: false, references: 'members.id'}, - label_id: {type: 'string', maxlength: 24, nullable: false, references: 'labels.id'}, + member_id: {type: 'string', maxlength: 24, nullable: false, references: 'members.id', cascadeDelete: true}, + label_id: {type: 'string', maxlength: 24, nullable: false, references: 'labels.id', cascadeDelete: true}, sort_order: {type: 'integer', nullable: false, unsigned: true, defaultTo: 0} }, members_stripe_customers: { id: {type: 'string', maxlength: 24, nullable: false, primary: true}, - member_id: {type: 'string', maxlength: 24, nullable: false, unique: false}, - // customer_id is unique: false because mysql with innodb utf8mb4 cannot have unqiue columns larger than 191 chars - customer_id: {type: 'string', maxlength: 255, nullable: false, unique: false}, + member_id: {type: 'string', maxlength: 24, nullable: false, unique: false, references: 'members.id', cascadeDelete: true}, + customer_id: {type: 'string', maxlength: 255, nullable: false, unique: true}, name: {type: 'string', maxlength: 191, nullable: true}, email: {type: 'string', maxlength: 191, nullable: true}, created_at: {type: 'dateTime', nullable: false}, @@ -405,8 +404,8 @@ module.exports = { }, members_stripe_customers_subscriptions: { id: {type: 'string', maxlength: 24, nullable: false, primary: true}, - customer_id: {type: 'string', maxlength: 255, nullable: false, unique: false}, - subscription_id: {type: 'string', maxlength: 255, nullable: false, unique: false}, + customer_id: {type: 'string', maxlength: 255, nullable: false, unique: false, references: 'members_stripe_customers.customer_id', cascadeDelete: true}, + subscription_id: {type: 'string', maxlength: 255, nullable: false, unique: true}, plan_id: {type: 'string', maxlength: 255, nullable: false, unique: false}, status: {type: 'string', maxlength: 50, nullable: false}, cancel_at_period_end: {type: 'bool', nullable: false, defaultTo: false}, diff --git a/test/regression/models/model_member_stripe_customer_spec.js b/test/regression/models/model_member_stripe_customer_spec.js index c2e9619130..41e0b4dc82 100644 --- a/test/regression/models/model_member_stripe_customer_spec.js +++ b/test/regression/models/model_member_stripe_customer_spec.js @@ -15,8 +15,13 @@ describe('MemberStripeCustomer Model', function run() { // For some reason the initial .add of MemberStripeCustomer is **not** adding a StripeCustomerSubscription :( it.skip('Is correctly mapped to the stripe subscriptions', async function () { const context = testUtils.context.admin; + + const member = await Member.add({ + email: 'test@test.test' + }); + await MemberStripeCustomer.add({ - member_id: 'fake_member_id', + member_id: member.get('id'), customer_id: 'fake_customer_id', subscriptions: [{ subscription_id: 'fake_subscription_id1', @@ -72,13 +77,12 @@ describe('MemberStripeCustomer Model', function run() { describe('member', function () { it('Is correctly mapped to the member', async function () { const context = testUtils.context.admin; - await Member.add({ - id: 'fake_member_id', + const member = await Member.add({ email: 'test@test.member' }, context); await MemberStripeCustomer.add({ - member_id: 'fake_member_id', + member_id: member.get('id'), customer_id: 'fake_customer_id' }, context); @@ -88,25 +92,29 @@ describe('MemberStripeCustomer Model', function run() { withRelated: ['member'] })); - const member = customer.related('member'); + const memberFromRelation = customer.related('member'); - should.exist(member, 'MemberStripeCustomer should have been fetched with member'); + should.exist(memberFromRelation, 'MemberStripeCustomer should have been fetched with member'); - should.equal(member.get('id'), 'fake_member_id'); - should.equal(member.get('email'), 'test@test.member'); + should.equal(memberFromRelation.get('id'), member.get('id')); + should.equal(memberFromRelation.get('email'), 'test@test.member'); }); }); describe('destroy', function () { it('Cascades to members_stripe_customers_subscriptions', async function () { const context = testUtils.context.admin; + const member = await Member.add({ + email: 'test@test.member' + }, context); + await MemberStripeCustomer.add({ - member_id: 'fake_member_id', + member_id: member.get('id'), customer_id: 'fake_customer_id' }, context); const customer = await MemberStripeCustomer.findOne({ - member_id: 'fake_member_id' + customer_id: 'fake_customer_id' }, context); should.exist(customer, 'Customer should have been created'); @@ -136,12 +144,12 @@ describe('MemberStripeCustomer Model', function run() { }, context)); const customerAfterDestroy = await MemberStripeCustomer.findOne({ - member_id: 'fake_member_id' + customer_id: 'fake_customer_id' }); should.not.exist(customerAfterDestroy, 'MemberStripeCustomer should have been destroyed'); const subscriptionAfterDestroy = await StripeCustomerSubscription.findOne({ - customer_id: customer.get('customer_id') + customer_id: 'fake_customer_id' }); should.not.exist(subscriptionAfterDestroy, 'StripeCustomerSubscription should have been destroyed'); }); diff --git a/test/regression/models/model_stripe_customer_subscription_spec.js b/test/regression/models/model_stripe_customer_subscription_spec.js index dd6ccdb6e5..cf562085f9 100644 --- a/test/regression/models/model_stripe_customer_subscription_spec.js +++ b/test/regression/models/model_stripe_customer_subscription_spec.js @@ -1,4 +1,5 @@ const should = require('should'); +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'); @@ -12,8 +13,11 @@ describe('StripeCustomerSubscription Model', function run() { describe('customer', function () { it('Is correctly mapped to the stripe customer', async function () { const context = testUtils.context.admin; + const member = await Member.add({ + email: 'test@test.member' + }, context); await MemberStripeCustomer.add({ - member_id: 'fake_member_id', + member_id: member.get('id'), customer_id: 'fake_customer_id' }, context); diff --git a/test/unit/data/schema/integrity_spec.js b/test/unit/data/schema/integrity_spec.js index 535ce958dc..253c674de0 100644 --- a/test/unit/data/schema/integrity_spec.js +++ b/test/unit/data/schema/integrity_spec.js @@ -21,7 +21,7 @@ const defaultSettings = require('../../../../core/server/data/schema/default-set */ describe('DB version integrity', function () { // Only these variables should need updating - const currentSchemaHash = '134c9de4e59b31ec6b73f03638a01396'; + const currentSchemaHash = '42a966364eb4b5851e807133374821da'; const currentFixturesHash = '3d942c46e8487c4aee1e9ac898ed29ca'; const currentSettingsHash = 'a4ac78d3810175428b4833645231d6d5';