From f82bb4e4ebf1bae219c59181b69c7ee8b543e45b Mon Sep 17 00:00:00 2001
From: ilkin-overleaf <100852799+ilkin-overleaf@users.noreply.github.com>
Date: Tue, 28 Feb 2023 11:48:48 +0200
Subject: [PATCH] Merge pull request #11963 from
overleaf/ii-react-subscription-dash-reactivate-subscription
[web] Subscription dash reactivate button react migration
GitOrigin-RevId: dde8dd1abb8979bdf90d71ea07e1336e9af491b3
---
.../dashboard/reactivate-subscription.tsx | 31 +++++++++++++++++
.../components/dashboard/states/canceled.tsx | 8 ++---
.../subscription/data/subscription-url.ts | 1 +
.../dashboard/personal-subscription.test.tsx | 34 +++++++++++++++++++
.../subscription/fixtures/subscriptions.tsx | 2 ++
5 files changed, 70 insertions(+), 6 deletions(-)
create mode 100644 services/web/frontend/js/features/subscription/components/dashboard/reactivate-subscription.tsx
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
new file mode 100644
index 0000000000..4709bbcd65
--- /dev/null
+++ b/services/web/frontend/js/features/subscription/components/dashboard/reactivate-subscription.tsx
@@ -0,0 +1,31 @@
+import { useTranslation } from 'react-i18next'
+import { postJSON } from '../../../../infrastructure/fetch-json'
+import { reactivateSubscriptionUrl } from '../../data/subscription-url'
+import { reload } from '../../../../shared/components/location'
+import useAsync from '../../../../shared/hooks/use-async'
+
+function ReactivateSubscription() {
+ const { t } = useTranslation()
+ const { isLoading, isSuccess, runAsync } = useAsync()
+
+ const handleReactivate = () => {
+ runAsync(postJSON(reactivateSubscriptionUrl)).catch(console.error)
+ }
+
+ if (isSuccess) {
+ reload()
+ }
+
+ return (
+
+ )
+}
+
+export default ReactivateSubscription
diff --git a/services/web/frontend/js/features/subscription/components/dashboard/states/canceled.tsx b/services/web/frontend/js/features/subscription/components/dashboard/states/canceled.tsx
index b920e74a3c..e7c6cd430a 100644
--- a/services/web/frontend/js/features/subscription/components/dashboard/states/canceled.tsx
+++ b/services/web/frontend/js/features/subscription/components/dashboard/states/canceled.tsx
@@ -1,6 +1,7 @@
import { useTranslation, Trans } from 'react-i18next'
import { RecurlySubscription } from '../../../../../../../types/subscription/dashboard/subscription'
import PremiumFeaturesLink from '../premium-features-link'
+import ReactivateSubscription from '../reactivate-subscription'
export function CanceledSubscription({
subscription,
@@ -46,12 +47,7 @@ export function CanceledSubscription({
{t('view_your_invoices')}
-
+
>
)
}
diff --git a/services/web/frontend/js/features/subscription/data/subscription-url.ts b/services/web/frontend/js/features/subscription/data/subscription-url.ts
index 075635c8d6..01ad6a0fe5 100644
--- a/services/web/frontend/js/features/subscription/data/subscription-url.ts
+++ b/services/web/frontend/js/features/subscription/data/subscription-url.ts
@@ -4,3 +4,4 @@ export const cancelPendingSubscriptionChangeUrl =
export const cancelSubscriptionUrl = '/user/subscription/cancel'
export const redirectAfterCancelSubscriptionUrl = '/user/subscription/canceled'
export const extendTrialUrl = '/user/subscription/extend'
+export const reactivateSubscriptionUrl = '/user/subscription/reactivate'
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 89ed466425..9d8d2f32e9 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
@@ -16,7 +16,10 @@ import {
cleanUpContext,
renderWithSubscriptionDashContext,
} from '../../helpers/render-with-subscription-dash-context'
+import { reactivateSubscriptionUrl } from '../../../../../../frontend/js/features/subscription/data/subscription-url'
+import * as locationModule from '../../../../../../frontend/js/shared/components/location'
import fetchMock from 'fetch-mock'
+import sinon from 'sinon'
describe('', function () {
afterEach(function () {
@@ -78,6 +81,37 @@ describe('', function () {
screen.getByRole('button', { name: 'Reactivate your subscription' })
})
+ it('reactivates canceled plan', async function () {
+ const reload = sinon.stub(locationModule, 'reload')
+
+ renderWithSubscriptionDashContext(, {
+ metaTags: [{ name: 'ol-subscription', value: canceledSubscription }],
+ })
+
+ const reactivateBtn = screen.getByRole('button', {
+ name: 'Reactivate your subscription',
+ })
+
+ // 1st click - fail
+ fetchMock.postOnce(reactivateSubscriptionUrl, 400)
+ fireEvent.click(reactivateBtn)
+ expect(reactivateBtn.disabled).to.be.true
+ await fetchMock.flush(true)
+ expect(reactivateBtn.disabled).to.be.false
+ expect(reload).not.to.have.been.called
+ fetchMock.reset()
+
+ // 2nd click - success
+ fetchMock.postOnce(reactivateSubscriptionUrl, 200)
+ fireEvent.click(reactivateBtn)
+ await fetchMock.flush(true)
+ expect(reload).to.have.been.calledOnce
+ expect(reactivateBtn.disabled).to.be.true
+ fetchMock.reset()
+
+ reload.restore()
+ })
+
it('renders the expired dash', function () {
renderWithSubscriptionDashContext(, {
metaTags: [
diff --git a/services/web/test/frontend/features/subscription/fixtures/subscriptions.tsx b/services/web/test/frontend/features/subscription/fixtures/subscriptions.tsx
index 5926e86ccc..bbdbec3515 100644
--- a/services/web/test/frontend/features/subscription/fixtures/subscriptions.tsx
+++ b/services/web/test/frontend/features/subscription/fixtures/subscriptions.tsx
@@ -475,6 +475,7 @@ export const trialCollaboratorSubscription: RecurlySubscription = {
trial_ends_at: new Date(sevenDaysFromToday).toString(),
activeCoupons: [],
account: {
+ email: 'foo@example.com',
has_canceled_subscription: {
_: 'false',
$: {
@@ -523,6 +524,7 @@ export const monthlyActiveCollaborator: RecurlySubscription = {
trial_ends_at: null,
activeCoupons: [],
account: {
+ email: 'foo@example.com',
has_canceled_subscription: { _: 'false', $: { type: 'boolean' } },
has_past_due_invoice: { _: 'false', $: { type: 'boolean' } },
},