diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Auth/AuthProviders/BasicAuthProvider.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Auth/AuthProviders/BasicAuthProvider.tsx index 649b37fc269..ff6d0a01749 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Auth/AuthProviders/BasicAuthProvider.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Auth/AuthProviders/BasicAuthProvider.tsx @@ -169,18 +169,7 @@ const BasicAuthProvider = ({ }; const handleForgotPassword = async (email: string) => { - try { - await generatePasswordResetLink(email); - } catch (err) { - if ( - (err as AxiosError).response?.status === - HTTP_STATUS_CODE.FAILED_DEPENDENCY - ) { - showErrorToast(t('server.forgot-password-email-error')); - } else { - showErrorToast(t('server.email-not-found')); - } - } + await generatePasswordResetLink(email); }; const handleResetPassword = async (payload: PasswordResetRequest) => { diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/ForgotPassword/ForgotPassword.component.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/ForgotPassword/ForgotPassword.component.tsx index 4e19c8fb768..349e3e8ef22 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/ForgotPassword/ForgotPassword.component.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/ForgotPassword/ForgotPassword.component.tsx @@ -13,13 +13,16 @@ import Icon from '@ant-design/icons/lib/components/Icon'; import { Button, Card, Col, Divider, Form, Input, Row, Typography } from 'antd'; +import { AxiosError } from 'axios'; import React, { useCallback, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useHistory } from 'react-router-dom'; import { ReactComponent as IconSuccessBadge } from '../../assets/svg/success-badge.svg'; import { useBasicAuth } from '../../components/Auth/AuthProviders/BasicAuthProvider'; import BrandImage from '../../components/common/BrandImage/BrandImage'; +import { HTTP_STATUS_CODE } from '../../constants/Auth.constants'; import { ROUTES } from '../../constants/constants'; +import { showErrorToast } from '../../utils/ToastUtils'; import './forgot-password.styles.less'; const ForgotPassword = () => { @@ -34,9 +37,16 @@ const ForgotPassword = () => { async (data: { email: string }) => { try { setLoading(true); - handleForgotPassword && (await handleForgotPassword(data.email)); + await handleForgotPassword?.(data.email); setShowResetLinkSentAlert(true); } catch (error) { + showErrorToast( + (error as AxiosError).response?.status === + HTTP_STATUS_CODE.FAILED_DEPENDENCY + ? t('server.forgot-password-email-error') + : t('server.email-not-found') + ); + setShowResetLinkSentAlert(false); } finally { setLoading(false); diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/ForgotPassword/ForgotPassword.test.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/ForgotPassword/ForgotPassword.test.tsx index f442d2cdb17..41ec536172d 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/ForgotPassword/ForgotPassword.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/ForgotPassword/ForgotPassword.test.tsx @@ -13,19 +13,31 @@ import { act, fireEvent, render } from '@testing-library/react'; import React from 'react'; import { useBasicAuth } from '../../components/Auth/AuthProviders/BasicAuthProvider'; +import { showErrorToast } from '../../utils/ToastUtils'; import ForgotPassword from './ForgotPassword.component'; const mockPush = jest.fn(); -const handleForgotPassword = jest.fn(); +const mockHandleForgotPassword = jest.fn(); +const mockHandleError = jest.fn().mockImplementation(() => { + return Promise.reject({ + response: { + data: { message: 'Error!' }, + }, + }); +}); jest.mock('../../components/Auth/AuthProviders/BasicAuthProvider', () => { return { useBasicAuth: jest.fn().mockImplementation(() => ({ - handleResetPassword: handleForgotPassword, + handleForgotPassword: mockHandleForgotPassword, })), }; }); +jest.mock('../../utils/ToastUtils', () => ({ + showErrorToast: jest.fn(), +})); + jest.mock('react-router-dom', () => ({ useHistory: jest.fn().mockImplementation(() => ({ push: mockPush, @@ -43,7 +55,9 @@ describe('ForgotPassword', () => { }); it('calls handleForgotPassword with the correct email', async () => { - (useBasicAuth as jest.Mock).mockReturnValue({ handleForgotPassword }); + (useBasicAuth as jest.Mock).mockReturnValue({ + handleForgotPassword: mockHandleForgotPassword, + }); const { getByLabelText, getByText } = render(); const emailInput = getByLabelText('label.email'); @@ -55,7 +69,7 @@ describe('ForgotPassword', () => { fireEvent.click(submitButton); }); - expect(handleForgotPassword).toHaveBeenCalledWith('test@example.com'); + expect(mockHandleForgotPassword).toHaveBeenCalledWith('test@example.com'); }); it('shows an error when email is not provided', async () => { @@ -89,7 +103,7 @@ describe('ForgotPassword', () => { fireEvent.click(submitButton); }); - expect(handleForgotPassword).toHaveBeenCalledWith('test@example.com'); + expect(mockHandleForgotPassword).toHaveBeenCalledWith('test@example.com'); expect(getByTestId('success-screen-container')).toBeInTheDocument(); expect(getByTestId('success-icon')).toBeInTheDocument(); expect(getByTestId('success-line')).toBeInTheDocument(); @@ -104,4 +118,26 @@ describe('ForgotPassword', () => { expect(mockPush).toHaveBeenCalled(); }); + + it('should call show error toast', async () => { + (useBasicAuth as jest.Mock).mockReturnValueOnce({ + handleForgotPassword: mockHandleError, + }); + + const { getByLabelText, getByText, queryByTestId } = render( + + ); + const emailInput = getByLabelText('label.email'); + const submitButton = getByText('label.submit'); + await act(async () => { + fireEvent.change(emailInput, { target: { value: 'test@example.com' } }); + }); + await act(async () => { + fireEvent.click(submitButton); + }); + + expect(showErrorToast).toHaveBeenCalledWith('server.email-not-found'); + expect(mockHandleError).toHaveBeenCalledWith('test@example.com'); + expect(queryByTestId('success-screen-container')).not.toBeInTheDocument(); + }); });