Просмотр исходного кода

Merge pull request #24430 from overleaf/ii-flexible-group-licensing-tear-down-feature-flag

[web] Tear down flexible group licensing feature flag

GitOrigin-RevId: 181713f1f2371b51cbc4256debea59bbcf3668f3
ilkin-overleaf 1 год назад
Родитель
Сommit
61ce012fb5
19 измененных файлов с 94 добавлено и 484 удалено
  1. 0 8
      services/web/app/src/Features/Subscription/SubscriptionController.js
  2. 0 17
      services/web/app/src/Features/Subscription/SubscriptionGroupController.mjs
  3. 0 5
      services/web/app/src/Features/Subscription/SubscriptionRouter.mjs
  4. 0 6
      services/web/app/src/Features/UserMembership/UserMembershipController.mjs
  5. 50 62
      services/web/app/views/subscriptions/plans/_plans_faq_tabs.pug
  6. 0 9
      services/web/frontend/extracted-translations.json
  7. 5 19
      services/web/frontend/js/features/group-management/components/group-members.tsx
  8. 1 5
      services/web/frontend/js/features/subscription/components/dashboard/group-settings-button.tsx
  9. 3 17
      services/web/frontend/js/features/subscription/components/dashboard/managed-group-subscriptions.tsx
  10. 1 17
      services/web/frontend/js/features/subscription/components/dashboard/personal-subscription.tsx
  11. 7 20
      services/web/frontend/js/features/subscription/components/dashboard/premium-features-link.tsx
  12. 0 221
      services/web/frontend/js/features/subscription/components/dashboard/states/active/active-ai-addon.tsx
  13. 0 9
      services/web/locales/en.json
  14. 15 29
      services/web/test/frontend/features/group-management/components/group-members.spec.tsx
  15. 3 3
      services/web/test/frontend/features/subscription/components/dashboard/managed-group-subscriptions.test.tsx
  16. 1 1
      services/web/test/frontend/features/subscription/components/dashboard/personal-subscription.test.tsx
  17. 2 5
      services/web/test/frontend/features/subscription/components/dashboard/subscription-dashboard.test.tsx
  18. 6 4
      services/web/test/frontend/features/subscription/components/successful-subscription/successful-subscription.test.tsx
  19. 0 27
      services/web/test/unit/src/Subscription/SubscriptionGroupControllerTests.mjs

+ 0 - 8
services/web/app/src/Features/Subscription/SubscriptionController.js

@@ -56,13 +56,6 @@ async function userSubscriptionPage(req, res) {
 
 
   const showGroupDiscount = groupPricingDiscount.variant === 'enabled'
   const showGroupDiscount = groupPricingDiscount.variant === 'enabled'
 
 
-  const { variant: flexibleLicensingVariant } =
-    await SplitTestHandler.promises.getAssignment(
-      req,
-      res,
-      'flexible-group-licensing'
-    )
-
   const results =
   const results =
     await SubscriptionViewModelBuilder.promises.buildUsersSubscriptionViewModel(
     await SubscriptionViewModelBuilder.promises.buildUsersSubscriptionViewModel(
       user,
       user,
@@ -147,7 +140,6 @@ async function userSubscriptionPage(req, res) {
           (managedUsersResults?.[0] === true ||
           (managedUsersResults?.[0] === true ||
             groupSSOResults?.[0] === true) &&
             groupSSOResults?.[0] === true) &&
           isGroupAdmin &&
           isGroupAdmin &&
-          flexibleLicensingVariant === 'enabled' &&
           plan?.canUseFlexibleLicensing
           plan?.canUseFlexibleLicensing
         )
         )
       }
       }

+ 0 - 17
services/web/app/src/Features/Subscription/SubscriptionGroupController.mjs

@@ -8,8 +8,6 @@ import SessionManager from '../Authentication/SessionManager.js'
 import UserAuditLogHandler from '../User/UserAuditLogHandler.js'
 import UserAuditLogHandler from '../User/UserAuditLogHandler.js'
 import { expressify } from '@overleaf/promise-utils'
 import { expressify } from '@overleaf/promise-utils'
 import Modules from '../../infrastructure/Modules.js'
 import Modules from '../../infrastructure/Modules.js'
-import SplitTestHandler from '../SplitTests/SplitTestHandler.js'
-import ErrorController from '../Errors/ErrorController.js'
 import UserGetter from '../User/UserGetter.js'
 import UserGetter from '../User/UserGetter.js'
 import { Subscription } from '../../models/Subscription.js'
 import { Subscription } from '../../models/Subscription.js'
 import { isProfessionalGroupPlan } from './PlansHelper.mjs'
 import { isProfessionalGroupPlan } from './PlansHelper.mjs'
@@ -288,20 +286,6 @@ async function submitForm(req, res) {
   res.sendStatus(204)
   res.sendStatus(204)
 }
 }
 
 
-async function flexibleLicensingSplitTest(req, res, next) {
-  const { variant } = await SplitTestHandler.promises.getAssignment(
-    req,
-    res,
-    'flexible-group-licensing'
-  )
-
-  if (variant !== 'enabled') {
-    return ErrorController.notFound(req, res)
-  }
-
-  next()
-}
-
 async function subscriptionUpgradePage(req, res) {
 async function subscriptionUpgradePage(req, res) {
   try {
   try {
     const userId = SessionManager.getLoggedInUserId(req.session)
     const userId = SessionManager.getLoggedInUserId(req.session)
@@ -409,7 +393,6 @@ export default {
   removeSelfFromGroup: expressify(removeSelfFromGroup),
   removeSelfFromGroup: expressify(removeSelfFromGroup),
   addSeatsToGroupSubscription: expressify(addSeatsToGroupSubscription),
   addSeatsToGroupSubscription: expressify(addSeatsToGroupSubscription),
   submitForm: expressify(submitForm),
   submitForm: expressify(submitForm),
-  flexibleLicensingSplitTest: expressify(flexibleLicensingSplitTest),
   previewAddSeatsSubscriptionChange: expressify(
   previewAddSeatsSubscriptionChange: expressify(
     previewAddSeatsSubscriptionChange
     previewAddSeatsSubscriptionChange
   ),
   ),

+ 0 - 5
services/web/app/src/Features/Subscription/SubscriptionRouter.mjs

@@ -73,7 +73,6 @@ export default {
       '/user/subscription/group/add-users',
       '/user/subscription/group/add-users',
       AuthenticationController.requireLogin(),
       AuthenticationController.requireLogin(),
       RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
       RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
-      SubscriptionGroupController.flexibleLicensingSplitTest,
       SubscriptionGroupController.addSeatsToGroupSubscription
       SubscriptionGroupController.addSeatsToGroupSubscription
     )
     )
 
 
@@ -108,7 +107,6 @@ export default {
       '/user/subscription/group/upgrade-subscription',
       '/user/subscription/group/upgrade-subscription',
       AuthenticationController.requireLogin(),
       AuthenticationController.requireLogin(),
       RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
       RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
-      SubscriptionGroupController.flexibleLicensingSplitTest,
       SubscriptionGroupController.subscriptionUpgradePage
       SubscriptionGroupController.subscriptionUpgradePage
     )
     )
 
 
@@ -123,7 +121,6 @@ export default {
       '/user/subscription/group/missing-billing-information',
       '/user/subscription/group/missing-billing-information',
       AuthenticationController.requireLogin(),
       AuthenticationController.requireLogin(),
       RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
       RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
-      SubscriptionGroupController.flexibleLicensingSplitTest,
       SubscriptionGroupController.missingBillingInformation
       SubscriptionGroupController.missingBillingInformation
     )
     )
 
 
@@ -131,7 +128,6 @@ export default {
       '/user/subscription/group/manually-collected-subscription',
       '/user/subscription/group/manually-collected-subscription',
       AuthenticationController.requireLogin(),
       AuthenticationController.requireLogin(),
       RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
       RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
-      SubscriptionGroupController.flexibleLicensingSplitTest,
       SubscriptionGroupController.manuallyCollectedSubscription
       SubscriptionGroupController.manuallyCollectedSubscription
     )
     )
 
 
@@ -139,7 +135,6 @@ export default {
       '/user/subscription/group/subtotal-limit-exceeded',
       '/user/subscription/group/subtotal-limit-exceeded',
       AuthenticationController.requireLogin(),
       AuthenticationController.requireLogin(),
       RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
       RateLimiterMiddleware.rateLimit(subscriptionRateLimiter),
-      SubscriptionGroupController.flexibleLicensingSplitTest,
       SubscriptionGroupController.subtotalLimitExceeded
       SubscriptionGroupController.subtotalLimitExceeded
     )
     )
 
 

+ 0 - 6
services/web/app/src/Features/UserMembership/UserMembershipController.mjs

@@ -32,12 +32,6 @@ async function manageGroupMembers(req, res, next) {
   )
   )
   const ssoConfig = await SSOConfig.findById(subscription.ssoConfig).exec()
   const ssoConfig = await SSOConfig.findById(subscription.ssoConfig).exec()
 
 
-  await SplitTestHandler.promises.getAssignment(
-    req,
-    res,
-    'flexible-group-licensing'
-  )
-
   await SplitTestHandler.promises.getAssignment(req, res, 'bootstrap-5-groups')
   await SplitTestHandler.promises.getAssignment(req, res, 'bootstrap-5-groups')
 
 
   const plan = PlansLocator.findLocalPlanInSettings(subscription.planCode)
   const plan = PlansLocator.findLocalPlanInSettings(subscription.planCode)

+ 50 - 62
services/web/app/views/subscriptions/plans/_plans_faq_tabs.pug

@@ -165,56 +165,15 @@ mixin overleafGroupPlans()
 			.collapse(id="overleafGroupPlansQ3")
 			.collapse(id="overleafGroupPlansQ3")
 				.custom-accordion-body
 				.custom-accordion-body
 					| The educational discount for group subscriptions is for students or faculty who are using Overleaf primarily for teaching. 
 					| The educational discount for group subscriptions is for students or faculty who are using Overleaf primarily for teaching. 
-		if canUseFlexibleLicensing
-			.custom-accordion-item
-				button.custom-accordion-header.collapsed(type="button" data-toggle="collapse" data-target="#overleafGroupPlansQ4" aria-expanded="false" aria-controls="overleafGroupPlansQ4")
-					| How do I add more licenses to my group subscription, and what will it cost?
-					span.custom-accordion-icon
-						i.material-symbols.material-symbols-outlined(aria-hidden="true") keyboard_arrow_down
-				.collapse(id="overleafGroupPlansQ4")
-					.custom-accordion-body
-						div 
-							| You can add up to 20 licenses using the 
-							a.inline-green-link(
-								target="_blank"
-								href="/user/subscription"
-								event-tracking="plans-page-click"
-								event-tracking-mb="true"
-								event-tracking-trigger="click"
-								event-segmentation={ button: 'contact', location: 'faq' }
-							)
-								span subscription management page
-							|  accessed by going to Account > 
-							a.inline-green-link(
-								target="_blank"
-								href="/user/subscription"
-								event-tracking="plans-page-click"
-								event-tracking-mb="true"
-								event-tracking-trigger="click"
-								event-segmentation={ button: 'contact', location: 'faq' }
-							)
-								span Subscription
-							|  when logged into Overleaf. The cost per license will be prorated at the current per license rate, and will end with your existing renewal date.
-						div.mt-2 
-							| If you need more than 20 licenses added to your subscription, please 
-							a.inline-green-link(
-								target="_blank"
-								href="/for/contact-sales"
-								event-tracking="plans-page-click"
-								event-tracking-mb="true"
-								event-tracking-trigger="click"
-								event-segmentation={ button: 'contact', location: 'faq' }
-							)
-								span contact the Sales team
-							| .
-			.custom-accordion-item
-				button.custom-accordion-header.collapsed(type="button" data-toggle="collapse" data-target="#overleafGroupPlansQ5" aria-expanded="false" aria-controls="overleafGroupPlansQ5")
-					| How do I upgrade my plan from Group Standard to Group Professional?
-					span.custom-accordion-icon
-						i.material-symbols.material-symbols-outlined(aria-hidden="true") keyboard_arrow_down
-				.collapse(id="overleafGroupPlansQ5")
-					.custom-accordion-body
-						| You can upgrade your plan from Group Standard to Group Professional on the 
+		.custom-accordion-item
+			button.custom-accordion-header.collapsed(type="button" data-toggle="collapse" data-target="#overleafGroupPlansQ4" aria-expanded="false" aria-controls="overleafGroupPlansQ4")
+				| How do I add more licenses to my group subscription, and what will it cost?
+				span.custom-accordion-icon
+					i.material-symbols.material-symbols-outlined(aria-hidden="true") keyboard_arrow_down
+			.collapse(id="overleafGroupPlansQ4")
+				.custom-accordion-body
+					div 
+						| You can add up to 20 licenses using the 
 						a.inline-green-link(
 						a.inline-green-link(
 							target="_blank"
 							target="_blank"
 							href="/user/subscription"
 							href="/user/subscription"
@@ -224,15 +183,44 @@ mixin overleafGroupPlans()
 							event-segmentation={ button: 'contact', location: 'faq' }
 							event-segmentation={ button: 'contact', location: 'faq' }
 						)
 						)
 							span subscription management page
 							span subscription management page
-						| .	
-		else
-			.custom-accordion-item
-				button.custom-accordion-header.collapsed(type="button" data-toggle="collapse" data-target="#overleafGroupPlansQ4" aria-expanded="false" aria-controls="overleafGroupPlansQ4")
-					| Can I add more users to my group subscription at a later date?
-					span.custom-accordion-icon
-						i.material-symbols.material-symbols-outlined(aria-hidden="true") keyboard_arrow_down
-				.collapse(id="overleafGroupPlansQ4")
-					.custom-accordion-body
-						| Yes. To add more users to your subscription you’ll need to 
-						button.btn-link.inline-green-link(data-ol-open-contact-form-modal="general")
-							span #{translate("contact_us")}
+						|  accessed by going to Account > 
+						a.inline-green-link(
+							target="_blank"
+							href="/user/subscription"
+							event-tracking="plans-page-click"
+							event-tracking-mb="true"
+							event-tracking-trigger="click"
+							event-segmentation={ button: 'contact', location: 'faq' }
+						)
+							span Subscription
+						|  when logged into Overleaf. The cost per license will be prorated at the current per license rate, and will end with your existing renewal date.
+					div.mt-2 
+						| If you need more than 20 licenses added to your subscription, please 
+						a.inline-green-link(
+							target="_blank"
+							href="/for/contact-sales"
+							event-tracking="plans-page-click"
+							event-tracking-mb="true"
+							event-tracking-trigger="click"
+							event-segmentation={ button: 'contact', location: 'faq' }
+						)
+							span contact the Sales team
+						| .
+		.custom-accordion-item
+			button.custom-accordion-header.collapsed(type="button" data-toggle="collapse" data-target="#overleafGroupPlansQ5" aria-expanded="false" aria-controls="overleafGroupPlansQ5")
+				| How do I upgrade my plan from Group Standard to Group Professional?
+				span.custom-accordion-icon
+					i.material-symbols.material-symbols-outlined(aria-hidden="true") keyboard_arrow_down
+			.collapse(id="overleafGroupPlansQ5")
+				.custom-accordion-body
+					| You can upgrade your plan from Group Standard to Group Professional on the 
+					a.inline-green-link(
+						target="_blank"
+						href="/user/subscription"
+						event-tracking="plans-page-click"
+						event-tracking-mb="true"
+						event-tracking-trigger="click"
+						event-segmentation={ button: 'contact', location: 'faq' }
+					)
+						span subscription management page
+					| .

+ 0 - 9
services/web/frontend/extracted-translations.json

@@ -74,13 +74,11 @@
   "add_files": "",
   "add_files": "",
   "add_more_editors": "",
   "add_more_editors": "",
   "add_more_managers": "",
   "add_more_managers": "",
-  "add_more_members": "",
   "add_more_users": "",
   "add_more_users": "",
   "add_more_users_to_my_plan": "",
   "add_more_users_to_my_plan": "",
   "add_new_email": "",
   "add_new_email": "",
   "add_on": "",
   "add_on": "",
   "add_ons": "",
   "add_ons": "",
-  "add_ons_are": "",
   "add_or_remove_project_from_tag": "",
   "add_or_remove_project_from_tag": "",
   "add_overleaf_assist": "",
   "add_overleaf_assist": "",
   "add_overleaf_assist_to_your_group_subscription": "",
   "add_overleaf_assist_to_your_group_subscription": "",
@@ -609,7 +607,6 @@
   "get_error_assist": "",
   "get_error_assist": "",
   "get_exclusive_access_to_labs": "",
   "get_exclusive_access_to_labs": "",
   "get_in_touch": "",
   "get_in_touch": "",
-  "get_most_subscription_by_checking_features": "",
   "get_most_subscription_discover_premium_features": "",
   "get_most_subscription_discover_premium_features": "",
   "git": "",
   "git": "",
   "git_authentication_token": "",
   "git_authentication_token": "",
@@ -952,7 +949,6 @@
   "make_private": "",
   "make_private": "",
   "manage_beta_program_membership": "",
   "manage_beta_program_membership": "",
   "manage_files_from_your_dropbox_folder": "",
   "manage_files_from_your_dropbox_folder": "",
-  "manage_group_managers": "",
   "manage_group_members_subtext": "",
   "manage_group_members_subtext": "",
   "manage_group_settings": "",
   "manage_group_settings": "",
   "manage_group_settings_subtext": "",
   "manage_group_settings_subtext": "",
@@ -960,7 +956,6 @@
   "manage_group_settings_subtext_managed_users": "",
   "manage_group_settings_subtext_managed_users": "",
   "manage_institution_managers": "",
   "manage_institution_managers": "",
   "manage_managers_subtext": "",
   "manage_managers_subtext": "",
-  "manage_members": "",
   "manage_newsletter": "",
   "manage_newsletter": "",
   "manage_publisher_managers": "",
   "manage_publisher_managers": "",
   "manage_sessions": "",
   "manage_sessions": "",
@@ -1326,7 +1321,6 @@
   "remote_service_error": "",
   "remote_service_error": "",
   "remove": "",
   "remove": "",
   "remove_access": "",
   "remove_access": "",
-  "remove_add_on": "",
   "remove_email_address": "",
   "remove_email_address": "",
   "remove_from_group": "",
   "remove_from_group": "",
   "remove_link": "",
   "remove_link": "",
@@ -1634,7 +1628,6 @@
   "sure_you_want_to_leave_group": "",
   "sure_you_want_to_leave_group": "",
   "switch_back_to_monthly_pay_20_more": "",
   "switch_back_to_monthly_pay_20_more": "",
   "switch_compile_mode_for_faster_draft_compilation": "",
   "switch_compile_mode_for_faster_draft_compilation": "",
-  "switch_plan": "",
   "switch_to_editor": "",
   "switch_to_editor": "",
   "switch_to_new_editor": "",
   "switch_to_new_editor": "",
   "switch_to_old_editor": "",
   "switch_to_old_editor": "",
@@ -1892,7 +1885,6 @@
   "untrash": "",
   "untrash": "",
   "update": "",
   "update": "",
   "update_account_info": "",
   "update_account_info": "",
-  "update_billing_details": "",
   "update_dropbox_settings": "",
   "update_dropbox_settings": "",
   "update_your_billing_details": "",
   "update_your_billing_details": "",
   "updates_to_project_sharing": "",
   "updates_to_project_sharing": "",
@@ -2095,7 +2087,6 @@
   "your_new_plan": "",
   "your_new_plan": "",
   "your_password_was_detected": "",
   "your_password_was_detected": "",
   "your_plan": "",
   "your_plan": "",
-  "your_plan_is": "",
   "your_plan_is_changing_at_term_end": "",
   "your_plan_is_changing_at_term_end": "",
   "your_plan_is_limited_to_n_editors": "",
   "your_plan_is_limited_to_n_editors": "",
   "your_plan_is_limited_to_n_editors_plural": "",
   "your_plan_is_limited_to_n_editors_plural": "",

+ 5 - 19
services/web/frontend/js/features/group-management/components/group-members.tsx

@@ -5,7 +5,6 @@ import getMeta from '../../../utils/meta'
 import { useGroupMembersContext } from '../context/group-members-context'
 import { useGroupMembersContext } from '../context/group-members-context'
 import ErrorAlert from './error-alert'
 import ErrorAlert from './error-alert'
 import MembersList from './members-table/members-list'
 import MembersList from './members-table/members-list'
-import { useFeatureFlag } from '@/shared/context/split-test-context'
 import { sendMB } from '../../../infrastructure/event-tracking'
 import { sendMB } from '../../../infrastructure/event-tracking'
 import BackButton from '@/features/group-management/components/back-button'
 import BackButton from '@/features/group-management/components/back-button'
 import OLRow from '@/features/ui/components/ol/ol-row'
 import OLRow from '@/features/ui/components/ol/ol-row'
@@ -30,17 +29,12 @@ export default function GroupMembers() {
     paths,
     paths,
   } = useGroupMembersContext()
   } = useGroupMembersContext()
   const [emailString, setEmailString] = useState<string>('')
   const [emailString, setEmailString] = useState<string>('')
-  const isFlexibleGroupLicensingFeatureFlagEnabled = useFeatureFlag(
-    'flexible-group-licensing'
-  )
 
 
   const groupId = getMeta('ol-groupId')
   const groupId = getMeta('ol-groupId')
   const groupName = getMeta('ol-groupName')
   const groupName = getMeta('ol-groupName')
   const groupSize = getMeta('ol-groupSize')
   const groupSize = getMeta('ol-groupSize')
   const canUseFlexibleLicensing = getMeta('ol-canUseFlexibleLicensing')
   const canUseFlexibleLicensing = getMeta('ol-canUseFlexibleLicensing')
   const canUseAddSeatsFeature = getMeta('ol-canUseAddSeatsFeature')
   const canUseAddSeatsFeature = getMeta('ol-canUseAddSeatsFeature')
-  const isFlexibleGroupLicensing =
-    canUseFlexibleLicensing && isFlexibleGroupLicensingFeatureFlagEnabled
 
 
   const handleEmailsChange = useCallback(
   const handleEmailsChange = useCallback(
     e => {
     e => {
@@ -59,7 +53,7 @@ export default function GroupMembers() {
   }
   }
 
 
   const groupSizeDetails = () => {
   const groupSizeDetails = () => {
-    if (isFlexibleGroupLicensing) {
+    if (canUseFlexibleLicensing) {
       return (
       return (
         <small data-testid="group-size-details">
         <small data-testid="group-size-details">
           <strong>
           <strong>
@@ -145,11 +139,7 @@ export default function GroupMembers() {
                 className="add-more-members-form"
                 className="add-more-members-form"
                 data-testid="add-more-members-form"
                 data-testid="add-more-members-form"
               >
               >
-                <p className="small">
-                  {isFlexibleGroupLicensing
-                    ? t('invite_more_members')
-                    : t('add_more_members')}
-                </p>
+                <p className="small">{t('invite_more_members')}</p>
                 <ErrorAlert error={inviteError} />
                 <ErrorAlert error={inviteError} />
                 <form onSubmit={onAddMembersSubmit}>
                 <form onSubmit={onAddMembersSubmit}>
                   <OLRow>
                   <OLRow>
@@ -170,19 +160,15 @@ export default function GroupMembers() {
                         bs3Props={{
                         bs3Props={{
                           loading: inviteMemberLoading ? (
                           loading: inviteMemberLoading ? (
                             <>
                             <>
-                              {isFlexibleGroupLicensing
-                                ? t('inviting')
-                                : t('adding')}
+                              {t('inviting')}
                               &hellip;
                               &hellip;
                             </>
                             </>
-                          ) : isFlexibleGroupLicensing ? (
-                            t('invite')
                           ) : (
                           ) : (
-                            t('add')
+                            t('invite')
                           ),
                           ),
                         }}
                         }}
                       >
                       >
-                        {isFlexibleGroupLicensing ? t('invite') : t('add')}
+                        {t('invite')}
                       </OLButton>
                       </OLButton>
                     </OLCol>
                     </OLCol>
                     <OLCol xs={2}>
                     <OLCol xs={2}>

+ 1 - 5
services/web/frontend/js/features/subscription/components/dashboard/group-settings-button.tsx

@@ -1,6 +1,5 @@
 import { RowLink } from '@/features/subscription/components/dashboard/row-link'
 import { RowLink } from '@/features/subscription/components/dashboard/row-link'
 import { useTranslation } from 'react-i18next'
 import { useTranslation } from 'react-i18next'
-import { useFeatureFlag } from '@/shared/context/split-test-context'
 import { useLocation } from '@/shared/hooks/use-location'
 import { useLocation } from '@/shared/hooks/use-location'
 import MaterialIcon from '@/shared/components/material-icon'
 import MaterialIcon from '@/shared/components/material-icon'
 import OLTag from '@/features/ui/components/ol/ol-tag'
 import OLTag from '@/features/ui/components/ol/ol-tag'
@@ -36,13 +35,10 @@ function AvailableWithGroupProfessionalBadge() {
 
 
 function useGroupSettingsButton(subscription: ManagedGroupSubscription) {
 function useGroupSettingsButton(subscription: ManagedGroupSubscription) {
   const { t } = useTranslation()
   const { t } = useTranslation()
-  const isFlexibleGroupLicensing = useFeatureFlag('flexible-group-licensing')
   const subscriptionHasManagedUsers =
   const subscriptionHasManagedUsers =
     subscription.features?.managedUsers === true
     subscription.features?.managedUsers === true
   const subscriptionHasGroupSSO = subscription.features?.groupSSO === true
   const subscriptionHasGroupSSO = subscription.features?.groupSSO === true
-  const heading = isFlexibleGroupLicensing
-    ? t('group_settings')
-    : t('manage_group_settings')
+  const heading = t('group_settings')
 
 
   let groupSettingRowSubText = ''
   let groupSettingRowSubText = ''
   if (subscriptionHasGroupSSO && subscriptionHasManagedUsers) {
   if (subscriptionHasGroupSSO && subscriptionHasManagedUsers) {

+ 3 - 17
services/web/frontend/js/features/subscription/components/dashboard/managed-group-subscriptions.tsx

@@ -8,7 +8,6 @@ import { useSubscriptionDashboardContext } from '../../context/subscription-dash
 import { RowLink } from './row-link'
 import { RowLink } from './row-link'
 import { ManagedGroupSubscription } from '../../../../../../types/subscription/dashboard/subscription'
 import { ManagedGroupSubscription } from '../../../../../../types/subscription/dashboard/subscription'
 import { bsVersion } from '@/features/utils/bootstrap-5'
 import { bsVersion } from '@/features/utils/bootstrap-5'
-import { useFeatureFlag } from '@/shared/context/split-test-context'
 import classnames from 'classnames'
 import classnames from 'classnames'
 
 
 function ManagedGroupAdministrator({
 function ManagedGroupAdministrator({
@@ -91,7 +90,6 @@ function ManagedGroupAdministrator({
 export default function ManagedGroupSubscriptions() {
 export default function ManagedGroupSubscriptions() {
   const { t } = useTranslation()
   const { t } = useTranslation()
   const { managedGroupSubscriptions } = useSubscriptionDashboardContext()
   const { managedGroupSubscriptions } = useSubscriptionDashboardContext()
-  const isFlexibleGroupLicensing = useFeatureFlag('flexible-group-licensing')
 
 
   if (!managedGroupSubscriptions) {
   if (!managedGroupSubscriptions) {
     return null
     return null
@@ -115,21 +113,13 @@ export default function ManagedGroupSubscriptions() {
             <ul className="list-group p-0">
             <ul className="list-group p-0">
               <RowLink
               <RowLink
                 href={`/manage/groups/${subscription._id}/members`}
                 href={`/manage/groups/${subscription._id}/members`}
-                heading={
-                  isFlexibleGroupLicensing
-                    ? t('group_members')
-                    : t('manage_members')
-                }
+                heading={t('group_members')}
                 subtext={t('manage_group_members_subtext')}
                 subtext={t('manage_group_members_subtext')}
                 icon="groups"
                 icon="groups"
               />
               />
               <RowLink
               <RowLink
                 href={`/manage/groups/${subscription._id}/managers`}
                 href={`/manage/groups/${subscription._id}/managers`}
-                heading={
-                  isFlexibleGroupLicensing
-                    ? t('group_managers')
-                    : t('manage_group_managers')
-                }
+                heading={t('group_managers')}
                 subtext={t('manage_managers_subtext')}
                 subtext={t('manage_managers_subtext')}
                 icon="manage_accounts"
                 icon="manage_accounts"
               />
               />
@@ -141,11 +131,7 @@ export default function ManagedGroupSubscriptions() {
               )}
               )}
               <RowLink
               <RowLink
                 href={`/metrics/groups/${subscription._id}`}
                 href={`/metrics/groups/${subscription._id}`}
-                heading={
-                  isFlexibleGroupLicensing
-                    ? t('usage_metrics')
-                    : t('view_metrics')
-                }
+                heading={t('usage_metrics')}
                 subtext={t('view_metrics_group_subtext')}
                 subtext={t('view_metrics_group_subtext')}
                 icon="insights"
                 icon="insights"
               />
               />

+ 1 - 17
services/web/frontend/js/features/subscription/components/dashboard/personal-subscription.tsx

@@ -1,7 +1,5 @@
 import { Trans, useTranslation } from 'react-i18next'
 import { Trans, useTranslation } from 'react-i18next'
 import { RecurlySubscription } from '../../../../../../types/subscription/dashboard/subscription'
 import { RecurlySubscription } from '../../../../../../types/subscription/dashboard/subscription'
-import { ActiveSubscription } from './states/active/active'
-import { ActiveAiAddonSubscription } from './states/active/active-ai-addon'
 import { PausedSubscription } from './states/active/paused'
 import { PausedSubscription } from './states/active/paused'
 import { ActiveSubscriptionNew } from '@/features/subscription/components/dashboard/states/active/active-new'
 import { ActiveSubscriptionNew } from '@/features/subscription/components/dashboard/states/active/active-new'
 import { CanceledSubscription } from './states/canceled'
 import { CanceledSubscription } from './states/canceled'
@@ -9,8 +7,6 @@ import { ExpiredSubscription } from './states/expired'
 import { useSubscriptionDashboardContext } from '../../context/subscription-dashboard-context'
 import { useSubscriptionDashboardContext } from '../../context/subscription-dashboard-context'
 import PersonalSubscriptionRecurlySyncEmail from './personal-subscription-recurly-sync-email'
 import PersonalSubscriptionRecurlySyncEmail from './personal-subscription-recurly-sync-email'
 import OLNotification from '@/features/ui/components/ol/ol-notification'
 import OLNotification from '@/features/ui/components/ol/ol-notification'
-import { isStandaloneAiPlanCode, AI_ADD_ON_CODE } from '../../data/add-on-codes'
-import { useFeatureFlag } from '@/shared/context/split-test-context'
 
 
 function PastDueSubscriptionAlert({
 function PastDueSubscriptionAlert({
   subscription,
   subscription,
@@ -44,22 +40,10 @@ function PersonalSubscriptionStates({
 }) {
 }) {
   const { t } = useTranslation()
   const { t } = useTranslation()
   const state = subscription?.recurly.state
   const state = subscription?.recurly.state
-  const isFlexibleGroupLicensing = useFeatureFlag('flexible-group-licensing')
 
 
-  const hasAiAddon = subscription?.addOns?.some(
-    addOn => addOn.addOnCode === AI_ADD_ON_CODE
-  )
-
-  const onAiStandalonePlan = isStandaloneAiPlanCode(subscription.planCode)
-  const planHasAi = onAiStandalonePlan || hasAiAddon
-
-  if (state === 'active' && isFlexibleGroupLicensing) {
+  if (state === 'active') {
     // This version handles subscriptions with and without addons
     // This version handles subscriptions with and without addons
     return <ActiveSubscriptionNew subscription={subscription} />
     return <ActiveSubscriptionNew subscription={subscription} />
-  } else if (state === 'active' && planHasAi) {
-    return <ActiveAiAddonSubscription subscription={subscription} />
-  } else if (state === 'active') {
-    return <ActiveSubscription subscription={subscription} />
   } else if (state === 'canceled') {
   } else if (state === 'canceled') {
     return <CanceledSubscription subscription={subscription} />
     return <CanceledSubscription subscription={subscription} />
   } else if (state === 'expired') {
   } else if (state === 'expired') {

+ 7 - 20
services/web/frontend/js/features/subscription/components/dashboard/premium-features-link.tsx

@@ -1,28 +1,15 @@
 import { Trans } from 'react-i18next'
 import { Trans } from 'react-i18next'
-import { useFeatureFlag } from '@/shared/context/split-test-context'
 
 
 function PremiumFeaturesLink() {
 function PremiumFeaturesLink() {
-  const isFlexibleGroupLicensing = useFeatureFlag('flexible-group-licensing')
-
   return (
   return (
     <p>
     <p>
-      {isFlexibleGroupLicensing ? (
-        <Trans
-          i18nKey="get_most_subscription_discover_premium_features"
-          components={[
-            // eslint-disable-next-line react/jsx-key, jsx-a11y/anchor-has-content
-            <a href="/learn/how-to/Overleaf_premium_features" />,
-          ]}
-        />
-      ) : (
-        <Trans
-          i18nKey="get_most_subscription_by_checking_features"
-          components={[
-            // eslint-disable-next-line react/jsx-key, jsx-a11y/anchor-has-content
-            <a href="/about/features-overview" />,
-          ]}
-        />
-      )}
+      <Trans
+        i18nKey="get_most_subscription_discover_premium_features"
+        components={[
+          // eslint-disable-next-line react/jsx-key, jsx-a11y/anchor-has-content
+          <a href="/learn/how-to/Overleaf_premium_features" />,
+        ]}
+      />
     </p>
     </p>
   )
   )
 }
 }

+ 0 - 221
services/web/frontend/js/features/subscription/components/dashboard/states/active/active-ai-addon.tsx

@@ -1,221 +0,0 @@
-import { useTranslation, Trans } from 'react-i18next'
-import { PriceExceptions } from '../../../shared/price-exceptions'
-import { useSubscriptionDashboardContext } from '../../../../context/subscription-dashboard-context'
-import { RecurlySubscription } from '../../../../../../../../types/subscription/dashboard/subscription'
-import { CancelSubscription } from './cancel-plan/cancel-subscription'
-import { PendingPlanChange } from './pending-plan-change'
-import SubscriptionRemainder from './subscription-remainder'
-import { ChangePlanModal } from './change-plan/modals/change-plan-modal'
-import { ConfirmChangePlanModal } from './change-plan/modals/confirm-change-plan-modal'
-import { KeepCurrentPlanModal } from './change-plan/modals/keep-current-plan-modal'
-import { ChangeToGroupModal } from './change-plan/modals/change-to-group-modal'
-import { CancelAiAddOnModal } from './change-plan/modals/cancel-ai-add-on-modal'
-import { PendingRecurlyPlan } from '../../../../../../../../types/subscription/plan'
-import {
-  ADD_ON_NAME,
-  AI_ADD_ON_CODE,
-  isStandaloneAiPlanCode,
-} from '../../../../data/add-on-codes'
-import { CancelSubscriptionButton } from './cancel-subscription-button'
-
-import OLButton from '@/features/ui/components/ol/ol-button'
-
-export function ActiveAiAddonSubscription({
-  subscription,
-}: {
-  subscription: RecurlySubscription
-}) {
-  const { t } = useTranslation()
-  const {
-    recurlyLoadError,
-    showCancellation,
-    setModalIdShown,
-    memberGroupSubscriptions,
-    institutionMemberships,
-  } = useSubscriptionDashboardContext()
-  if (showCancellation) return <CancelSubscription />
-
-  const onStandalonePlan = isStandaloneAiPlanCode(subscription.planCode)
-
-  let planName
-  if (onStandalonePlan) {
-    planName = 'Overleaf Free'
-    if (institutionMemberships && institutionMemberships.length > 0) {
-      planName = 'Overleaf Professional'
-    }
-    if (memberGroupSubscriptions.length > 0) {
-      if (
-        memberGroupSubscriptions.some(s => s.planLevelName === 'Professional')
-      ) {
-        planName = 'Overleaf Professional'
-      } else {
-        planName = 'Overleaf Standard'
-      }
-    }
-  } else {
-    planName = subscription.plan.name
-  }
-
-  const handlePlanChange = () => setModalIdShown('change-plan')
-
-  const handleCancelClick = () => setModalIdShown('cancel-ai-add-on')
-
-  return (
-    <>
-      <p className="mb-0">
-        <Trans
-          i18nKey="your_plan_is"
-          values={{ planName }}
-          shouldUnescape
-          tOptions={{ interpolation: { escapeValue: true } }}
-          components={{ strong: <strong /> }}
-        />
-      </p>
-      <p>
-        <Trans
-          i18nKey="add_ons_are"
-          shouldUnescape
-          tOptions={{ interpolation: { escapeValue: true } }}
-          values={{
-            addOnName: ADD_ON_NAME,
-          }}
-          components={{ strong: <strong /> }}
-        />
-      </p>
-      <p>
-        {subscription.pendingPlan && (
-          <PendingPlanChange subscription={subscription} />
-        )}
-      </p>
-      {subscription.pendingPlan &&
-        subscription.pendingPlan.name !== subscription.plan.name && (
-          <p>{t('want_change_to_apply_before_plan_end')}</p>
-        )}
-      <p>
-        <Trans
-          i18nKey="next_payment_of_x_collectected_on_y"
-          values={{
-            paymentAmmount: subscription.recurly.displayPrice,
-            collectionDate: subscription.recurly.nextPaymentDueDate,
-          }}
-          shouldUnescape
-          tOptions={{ interpolation: { escapeValue: true } }}
-          components={[
-            // eslint-disable-next-line react/jsx-key
-            <strong />,
-            // eslint-disable-next-line react/jsx-key
-            <strong />,
-          ]}
-        />
-      </p>
-      <PriceExceptions subscription={subscription} />
-      {!recurlyLoadError && (
-        <p>
-          <i>
-            <SubscriptionRemainder subscription={subscription} hideTime />
-          </i>
-        </p>
-      )}
-      {!recurlyLoadError && (
-        <p className="d-inline-flex flex-wrap gap-1">
-          {onStandalonePlan ? (
-            <StandaloneAiPlanActions
-              handlePlanChange={handlePlanChange}
-              handleCancelClick={handleCancelClick}
-            />
-          ) : (
-            <PlanWithAddonsActions
-              handlePlanChange={handlePlanChange}
-              handleCancelClick={handleCancelClick}
-              subscription={subscription}
-            />
-          )}
-        </p>
-      )}
-      <p>
-        <a
-          href={subscription.recurly.accountManagementLink}
-          target="_blank"
-          rel="noreferrer noopener"
-        >
-          {t('view_invoices')}
-        </a>
-      </p>
-      <p>
-        <a
-          href={subscription.recurly.billingDetailsLink}
-          target="_blank"
-          rel="noreferrer noopener"
-        >
-          {t('update_billing_details')}
-        </a>
-      </p>
-
-      <ChangePlanModal />
-      <ConfirmChangePlanModal />
-      <KeepCurrentPlanModal />
-      <ChangeToGroupModal />
-      <CancelAiAddOnModal />
-    </>
-  )
-}
-
-function StandaloneAiPlanActions({
-  handlePlanChange,
-  handleCancelClick,
-}: {
-  handlePlanChange(): void
-  handleCancelClick(): void
-}) {
-  const { t } = useTranslation()
-  return (
-    <>
-      <OLButton variant="secondary" onClick={handlePlanChange}>
-        {t('upgrade')}
-      </OLButton>
-      <OLButton variant="danger-ghost" onClick={handleCancelClick}>
-        {t('remove_add_on')}
-      </OLButton>
-    </>
-  )
-}
-
-function PlanWithAddonsActions({
-  handlePlanChange,
-  handleCancelClick,
-  subscription,
-}: {
-  handlePlanChange(): void
-  handleCancelClick(): void
-  subscription: RecurlySubscription
-}) {
-  const { t } = useTranslation()
-
-  const pendingPlan = subscription.pendingPlan as PendingRecurlyPlan
-
-  const hasAiAddon = subscription.addOns?.some(
-    addOn => addOn.addOnCode === AI_ADD_ON_CODE
-  )
-
-  const pendingCancellation = Boolean(
-    hasAiAddon &&
-      pendingPlan &&
-      !pendingPlan.addOns?.some(addOn => addOn.add_on_code === AI_ADD_ON_CODE)
-  )
-  return (
-    <>
-      <OLButton variant="secondary" onClick={handlePlanChange}>
-        {t('switch_plan')}
-      </OLButton>
-
-      <>
-        {!pendingCancellation && (
-          <OLButton variant="danger-ghost" onClick={handleCancelClick}>
-            {t('remove_add_on')}
-          </OLButton>
-        )}
-        <CancelSubscriptionButton />
-      </>
-    </>
-  )
-}

+ 0 - 9
services/web/locales/en.json

@@ -89,13 +89,11 @@
   "add_files": "Add Files",
   "add_files": "Add Files",
   "add_more_editors": "Add more editors",
   "add_more_editors": "Add more editors",
   "add_more_managers": "Add more managers",
   "add_more_managers": "Add more managers",
-  "add_more_members": "Add more members",
   "add_more_users": "Add more users",
   "add_more_users": "Add more users",
   "add_more_users_to_my_plan": "Add more users to my plan",
   "add_more_users_to_my_plan": "Add more users to my plan",
   "add_new_email": "Add new email",
   "add_new_email": "Add new email",
   "add_on": "Add-on",
   "add_on": "Add-on",
   "add_ons": "Add-ons",
   "add_ons": "Add-ons",
-  "add_ons_are": "<strong>Add-ons:</strong> __addOnName__",
   "add_or_remove_project_from_tag": "Add or remove project from tag __tagName__",
   "add_or_remove_project_from_tag": "Add or remove project from tag __tagName__",
   "add_overleaf_assist": "Add Overleaf Assist",
   "add_overleaf_assist": "Add Overleaf Assist",
   "add_overleaf_assist_to_your_group_subscription": "Add Overleaf Assist to your group subscription",
   "add_overleaf_assist_to_your_group_subscription": "Add Overleaf Assist to your group subscription",
@@ -810,7 +808,6 @@
   "get_in_touch": "Get in touch",
   "get_in_touch": "Get in touch",
   "get_in_touch_having_problems": "<a href=\"__link__\">Get in touch with support</a> if you’re having problems",
   "get_in_touch_having_problems": "<a href=\"__link__\">Get in touch with support</a> if you’re having problems",
   "get_involved": "Get involved",
   "get_involved": "Get involved",
-  "get_most_subscription_by_checking_features": "Get the most out of your __appName__ subscription by checking out <0>__appName__’s features</0>.",
   "get_most_subscription_discover_premium_features": "Get the most from your __appName__ subscription. <0>Discover premium features</0>.",
   "get_most_subscription_discover_premium_features": "Get the most from your __appName__ subscription. <0>Discover premium features</0>.",
   "get_the_best_overleaf_experience": "Get the best Overleaf experience",
   "get_the_best_overleaf_experience": "Get the best Overleaf experience",
   "get_the_most_out_headline": "Get the most out of __appName__ with features such as:",
   "get_the_most_out_headline": "Get the most out of __appName__ with features such as:",
@@ -1260,7 +1257,6 @@
   "make_private": "Make Private",
   "make_private": "Make Private",
   "manage_beta_program_membership": "Manage Beta Program Membership",
   "manage_beta_program_membership": "Manage Beta Program Membership",
   "manage_files_from_your_dropbox_folder": "Manage files from your Dropbox folder",
   "manage_files_from_your_dropbox_folder": "Manage files from your Dropbox folder",
-  "manage_group_managers": "Manage group managers",
   "manage_group_members_subtext": "Add or remove members from your group subscription",
   "manage_group_members_subtext": "Add or remove members from your group subscription",
   "manage_group_settings": "Manage group settings",
   "manage_group_settings": "Manage group settings",
   "manage_group_settings_subtext": "Configure and manage SSO and Managed Users",
   "manage_group_settings_subtext": "Configure and manage SSO and Managed Users",
@@ -1268,7 +1264,6 @@
   "manage_group_settings_subtext_managed_users": "Turn on Managed Users",
   "manage_group_settings_subtext_managed_users": "Turn on Managed Users",
   "manage_institution_managers": "Manage institution managers",
   "manage_institution_managers": "Manage institution managers",
   "manage_managers_subtext": "Assign or remove manager privileges",
   "manage_managers_subtext": "Assign or remove manager privileges",
-  "manage_members": "Manage members",
   "manage_newsletter": "Manage Your Newsletter Preferences",
   "manage_newsletter": "Manage Your Newsletter Preferences",
   "manage_publisher_managers": "Manage publisher managers",
   "manage_publisher_managers": "Manage publisher managers",
   "manage_sessions": "Manage Your Sessions",
   "manage_sessions": "Manage Your Sessions",
@@ -1761,7 +1756,6 @@
   "remote_service_error": "The remote service produced an error",
   "remote_service_error": "The remote service produced an error",
   "remove": "Remove",
   "remove": "Remove",
   "remove_access": "Remove access",
   "remove_access": "Remove access",
-  "remove_add_on": "Remove add-on",
   "remove_email_address": "Remove email address",
   "remove_email_address": "Remove email address",
   "remove_from_group": "Remove from group",
   "remove_from_group": "Remove from group",
   "remove_link": "Remove link",
   "remove_link": "Remove link",
@@ -2133,7 +2127,6 @@
   "sv": "Swedish",
   "sv": "Swedish",
   "switch_back_to_monthly_pay_20_more": "Switch back to monthly (20% more)",
   "switch_back_to_monthly_pay_20_more": "Switch back to monthly (20% more)",
   "switch_compile_mode_for_faster_draft_compilation": "Switch compile mode for faster draft compilation",
   "switch_compile_mode_for_faster_draft_compilation": "Switch compile mode for faster draft compilation",
-  "switch_plan": "Switch plan",
   "switch_to_editor": "Switch to editor",
   "switch_to_editor": "Switch to editor",
   "switch_to_new_editor": "Switch to new editor",
   "switch_to_new_editor": "Switch to new editor",
   "switch_to_old_editor": "Switch to old editor",
   "switch_to_old_editor": "Switch to old editor",
@@ -2429,7 +2422,6 @@
   "untrash": "Restore",
   "untrash": "Restore",
   "update": "Update",
   "update": "Update",
   "update_account_info": "Update Account Info",
   "update_account_info": "Update Account Info",
-  "update_billing_details": "Update billing details",
   "update_dropbox_settings": "Update Dropbox Settings",
   "update_dropbox_settings": "Update Dropbox Settings",
   "update_your_billing_details": "Update your billing details",
   "update_your_billing_details": "Update your billing details",
   "updates_to_project_sharing": "Updates to project sharing",
   "updates_to_project_sharing": "Updates to project sharing",
@@ -2657,7 +2649,6 @@
   "your_password_has_been_successfully_changed": "Your password has been successfully changed",
   "your_password_has_been_successfully_changed": "Your password has been successfully changed",
   "your_password_was_detected": "Your password is on a <0>public list of known compromised passwords</0>. Keep your account safe by changing your password now.",
   "your_password_was_detected": "Your password is on a <0>public list of known compromised passwords</0>. Keep your account safe by changing your password now.",
   "your_plan": "Your plan",
   "your_plan": "Your plan",
-  "your_plan_is": "<strong>Your plan:</strong> __planName__",
   "your_plan_is_changing_at_term_end": "Your plan is changing to <0>__pendingPlanName__</0> at the end of the current billing period.",
   "your_plan_is_changing_at_term_end": "Your plan is changing to <0>__pendingPlanName__</0> at the end of the current billing period.",
   "your_plan_is_limited_to_n_editors": "Your plan allows __count__ collaborator with edit access and unlimited viewers.",
   "your_plan_is_limited_to_n_editors": "Your plan allows __count__ collaborator with edit access and unlimited viewers.",
   "your_plan_is_limited_to_n_editors_plural": "Your plan allows __count__ collaborators with edit access and unlimited viewers.",
   "your_plan_is_limited_to_n_editors_plural": "Your plan allows __count__ collaborators with edit access and unlimited viewers.",

+ 15 - 29
services/web/test/frontend/features/group-management/components/group-members.spec.tsx

@@ -1,7 +1,6 @@
 import GroupMembers from '@/features/group-management/components/group-members'
 import GroupMembers from '@/features/group-management/components/group-members'
 import { GroupMembersProvider } from '@/features/group-management/context/group-members-context'
 import { GroupMembersProvider } from '@/features/group-management/context/group-members-context'
 import { User } from '../../../../../types/group-management/user'
 import { User } from '../../../../../types/group-management/user'
-import { SplitTestProvider } from '@/shared/context/split-test-context'
 
 
 const GROUP_ID = '777fff777fff'
 const GROUP_ID = '777fff777fff'
 const PATHS = {
 const PATHS = {
@@ -14,11 +13,9 @@ const PATHS = {
 describe('GroupMembers', function () {
 describe('GroupMembers', function () {
   function mountGroupMembersProvider() {
   function mountGroupMembersProvider() {
     cy.mount(
     cy.mount(
-      <SplitTestProvider>
-        <GroupMembersProvider>
-          <GroupMembers />
-        </GroupMembersProvider>
-      </SplitTestProvider>
+      <GroupMembersProvider>
+        <GroupMembers />
+      </GroupMembersProvider>
     )
     )
   }
   }
 
 
@@ -49,11 +46,9 @@ describe('GroupMembers', function () {
       })
       })
 
 
       cy.mount(
       cy.mount(
-        <SplitTestProvider>
-          <GroupMembersProvider>
-            <GroupMembers />
-          </GroupMembersProvider>
-        </SplitTestProvider>
+        <GroupMembersProvider>
+          <GroupMembers />
+        </GroupMembersProvider>
       )
       )
     })
     })
 
 
@@ -517,9 +512,6 @@ describe('GroupMembers', function () {
         win.metaAttributesCache.set('ol-groupId', GROUP_ID)
         win.metaAttributesCache.set('ol-groupId', GROUP_ID)
         win.metaAttributesCache.set('ol-groupName', 'My Awesome Team')
         win.metaAttributesCache.set('ol-groupName', 'My Awesome Team')
         win.metaAttributesCache.set('ol-groupSize', 10)
         win.metaAttributesCache.set('ol-groupSize', 10)
-        win.metaAttributesCache.set('ol-splitTestVariants', {
-          'flexible-group-licensing': 'enabled',
-        })
         win.metaAttributesCache.set('ol-canUseFlexibleLicensing', true)
         win.metaAttributesCache.set('ol-canUseFlexibleLicensing', true)
         win.metaAttributesCache.set('ol-canUseAddSeatsFeature', true)
         win.metaAttributesCache.set('ol-canUseAddSeatsFeature', true)
       })
       })
@@ -534,11 +526,9 @@ describe('GroupMembers', function () {
       })
       })
 
 
       cy.mount(
       cy.mount(
-        <SplitTestProvider>
-          <GroupMembersProvider>
-            <GroupMembers />
-          </GroupMembersProvider>
-        </SplitTestProvider>
+        <GroupMembersProvider>
+          <GroupMembers />
+        </GroupMembersProvider>
       )
       )
 
 
       cy.findByTestId('group-size-details').contains(
       cy.findByTestId('group-size-details').contains(
@@ -556,11 +546,9 @@ describe('GroupMembers', function () {
       })
       })
 
 
       cy.mount(
       cy.mount(
-        <SplitTestProvider>
-          <GroupMembersProvider>
-            <GroupMembers />
-          </GroupMembersProvider>
-        </SplitTestProvider>
+        <GroupMembersProvider>
+          <GroupMembers />
+        </GroupMembersProvider>
       )
       )
 
 
       cy.findByTestId('group-size-details').contains(
       cy.findByTestId('group-size-details').contains(
@@ -575,11 +563,9 @@ describe('GroupMembers', function () {
       })
       })
 
 
       cy.mount(
       cy.mount(
-        <SplitTestProvider>
-          <GroupMembersProvider>
-            <GroupMembers />
-          </GroupMembersProvider>
-        </SplitTestProvider>
+        <GroupMembersProvider>
+          <GroupMembers />
+        </GroupMembersProvider>
       )
       )
 
 
       cy.findByTestId('group-size-details').within(() => {
       cy.findByTestId('group-size-details').within(() => {

+ 3 - 3
services/web/test/frontend/features/subscription/components/dashboard/managed-group-subscriptions.test.tsx

@@ -190,7 +190,7 @@ describe('<ManagedGroupSubscriptions />', function () {
         },
         },
       ],
       ],
     })
     })
-    await screen.findAllByText('Manage group settings')
+    await screen.findAllByText('Group settings')
     await screen.findAllByText('Configure and manage SSO and Managed Users')
     await screen.findAllByText('Configure and manage SSO and Managed Users')
   })
   })
 
 
@@ -207,7 +207,7 @@ describe('<ManagedGroupSubscriptions />', function () {
         },
         },
       ],
       ],
     })
     })
-    await screen.findAllByText('Manage group settings')
+    await screen.findAllByText('Group settings')
     await screen.findAllByText('Turn on Managed Users')
     await screen.findAllByText('Turn on Managed Users')
     expect(screen.queryByText('Configure and manage SSO and Managed Users')).to
     expect(screen.queryByText('Configure and manage SSO and Managed Users')).to
       .not.exist
       .not.exist
@@ -227,7 +227,7 @@ describe('<ManagedGroupSubscriptions />', function () {
         },
         },
       ],
       ],
     })
     })
-    await screen.findAllByText('Manage group settings')
+    await screen.findAllByText('Group settings')
     await screen.findAllByText('Configure and manage SSO')
     await screen.findAllByText('Configure and manage SSO')
     expect(screen.queryByText('Turn on Managed Users')).to.not.exist
     expect(screen.queryByText('Turn on Managed Users')).to.not.exist
     expect(screen.queryByText('Configure and manage SSO and Managed Users')).to
     expect(screen.queryByText('Configure and manage SSO and Managed Users')).to

+ 1 - 1
services/web/test/frontend/features/subscription/components/dashboard/personal-subscription.test.tsx

@@ -72,7 +72,7 @@ describe('<PersonalSubscription />', function () {
         ],
         ],
       })
       })
 
 
-      screen.getByText('You are currently subscribed to the', { exact: false })
+      screen.getByRole('heading', { name: /billing/i })
     })
     })
 
 
     it('renders the canceled dash', function () {
     it('renders the canceled dash', function () {

+ 2 - 5
services/web/test/frontend/features/subscription/components/dashboard/subscription-dashboard.test.tsx

@@ -31,11 +31,8 @@ describe('<SubscriptionDashboard />', function () {
       })
       })
     })
     })
 
 
-    it('renders the "Get the most out of your" subscription text', function () {
-      screen.getByText(
-        'Get the most out of your Overleaf subscription by checking out',
-        { exact: false }
-      )
+    it('renders the "Get the most from your subscription" text', function () {
+      screen.getByText(/get the most from your Overleaf subscription/i)
     })
     })
   })
   })
 
 

+ 6 - 4
services/web/test/frontend/features/subscription/components/successful-subscription/successful-subscription.test.tsx

@@ -36,8 +36,8 @@ describe('successful subscription page', function () {
     screen.getByText(
     screen.getByText(
       /it’s support from people like yourself that allows .* to continue to grow and improve/i
       /it’s support from people like yourself that allows .* to continue to grow and improve/i
     )
     )
-    expect(screen.getByText(/get the most out of your/i).textContent).to.match(
-      /get the most out of your .* subscription by checking out .*’s features/i
+    expect(screen.getByText(/get the most from your/i).textContent).to.match(
+      /get the most from your .* subscription\. discover premium features/i
     )
     )
     expect(
     expect(
       screen
       screen
@@ -66,9 +66,11 @@ describe('successful subscription page', function () {
     )
     )
 
 
     const helpLink = screen.getByRole('link', {
     const helpLink = screen.getByRole('link', {
-      name: /.*’s features/i,
+      name: /discover premium features/i,
     })
     })
-    expect(helpLink.getAttribute('href')).to.equal('/about/features-overview')
+    expect(helpLink.getAttribute('href')).to.equal(
+      '/learn/how-to/Overleaf_premium_features'
+    )
 
 
     const backToYourProjectsLink = screen.getByRole('link', {
     const backToYourProjectsLink = screen.getByRole('link', {
       name: /back to your projects/i,
       name: /back to your projects/i,

+ 0 - 27
services/web/test/unit/src/Subscription/SubscriptionGroupControllerTests.mjs

@@ -615,33 +615,6 @@ describe('SubscriptionGroupController', function () {
     })
     })
   })
   })
 
 
-  describe('flexibleLicensingSplitTest', function () {
-    it('passes when the variant is "enabled"', function (done) {
-      const res = sinon.stub()
-      const next = () => {
-        this.ErrorController.notFound.notCalled.should.equal(true)
-        done()
-      }
-      this.SplitTestHandler.promises.getAssignment.resolves({
-        variant: 'enabled',
-      })
-      this.Controller.flexibleLicensingSplitTest(this.req, res, next, done)
-    })
-
-    it('returns error page when the variant is "default"', function (done) {
-      const res = sinon.stub()
-      const next = sinon.stub()
-      this.ErrorController.notFound = sinon.stub().callsFake(() => {
-        next.notCalled.should.equal(true)
-        done()
-      })
-      this.SplitTestHandler.promises.getAssignment.resolves({
-        variant: 'default',
-      })
-      this.Controller.flexibleLicensingSplitTest(this.req, res, next, done)
-    })
-  })
-
   describe('subscriptionUpgradePage', function () {
   describe('subscriptionUpgradePage', function () {
     it('should render "subscription upgrade" page', function (done) {
     it('should render "subscription upgrade" page', function (done) {
       const olSubscription = { membersLimit: 1, teamName: 'test team' }
       const olSubscription = { membersLimit: 1, teamName: 'test team' }