diff --git a/services/web/app/src/Features/Subscription/SubscriptionController.mjs b/services/web/app/src/Features/Subscription/SubscriptionController.mjs index b8d15c305d..9e0009585f 100644 --- a/services/web/app/src/Features/Subscription/SubscriptionController.mjs +++ b/services/web/app/src/Features/Subscription/SubscriptionController.mjs @@ -337,6 +337,7 @@ async function userSubscriptionPage(req, res) { groupSettingsAdvertisedFor, groupSettingsEnabledFor, isManagedAccount: !!req.managedBy, + isManagedGroupAdmin: !!req.isManagedGroupAdmin, userRestrictions: Array.from(req.userRestrictions || []), hasAiAssistViaWritefull, aiAssistViaWritefullSource, diff --git a/services/web/app/views/subscriptions/dashboard-react.pug b/services/web/app/views/subscriptions/dashboard-react.pug index 12ab2d272c..0348a1cc55 100644 --- a/services/web/app/views/subscriptions/dashboard-react.pug +++ b/services/web/app/views/subscriptions/dashboard-react.pug @@ -84,6 +84,11 @@ block append meta data-type='string' content=aiAssistViaWritefullSource ) + meta( + name='ol-isManagedGroupAdmin' + data-type='boolean' + content=isManagedGroupAdmin + ) meta(name='ol-user' data-type='json' content=user) if personalSubscription && personalSubscription.payment meta(name='ol-recurlyApiKey' content=settings.apis.recurly.publicKey) diff --git a/services/web/frontend/js/features/subscription/components/dashboard/reactivate-subscription.tsx b/services/web/frontend/js/features/subscription/components/dashboard/reactivate-subscription.tsx index 26416731b5..6717f843dd 100644 --- a/services/web/frontend/js/features/subscription/components/dashboard/reactivate-subscription.tsx +++ b/services/web/frontend/js/features/subscription/components/dashboard/reactivate-subscription.tsx @@ -20,8 +20,12 @@ function ReactivateSubscription() { 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 } diff --git a/services/web/frontend/js/utils/meta.ts b/services/web/frontend/js/utils/meta.ts index d4462a3bc0..86d32af02a 100644 --- a/services/web/frontend/js/utils/meta.ts +++ b/services/web/frontend/js/utils/meta.ts @@ -185,6 +185,7 @@ export interface Meta { 'ol-isCollectionMethodManual': boolean 'ol-isExternalAuthenticationSystemUsed': boolean 'ol-isManagedAccount': boolean + 'ol-isManagedGroupAdmin': boolean 'ol-isProfessional': boolean 'ol-isRegisteredViaGoogle': boolean 'ol-isRestrictedTokenMember': boolean diff --git a/services/web/test/frontend/features/subscription/components/dashboard/personal-subscription.test.tsx b/services/web/test/frontend/features/subscription/components/dashboard/personal-subscription.test.tsx index a61c9fca7f..37e2861ec8 100644 --- a/services/web/test/frontend/features/subscription/components/dashboard/personal-subscription.test.tsx +++ b/services/web/test/frontend/features/subscription/components/dashboard/personal-subscription.test.tsx @@ -115,6 +115,45 @@ describe('', function () { fetchMock.removeRoutes().clearHistory() }) + it('hides reactivate button for managed users who cannot reactivate', function () { + renderWithSubscriptionDashContext(, { + 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(, { + 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 () { renderWithSubscriptionDashContext(, { metaTags: [ diff --git a/services/web/test/unit/src/Subscription/SubscriptionController.test.mjs b/services/web/test/unit/src/Subscription/SubscriptionController.test.mjs index 1d150dd56c..1abd80a383 100644 --- a/services/web/test/unit/src/Subscription/SubscriptionController.test.mjs +++ b/services/web/test/unit/src/Subscription/SubscriptionController.test.mjs @@ -492,6 +492,32 @@ describe('SubscriptionController', function () { 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 () { beforeEach(async function (ctx) { ctx.req.query.errorCode = 'payment_failed'