Merge pull request #32871 from overleaf/rh-cio-comms-attributes
Expose remaining marketing properties to customer.io GitOrigin-RevId: 6956e1faf90ecc650108404fe13b2f6de2eb4d0c
This commit is contained in:
@@ -449,10 +449,200 @@ describe('FeaturesUpdater', function () {
|
||||
ai_plan: 'none',
|
||||
next_renewal_date: Math.floor(ctx.renewalDate.getTime() / 1000),
|
||||
expiry_date: '',
|
||||
group: false,
|
||||
commons: false,
|
||||
individual_subscription: true,
|
||||
payment_provider: 'recurly',
|
||||
features: sinon.match.object,
|
||||
})
|
||||
)
|
||||
})
|
||||
|
||||
it('should not set trial_end_date when no trial is active', function (ctx) {
|
||||
const call = ctx.Modules.promises.hooks.fire
|
||||
.getCalls()
|
||||
.find(c => c.args[0] === 'setUserProperties')
|
||||
expect(call).to.exist
|
||||
expect(call.args[2]).to.not.have.property('trial_end_date')
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the individual subscription is on a trial', function () {
|
||||
beforeEach(async function (ctx) {
|
||||
ctx.trialEndsAt = new Date('2099-05-01T00:00:00Z')
|
||||
const trialingSubscription = {
|
||||
...ctx.subscriptions.individual,
|
||||
recurlyStatus: {
|
||||
state: 'active',
|
||||
trialEndsAt: ctx.trialEndsAt,
|
||||
},
|
||||
}
|
||||
ctx.SubscriptionViewModelBuilder.promises.getUsersSubscriptionDetails.resolves(
|
||||
{
|
||||
bestSubscription: { type: 'individual' },
|
||||
individualSubscription: trialingSubscription,
|
||||
memberGroupSubscriptions: [],
|
||||
managedGroupSubscriptions: [],
|
||||
}
|
||||
)
|
||||
ctx.Modules.promises.hooks.fire
|
||||
.withArgs('getPaymentFromRecordPromise', trialingSubscription)
|
||||
.resolves([
|
||||
{
|
||||
subscription: {
|
||||
state: 'active',
|
||||
periodEnd: ctx.renewalDate,
|
||||
},
|
||||
},
|
||||
])
|
||||
await ctx.FeaturesUpdater.promises.refreshFeatures(ctx.user._id, 'test')
|
||||
})
|
||||
|
||||
it('should sync trial_end_date to customer.io', function (ctx) {
|
||||
expect(ctx.Modules.promises.hooks.fire).to.have.been.calledWith(
|
||||
'setUserProperties',
|
||||
ctx.user._id,
|
||||
sinon.match({
|
||||
trial_end_date: Math.floor(ctx.trialEndsAt.getTime() / 1000),
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the individual subscription uses stripe', function () {
|
||||
beforeEach(async function (ctx) {
|
||||
const stripeSubscription = {
|
||||
...ctx.subscriptions.individual,
|
||||
paymentProvider: { service: 'stripe-us', state: 'active' },
|
||||
}
|
||||
ctx.SubscriptionViewModelBuilder.promises.getUsersSubscriptionDetails.resolves(
|
||||
{
|
||||
bestSubscription: { type: 'individual' },
|
||||
individualSubscription: stripeSubscription,
|
||||
memberGroupSubscriptions: [],
|
||||
managedGroupSubscriptions: [],
|
||||
}
|
||||
)
|
||||
ctx.Modules.promises.hooks.fire
|
||||
.withArgs('getPaymentFromRecordPromise', stripeSubscription)
|
||||
.resolves([
|
||||
{
|
||||
subscription: {
|
||||
state: 'active',
|
||||
periodEnd: ctx.renewalDate,
|
||||
},
|
||||
},
|
||||
])
|
||||
await ctx.FeaturesUpdater.promises.refreshFeatures(ctx.user._id, 'test')
|
||||
})
|
||||
|
||||
it('should report stripe as the payment_provider', function (ctx) {
|
||||
expect(ctx.Modules.promises.hooks.fire).to.have.been.calledWith(
|
||||
'setUserProperties',
|
||||
ctx.user._id,
|
||||
sinon.match({
|
||||
payment_provider: 'stripe',
|
||||
individual_subscription: true,
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the user has a commons institution licence', function () {
|
||||
beforeEach(async function (ctx) {
|
||||
ctx.SubscriptionViewModelBuilder.promises.getUsersSubscriptionDetails.resolves(
|
||||
{
|
||||
bestSubscription: { type: 'commons' },
|
||||
individualSubscription: null,
|
||||
memberGroupSubscriptions: [],
|
||||
managedGroupSubscriptions: [],
|
||||
currentInstitutionsWithLicence: [{ id: 1, name: 'Uni' }],
|
||||
}
|
||||
)
|
||||
await ctx.FeaturesUpdater.promises.refreshFeatures(ctx.user._id, 'test')
|
||||
})
|
||||
|
||||
it('should sync commons=true to customer.io', function (ctx) {
|
||||
expect(ctx.Modules.promises.hooks.fire).to.have.been.calledWith(
|
||||
'setUserProperties',
|
||||
ctx.user._id,
|
||||
sinon.match({
|
||||
commons: true,
|
||||
group: false,
|
||||
individual_subscription: false,
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the user has commons and an individual AI add-on', function () {
|
||||
beforeEach(async function (ctx) {
|
||||
ctx.SubscriptionViewModelBuilder.promises.getUsersSubscriptionDetails.resolves(
|
||||
{
|
||||
bestSubscription: {
|
||||
type: 'individual',
|
||||
plan: { planCode: 'individual-plan' },
|
||||
},
|
||||
individualSubscription: ctx.subscriptions.individual,
|
||||
memberGroupSubscriptions: [],
|
||||
managedGroupSubscriptions: [],
|
||||
currentInstitutionsWithLicence: [{ id: 1, name: 'Uni' }],
|
||||
}
|
||||
)
|
||||
ctx.Modules.promises.hooks.fire
|
||||
.withArgs('getPaymentFromRecordPromise', ctx.subscriptions.individual)
|
||||
.resolves([
|
||||
{
|
||||
subscription: {
|
||||
state: 'active',
|
||||
periodEnd: ctx.renewalDate,
|
||||
addOns: [{ code: AI_ADD_ON_CODE }],
|
||||
},
|
||||
},
|
||||
])
|
||||
await ctx.FeaturesUpdater.promises.refreshFeatures(ctx.user._id, 'test')
|
||||
})
|
||||
|
||||
it('should set commons, individual_subscription, and ai-assist-add-on together', function (ctx) {
|
||||
expect(ctx.Modules.promises.hooks.fire).to.have.been.calledWith(
|
||||
'setUserProperties',
|
||||
ctx.user._id,
|
||||
sinon.match({
|
||||
commons: true,
|
||||
individual_subscription: true,
|
||||
group: false,
|
||||
ai_plan: 'ai-assist-add-on',
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the user has no subscription', function () {
|
||||
beforeEach(async function (ctx) {
|
||||
ctx.SubscriptionViewModelBuilder.promises.getUsersSubscriptionDetails.resolves(
|
||||
{
|
||||
bestSubscription: null,
|
||||
individualSubscription: null,
|
||||
memberGroupSubscriptions: [],
|
||||
managedGroupSubscriptions: [],
|
||||
}
|
||||
)
|
||||
await ctx.FeaturesUpdater.promises.refreshFeatures(ctx.user._id, 'test')
|
||||
})
|
||||
|
||||
it('should sync false subscription flags and no payment_provider', function (ctx) {
|
||||
const call = ctx.Modules.promises.hooks.fire
|
||||
.getCalls()
|
||||
.find(c => c.args[0] === 'setUserProperties')
|
||||
expect(call).to.exist
|
||||
expect(call.args[2]).to.include({
|
||||
group: false,
|
||||
commons: false,
|
||||
individual_subscription: false,
|
||||
})
|
||||
expect(call.args[2]).to.not.have.property('payment_provider')
|
||||
expect(call.args[2]).to.not.have.property('trial_end_date')
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the individual subscription has a pending cancellation', function () {
|
||||
@@ -544,6 +734,10 @@ describe('FeaturesUpdater', function () {
|
||||
group_size: 8,
|
||||
next_renewal_date: '',
|
||||
expiry_date: '',
|
||||
group: true,
|
||||
commons: false,
|
||||
individual_subscription: false,
|
||||
payment_provider: 'recurly',
|
||||
features: sinon.match.object,
|
||||
overleaf_id: ctx.user._id,
|
||||
})
|
||||
@@ -551,6 +745,49 @@ describe('FeaturesUpdater', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the user is in a stripe group subscription', function () {
|
||||
beforeEach(async function (ctx) {
|
||||
ctx.SubscriptionViewModelBuilder.promises.getUsersSubscriptionDetails.resolves(
|
||||
{
|
||||
bestSubscription: {
|
||||
type: 'group',
|
||||
plan: {
|
||||
planCode: 'group-plan-1',
|
||||
groupPlan: true,
|
||||
membersLimit: 5,
|
||||
},
|
||||
subscription: {
|
||||
teamName: 'Team Alpha',
|
||||
},
|
||||
},
|
||||
memberGroupSubscriptions: [
|
||||
{
|
||||
planCode: 'group-plan-1',
|
||||
teamName: 'Team Alpha',
|
||||
membersLimit: 8,
|
||||
paymentProvider: { service: 'stripe-uk' },
|
||||
},
|
||||
],
|
||||
managedGroupSubscriptions: [],
|
||||
individualSubscription: null,
|
||||
}
|
||||
)
|
||||
await ctx.FeaturesUpdater.promises.refreshFeatures(ctx.user._id, 'test')
|
||||
})
|
||||
|
||||
it('should derive payment_provider from the group subscription', function (ctx) {
|
||||
expect(ctx.Modules.promises.hooks.fire).to.have.been.calledWith(
|
||||
'setUserProperties',
|
||||
ctx.user._id,
|
||||
sinon.match({
|
||||
payment_provider: 'stripe',
|
||||
group: true,
|
||||
individual_subscription: false,
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with a non-standard feature set', async function () {
|
||||
beforeEach(async function (ctx) {
|
||||
ctx.SubscriptionLocator.promises.getGroupSubscriptionsMemberOf
|
||||
|
||||
Reference in New Issue
Block a user