Kaynağa Gözat

Merge pull request #7481 from overleaf/ta-leave-modal-no-password

[DeleteAccount] Handle Password-Less Users

GitOrigin-RevId: b7d03d26d43b9ab7f50a199d9aabd226ac79972d
ilkin-overleaf 4 yıl önce
ebeveyn
işleme
a8fdf6269e

+ 31 - 2
services/web/frontend/js/features/settings/components/leave/modal-content.tsx

@@ -1,7 +1,8 @@
 import { useState, Dispatch, SetStateAction } from 'react'
 import { Modal, Button } from 'react-bootstrap'
 import { useTranslation, Trans } from 'react-i18next'
-import LeaveModalForm from './modal-form'
+import getMeta from '../../../../utils/meta'
+import LeaveModalForm, { LeaveModalFormProps } from './modal-form'
 
 type LeaveModalContentProps = {
   handleHide: () => void
@@ -9,6 +10,34 @@ type LeaveModalContentProps = {
   setInFlight: Dispatch<SetStateAction<boolean>>
 }
 
+function LeaveModalContentBlock({
+  setInFlight,
+  isFormValid,
+  setIsFormValid,
+}: LeaveModalFormProps) {
+  const { t } = useTranslation()
+  const isSaas = getMeta('ol-isSaas') as boolean
+  const hasPassword = getMeta('ol-hasPassword') as boolean
+
+  if (isSaas && !hasPassword) {
+    return (
+      <p>
+        <b>
+          <a href="/user/password/reset">{t('delete_acct_no_existing_pw')}</a>
+        </b>
+      </p>
+    )
+  }
+
+  return (
+    <LeaveModalForm
+      setInFlight={setInFlight}
+      isFormValid={isFormValid}
+      setIsFormValid={setIsFormValid}
+    />
+  )
+}
+
 function LeaveModalContent({
   handleHide,
   inFlight,
@@ -30,7 +59,7 @@ function LeaveModalContent({
             components={[<strong />]} // eslint-disable-line react/jsx-key
           />
         </p>
-        <LeaveModalForm
+        <LeaveModalContentBlock
           setInFlight={setInFlight}
           isFormValid={isFormValid}
           setIsFormValid={setIsFormValid}

+ 1 - 1
services/web/frontend/js/features/settings/components/leave/modal-form.tsx

@@ -5,7 +5,7 @@ import { postJSON, FetchError } from '../../../../infrastructure/fetch-json'
 import getMeta from '../../../../utils/meta'
 import LeaveModalFormError from './modal-form-error'
 
-type LeaveModalFormProps = {
+export type LeaveModalFormProps = {
   setInFlight: Dispatch<SetStateAction<boolean>>
   isFormValid: boolean
   setIsFormValid: Dispatch<SetStateAction<boolean>>

+ 19 - 5
services/web/frontend/stories/settings/leave.stories.js

@@ -11,9 +11,15 @@ function defaultSetupMocks(fetchMock) {
   })
 }
 
-export const Section = args => {
+function setDefaultMeta() {
   window.metaAttributesCache.set('ol-userDefaultEmail', 'user@primary.com')
+  window.metaAttributesCache.set('ol-isSaas', true)
+  window.metaAttributesCache.set('ol-hasPassword', true)
+}
+
+export const Section = args => {
   useFetchMock(defaultSetupMocks)
+  setDefaultMeta()
 
   return <LeaveSection {...args} />
 }
@@ -21,14 +27,22 @@ Section.component = LeaveSection
 Section.parameters = { controls: { include: [], hideNoControlsWarning: true } }
 
 export const ModalSuccess = args => {
-  window.metaAttributesCache.set('ol-userDefaultEmail', 'user@primary.com')
+  setDefaultMeta()
+  useFetchMock(defaultSetupMocks)
+
+  return <LeaveModal {...args} />
+}
+
+export const ModalWithoutPassword = args => {
+  setDefaultMeta()
+  window.metaAttributesCache.set('ol-hasPassword', false)
   useFetchMock(defaultSetupMocks)
 
   return <LeaveModal {...args} />
 }
 
 export const ModalAuthError = args => {
-  window.metaAttributesCache.set('ol-userDefaultEmail', 'user@primary.com')
+  setDefaultMeta()
   useFetchMock(fetchMock => {
     fetchMock.post(/\/user\/delete/, 403)
   })
@@ -37,7 +51,7 @@ export const ModalAuthError = args => {
 }
 
 export const ModalServerError = args => {
-  window.metaAttributesCache.set('ol-userDefaultEmail', 'user@primary.com')
+  setDefaultMeta()
   useFetchMock(fetchMock => {
     fetchMock.post(/\/user\/delete/, 500)
   })
@@ -46,7 +60,7 @@ export const ModalServerError = args => {
 }
 
 export const ModalSubscriptionError = args => {
-  window.metaAttributesCache.set('ol-userDefaultEmail', 'user@primary.com')
+  setDefaultMeta()
   useFetchMock(fetchMock => {
     fetchMock.post(/\/user\/delete/, {
       status: 422,

+ 25 - 0
services/web/test/frontend/features/settings/components/leave/modal-content.test.tsx

@@ -5,7 +5,14 @@ import fetchMock from 'fetch-mock'
 import LeaveModalContent from '../../../../../../frontend/js/features/settings/components/leave/modal-content'
 
 describe('<LeaveModalContent />', function () {
+  beforeEach(function () {
+    window.metaAttributesCache = new Map()
+    window.metaAttributesCache.set('ol-isSaas', false)
+    window.metaAttributesCache.set('ol-hasPassword', true)
+  })
+
   afterEach(function () {
+    window.metaAttributesCache = new Map()
     fetchMock.reset()
   })
 
@@ -17,10 +24,28 @@ describe('<LeaveModalContent />', function () {
         setInFlight={() => {}}
       />
     )
+    screen.getByLabelText('Email')
 
     const deleteButton = screen.getByRole('button', {
       name: 'Delete',
     })
     expect(deleteButton.hasAttribute('disabled')).to.be.true
   })
+
+  it('shows no password message', function () {
+    window.metaAttributesCache.set('ol-isSaas', true)
+    window.metaAttributesCache.set('ol-hasPassword', false)
+    render(
+      <LeaveModalContent
+        handleHide={() => {}}
+        inFlight={false}
+        setInFlight={() => {}}
+      />
+    )
+
+    const link = screen.getByRole('link', {
+      name: 'Please use the password reset form to set a password before deleting your account',
+    })
+    expect(link.getAttribute('href')).to.equal('/user/password/reset')
+  })
 })