Merge pull request #34976 from overleaf/rh-cio-beta-program

Expose beta program participation to Customer.io

GitOrigin-RevId: e28d9b41afb2e50e62b7e06c94482f4240c6becc
This commit is contained in:
roo hutton
2026-09-17 11:14:06 +00:00
committed by Copybot
parent d74ecc0f2c
commit e5c815129b
2 changed files with 55 additions and 0 deletions
@@ -1,7 +1,20 @@
import { callbackify } from 'node:util'
import logger from '@overleaf/logger'
import metrics from '@overleaf/metrics'
import UserUpdater from '../User/UserUpdater.mjs'
import AnalyticsManager from '../Analytics/AnalyticsManager.mjs'
import Modules from '../../infrastructure/Modules.mjs'
function setBetaProgramUserProperty(userId, betaProgram) {
Modules.promises.hooks
.fire('setUserProperties', userId, { beta_program: betaProgram })
.catch(err => {
logger.error(
{ err, userId },
'Failed to set beta_program user property for customer.io'
)
})
}
async function optIn(session, userId) {
await UserUpdater.promises.updateUser(userId, { $set: { betaProgram: true } })
@@ -11,6 +24,7 @@ async function optIn(session, userId) {
'beta-program',
true
)
setBetaProgramUserProperty(userId, true)
}
async function optOut(session, userId) {
@@ -23,6 +37,7 @@ async function optOut(session, userId) {
'beta-program',
false
)
setBetaProgramUserProperty(userId, false)
}
export default {
@@ -39,6 +39,16 @@ describe('BetaProgramHandler', function () {
})
)
vi.doMock('../../../../app/src/infrastructure/Modules', () => ({
default: (ctx.Modules = {
promises: {
hooks: {
fire: sinon.stub().resolves(),
},
},
}),
}))
ctx.session = {}
ctx.handler = (await import(modulePath)).default
})
@@ -76,6 +86,21 @@ describe('BetaProgramHandler', function () {
})
})
it('should set beta_program=true user property in customer.io', async function (ctx) {
await new Promise(resolve => {
ctx.call(err => {
expect(err).to.not.exist
sinon.assert.calledWith(
ctx.Modules.promises.hooks.fire,
'setUserProperties',
ctx.user_id,
{ beta_program: true }
)
resolve()
})
})
})
it('should not produce an error', async function (ctx) {
await new Promise(resolve => {
ctx.call(err => {
@@ -135,6 +160,21 @@ describe('BetaProgramHandler', function () {
})
})
it('should set beta_program=false user property in customer.io', async function (ctx) {
await new Promise(resolve => {
ctx.call(err => {
expect(err).to.not.exist
sinon.assert.calledWith(
ctx.Modules.promises.hooks.fire,
'setUserProperties',
ctx.user_id,
{ beta_program: false }
)
resolve()
})
})
})
it('should not produce an error', async function (ctx) {
await new Promise(resolve => {
ctx.call(err => {