Просмотр исходного кода

Merge pull request #25998 from overleaf/mf-update-stripe-email-from-subscription-dashboard

[web] Make user able to sync their email address in subscription dashboard for Stripe subscription

GitOrigin-RevId: 9abdc0e18ebea29b18c2041130946b9e50fa43db
M Fahru 1 год назад
Родитель
Сommit
832f9923b9

+ 2 - 1
services/web/app/src/Features/Subscription/SubscriptionController.js

@@ -538,7 +538,8 @@ function cancelPendingSubscriptionChange(req, res, next) {
 async function updateAccountEmailAddress(req, res, next) {
   const user = SessionManager.getSessionUser(req.session)
   try {
-    await RecurlyWrapper.promises.updateAccountEmailAddress(
+    await Modules.promises.hooks.fire(
+      'updateAccountEmailAddress',
       user._id,
       user.email
     )

+ 9 - 9
services/web/frontend/js/features/subscription/components/dashboard/personal-subscription-recurly-sync-email.tsx → services/web/frontend/js/features/subscription/components/dashboard/personal-subscription-sync-email.tsx

@@ -7,23 +7,23 @@ import OLNotification from '@/features/ui/components/ol/ol-notification'
 import OLButton from '@/features/ui/components/ol/ol-button'
 import OLFormGroup from '@/features/ui/components/ol/ol-form-group'
 
-function PersonalSubscriptionRecurlySyncEmail() {
+function PersonalSubscriptionSyncEmail() {
   const { t } = useTranslation()
   const { personalSubscription } = useSubscriptionDashboardContext()
   const userEmail = getMeta('ol-usersEmail')
   const { isLoading, isSuccess, runAsync } = useAsync()
 
+  if (!personalSubscription || !('payment' in personalSubscription)) return null
+
+  const accountEmail = personalSubscription.payment.accountEmail
+
+  if (!userEmail || accountEmail === userEmail) return null
+
   const handleSubmit = (e: React.FormEvent) => {
     e.preventDefault()
     runAsync(postJSON('/user/subscription/account/email'))
   }
 
-  if (!personalSubscription || !('payment' in personalSubscription)) return null
-
-  const recurlyEmail = personalSubscription.payment.accountEmail
-
-  if (!userEmail || recurlyEmail === userEmail) return null
-
   return (
     <>
       <form onSubmit={handleSubmit}>
@@ -39,7 +39,7 @@ function PersonalSubscriptionRecurlySyncEmail() {
                 <Trans
                   i18nKey="recurly_email_update_needed"
                   components={[<em />, <em />]} // eslint-disable-line react/jsx-key
-                  values={{ recurlyEmail, userEmail }}
+                  values={{ recurlyEmail: accountEmail, userEmail }}
                   shouldUnescape
                   tOptions={{ interpolation: { escapeValue: true } }}
                 />
@@ -64,4 +64,4 @@ function PersonalSubscriptionRecurlySyncEmail() {
   )
 }
 
-export default PersonalSubscriptionRecurlySyncEmail
+export default PersonalSubscriptionSyncEmail

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

@@ -5,7 +5,7 @@ import { ActiveSubscriptionNew } from '@/features/subscription/components/dashbo
 import { CanceledSubscription } from './states/canceled'
 import { ExpiredSubscription } from './states/expired'
 import { useSubscriptionDashboardContext } from '../../context/subscription-dashboard-context'
-import PersonalSubscriptionRecurlySyncEmail from './personal-subscription-recurly-sync-email'
+import PersonalSubscriptionSyncEmail from './personal-subscription-sync-email'
 import OLNotification from '@/features/ui/components/ol/ol-notification'
 import RedirectAlerts from './redirect-alerts'
 
@@ -90,7 +90,7 @@ function PersonalSubscription() {
         />
       )}
       <hr />
-      <PersonalSubscriptionRecurlySyncEmail />
+      <PersonalSubscriptionSyncEmail />
     </>
   )
 }

+ 3 - 1
services/web/test/frontend/features/subscription/components/dashboard/personal-subscription.test.tsx

@@ -190,7 +190,9 @@ describe('<PersonalSubscription />', function () {
   })
 
   it('shows different payment email address section', async function () {
-    fetchMock.post('/user/subscription/account/email', 200)
+    fetchMock.post('/user/subscription/account/email', {
+      status: 200,
+    })
     const usersEmail = 'foo@example.com'
     renderWithSubscriptionDashContext(<PersonalSubscription />, {
       metaTags: [

+ 18 - 7
services/web/test/unit/src/Subscription/SubscriptionControllerTests.js

@@ -311,15 +311,25 @@ describe('SubscriptionController', function () {
   })
 
   describe('updateAccountEmailAddress via put', function () {
-    it('should send the user and subscriptionId to RecurlyWrapper', async function () {
+    beforeEach(function () {
+      this.req.body = {
+        account_email: 'current_account_email@overleaf.com',
+      }
+    })
+
+    it('should send the user and subscriptionId to "updateAccountEmailAddress" hooks', async function () {
       this.res.sendStatus = sinon.spy()
+
       await this.SubscriptionController.updateAccountEmailAddress(
         this.req,
         this.res
       )
-      this.RecurlyWrapper.promises.updateAccountEmailAddress
-        .calledWith(this.user._id, this.user.email)
-        .should.equal(true)
+
+      expect(this.Modules.promises.hooks.fire).to.have.been.calledWith(
+        'updateAccountEmailAddress',
+        this.user._id,
+        this.user.email
+      )
     })
 
     it('should respond with 200', async function () {
@@ -332,9 +342,10 @@ describe('SubscriptionController', function () {
     })
 
     it('should send the error to the next handler when updating recurly account email fails', async function () {
-      this.RecurlyWrapper.promises.updateAccountEmailAddress.rejects(
-        new Error()
-      )
+      this.Modules.promises.hooks.fire
+        .withArgs('updateAccountEmailAddress', this.user._id, this.user.email)
+        .rejects(new Error())
+
       this.next = sinon.spy(error => {
         expect(error).to.be.instanceOf(Error)
       })