From 50b5aa33b12b7d79acc4d687bf688dd87079df8b Mon Sep 17 00:00:00 2001 From: roo hutton Date: Tue, 24 Jun 2025 10:30:17 +0100 Subject: [PATCH] Merge pull request #26495 from overleaf/rh-prevent-pause-cancel-last-term Redirect to support if trying to cancel in last month of pause GitOrigin-RevId: d92f84c79482bb7c409f4e3070337b0ac958756a --- .../active/cancel-subscription-button.tsx | 14 +++++++-- .../dashboard/states/active/active.test.tsx | 29 +++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/services/web/frontend/js/features/subscription/components/dashboard/states/active/cancel-subscription-button.tsx b/services/web/frontend/js/features/subscription/components/dashboard/states/active/cancel-subscription-button.tsx index 7713b4671d..f99b145b9b 100644 --- a/services/web/frontend/js/features/subscription/components/dashboard/states/active/cancel-subscription-button.tsx +++ b/services/web/frontend/js/features/subscription/components/dashboard/states/active/cancel-subscription-button.tsx @@ -4,6 +4,7 @@ import { useSubscriptionDashboardContext } from '../../../../context/subscriptio import OLButton from '@/features/ui/components/ol/ol-button' import { PaidSubscription } from '../../../../../../../../types/subscription/dashboard/subscription' import { useFeatureFlag } from '@/shared/context/split-test-context' +import { useLocation } from '@/shared/hooks/use-location' export function CancelSubscriptionButton() { const { t } = useTranslation() @@ -13,6 +14,7 @@ export function CancelSubscriptionButton() { setModalIdShown, setShowCancellation, } = useSubscriptionDashboardContext() + const location = useLocation() const subscription = personalSubscription as PaidSubscription const isInTrial = @@ -29,14 +31,22 @@ export function CancelSubscriptionButton() { useFeatureFlag('pause-subscription') && !hasPendingOrActivePause && planIsEligibleForPause + const shouldContactSupport = + subscription.payment.state === 'paused' && + subscription.payment.remainingPauseCycles === 0 function handleCancelSubscriptionClick() { eventTracking.sendMB('subscription-page-cancel-button-click', { plan_code: subscription?.planCode, is_trial: isInTrial, }) - if (enablePause) setModalIdShown('pause-subscription') - else setShowCancellation(true) + if (shouldContactSupport) { + location.assign('/contact') + } else if (enablePause) { + setModalIdShown('pause-subscription') + } else { + setShowCancellation(true) + } } if (recurlyLoadError) return null diff --git a/services/web/test/frontend/features/subscription/components/dashboard/states/active/active.test.tsx b/services/web/test/frontend/features/subscription/components/dashboard/states/active/active.test.tsx index baada41976..f5802a2368 100644 --- a/services/web/test/frontend/features/subscription/components/dashboard/states/active/active.test.tsx +++ b/services/web/test/frontend/features/subscription/components/dashboard/states/active/active.test.tsx @@ -516,6 +516,35 @@ describe('', function () { }) }) + describe('contact support for paused subscription with 0 remaining cycles', function () { + beforeEach(function () { + this.locationWrapperSandbox = sinon.createSandbox() + this.locationWrapperStub = this.locationWrapperSandbox.stub(location) + }) + + afterEach(function () { + this.locationWrapperSandbox.restore() + }) + + it('redirects to contact page when cancel button clicked', function () { + const pausedSubscription = cloneDeep(annualActiveSubscription) + pausedSubscription.payment.state = 'paused' + pausedSubscription.payment.remainingPauseCycles = 0 + + renderActiveSubscription(pausedSubscription) + + const button = screen.getByRole('button', { + name: 'Cancel your subscription', + }) + fireEvent.click(button) + + expect(sendMBSpy).to.be.calledOnceWith( + 'subscription-page-cancel-button-click' + ) + expect(this.locationWrapperStub.assign).to.be.calledOnceWith('/contact') + }) + }) + describe('group plans', function () { it('does not show "Change plan" option for group plans', function () { renderActiveSubscription(groupActiveSubscription)