mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-23 17:19:37 +02:00
Merge pull request #29982 from overleaf/ls-group-ownership-transfer
Stripe subscription ownership transfer GitOrigin-RevId: 8285f635ecc220595782fbea6def74fdc9a92f36
This commit is contained in:
@@ -21,6 +21,7 @@ import Modules from '../../infrastructure/Modules.mjs'
|
||||
* @typedef {import('../../../../types/subscription/dashboard/subscription').PaymentProvider} PaymentProvider
|
||||
* @typedef {import('../../../../types/group-management/group-audit-log').GroupAuditLog} GroupAuditLog
|
||||
* @import { AddOn } from '../../../../types/subscription/plan'
|
||||
* @typedef {InstanceType<Subscription>} MongoSubscription
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -528,6 +529,38 @@ async function setRestorePoint(subscriptionId, planCode, addOns, consumed) {
|
||||
await Subscription.updateOne({ _id: subscriptionId }, update).exec()
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the ownershiop of the given subscription.
|
||||
* @param {MongoSubscription} subscription
|
||||
* @param {string} adminId
|
||||
* @param {boolean} clearPreviousPaymentProvider whether to clear the previousPaymentProvider field or set it to the current paymentProvider
|
||||
*/
|
||||
async function transferSubscriptionOwnership(
|
||||
subscription,
|
||||
adminId,
|
||||
clearPreviousPaymentProvider
|
||||
) {
|
||||
const query = {
|
||||
_id: new ObjectId(subscription._id),
|
||||
}
|
||||
|
||||
const update = {
|
||||
$set: { admin_id: new ObjectId(adminId) },
|
||||
}
|
||||
if (subscription.groupPlan) {
|
||||
update.$addToSet = { manager_ids: new ObjectId(adminId) }
|
||||
} else {
|
||||
update.$set.manager_ids = [new ObjectId(adminId)]
|
||||
}
|
||||
|
||||
if (clearPreviousPaymentProvider) {
|
||||
update.$unset = { previousPaymentProvider: 1 }
|
||||
} else {
|
||||
update.$set.previousPaymentProvider = subscription.paymentProvider
|
||||
}
|
||||
await Subscription.updateOne(query, update).exec()
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the restore point for a given subscription, and signals that the subscription was sucessfully reverted.
|
||||
*
|
||||
@@ -588,5 +621,6 @@ export default {
|
||||
setSubscriptionWasReverted,
|
||||
voidRestorePoint,
|
||||
handleExpiredSubscription,
|
||||
transferSubscriptionOwnership,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -4,6 +4,30 @@ import { TeamInviteSchema } from './TeamInvite.mjs'
|
||||
const { Schema } = mongoose
|
||||
const { ObjectId } = Schema
|
||||
|
||||
const PaymentProvider = {
|
||||
service: {
|
||||
type: String,
|
||||
},
|
||||
subscriptionId: {
|
||||
type: String,
|
||||
},
|
||||
state: {
|
||||
type: String,
|
||||
},
|
||||
pausePeriodStart: {
|
||||
type: Date,
|
||||
},
|
||||
pausePeriodEnd: {
|
||||
type: Date,
|
||||
},
|
||||
trialStartedAt: {
|
||||
type: Date,
|
||||
},
|
||||
trialEndsAt: {
|
||||
type: Date,
|
||||
},
|
||||
}
|
||||
|
||||
export const SubscriptionSchema = new Schema(
|
||||
{
|
||||
admin_id: {
|
||||
@@ -68,29 +92,8 @@ export const SubscriptionSchema = new Schema(
|
||||
type: Date,
|
||||
},
|
||||
},
|
||||
paymentProvider: {
|
||||
service: {
|
||||
type: String,
|
||||
},
|
||||
subscriptionId: {
|
||||
type: String,
|
||||
},
|
||||
state: {
|
||||
type: String,
|
||||
},
|
||||
pausePeriodStart: {
|
||||
type: Date,
|
||||
},
|
||||
pausePeriodEnd: {
|
||||
type: Date,
|
||||
},
|
||||
trialStartedAt: {
|
||||
type: Date,
|
||||
},
|
||||
trialEndsAt: {
|
||||
type: Date,
|
||||
},
|
||||
},
|
||||
paymentProvider: PaymentProvider,
|
||||
previousPaymentProvider: PaymentProvider,
|
||||
collectionMethod: {
|
||||
type: String,
|
||||
enum: ['automatic', 'manual'],
|
||||
|
||||
@@ -303,6 +303,81 @@ describe('SubscriptionUpdater', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('transferSubscriptionOwnership', function () {
|
||||
it('should transfer the subscription ownership for group subscriptions', async function (ctx) {
|
||||
ctx.subscription.groupPlan = true
|
||||
ctx.subscription.paymentProvider = {
|
||||
id: 'stripe-123',
|
||||
name: 'stripe-us',
|
||||
}
|
||||
await ctx.SubscriptionUpdater.promises.transferSubscriptionOwnership(
|
||||
ctx.subscription,
|
||||
ctx.otherUserId,
|
||||
false
|
||||
)
|
||||
const query = {
|
||||
_id: new ObjectId(ctx.subscription._id),
|
||||
}
|
||||
const update = {
|
||||
$set: {
|
||||
admin_id: new ObjectId(ctx.otherUserId),
|
||||
previousPaymentProvider: ctx.subscription.paymentProvider,
|
||||
},
|
||||
$addToSet: { manager_ids: new ObjectId(ctx.otherUserId) },
|
||||
}
|
||||
ctx.SubscriptionModel.updateOne.should.have.been.calledOnce
|
||||
ctx.SubscriptionModel.updateOne.should.have.been.calledWith(query, update)
|
||||
})
|
||||
|
||||
it('should transfer the subscription ownership for non-group subscriptions', async function (ctx) {
|
||||
ctx.subscription.paymentProvider = {
|
||||
id: 'stripe-123',
|
||||
name: 'stripe-us',
|
||||
}
|
||||
await ctx.SubscriptionUpdater.promises.transferSubscriptionOwnership(
|
||||
ctx.subscription,
|
||||
ctx.otherUserId,
|
||||
false
|
||||
)
|
||||
const query = {
|
||||
_id: new ObjectId(ctx.subscription._id),
|
||||
}
|
||||
const update = {
|
||||
$set: {
|
||||
admin_id: new ObjectId(ctx.otherUserId),
|
||||
manager_ids: [new ObjectId(ctx.otherUserId)],
|
||||
previousPaymentProvider: ctx.subscription.paymentProvider,
|
||||
},
|
||||
}
|
||||
ctx.SubscriptionModel.updateOne.should.have.been.calledOnce
|
||||
ctx.SubscriptionModel.updateOne.should.have.been.calledWith(query, update)
|
||||
})
|
||||
|
||||
it('should clear previousPaymentProvider when clearPreviousPaymentProvider is true', async function (ctx) {
|
||||
ctx.subscription.paymentProvider = {
|
||||
id: 'stripe-123',
|
||||
name: 'stripe-us',
|
||||
}
|
||||
await ctx.SubscriptionUpdater.promises.transferSubscriptionOwnership(
|
||||
ctx.subscription,
|
||||
ctx.otherUserId,
|
||||
true
|
||||
)
|
||||
const query = {
|
||||
_id: new ObjectId(ctx.subscription._id),
|
||||
}
|
||||
const update = {
|
||||
$set: {
|
||||
admin_id: new ObjectId(ctx.otherUserId),
|
||||
manager_ids: [new ObjectId(ctx.otherUserId)],
|
||||
},
|
||||
$unset: { previousPaymentProvider: 1 },
|
||||
}
|
||||
ctx.SubscriptionModel.updateOne.should.have.been.calledOnce
|
||||
ctx.SubscriptionModel.updateOne.should.have.been.calledWith(query, update)
|
||||
})
|
||||
})
|
||||
|
||||
describe('syncSubscription', function () {
|
||||
beforeEach(function (ctx) {
|
||||
ctx.SubscriptionLocator.promises.getUsersSubscription.resolves(
|
||||
|
||||
Reference in New Issue
Block a user