mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-30 12:24:25 +02:00
Merge pull request #31678 from overleaf/rh-cio-subscription-status
Sync subscription type and features to customer.io GitOrigin-RevId: 4c23a6b4ec9f103e73b26203b0d43f177e56bb6e
This commit is contained in:
@@ -15,6 +15,7 @@ import UserGetter from '../User/UserGetter.mjs'
|
||||
import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'
|
||||
import Queues from '../../infrastructure/Queues.mjs'
|
||||
import Modules from '../../infrastructure/Modules.mjs'
|
||||
import SubscriptionViewModelBuilder from './SubscriptionViewModelBuilder.mjs'
|
||||
import { AI_ADD_ON_CODE } from './AiHelper.mjs'
|
||||
import { fetchNothing } from '@overleaf/fetch-utils'
|
||||
|
||||
@@ -54,6 +55,20 @@ async function refreshFeatures(userId, reason) {
|
||||
|
||||
const { features: newFeatures, featuresChanged } =
|
||||
await UserFeaturesUpdater.promises.updateFeatures(userId, features)
|
||||
|
||||
// TODO: this call is quite expensive, so ideally we'd update cio with something
|
||||
// that doesn't require the best subscription to be computed, ie. the plan code (or type)
|
||||
const bestSubscriptionType = await _getBestSubscriptionType(userId)
|
||||
|
||||
Modules.promises.hooks
|
||||
.fire('setUserProperties', userId, {
|
||||
features,
|
||||
'best-subscription-type': bestSubscriptionType,
|
||||
})
|
||||
.catch(err => {
|
||||
logger.error({ err, userId }, 'Failed to sync features to customer.io')
|
||||
})
|
||||
|
||||
if (oldFeatures.dropbox === true && features.dropbox === false) {
|
||||
logger.debug({ userId }, '[FeaturesUpdater] must unlink dropbox')
|
||||
try {
|
||||
@@ -101,6 +116,22 @@ async function refreshFeatures(userId, reason) {
|
||||
return { features: newFeatures, featuresChanged }
|
||||
}
|
||||
|
||||
async function _getBestSubscriptionType(userId) {
|
||||
try {
|
||||
const { bestSubscription } =
|
||||
await SubscriptionViewModelBuilder.promises.getUsersSubscriptionDetails({
|
||||
_id: userId,
|
||||
})
|
||||
return bestSubscription?.type || 'free'
|
||||
} catch (err) {
|
||||
logger.warn(
|
||||
{ err, userId },
|
||||
'Failed to calculate best-subscription-type for customer.io'
|
||||
)
|
||||
return 'free'
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the features that the given user should have.
|
||||
*/
|
||||
|
||||
@@ -113,6 +113,13 @@ describe('FeaturesUpdater', function () {
|
||||
ctx.Modules = {
|
||||
promises: { hooks: { fire: sinon.stub().resolves() } },
|
||||
}
|
||||
ctx.SubscriptionViewModelBuilder = {
|
||||
promises: {
|
||||
getUsersSubscriptionDetails: sinon.stub().resolves({
|
||||
bestSubscription: { type: 'individual' },
|
||||
}),
|
||||
},
|
||||
}
|
||||
ctx.Queues = {
|
||||
getQueue: sinon.stub().returns({
|
||||
add: sinon.stub().resolves(),
|
||||
@@ -170,6 +177,13 @@ describe('FeaturesUpdater', function () {
|
||||
default: ctx.Modules,
|
||||
}))
|
||||
|
||||
vi.doMock(
|
||||
'../../../../app/src/Features/Subscription/SubscriptionViewModelBuilder',
|
||||
() => ({
|
||||
default: ctx.SubscriptionViewModelBuilder,
|
||||
})
|
||||
)
|
||||
|
||||
vi.doMock('../../../../app/src/infrastructure/Queues', () => ({
|
||||
default: ctx.Queues,
|
||||
}))
|
||||
@@ -374,6 +388,17 @@ describe('FeaturesUpdater', function () {
|
||||
ctx.AnalyticsManager.setUserPropertyForUserInBackground
|
||||
).to.have.been.calledWith(ctx.user._id, 'feature-set', 'all')
|
||||
})
|
||||
|
||||
it('should sync features to customer.io', function (ctx) {
|
||||
expect(ctx.Modules.promises.hooks.fire).to.have.been.calledWith(
|
||||
'setUserProperties',
|
||||
ctx.user._id,
|
||||
{
|
||||
features: ctx.Settings.features.all,
|
||||
'best-subscription-type': 'individual',
|
||||
}
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with a non-standard feature set', async function () {
|
||||
|
||||
Reference in New Issue
Block a user