瀏覽代碼

fix: [web] managed group admins unable to re-subscribe (#29634)

GitOrigin-RevId: 5e3d46c39f4657fcc737403a80093b870bc42240
Simon Gardner 3 月之前
父節點
當前提交
8a331bc943

+ 1 - 0
services/web/app/src/Features/Subscription/SubscriptionController.mjs

@@ -337,6 +337,7 @@ async function userSubscriptionPage(req, res) {
     groupSettingsAdvertisedFor,
     groupSettingsAdvertisedFor,
     groupSettingsEnabledFor,
     groupSettingsEnabledFor,
     isManagedAccount: !!req.managedBy,
     isManagedAccount: !!req.managedBy,
+    isManagedGroupAdmin: !!req.isManagedGroupAdmin,
     userRestrictions: Array.from(req.userRestrictions || []),
     userRestrictions: Array.from(req.userRestrictions || []),
     hasAiAssistViaWritefull,
     hasAiAssistViaWritefull,
     aiAssistViaWritefullSource,
     aiAssistViaWritefullSource,

+ 5 - 0
services/web/app/views/subscriptions/dashboard-react.pug

@@ -84,6 +84,11 @@ block append meta
 		data-type='string'
 		data-type='string'
 		content=aiAssistViaWritefullSource
 		content=aiAssistViaWritefullSource
 	)
 	)
+	meta(
+		name='ol-isManagedGroupAdmin'
+		data-type='boolean'
+		content=isManagedGroupAdmin
+	)
 	meta(name='ol-user' data-type='json' content=user)
 	meta(name='ol-user' data-type='json' content=user)
 	if personalSubscription && personalSubscription.payment
 	if personalSubscription && personalSubscription.payment
 		meta(name='ol-recurlyApiKey' content=settings.apis.recurly.publicKey)
 		meta(name='ol-recurlyApiKey' content=settings.apis.recurly.publicKey)

+ 6 - 2
services/web/frontend/js/features/subscription/components/dashboard/reactivate-subscription.tsx

@@ -20,8 +20,12 @@ function ReactivateSubscription() {
     location.reload()
     location.reload()
   }
   }
 
 
-  // Don't show the button to reactivate the subscription for managed users
-  if (getMeta('ol-cannot-reactivate-subscription')) {
+  // Don't show the button to reactivate the subscription for managed users,
+  // unless they are a managed group admin (who should be able to reactivate their own subscription)
+  if (
+    getMeta('ol-cannot-reactivate-subscription') &&
+    !getMeta('ol-isManagedGroupAdmin')
+  ) {
     return null
     return null
   }
   }
 
 

+ 1 - 0
services/web/frontend/js/utils/meta.ts

@@ -185,6 +185,7 @@ export interface Meta {
   'ol-isCollectionMethodManual': boolean
   'ol-isCollectionMethodManual': boolean
   'ol-isExternalAuthenticationSystemUsed': boolean
   'ol-isExternalAuthenticationSystemUsed': boolean
   'ol-isManagedAccount': boolean
   'ol-isManagedAccount': boolean
+  'ol-isManagedGroupAdmin': boolean
   'ol-isProfessional': boolean
   'ol-isProfessional': boolean
   'ol-isRegisteredViaGoogle': boolean
   'ol-isRegisteredViaGoogle': boolean
   'ol-isRestrictedTokenMember': boolean
   'ol-isRestrictedTokenMember': boolean

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

@@ -115,6 +115,45 @@ describe('<PersonalSubscription />', function () {
       fetchMock.removeRoutes().clearHistory()
       fetchMock.removeRoutes().clearHistory()
     })
     })
 
 
+    it('hides reactivate button for managed users who cannot reactivate', function () {
+      renderWithSubscriptionDashContext(<PersonalSubscription />, {
+        metaTags: [
+          { name: 'ol-subscription', value: canceledSubscription },
+          { name: 'ol-cannot-reactivate-subscription', value: true },
+        ],
+      })
+
+      screen.getByText(
+        'Your subscription has been canceled and will terminate on',
+        { exact: false }
+      )
+      screen.getByRole('link', { name: 'View your invoices' })
+
+      // Should not show the reactivate button
+      expect(
+        screen.queryByRole('button', { name: 'Reactivate your subscription' })
+      ).to.be.null
+    })
+
+    it('shows reactivate button for managed group admins even if they have reactivate restriction', function () {
+      renderWithSubscriptionDashContext(<PersonalSubscription />, {
+        metaTags: [
+          { name: 'ol-subscription', value: canceledSubscription },
+          { name: 'ol-cannot-reactivate-subscription', value: true },
+          { name: 'ol-isManagedGroupAdmin', value: true },
+        ],
+      })
+
+      screen.getByText(
+        'Your subscription has been canceled and will terminate on',
+        { exact: false }
+      )
+      screen.getByRole('link', { name: 'View your invoices' })
+
+      // Should show the reactivate button for group admins
+      screen.getByRole('button', { name: 'Reactivate your subscription' })
+    })
+
     it('renders the expired dash', function () {
     it('renders the expired dash', function () {
       renderWithSubscriptionDashContext(<PersonalSubscription />, {
       renderWithSubscriptionDashContext(<PersonalSubscription />, {
         metaTags: [
         metaTags: [

+ 26 - 0
services/web/test/unit/src/Subscription/SubscriptionController.test.mjs

@@ -492,6 +492,32 @@ describe('SubscriptionController', function () {
       expect(ctx.data.groupSettingsEnabledFor).to.deep.equal([])
       expect(ctx.data.groupSettingsEnabledFor).to.deep.equal([])
     })
     })
 
 
+    it('should pass isManagedGroupAdmin as false when not set', function (ctx) {
+      expect(ctx.data.isManagedGroupAdmin).to.equal(false)
+    })
+
+    describe('when user is a managed group admin', function () {
+      beforeEach(async function (ctx) {
+        ctx.req.isManagedGroupAdmin = true
+        await new Promise((resolve, reject) => {
+          ctx.res.render = (view, data) => {
+            ctx.data = data
+            expect(view).to.equal('subscriptions/dashboard-react')
+            resolve()
+          }
+          ctx.SubscriptionController.userSubscriptionPage(
+            ctx.req,
+            ctx.res,
+            ctx.rejectOnError(reject)
+          )
+        })
+      })
+
+      it('should pass isManagedGroupAdmin as true', function (ctx) {
+        expect(ctx.data.isManagedGroupAdmin).to.equal(true)
+      })
+    })
+
     describe('when errorCode query param is present', function () {
     describe('when errorCode query param is present', function () {
       beforeEach(async function (ctx) {
       beforeEach(async function (ctx) {
         ctx.req.query.errorCode = 'payment_failed'
         ctx.req.query.errorCode = 'payment_failed'