From aa9b07d323d95bbe38f18524952cf269e839520b Mon Sep 17 00:00:00 2001 From: Thomas Date: Thu, 26 Jan 2023 12:42:34 +0100 Subject: [PATCH] Merge pull request #11445 from overleaf/revert-11432-revert-11154-tm-lg-subscription-recurly-cache-name Re-instate change property name for recurly status cache to recurlyStatus GitOrigin-RevId: 3b3415d818629676ee44dbc558a6b87469fd1af0 --- .../Subscription/SubscriptionUpdater.js | 2 +- .../SubscriptionViewModelBuilder.js | 5 +- services/web/app/src/models/Subscription.js | 2 +- ...0110140452_rename_recurly_cached_status.js | 53 +++++++++++++++++++ .../SubscriptionViewModelBuilderTests.js | 8 +-- 5 files changed, 62 insertions(+), 8 deletions(-) create mode 100644 services/web/migrations/20230110140452_rename_recurly_cached_status.js diff --git a/services/web/app/src/Features/Subscription/SubscriptionUpdater.js b/services/web/app/src/Features/Subscription/SubscriptionUpdater.js index 65d9bf7417..5c3e4c3ae2 100644 --- a/services/web/app/src/Features/Subscription/SubscriptionUpdater.js +++ b/services/web/app/src/Features/Subscription/SubscriptionUpdater.js @@ -249,7 +249,7 @@ async function updateSubscriptionFromRecurly( subscription.recurlySubscription_id = recurlySubscription.uuid subscription.planCode = updatedPlanCode - subscription.recurly = { + subscription.recurlyStatus = { state: recurlySubscription.state, trialStartedAt: recurlySubscription.trial_started_at, trialEndsAt: recurlySubscription.trial_ends_at, diff --git a/services/web/app/src/Features/Subscription/SubscriptionViewModelBuilder.js b/services/web/app/src/Features/Subscription/SubscriptionViewModelBuilder.js index 84cd2e9985..7830517f81 100644 --- a/services/web/app/src/Features/Subscription/SubscriptionViewModelBuilder.js +++ b/services/web/app/src/Features/Subscription/SubscriptionViewModelBuilder.js @@ -193,6 +193,7 @@ function buildUsersSubscriptionViewModel(user, callback) { // Subscription DB object contains a recurly property, used to cache trial info // on the project-list. However, this can cause the wrong template to render, // if we do not have any subscription data from Recurly (recurlySubscription) + // TODO: Delete this workaround once recurly cache property name migration rolled out. if (personalSubscription) { delete personalSubscription.recurly } @@ -354,7 +355,7 @@ async function getBestSubscription(user) { individualSubscription && !individualSubscription.customAccount && individualSubscription.recurlySubscription_id && - !individualSubscription.recurly?.state + !individualSubscription.recurlyStatus?.state ) { const recurlySubscription = await RecurlyWrapper.promises.getSubscription( individualSubscription.recurlySubscription_id, @@ -480,7 +481,7 @@ function _isPlanEqualOrBetter(planA, planB) { function _getRemainingTrialDays(subscription) { const now = new Date() - const trialEndDate = subscription.recurly?.trialEndsAt + const trialEndDate = subscription.recurlyStatus?.trialEndsAt return trialEndDate && trialEndDate > now ? Math.ceil( (trialEndDate.getTime() - now.getTime()) / (24 * 60 * 60 * 1000) diff --git a/services/web/app/src/models/Subscription.js b/services/web/app/src/models/Subscription.js index a557d61873..a525c5d938 100644 --- a/services/web/app/src/models/Subscription.js +++ b/services/web/app/src/models/Subscription.js @@ -38,7 +38,7 @@ const SubscriptionSchema = new Schema({ }, }, }, - recurly: { + recurlyStatus: { state: { type: String, }, diff --git a/services/web/migrations/20230110140452_rename_recurly_cached_status.js b/services/web/migrations/20230110140452_rename_recurly_cached_status.js new file mode 100644 index 0000000000..81e90457ae --- /dev/null +++ b/services/web/migrations/20230110140452_rename_recurly_cached_status.js @@ -0,0 +1,53 @@ +/* eslint-disable no-unused-vars */ + +const Helpers = require('./lib/helpers') + +exports.tags = ['saas'] + +exports.migrate = async client => { + const { db } = client + // 'recurly' -> 'recurlyStatus' + await db.subscriptions.updateMany( + { + $and: [ + { recurlyStatus: { $exists: false } }, + { recurly: { $exists: true } }, + ], + }, + { $rename: { recurly: 'recurlyStatus' } } + ) + // some records may have already recached the recurly status, discard old cache + await db.subscriptions.updateMany( + { + $and: [ + { recurlyStatus: { $exists: true } }, + { recurly: { $exists: true } }, + ], + }, + { $unset: { recurly: 1 } } + ) +} + +exports.rollback = async client => { + const { db } = client + // 'recurlyStatus' -> 'recurly' + await db.subscriptions.updateMany( + { + $and: [ + { recurly: { $exists: false } }, + { recurlyStatus: { $exists: true } }, + ], + }, + { $rename: { recurlyStatus: 'recurly' } } + ) + // some records may have already recached the recurly status, discard old cache + await db.subscriptions.updateMany( + { + $and: [ + { recurlyStatus: { $exists: true } }, + { recurly: { $exists: true } }, + ], + }, + { $unset: { recurlyStatus: 1 } } + ) +} diff --git a/services/web/test/unit/src/Subscription/SubscriptionViewModelBuilderTests.js b/services/web/test/unit/src/Subscription/SubscriptionViewModelBuilderTests.js index 0d9fd82d1e..65f019d61c 100644 --- a/services/web/test/unit/src/Subscription/SubscriptionViewModelBuilderTests.js +++ b/services/web/test/unit/src/Subscription/SubscriptionViewModelBuilderTests.js @@ -22,7 +22,7 @@ describe('SubscriptionViewModelBuilder', function () { planCode: this.planCode, plan: this.plan, recurlySubscription_id: this.recurlySubscription_id, - recurly: { + recurlyStatus: { state: 'active', }, } @@ -46,7 +46,7 @@ describe('SubscriptionViewModelBuilder', function () { this.groupSubscription = { planCode: this.groupPlanCode, plan: this.plan, - recurly: { + recurlyStatus: { state: 'active', }, } @@ -168,7 +168,7 @@ describe('SubscriptionViewModelBuilder', function () { it('should return a individual subscription with remaining free trial days', async function () { const threeDaysLater = new Date() threeDaysLater.setDate(threeDaysLater.getDate() + 3) - this.individualSubscription.recurly.trialEndsAt = threeDaysLater + this.individualSubscription.recurlyStatus.trialEndsAt = threeDaysLater this.SubscriptionLocator.promises.getUsersSubscription .withArgs(this.user) .resolves(this.individualSubscription) @@ -189,7 +189,7 @@ describe('SubscriptionViewModelBuilder', function () { it('should return a individual subscription with free trial on last day', async function () { const threeHoursLater = new Date() threeHoursLater.setTime(threeHoursLater.getTime() + 3 * 60 * 60 * 1000) - this.individualSubscription.recurly.trialEndsAt = threeHoursLater + this.individualSubscription.recurlyStatus.trialEndsAt = threeHoursLater this.SubscriptionLocator.promises.getUsersSubscription .withArgs(this.user) .resolves(this.individualSubscription)