Переглянути джерело

Merge pull request #8179 from overleaf/ii-settings-make-primary-btn-tooltip

Fix make primary button states

GitOrigin-RevId: a3c6fef4fd7c40f0308605f5bed4a91447838bef
Alf Eaton 4 роки тому
батько
коміт
c138e43b64

+ 7 - 10
services/web/frontend/js/features/settings/components/emails/actions/make-primary.tsx

@@ -28,16 +28,14 @@ const getDescription = (
   }
 
   const ssoAvailable = ssoAvailableForInstitution(
-    userEmailData.affiliation?.institution
+    userEmailData.affiliation?.institution || null
   )
 
-  if (!institutionAlreadyLinked(state, userEmailData)) {
-    return ssoAvailable
-      ? t('please_link_before_making_primary')
-      : t('please_confirm_your_email_before_making_it_default')
+  if (!institutionAlreadyLinked(state, userEmailData) && ssoAvailable) {
+    return t('please_link_before_making_primary')
   }
 
-  return ''
+  return t('please_confirm_your_email_before_making_it_default')
 }
 
 function PrimaryButton({ children, disabled, onClick }: Button.ButtonProps) {
@@ -87,7 +85,7 @@ function MakePrimary({ userEmailData, makePrimaryAsync }: MakePrimaryProps) {
 
   return (
     <Tooltip
-      id={`tooltip-make-primary-${userEmailData.email}`}
+      id={`make-primary-${userEmailData.email}`}
       description={getDescription(t, state, userEmailData)}
     >
       {/*
@@ -97,10 +95,9 @@ function MakePrimary({ userEmailData, makePrimaryAsync }: MakePrimaryProps) {
       <span>
         <PrimaryButton
           disabled={
+            !userEmailData.confirmedAt ||
             state.isLoading ||
-            inReconfirmNotificationPeriod(userEmailData) ||
-            (!userEmailData.confirmedAt &&
-              !institutionAlreadyLinked(state, userEmailData))
+            inReconfirmNotificationPeriod(userEmailData)
           }
           onClick={handleSetDefaultUserEmail}
         >

+ 132 - 0
services/web/test/frontend/features/settings/components/emails/emails-section-actions.test.tsx

@@ -4,10 +4,13 @@ import {
   waitForElementToBeRemoved,
   fireEvent,
 } from '@testing-library/react'
+import userEvent from '@testing-library/user-event'
 import { expect } from 'chai'
 import { UserEmailData } from '../../../../../../types/user-email'
 import fetchMock from 'fetch-mock'
 import EmailsSection from '../../../../../../frontend/js/features/settings/components/emails-section'
+import { Institution } from '../../../../../../types/institution'
+import { Affiliation } from '../../../../../../types/affiliation'
 
 const userEmailData: UserEmailData = {
   confirmedAt: '2022-03-10T10:59:44.139Z',
@@ -15,6 +18,18 @@ const userEmailData: UserEmailData = {
   default: false,
 }
 
+const userEmailData2: UserEmailData = {
+  affiliation: {
+    inReconfirmNotificationPeriod: false,
+    institution: {
+      confirmed: false,
+    } as Institution,
+  } as Affiliation,
+  confirmedAt: '2022-03-10T10:59:44.139Z',
+  email: 'bar@overleaf.com',
+  default: false,
+}
+
 describe('email actions - make primary', function () {
   beforeEach(function () {
     window.metaAttributesCache.set('ol-ExposedSettings', {
@@ -28,6 +43,123 @@ describe('email actions - make primary', function () {
     fetchMock.reset()
   })
 
+  describe('disabled `make primary` button', function () {
+    it('when renders with unconfirmed email', async function () {
+      const userEmailDataCopy = { ...userEmailData2 }
+      const { confirmedAt: _, ...userEmailData } = userEmailDataCopy
+      fetchMock.get('/user/emails?ensureAffiliation=true', [userEmailData])
+      render(<EmailsSection />)
+
+      const button = (await screen.findByRole('button', {
+        name: /make primary/i,
+      })) as HTMLButtonElement
+      expect(button.disabled).to.be.true
+    })
+
+    it('when renders with email in reconfirmation period', async function () {
+      const userEmailDataCopy = {
+        ...userEmailData2,
+        affiliation: {
+          ...userEmailData2.affiliation,
+          inReconfirmNotificationPeriod: true,
+        },
+      }
+      fetchMock.get('/user/emails?ensureAffiliation=true', [userEmailDataCopy])
+      render(<EmailsSection />)
+
+      const button = (await screen.findByRole('button', {
+        name: /make primary/i,
+      })) as HTMLButtonElement
+      expect(button.disabled).to.be.true
+    })
+  })
+
+  describe('button tooltips', function () {
+    it('when the email is in reconfirmation period', async function () {
+      const userEmailDataCopy = {
+        ...userEmailData2,
+        affiliation: {
+          ...userEmailData2.affiliation,
+          inReconfirmNotificationPeriod: true,
+        },
+      }
+
+      fetchMock.get('/user/emails?ensureAffiliation=true', [userEmailDataCopy])
+      render(<EmailsSection />)
+
+      const button = (await screen.findByRole('button', {
+        name: /make primary/i,
+      })) as HTMLButtonElement
+
+      userEvent.hover(button.parentElement)
+
+      screen.getByText(
+        /Please confirm your affiliation before making this the primary/i
+      )
+    })
+
+    it('when the email is confirmed', async function () {
+      const userEmailDataCopy = { ...userEmailData2 }
+
+      fetchMock.get('/user/emails?ensureAffiliation=true', [userEmailDataCopy])
+      render(<EmailsSection />)
+
+      const button = (await screen.findByRole('button', {
+        name: /make primary/i,
+      })) as HTMLButtonElement
+
+      userEvent.hover(button.parentElement)
+
+      screen.getByText('Make this the primary email, used to log in', {
+        exact: false,
+      })
+    })
+
+    it('when not linked to institution', async function () {
+      window.metaAttributesCache.set('ol-ExposedSettings', {
+        hasAffiliationsFeature: true,
+        hasSamlFeature: true,
+      })
+
+      const userEmailDataCopy = { ...userEmailData2 }
+      const { confirmedAt: _, ...userEmailData } = userEmailDataCopy
+      const userEmailDataCopy1 = { ...userEmailData }
+      const userEmailDataCopy2 = {
+        ...userEmailData,
+        email: 'baz@overleaf.com',
+        affiliation: {
+          ...userEmailData.affiliation,
+          institution: {
+            ...userEmailData.affiliation.institution,
+            id: 123,
+            confirmed: true,
+            isUniversity: true,
+            ssoEnabled: true,
+          },
+        },
+      }
+
+      fetchMock.get('/user/emails?ensureAffiliation=true', [
+        userEmailDataCopy1,
+        userEmailDataCopy2,
+      ])
+      render(<EmailsSection />)
+
+      const buttons = (await screen.findAllByRole('button', {
+        name: /make primary/i,
+      })) as HTMLButtonElement[]
+
+      userEvent.hover(buttons[1].parentElement)
+
+      screen.getByText(
+        'Please confirm your email by linking to your institutional account before making it the primary email',
+        {
+          exact: false,
+        }
+      )
+    })
+  })
+
   it('shows loader when making email primary and removes button', async function () {
     fetchMock
       .get('/user/emails?ensureAffiliation=true', [userEmailData])