diff --git a/src/components/Tool/FixEmailAddresses/EmailValidationForm.tsx b/src/components/Tool/FixEmailAddresses/EmailValidationForm.tsx index 2487ee12a..98636c499 100644 --- a/src/components/Tool/FixEmailAddresses/EmailValidationForm.tsx +++ b/src/components/Tool/FixEmailAddresses/EmailValidationForm.tsx @@ -1,10 +1,12 @@ import { Grid, IconButton, TextField } from '@mui/material'; import { styled } from '@mui/material/styles'; import { Form, Formik } from 'formik'; +import { useSnackbar } from 'notistack'; import { useTranslation } from 'react-i18next'; -import * as Yup from 'yup'; +import * as yup from 'yup'; import { AddIcon } from 'src/components/Contacts/ContactDetails/ContactDetailsTab/StyledComponents'; import { useAccountListId } from 'src/hooks/useAccountListId'; +import i18n from 'src/lib/i18n'; import { useEmailAddressesMutation } from './AddEmailAddress.generated'; import { RowWrapper } from './FixEmailAddressPerson'; import { @@ -32,10 +34,23 @@ interface EmailValidationFormProps { personId: string; } +const validationSchema = yup.object({ + email: yup + .string() + .email(i18n.t('Invalid Email Address Format')) + .required(i18n.t('Please enter a valid email address')), + isPrimary: yup.bool().default(false), + updatedAt: yup.string(), + source: yup.string(), + personId: yup.string(), + isValid: yup.bool().default(false), +}); + const EmailValidationForm = ({ personId }: EmailValidationFormProps) => { const { t } = useTranslation(); const accountListId = useAccountListId(); const [emailAddressesMutation] = useEmailAddressesMutation(); + const { enqueueSnackbar } = useSnackbar(); const initialEmail = { email: '', @@ -46,21 +61,11 @@ const EmailValidationForm = ({ personId }: EmailValidationFormProps) => { isValid: false, } as EmailValidationFormEmail; - const validationSchema = Yup.object({ - email: Yup.string() - .email(t('Invalid Email Address Format')) - .required('Please enter a valid email address'), - isPrimary: Yup.bool().default(false), - updatedAt: Yup.string(), - source: Yup.string(), - personId: Yup.string(), - isValid: Yup.bool().default(false), - }); - const onSubmit = (values, actions) => { emailAddressesMutation({ variables: { input: { + accountListId: accountListId || '', attributes: { id: personId, emailAddresses: [ @@ -69,7 +74,6 @@ const EmailValidationForm = ({ personId }: EmailValidationFormProps) => { }, ], }, - accountListId: accountListId || '', }, }, update: (cache, { data: addEmailAddressData }) => { @@ -114,6 +118,12 @@ const EmailValidationForm = ({ personId }: EmailValidationFormProps) => { }); } }, + onCompleted: () => { + enqueueSnackbar(t('Added email address'), { variant: 'success' }); + }, + onError: () => { + enqueueSnackbar(t('Failed to add email address'), { variant: 'error' }); + }, }); }; diff --git a/src/components/Tool/FixEmailAddresses/FixEmailAddresses.test.tsx b/src/components/Tool/FixEmailAddresses/FixEmailAddresses.test.tsx index 03a33cb0e..33668ed05 100644 --- a/src/components/Tool/FixEmailAddresses/FixEmailAddresses.test.tsx +++ b/src/components/Tool/FixEmailAddresses/FixEmailAddresses.test.tsx @@ -4,8 +4,8 @@ import { ThemeProvider } from '@mui/material/styles'; import { render, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { ApolloErgonoMockMap, ErgonoMockShape } from 'graphql-ergonomock'; +import { SnackbarProvider } from 'notistack'; import TestRouter from '__tests__/util/TestRouter'; -import TestWrapper from '__tests__/util/TestWrapper'; import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; import { GetInvalidEmailAddressesQuery } from 'src/components/Tool/FixEmailAddresses/FixEmailAddresses.generated'; import theme from '../../../theme'; @@ -21,43 +21,58 @@ import { newEmail, } from './FixEmailAddressesMocks'; -const accountListId = 'test121'; +const accountListId = 'accountListId'; const router = { query: { accountListId }, isReady: true, }; const setContactFocus = jest.fn(); +const mutationSpy = jest.fn(); +const mockEnqueue = jest.fn(); + +jest.mock('notistack', () => ({ + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + ...jest.requireActual('notistack'), + useSnackbar: () => { + return { + enqueueSnackbar: mockEnqueue, + }; + }, +})); -const Components = ({ - mocks = { - GetInvalidEmailAddresses: { - people: { nodes: mockInvalidEmailAddressesResponse }, - }, +const defaultGraphQLMock = { + GetInvalidEmailAddresses: { + people: { nodes: mockInvalidEmailAddressesResponse }, }, - cache, -}: { +}; + +interface ComponentsProps { mocks?: ApolloErgonoMockMap; cache?: ApolloCache; -}) => ( - - - +} + +const Components = ({ mocks = defaultGraphQLMock, cache }: ComponentsProps) => ( + + + mocks={mocks} cache={cache} + onCall={mutationSpy} > - - - + + + ); describe('FixEmailAddresses-Home', () => { @@ -92,6 +107,39 @@ describe('FixEmailAddresses-Home', () => { expect(getByTestId('starOutlineIcon-testid-0')).toBeInTheDocument(); }); + it('should add an new email address, firing a GraphQL mutation and resetting the form', async () => { + const { getByTestId, getAllByLabelText } = render(); + await waitFor(() => { + expect(getByTestId('textfield-testid-0')).toBeInTheDocument(); + }); + const textFieldNew = getAllByLabelText('New Email Address')[0]; + userEvent.type(textFieldNew, newEmail.email); + const addButton = getByTestId('addButton-testid'); + expect(textFieldNew).toHaveValue(newEmail.email); + + userEvent.click(addButton); + + await waitFor(() => + expect(mockEnqueue).toHaveBeenCalledWith('Added email address', { + variant: 'success', + }), + ); + + expect(mutationSpy.mock.calls[1][0].operation.operationName).toEqual( + 'EmailAddresses', + ); + expect(mutationSpy.mock.calls[1][0].operation.variables).toEqual({ + input: { + accountListId: accountListId, + attributes: { + id: 'testid', + emailAddresses: [{ email: newEmail.email }], + }, + }, + }); + expect(textFieldNew).toHaveValue(''); + }); + //TODO: Fix during MPDX-7936 it.skip('delete third email from first person', async () => { const { getByTestId, queryByTestId } = render(); @@ -124,7 +172,53 @@ describe('FixEmailAddresses-Home', () => { expect(getByTestId('starIcon-testid2-0')).toBeInTheDocument(); }); - describe('add email address', () => { + it('should render no contacts with no data', async () => { + const { getByText, getByTestId } = render( + , + ); + await waitFor(() => + expect(getByTestId('fixEmailAddresses-null-state')).toBeInTheDocument(), + ); + expect( + getByText('No people with email addresses need attention'), + ).toBeInTheDocument(); + }); + + it('should modify first email of first contact', async () => { + const { getByTestId } = render(); + await waitFor(() => { + expect(getByTestId('textfield-testid-0')).toBeInTheDocument(); + }); + const firstInput = getByTestId('textfield-testid-0'); + + expect(firstInput).toHaveValue('email1@gmail.com'); + userEvent.type(firstInput, '123'); + expect(firstInput).toHaveValue('email1@gmail.com123'); + }); + + describe('setContactFocus()', () => { + it('should open up contact details', async () => { + const { getByText, queryByTestId } = render(); + await waitFor(() => + expect(queryByTestId('loading')).not.toBeInTheDocument(), + ); + expect(setContactFocus).not.toHaveBeenCalled(); + + const contactName = getByText('Test Contact'); + + expect(contactName).toBeInTheDocument(); + userEvent.click(contactName); + expect(setContactFocus).toHaveBeenCalledWith(contactId); + }); + }); + + describe('Add email address - Testing cache', () => { interface AddEmailAddressProps { postSaveResponse: object; emailAddressNodes: object[]; @@ -254,50 +348,4 @@ describe('FixEmailAddresses-Home', () => { }); }); }); - - it('should render no contacts with no data', async () => { - const { getByText, getByTestId } = render( - , - ); - await waitFor(() => - expect(getByTestId('fixEmailAddresses-null-state')).toBeInTheDocument(), - ); - expect( - getByText('No people with email addresses need attention'), - ).toBeInTheDocument(); - }); - - it('should modify first email of first contact', async () => { - const { getByTestId } = render(); - await waitFor(() => { - expect(getByTestId('textfield-testid-0')).toBeInTheDocument(); - }); - const firstInput = getByTestId('textfield-testid-0'); - - expect(firstInput).toHaveValue('email1@gmail.com'); - userEvent.type(firstInput, '123'); - expect(firstInput).toHaveValue('email1@gmail.com123'); - }); - - describe('setContactFocus()', () => { - it('should open up contact details', async () => { - const { getByText, queryByTestId } = render(); - await waitFor(() => - expect(queryByTestId('loading')).not.toBeInTheDocument(), - ); - expect(setContactFocus).not.toHaveBeenCalled(); - - const contactName = getByText('Test Contact'); - - expect(contactName).toBeInTheDocument(); - userEvent.click(contactName); - expect(setContactFocus).toHaveBeenCalledWith(contactId); - }); - }); });