[web] Disable AI Assist add-on purchase for plans-2026-phase-1 users (#33178)

Users in the plans-2026-phase-1=enabled split test can no longer
purchase the AI Assist add-on via crafted HTTP requests. The preview
and purchase endpoints return 404/redirect for these users.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
GitOrigin-RevId: 2c75eb622cf44dc91019a692290ac646b51fd72c
This commit is contained in:
Antoine Clausse
2026-04-30 14:45:02 +02:00
committed by Copybot
parent e3f88791da
commit 353c681d51
2 changed files with 48 additions and 0 deletions
@@ -532,6 +532,18 @@ async function previewAddonPurchase(req, res) {
return HttpErrorHandler.notFound(req, res, `Unknown add-on: ${addOnCode}`)
}
const { variant: plans2026Phase1Variant } =
await SplitTestHandler.promises.getAssignment(
req,
res,
'plans-2026-phase-1'
)
if (plans2026Phase1Variant === 'enabled') {
return res.redirect(
'/user/subscription?redirect-reason=ai-assist-unavailable'
)
}
const canUseAi = await PermissionsManager.promises.checkUserPermissions(
user,
['use-ai']
@@ -656,6 +668,16 @@ async function purchaseAddon(req, res, next) {
return res.sendStatus(404)
}
const { variant: plans2026Phase1Variant } =
await SplitTestHandler.promises.getAssignment(
req,
res,
'plans-2026-phase-1'
)
if (plans2026Phase1Variant === 'enabled') {
return res.sendStatus(404)
}
const { isPaused } = await checkSubscriptionPauseStatus(user)
if (isPaused) {
return HttpErrorHandler.badRequest(
@@ -932,6 +932,19 @@ describe('SubscriptionController', function () {
expect(ctx.res.sendStatus).to.have.been.calledWith(404)
})
it('should return 404 when plans-2026-phase-1 split test is enabled', async function (ctx) {
ctx.SplitTestV2Hander.promises.getAssignment.resolves({
variant: 'enabled',
})
ctx.res.sendStatus = sinon.spy()
await ctx.SubscriptionController.purchaseAddon(ctx.req, ctx.res, ctx.next)
expect(ctx.SubscriptionHandler.promises.purchaseAddon).to.not.have.been
.called
expect(ctx.res.sendStatus).to.have.been.calledWith(404)
})
it('should handle DuplicateAddOnError and send badRequest while sending 200', async function (ctx) {
ctx.req.params.addOnCode = AI_ADD_ON_CODE
ctx.SubscriptionHandler.promises.purchaseAddon.rejects(
@@ -1428,6 +1441,19 @@ describe('SubscriptionController', function () {
ctx.SubscriptionLocator.promises.getUsersSubscription.resolves(null)
})
it('should redirect with ai-assist-unavailable when plans-2026-phase-1 is enabled', async function (ctx) {
ctx.SplitTestV2Hander.promises.getAssignment.resolves({
variant: 'enabled',
})
ctx.res.redirect = sinon.stub()
await ctx.SubscriptionController.previewAddonPurchase(ctx.req, ctx.res)
expect(ctx.res.redirect).to.have.been.calledWith(
'/user/subscription?redirect-reason=ai-assist-unavailable'
)
})
describe('when user has manual or custom subscription', function () {
it('should redirect with ai-assist-unavailable when subscription has customAccount = true', async function (ctx) {
const customSubscription = {