Skip to content

Commit

Permalink
Implement single confirm button
Browse files Browse the repository at this point in the history
  • Loading branch information
wrandall22 committed Jul 24, 2024
1 parent 7e3678c commit 122cd9b
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const person: PersonInvalidEmailFragment = {
};

const setContactFocus = jest.fn();
const handleSingleConfirm = jest.fn();

const TestComponent = ({ mocks }: { mocks: ApolloErgonoMockMap }) => {
const handleChangeMock = jest.fn();
Expand All @@ -68,6 +69,7 @@ const TestComponent = ({ mocks }: { mocks: ApolloErgonoMockMap }) => {
handleChange={handleChangeMock}
handleDelete={handleDeleteModalOpenMock}
handleChangePrimary={handleChangePrimaryMock}
handleSingleConfirm={handleSingleConfirm}
setContactFocus={setContactFocus}
/>
</GqlMockedProvider>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { dateFormatShort } from 'src/lib/intlFormat';
import theme from 'src/theme';
import { ConfirmButtonIcon } from '../../ConfirmButtonIcon';
import EmailValidationForm from '../EmailValidationForm';
import { PersonEmailAddresses } from '../FixEmailAddresses';
import { EmailAddressData, PersonEmailAddresses } from '../FixEmailAddresses';
import { PersonInvalidEmailFragment } from '../FixEmailAddresses.generated';

const PersonCard = styled(Box)(({ theme }) => ({
Expand Down Expand Up @@ -102,6 +102,10 @@ export interface FixEmailAddressPersonProps {
) => void;
handleDelete: (personId: string, id: string, email: string) => void;
handleChangePrimary: (personId: string, emailIndex: number) => void;
handleSingleConfirm: (
person: PersonInvalidEmailFragment,
emails: EmailAddressData[],
) => void;
setContactFocus: SetContactFocus;
}

Expand All @@ -111,6 +115,7 @@ export const FixEmailAddressPerson: React.FC<FixEmailAddressPersonProps> = ({
handleChange,
handleDelete,
handleChangePrimary,
handleSingleConfirm,
setContactFocus,
}) => {
const { t } = useTranslation();
Expand All @@ -130,7 +135,7 @@ export const FixEmailAddressPerson: React.FC<FixEmailAddressPersonProps> = ({
...email,
isValid: false,
personId: id,
isPrimary: email.primary,
primary: email.primary,
})) || []
);
}, [person, dataState]);
Expand Down Expand Up @@ -202,7 +207,7 @@ export const FixEmailAddressPerson: React.FC<FixEmailAddressPersonProps> = ({
)})`}
</Typography>
</Box>
{email.isPrimary ? (
{email.primary ? (
<Box data-testid={`starIcon-${id}-${index}`}>
<HoverableIcon path={mdiStar} size={1} />
</Box>
Expand Down Expand Up @@ -289,7 +294,13 @@ export const FixEmailAddressPerson: React.FC<FixEmailAddressPersonProps> = ({
style={{ paddingLeft: theme.spacing(1) }}
>
<ConfirmButtonWrapper>
<Button variant="contained" style={{ width: '100%' }}>
<Button
variant="contained"
style={{ width: '100%' }}
onClick={() =>
handleSingleConfirm(person, emails as EmailAddressData[])
}
>
<ConfirmButtonIcon />
{t('Confirm')}
</Button>
Expand Down
144 changes: 127 additions & 17 deletions src/components/Tool/FixEmailAddresses/FixEmailAddresses.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ 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 {
GetInvalidEmailAddressesQuery,
UpdateEmailAddressesMutation,
} from 'src/components/Tool/FixEmailAddresses/FixEmailAddresses.generated';
import theme from '../../../theme';
import { EmailAddressesMutation } from './AddEmailAddress.generated';
import { FixEmailAddresses } from './FixEmailAddresses';
Expand All @@ -27,6 +31,18 @@ const router = {

const setContactFocus = 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: {
Expand All @@ -39,22 +55,25 @@ const Components = ({
cache?: ApolloCache<object>;
}) => (
<ThemeProvider theme={theme}>
<TestRouter router={router}>
<TestWrapper>
<GqlMockedProvider<{
GetInvalidEmailAddresses: GetInvalidEmailAddressesQuery;
EmailAddresses: EmailAddressesMutation;
}>
mocks={mocks}
cache={cache}
>
<FixEmailAddresses
accountListId={accountListId}
setContactFocus={setContactFocus}
/>
</GqlMockedProvider>
</TestWrapper>
</TestRouter>
<SnackbarProvider>
<TestRouter router={router}>
<TestWrapper>
<GqlMockedProvider<{
GetInvalidEmailAddresses: GetInvalidEmailAddressesQuery;
EmailAddresses: EmailAddressesMutation;
UpdateEmailAddresses: UpdateEmailAddressesMutation;
}>
mocks={mocks}
cache={cache}
>
<FixEmailAddresses
accountListId={accountListId}
setContactFocus={setContactFocus}
/>
</GqlMockedProvider>
</TestWrapper>
</TestRouter>
</SnackbarProvider>
</ThemeProvider>
);

Expand Down Expand Up @@ -304,4 +323,95 @@ describe('FixPhoneNumbers-Home', () => {
expect(setContactFocus).toHaveBeenCalledWith(contactId);
});
});

describe('handleSingleConfirm', () => {
it('should successfully submit changes to multiple emails', async () => {
const cache = new InMemoryCache();
const personName = 'Test Contact';

const updatePerson = {
person: {
id: mockInvalidEmailAddressesResponse[0].id,
emailAddresses: {
nodes: [
{
...contactOneEmailAddressNodes[0],
email: '[email protected]',
},
{
...contactOneEmailAddressNodes[1],
email: '[email protected]',
},
{
...contactOneEmailAddressNodes[2],
},
],
},
},
} as ErgonoMockShape;

const { getAllByRole, queryByTestId, queryByText } = render(
<Components
mocks={{
GetInvalidEmailAddresses: {
people: {
nodes: mockInvalidEmailAddressesResponse,
},
},
UpdateEmailAddresses: { updatePerson },
}}
cache={cache}
/>,
);

await waitFor(() =>
expect(queryByTestId('loading')).not.toBeInTheDocument(),
);

const confirmButton = getAllByRole('button', { name: 'Confirm' })[0];
userEvent.click(confirmButton);

await waitFor(() => {
expect(mockEnqueue).toHaveBeenCalledWith(
`Successfully updated email addresses for ${personName}`,
{ variant: 'success' },
);
expect(queryByText(personName)).not.toBeInTheDocument();
});
});

it('should handle an error', async () => {
const cache = new InMemoryCache();

const { getAllByRole, queryByTestId } = render(
<Components
mocks={{
GetInvalidEmailAddresses: {
people: {
nodes: mockInvalidEmailAddressesResponse,
},
},
UpdateEmailAddresses: () => {
throw new Error('Server Error');
},
}}
cache={cache}
/>,
);

await waitFor(() =>
expect(queryByTestId('loading')).not.toBeInTheDocument(),
);

const confirmButton = getAllByRole('button', { name: 'Confirm' })[0];
userEvent.click(confirmButton);

await waitFor(() => {
expect(mockEnqueue).toHaveBeenCalledWith(
'Error updating email addresses for Test Contact',
{ variant: 'error', autoHideDuration: 7000 },
);
});
});
});
});
48 changes: 48 additions & 0 deletions src/components/Tool/FixEmailAddresses/FixEmailAddresses.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ import { useSnackbar } from 'notistack';
import { Trans, useTranslation } from 'react-i18next';
import { SetContactFocus } from 'pages/accountLists/[accountListId]/tools/useToolsHelper';
import {
PersonInvalidEmailFragment,
useGetInvalidEmailAddressesQuery,
useUpdateEmailAddressesMutation,
} from 'src/components/Tool/FixEmailAddresses/FixEmailAddresses.generated';
import { PersonEmailAddressInput } from 'src/graphql/types.generated';
import theme from '../../../theme';
import { ConfirmButtonIcon } from '../ConfirmButtonIcon';
import NoData from '../NoData';
Expand Down Expand Up @@ -240,6 +242,51 @@ export const FixEmailAddresses: React.FC<FixEmailAddressesProps> = ({
setDefaultSource(event.target.value);
};

const handleSingleConfirm = async (
person: PersonInvalidEmailFragment,
emails: EmailAddressData[],
) => {
const personName = `${person.firstName} ${person.lastName}`;
const emailAddresses = [] as PersonEmailAddressInput[];
emails.map((emailAddress) => {
emailAddresses.push({
email: emailAddress.email,
id: emailAddress.id,
primary: emailAddress.primary,
validValues: true,
});
});

await updateEmailAddressesMutation({
variables: {
input: {
accountListId,
attributes: {
id: person.id,
emailAddresses,
},
},
},
update: (cache) => {
cache.evict({ id: `Person:${person.id}` });
},
onCompleted: () => {
enqueueSnackbar(
t(`Successfully updated email addresses for ${personName}`),
{
variant: 'success',
},
);
},
onError: () => {
enqueueSnackbar(t(`Error updating email addresses for ${personName}`), {
variant: 'error',
autoHideDuration: 7000,
});
},
});
};

return (
<Container>
{!loading && data && dataState ? (
Expand Down Expand Up @@ -298,6 +345,7 @@ export const FixEmailAddresses: React.FC<FixEmailAddressesProps> = ({
handleChange={handleChange}
handleDelete={handleDeleteModalOpen}
handleChangePrimary={handleChangePrimary}
handleSingleConfirm={handleSingleConfirm}
setContactFocus={setContactFocus}
/>
))}
Expand Down

0 comments on commit 122cd9b

Please sign in to comment.