diff --git a/services/web/frontend/js/features/subscription/components/dashboard/states/active/cancel-plan/cancel-subscription.tsx b/services/web/frontend/js/features/subscription/components/dashboard/states/active/cancel-plan/cancel-subscription.tsx
index 273a474eb7..08b8d987a3 100644
--- a/services/web/frontend/js/features/subscription/components/dashboard/states/active/cancel-plan/cancel-subscription.tsx
+++ b/services/web/frontend/js/features/subscription/components/dashboard/states/active/cancel-plan/cancel-subscription.tsx
@@ -141,8 +141,12 @@ function NotCancelOption({
export function CancelSubscription() {
const { t } = useTranslation()
const location = useLocation()
- const { personalSubscription, plans, userCanExtendTrial } =
- useSubscriptionDashboardContext()
+ const {
+ personalSubscription,
+ plans,
+ queryingIndividualPlansData,
+ userCanExtendTrial,
+ } = useSubscriptionDashboardContext()
const lossMessagingEnabled = useFeatureFlag('cancel-loss-messaging')
const {
isLoading: isLoadingCancel,
@@ -164,14 +168,15 @@ export function CancelSubscription() {
if (!personalSubscription || !('payment' in personalSubscription)) return null
- const showDowngrade =
- personalSubscription.payment.isEligibleForDowngradeUpsell
+ const { isEligibleForDowngradeUpsell } = personalSubscription.payment
+ if (isEligibleForDowngradeUpsell && queryingIndividualPlansData) {
+ return
+ }
const planToDowngradeTo = plans.find(
plan => plan.planCode === planCodeToDowngradeTo
)
- if (showDowngrade && !planToDowngradeTo) {
- return
- }
+ const showDowngrade =
+ isEligibleForDowngradeUpsell && Boolean(planToDowngradeTo)
async function handleCancelSubscription() {
try {
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 27cdf3344c..a2b62cbd05 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
@@ -16,8 +16,13 @@ import {
trialSubscription,
} from '../../../../fixtures/subscriptions'
import sinon from 'sinon'
-import { cleanUpContext } from '../../../../helpers/render-with-subscription-dash-context'
+import {
+ cleanUpContext,
+ renderWithSubscriptionDashContext,
+} from '../../../../helpers/render-with-subscription-dash-context'
import { renderActiveSubscription } from '../../../../helpers/render-active-subscription'
+import { ActiveSubscription } from '../../../../../../../../frontend/js/features/subscription/components/dashboard/states/active/active'
+import { plans } from '../../../../fixtures/plans'
import { cloneDeep } from 'lodash'
import fetchMock from 'fetch-mock'
import {
@@ -690,6 +695,52 @@ describe('', function () {
).to.be.null
})
+ it('falls back to the cancellation confirmation when the downgrade plan is unavailable', async function () {
+ renderWithSubscriptionDashContext(
+ ,
+ {
+ metaTags: [
+ {
+ name: 'ol-plans',
+ value: plans.filter(plan => plan.planCode !== 'paid-personal'),
+ },
+ { name: 'ol-subscription', value: monthlyActiveCollaborator },
+ { name: 'ol-recommendedCurrency', value: 'USD' },
+ ],
+ }
+ )
+ showConfirmCancelUI()
+ await screen.findByRole('button', { name: 'Cancel my subscription' })
+ screen.getByRole('button', { name: 'I want to stay' })
+ expect(
+ screen.queryByRole('button', {
+ name: downgradeButtonText,
+ })
+ ).to.be.null
+ })
+
+ it('shows a loading state while the plans data is being queried', function () {
+ renderWithSubscriptionDashContext(
+ ,
+ {
+ metaTags: [
+ { name: 'ol-subscription', value: monthlyActiveCollaborator },
+ { name: 'ol-recommendedCurrency', value: 'USD' },
+ ],
+ queryingRecurly: true,
+ }
+ )
+ showConfirmCancelUI()
+ screen.getByRole('status')
+ expect(
+ screen.queryByRole('button', {
+ name: downgradeButtonText,
+ })
+ ).to.be.null
+ expect(screen.queryByRole('button', { name: 'Cancel my subscription' }))
+ .to.be.null
+ })
+
it('does not show option to extend trial when on a collaborator trial', function () {
const trialPlan = cloneDeep(trialCollaboratorSubscription)
renderActiveSubscription(trialPlan)