mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #12473 from overleaf/ab-server-pro-split-test-overrides
[web] Add split test overrides through settings for non-SaaS env GitOrigin-RevId: 82cb6a573a992e730107f6287e7804cfe0f04aa5
This commit is contained in:
parent
17109393c5
commit
e780a09a15
2 changed files with 102 additions and 6 deletions
|
@ -11,6 +11,7 @@ const UserAnalyticsIdCache = require('../Analytics/UserAnalyticsIdCache')
|
|||
const { getAnalyticsIdFromMongoUser } = require('../Analytics/AnalyticsHelper')
|
||||
const Features = require('../../infrastructure/Features')
|
||||
const SplitTestUtils = require('./SplitTestUtils')
|
||||
const Settings = require('@overleaf/settings')
|
||||
|
||||
const DEFAULT_VARIANT = 'default'
|
||||
const ALPHA_PHASE = 'alpha'
|
||||
|
@ -49,7 +50,7 @@ const DEFAULT_ASSIGNMENT = {
|
|||
*/
|
||||
async function getAssignment(req, res, splitTestName, { sync = false } = {}) {
|
||||
if (!Features.hasFeature('saas')) {
|
||||
return DEFAULT_ASSIGNMENT
|
||||
return _getNonSaasAssignment(splitTestName)
|
||||
}
|
||||
|
||||
const query = req.query || {}
|
||||
|
@ -107,7 +108,7 @@ async function getAssignmentForUser(
|
|||
{ sync = false } = {}
|
||||
) {
|
||||
if (!Features.hasFeature('saas')) {
|
||||
return DEFAULT_ASSIGNMENT
|
||||
return _getNonSaasAssignment(splitTestName)
|
||||
}
|
||||
|
||||
const analyticsId = await UserAnalyticsIdCache.get(userId)
|
||||
|
@ -131,7 +132,7 @@ async function getAssignmentForMongoUser(
|
|||
{ sync = false } = {}
|
||||
) {
|
||||
if (!Features.hasFeature('saas')) {
|
||||
return DEFAULT_ASSIGNMENT
|
||||
return _getNonSaasAssignment(splitTestName)
|
||||
}
|
||||
|
||||
return _getAssignment(splitTestName, {
|
||||
|
@ -403,6 +404,18 @@ async function _loadSplitTestInfoInLocals(locals, splitTestName) {
|
|||
}
|
||||
}
|
||||
|
||||
function _getNonSaasAssignment(splitTestName) {
|
||||
if (Settings.splitTestOverrides?.[splitTestName]) {
|
||||
return {
|
||||
variant: Settings.splitTestOverrides?.[splitTestName],
|
||||
analytics: {
|
||||
segmentation: {},
|
||||
},
|
||||
}
|
||||
}
|
||||
return DEFAULT_ASSIGNMENT
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getPercentile,
|
||||
getAssignment: callbackify(getAssignment),
|
||||
|
|
|
@ -2,7 +2,9 @@ const Path = require('path')
|
|||
const SandboxedModule = require('sandboxed-module')
|
||||
const sinon = require('sinon')
|
||||
const { ObjectId } = require('mongodb')
|
||||
const { expect } = require('chai')
|
||||
const { assert, expect } = require('chai')
|
||||
const MockRequest = require('../helpers/MockRequest')
|
||||
const MockResponse = require('../helpers/MockResponse')
|
||||
|
||||
const MODULE_PATH = Path.join(
|
||||
__dirname,
|
||||
|
@ -39,6 +41,17 @@ describe('SplitTestHandler', function () {
|
|||
for (const splitTest of this.splitTests) {
|
||||
this.SplitTestCache.get.withArgs(splitTest.name).resolves(splitTest)
|
||||
}
|
||||
this.Settings = {
|
||||
moduleImportSequence: [],
|
||||
overleaf: {},
|
||||
}
|
||||
this.AnalyticsManager = {
|
||||
getIdsFromSession: sinon.stub(),
|
||||
}
|
||||
this.LocalsHelper = {
|
||||
setSplitTestVariant: sinon.stub(),
|
||||
setSplitTestInfo: sinon.stub(),
|
||||
}
|
||||
|
||||
this.SplitTestHandler = SandboxedModule.require(MODULE_PATH, {
|
||||
requires: {
|
||||
|
@ -46,10 +59,14 @@ describe('SplitTestHandler', function () {
|
|||
'./SplitTestCache': this.SplitTestCache,
|
||||
'../../models/SplitTest': { SplitTest: this.SplitTest },
|
||||
'../User/UserUpdater': {},
|
||||
'../Analytics/AnalyticsManager': {},
|
||||
'./LocalsHelper': {},
|
||||
'../Analytics/AnalyticsManager': this.AnalyticsManager,
|
||||
'./LocalsHelper': this.LocalsHelper,
|
||||
'@overleaf/settings': this.Settings,
|
||||
},
|
||||
})
|
||||
|
||||
this.req = new MockRequest()
|
||||
this.res = new MockResponse()
|
||||
})
|
||||
|
||||
describe('with an existing user', function () {
|
||||
|
@ -174,6 +191,72 @@ describe('SplitTestHandler', function () {
|
|||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('with settings overrides', function () {
|
||||
beforeEach(function () {
|
||||
this.Settings.splitTestOverrides = {
|
||||
'my-test-name': 'foo-1',
|
||||
}
|
||||
})
|
||||
|
||||
it('should not use the override when in SaaS mode', async function () {
|
||||
this.AnalyticsManager.getIdsFromSession.returns({
|
||||
userId: 'abc123abc123',
|
||||
})
|
||||
this.SplitTestCache.get.returns({
|
||||
name: 'my-test-name',
|
||||
versions: [
|
||||
{
|
||||
versionNumber: 0,
|
||||
active: true,
|
||||
variants: [
|
||||
{
|
||||
name: '100-percent-variant',
|
||||
rolloutPercent: 100,
|
||||
rolloutStripes: [{ start: 0, end: 100 }],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
const assignment = await this.SplitTestHandler.promises.getAssignment(
|
||||
this.req,
|
||||
this.res,
|
||||
'my-test-name'
|
||||
)
|
||||
|
||||
assert.equal('100-percent-variant', assignment.variant)
|
||||
})
|
||||
|
||||
it('should use the override when not in SaaS mode', async function () {
|
||||
this.Settings.splitTestOverrides = {
|
||||
'my-test-name': 'foo-1',
|
||||
}
|
||||
this.Settings.overleaf = undefined
|
||||
|
||||
const assignment = await this.SplitTestHandler.promises.getAssignment(
|
||||
this.req,
|
||||
this.res,
|
||||
'my-test-name'
|
||||
)
|
||||
|
||||
assert.equal('foo-1', assignment.variant)
|
||||
})
|
||||
|
||||
it('should use default when not in SaaS mode and no override is provided', async function () {
|
||||
this.Settings.splitTestOverrides = {}
|
||||
this.Settings.overleaf = undefined
|
||||
|
||||
const assignment = await this.SplitTestHandler.promises.getAssignment(
|
||||
this.req,
|
||||
this.res,
|
||||
'my-test-name'
|
||||
)
|
||||
|
||||
assert.equal('default', assignment.variant)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
function makeSplitTest(
|
||||
|
|
Loading…
Reference in a new issue