mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-23 17:19:37 +02:00
Merge pull request #33247 from overleaf/rh-cio-fix-ai-group-enabled
Base group ai enabled cio attribute on group policy GitOrigin-RevId: 2b2411aec3ffc694d2570e6031e9a876a1575e2c
This commit is contained in:
@@ -250,7 +250,8 @@ function hasPlanAiEnabled(plan) {
|
||||
function getGroupAiEnabled(
|
||||
memberGroupSubscriptions = [],
|
||||
managedGroupSubscriptions = [],
|
||||
userIsMemberOfGroupSubscription
|
||||
userIsMemberOfGroupSubscription,
|
||||
aiBlockedByPolicyId = new Map()
|
||||
) {
|
||||
if (!userIsMemberOfGroupSubscription) {
|
||||
return null
|
||||
@@ -261,12 +262,12 @@ function getGroupAiEnabled(
|
||||
...managedGroupSubscriptions,
|
||||
]
|
||||
|
||||
return allGroupSubscriptions.some(subscription => {
|
||||
const plan = Settings.plans.find(
|
||||
candidate => candidate.planCode === subscription.planCode
|
||||
)
|
||||
return hasPlanAiEnabled(plan)
|
||||
const someBlocked = allGroupSubscriptions.some(subscription => {
|
||||
const policyId = subscription.groupPolicy?.toString()
|
||||
return policyId ? aiBlockedByPolicyId.get(policyId) : false
|
||||
})
|
||||
|
||||
return !someBlocked
|
||||
}
|
||||
|
||||
function getGroupSize(
|
||||
@@ -373,6 +374,7 @@ function getPlanProperties({
|
||||
userIsMemberOfGroupSubscription,
|
||||
hasCommons,
|
||||
writefullData,
|
||||
aiBlockedByPolicyId,
|
||||
}) {
|
||||
const planType = normalizePlanType(bestSubscription)
|
||||
const displayPlanType = getFriendlyPlanName(planType)
|
||||
@@ -392,7 +394,8 @@ function getPlanProperties({
|
||||
const groupAiEnabled = getGroupAiEnabled(
|
||||
memberGroupSubscriptions,
|
||||
managedGroupSubscriptions,
|
||||
userIsMemberOfGroupSubscription
|
||||
userIsMemberOfGroupSubscription,
|
||||
aiBlockedByPolicyId
|
||||
)
|
||||
const nextRenewalDate = getNextRenewalDateFromPaymentRecord(
|
||||
individualPaymentRecord
|
||||
|
||||
@@ -17,6 +17,7 @@ import Queues from '../../infrastructure/Queues.mjs'
|
||||
import Modules from '../../infrastructure/Modules.mjs'
|
||||
import SubscriptionViewModelBuilder from './SubscriptionViewModelBuilder.mjs'
|
||||
import CustomerIoPlanHelpers from './CustomerIoPlanHelpers.mjs'
|
||||
import { GroupPolicy } from '../../models/GroupPolicy.mjs'
|
||||
import { AI_ADD_ON_CODE } from './AiHelper.mjs'
|
||||
import { fetchNothing } from '@overleaf/fetch-utils'
|
||||
import SplitTestHandler from '../SplitTests/SplitTestHandler.mjs'
|
||||
@@ -169,6 +170,11 @@ async function _updateCustomerIoSubscriptionProperties(user, features) {
|
||||
)
|
||||
}
|
||||
|
||||
const aiBlockedByPolicyId = await _loadAiBlockedByPolicyId([
|
||||
...memberGroupSubscriptions,
|
||||
...managedGroupSubscriptions,
|
||||
])
|
||||
|
||||
const planProperties = CustomerIoPlanHelpers.getPlanProperties({
|
||||
bestSubscription,
|
||||
individualSubscription,
|
||||
@@ -178,6 +184,7 @@ async function _updateCustomerIoSubscriptionProperties(user, features) {
|
||||
userIsMemberOfGroupSubscription,
|
||||
hasCommons,
|
||||
writefullData,
|
||||
aiBlockedByPolicyId,
|
||||
})
|
||||
|
||||
await Modules.promises.hooks.fire('setUserProperties', userId, {
|
||||
@@ -188,6 +195,29 @@ async function _updateCustomerIoSubscriptionProperties(user, features) {
|
||||
})
|
||||
}
|
||||
|
||||
async function _loadAiBlockedByPolicyId(groupSubscriptions) {
|
||||
const policyIds = [
|
||||
...new Set(
|
||||
groupSubscriptions.map(sub => sub.groupPolicy?.toString()).filter(Boolean)
|
||||
),
|
||||
]
|
||||
|
||||
if (policyIds.length === 0) {
|
||||
return new Map()
|
||||
}
|
||||
|
||||
const policies = await GroupPolicy.find(
|
||||
{ _id: { $in: policyIds } },
|
||||
{ _id: 1, userCannotUseAIFeatures: 1 }
|
||||
).exec()
|
||||
return new Map(
|
||||
policies.map(policy => [
|
||||
policy._id.toString(),
|
||||
Boolean(policy.userCannotUseAIFeatures),
|
||||
])
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the features that the given user should have.
|
||||
*/
|
||||
|
||||
@@ -167,6 +167,10 @@ describe('FeaturesUpdater', function () {
|
||||
},
|
||||
}
|
||||
|
||||
ctx.GroupPolicy = {
|
||||
find: sinon.stub().returns({ exec: sinon.stub().resolves([]) }),
|
||||
}
|
||||
|
||||
vi.doMock(
|
||||
'../../../../app/src/Features/Subscription/UserFeaturesUpdater',
|
||||
() => ({
|
||||
@@ -231,6 +235,10 @@ describe('FeaturesUpdater', function () {
|
||||
|
||||
vi.doMock('../../../../app/src/models/Subscription', () => ({}))
|
||||
|
||||
vi.doMock('../../../../app/src/models/GroupPolicy', () => ({
|
||||
GroupPolicy: ctx.GroupPolicy,
|
||||
}))
|
||||
|
||||
vi.doMock('@overleaf/fetch-utils', () => ({
|
||||
fetchNothing: sinon.stub().resolves(),
|
||||
}))
|
||||
@@ -730,7 +738,7 @@ describe('FeaturesUpdater', function () {
|
||||
display_plan_type: 'Group Standard',
|
||||
plan_term_label: 'monthly',
|
||||
ai_plan: 'none',
|
||||
group_ai_enabled: false,
|
||||
group_ai_enabled: true,
|
||||
group_size: 8,
|
||||
next_renewal_date: '',
|
||||
expiry_date: '',
|
||||
@@ -745,6 +753,49 @@ describe('FeaturesUpdater', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the group subscription has a policy that blocks AI', function () {
|
||||
beforeEach(async function (ctx) {
|
||||
const policyId = new ObjectId()
|
||||
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,
|
||||
groupPolicy: policyId,
|
||||
},
|
||||
],
|
||||
managedGroupSubscriptions: [],
|
||||
individualSubscription: null,
|
||||
}
|
||||
)
|
||||
ctx.GroupPolicy.find.returns({
|
||||
exec: sinon
|
||||
.stub()
|
||||
.resolves([{ _id: policyId, userCannotUseAIFeatures: true }]),
|
||||
})
|
||||
await ctx.FeaturesUpdater.promises.refreshFeatures(ctx.user._id, 'test')
|
||||
})
|
||||
|
||||
it('should set group_ai_enabled to false', function (ctx) {
|
||||
expect(ctx.Modules.promises.hooks.fire).to.have.been.calledWith(
|
||||
'setUserProperties',
|
||||
ctx.user._id,
|
||||
sinon.match({ group_ai_enabled: false })
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the user is in a stripe group subscription', function () {
|
||||
beforeEach(async function (ctx) {
|
||||
ctx.SubscriptionViewModelBuilder.promises.getUsersSubscriptionDetails.resolves(
|
||||
|
||||
Reference in New Issue
Block a user