mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #4200 from overleaf/ab-feature-set-user-property
Resolve and send feature set user property to analytics GitOrigin-RevId: 08ddd0fe9202b02f7d37547dab1d078bf441a8cf
This commit is contained in:
parent
255761b31b
commit
9f1784b4c4
2 changed files with 86 additions and 9 deletions
|
@ -10,6 +10,7 @@ const ReferalFeatures = require('../Referal/ReferalFeatures')
|
||||||
const V1SubscriptionManager = require('./V1SubscriptionManager')
|
const V1SubscriptionManager = require('./V1SubscriptionManager')
|
||||||
const InstitutionsFeatures = require('../Institutions/InstitutionsFeatures')
|
const InstitutionsFeatures = require('../Institutions/InstitutionsFeatures')
|
||||||
const UserGetter = require('../User/UserGetter')
|
const UserGetter = require('../User/UserGetter')
|
||||||
|
const AnalyticsManager = require('../Analytics/AnalyticsManager')
|
||||||
|
|
||||||
const FeaturesUpdater = {
|
const FeaturesUpdater = {
|
||||||
refreshFeatures(userId, reason, callback = () => {}) {
|
refreshFeatures(userId, reason, callback = () => {}) {
|
||||||
|
@ -23,6 +24,16 @@ const FeaturesUpdater = {
|
||||||
return callback(error)
|
return callback(error)
|
||||||
}
|
}
|
||||||
logger.log({ userId, features }, 'updating user features')
|
logger.log({ userId, features }, 'updating user features')
|
||||||
|
|
||||||
|
const matchedFeatureSet = FeaturesUpdater._getMatchedFeatureSet(
|
||||||
|
features
|
||||||
|
)
|
||||||
|
AnalyticsManager.setUserProperty(
|
||||||
|
userId,
|
||||||
|
'feature-set',
|
||||||
|
matchedFeatureSet
|
||||||
|
)
|
||||||
|
|
||||||
UserFeaturesUpdater.updateFeatures(
|
UserFeaturesUpdater.updateFeatures(
|
||||||
userId,
|
userId,
|
||||||
features,
|
features,
|
||||||
|
@ -301,6 +312,15 @@ const FeaturesUpdater = {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_getMatchedFeatureSet(features) {
|
||||||
|
for (const [name, featureSet] of Object.entries(Settings.features)) {
|
||||||
|
if (_.isEqual(features, featureSet)) {
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 'mixed'
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const refreshFeaturesPromise = (userId, reason) =>
|
const refreshFeaturesPromise = (userId, reason) =>
|
||||||
|
|
|
@ -13,11 +13,35 @@ describe('FeaturesUpdater', function () {
|
||||||
'./UserFeaturesUpdater': (this.UserFeaturesUpdater = {}),
|
'./UserFeaturesUpdater': (this.UserFeaturesUpdater = {}),
|
||||||
'./SubscriptionLocator': (this.SubscriptionLocator = {}),
|
'./SubscriptionLocator': (this.SubscriptionLocator = {}),
|
||||||
'./PlansLocator': (this.PlansLocator = {}),
|
'./PlansLocator': (this.PlansLocator = {}),
|
||||||
'settings-sharelatex': (this.Settings = {}),
|
'settings-sharelatex': (this.Settings = {
|
||||||
|
features: {
|
||||||
|
personal: {
|
||||||
|
collaborators: 1,
|
||||||
|
dropbox: false,
|
||||||
|
compileTimeout: 60,
|
||||||
|
compileGroup: 'standard',
|
||||||
|
},
|
||||||
|
collaborator: {
|
||||||
|
collaborators: 10,
|
||||||
|
dropbox: true,
|
||||||
|
compileTimeout: 240,
|
||||||
|
compileGroup: 'priority',
|
||||||
|
},
|
||||||
|
professional: {
|
||||||
|
collaborators: -1,
|
||||||
|
dropbox: true,
|
||||||
|
compileTimeout: 240,
|
||||||
|
compileGroup: 'priority',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
'../Referal/ReferalFeatures': (this.ReferalFeatures = {}),
|
'../Referal/ReferalFeatures': (this.ReferalFeatures = {}),
|
||||||
'./V1SubscriptionManager': (this.V1SubscriptionManager = {}),
|
'./V1SubscriptionManager': (this.V1SubscriptionManager = {}),
|
||||||
'../Institutions/InstitutionsFeatures': (this.InstitutionsFeatures = {}),
|
'../Institutions/InstitutionsFeatures': (this.InstitutionsFeatures = {}),
|
||||||
'../User/UserGetter': (this.UserGetter = {}),
|
'../User/UserGetter': (this.UserGetter = {}),
|
||||||
|
'../Analytics/AnalyticsManager': (this.AnalyticsManager = {
|
||||||
|
setUserProperty: sinon.stub(),
|
||||||
|
}),
|
||||||
'../../infrastructure/Modules': (this.Modules = {
|
'../../infrastructure/Modules': (this.Modules = {
|
||||||
hooks: { fire: sinon.stub() },
|
hooks: { fire: sinon.stub() },
|
||||||
}),
|
}),
|
||||||
|
@ -55,7 +79,6 @@ describe('FeaturesUpdater', function () {
|
||||||
this.UserGetter.getUser = sinon.stub().yields(null, this.user)
|
this.UserGetter.getUser = sinon.stub().yields(null, this.user)
|
||||||
this.callback = sinon.stub()
|
this.callback = sinon.stub()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should return features and featuresChanged', function () {
|
it('should return features and featuresChanged', function () {
|
||||||
this.FeaturesUpdater.refreshFeatures(
|
this.FeaturesUpdater.refreshFeatures(
|
||||||
this.user_id,
|
this.user_id,
|
||||||
|
@ -67,7 +90,6 @@ describe('FeaturesUpdater', function () {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('normally', function () {
|
describe('normally', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
this.FeaturesUpdater.refreshFeatures(
|
this.FeaturesUpdater.refreshFeatures(
|
||||||
|
@ -76,37 +98,31 @@ describe('FeaturesUpdater', function () {
|
||||||
this.callback
|
this.callback
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should get the individual features', function () {
|
it('should get the individual features', function () {
|
||||||
this.FeaturesUpdater._getIndividualFeatures
|
this.FeaturesUpdater._getIndividualFeatures
|
||||||
.calledWith(this.user_id)
|
.calledWith(this.user_id)
|
||||||
.should.equal(true)
|
.should.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should get the group features', function () {
|
it('should get the group features', function () {
|
||||||
this.FeaturesUpdater._getGroupFeatureSets
|
this.FeaturesUpdater._getGroupFeatureSets
|
||||||
.calledWith(this.user_id)
|
.calledWith(this.user_id)
|
||||||
.should.equal(true)
|
.should.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should get the institution features', function () {
|
it('should get the institution features', function () {
|
||||||
this.InstitutionsFeatures.getInstitutionsFeatures
|
this.InstitutionsFeatures.getInstitutionsFeatures
|
||||||
.calledWith(this.user_id)
|
.calledWith(this.user_id)
|
||||||
.should.equal(true)
|
.should.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should get the v1 features', function () {
|
it('should get the v1 features', function () {
|
||||||
this.FeaturesUpdater._getV1Features
|
this.FeaturesUpdater._getV1Features
|
||||||
.calledWith(this.user_id)
|
.calledWith(this.user_id)
|
||||||
.should.equal(true)
|
.should.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should get the bonus features', function () {
|
it('should get the bonus features', function () {
|
||||||
this.ReferalFeatures.getBonusFeatures
|
this.ReferalFeatures.getBonusFeatures
|
||||||
.calledWith(this.user_id)
|
.calledWith(this.user_id)
|
||||||
.should.equal(true)
|
.should.equal(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should merge from the default features', function () {
|
it('should merge from the default features', function () {
|
||||||
this.FeaturesUpdater._mergeFeatures
|
this.FeaturesUpdater._mergeFeatures
|
||||||
.calledWith(this.Settings.defaultFeatures)
|
.calledWith(this.Settings.defaultFeatures)
|
||||||
|
@ -152,6 +168,47 @@ describe('FeaturesUpdater', function () {
|
||||||
.should.equal(true)
|
.should.equal(true)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('analytics user properties', function () {
|
||||||
|
it('should send the corresponding feature set user property', function () {
|
||||||
|
this.FeaturesUpdater._mergeFeatures = sinon
|
||||||
|
.stub()
|
||||||
|
.returns(this.Settings.features.personal)
|
||||||
|
|
||||||
|
this.FeaturesUpdater.refreshFeatures(
|
||||||
|
this.user_id,
|
||||||
|
'test',
|
||||||
|
this.callback
|
||||||
|
)
|
||||||
|
|
||||||
|
sinon.assert.calledWith(
|
||||||
|
this.AnalyticsManager.setUserProperty,
|
||||||
|
this.user_id,
|
||||||
|
'feature-set',
|
||||||
|
'personal'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should send mixed feature set user property', function () {
|
||||||
|
this.FeaturesUpdater._mergeFeatures = sinon
|
||||||
|
.stub()
|
||||||
|
.returns({ dropbox: true, feature: 'some' })
|
||||||
|
|
||||||
|
this.FeaturesUpdater.refreshFeatures(
|
||||||
|
this.user_id,
|
||||||
|
'test',
|
||||||
|
this.callback
|
||||||
|
)
|
||||||
|
|
||||||
|
sinon.assert.calledWith(
|
||||||
|
this.AnalyticsManager.setUserProperty,
|
||||||
|
this.user_id,
|
||||||
|
'feature-set',
|
||||||
|
'mixed'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('when losing dropbox feature', function () {
|
describe('when losing dropbox feature', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
this.user = {
|
this.user = {
|
||||||
|
|
Loading…
Reference in a new issue