Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
caleballdrin committed Jun 26, 2024
1 parent e08a629 commit 6a5db31
Show file tree
Hide file tree
Showing 6 changed files with 356 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { useRouter } from 'next/router';
import { ThemeProvider } from '@mui/material/styles';
import { render, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { getSession } from 'next-auth/react';
import { SnackbarProvider } from 'notistack';
import { I18nextProvider } from 'react-i18next';
import TestRouter from '__tests__/util/TestRouter';
import { GqlMockedProvider } from '__tests__/util/graphqlMocking';
import { GetPersonDuplicatesQuery } from 'src/components/Tool/MergePeople/GetPersonDuplicates.generated';
import { getPersonDuplicatesMocks } from 'src/components/Tool/MergePeople/PersonDuplicatesMock';
import i18n from 'src/lib/i18n';
import theme from 'src/theme';
import MergePeoplePage from './[[...contactId]].page';

jest.mock('next-auth/react');
jest.mock('next/router', () => ({
useRouter: jest.fn(),
}));
jest.mock('src/lib/helpScout', () => ({
suggestArticles: jest.fn(),
}));
jest.mock('notistack', () => ({
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
...jest.requireActual('notistack'),
useSnackbar: () => {
return {
enqueueSnackbar: jest.fn(),
};
},
}));

const pushFn = jest.fn();
const accountListId = 'account-list-1';
const session = {
expires: '2021-10-28T14:48:20.897Z',
user: {
email: 'Chair Library Bed',
image: null,
name: 'Dung Tapestry',
token: 'superLongJwtString',
},
};
const Components = () => (
<ThemeProvider theme={theme}>
<TestRouter>
<GqlMockedProvider<{
GetPersonDuplicates: GetPersonDuplicatesQuery;
}>
mocks={getPersonDuplicatesMocks}
>
<I18nextProvider i18n={i18n}>
<SnackbarProvider>
<MergePeoplePage />
</SnackbarProvider>
</I18nextProvider>
</GqlMockedProvider>
</TestRouter>
</ThemeProvider>
);

describe('MergePeoplePage', () => {
beforeEach(() => {
(getSession as jest.Mock).mockResolvedValue(session);
(useRouter as jest.Mock).mockReturnValue({
query: {
accountListId,
},
isReady: true,
push: pushFn,
});
});

it('should open up contact details', async () => {
const { findByText, queryByTestId } = render(<Components />);
await waitFor(() =>
expect(queryByTestId('loading')).not.toBeInTheDocument(),
);

const contactName = await findByText('John Doe');

expect(contactName).toBeInTheDocument();
userEvent.click(contactName);

await waitFor(() => {
expect(pushFn).toHaveBeenCalledWith(
`/accountLists/${accountListId}/tools/mergePeople/${'contact-1'}`,
);
});
});
});
10 changes: 7 additions & 3 deletions src/components/Tool/MergeContacts/MergeContacts.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,11 @@ describe('Tools - MergeContacts', () => {
expect(confirmButton).toBeDisabled();
userEvent.click(getByText('123 John St Orlando, FL 32832'));
expect(await findByText('Use this one')).toBeInTheDocument();
expect(confirmButton).not.toBeDisabled();
expect(
getByRole('button', { name: 'Confirm and Continue' }),
).not.toBeDisabled();

userEvent.click(confirmButton);
userEvent.click(getByRole('button', { name: 'Confirm and Continue' }));
await waitFor(() =>
expect(mockEnqueue).toHaveBeenCalledWith('Success!', {
variant: 'success',
Expand Down Expand Up @@ -135,7 +137,9 @@ describe('Tools - MergeContacts', () => {
expect(await findByText('Use this one')).toBeInTheDocument();
userEvent.click(queryAllByTestId('ignoreButton')[0]);
expect(queryByText('Use this one')).not.toBeInTheDocument();
expect(confirmButton).not.toBeDisabled();
expect(
getByRole('button', { name: 'Confirm and Continue' }),
).not.toBeDisabled();
});

describe('setContactFocus()', () => {
Expand Down
12 changes: 6 additions & 6 deletions src/components/Tool/MergeContacts/MergeContacts.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useMemo, useState } from 'react';
import React, { memo, useMemo, useState } from 'react';
import {
Box,
CircularProgress,
Expand Down Expand Up @@ -66,13 +66,13 @@ const MergeContacts: React.FC<Props> = ({
});
const { appName } = useGetAppSettings();
const [contactsMerge, { loading: updating }] = useMassActionsMergeMutation();
const actionsLength = useMemo(
() => Object.entries(actions).length,
[actions],
const disabled = useMemo(
() => updating || Object.entries(actions).length === 0,
[actions, updating],
);
const disabled = updating || !actionsLength;
const totalCount = data?.contactDuplicates.totalCount || 0;
const showing = data?.contactDuplicates.nodes.length || 0;
const MemoizedStickyConfirmButtons = memo(StickyConfirmButtons);

const updateActions = (id1: string, id2: string, action: string): void => {
if (!updating) {
Expand Down Expand Up @@ -164,7 +164,7 @@ const MergeContacts: React.FC<Props> = ({
</Typography>
</Box>
</Grid>
<StickyConfirmButtons
<MemoizedStickyConfirmButtons
accountListId={accountListId}
loading={loading}
updating={updating}
Expand Down
165 changes: 165 additions & 0 deletions src/components/Tool/MergePeople/MergePeople.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import React from 'react';
import { ThemeProvider } from '@mui/material/styles';
import { render, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { SnackbarProvider } from 'notistack';
import TestRouter from '__tests__/util/TestRouter';
import { GqlMockedProvider } from '__tests__/util/graphqlMocking';
import { ContactsProvider } from 'src/components/Contacts/ContactsContext/ContactsContext';
import theme from 'src/theme';
import { GetPersonDuplicatesQuery } from './GetPersonDuplicates.generated';
import MergePeople from './MergePeople';
import { getPersonDuplicatesMocks } from './PersonDuplicatesMock';

const accountListId = '123';

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,
};
},
}));

interface MergePeopleWrapperProps {
mutationSpy?: () => void;
}

const MergePeopleWrapper: React.FC<MergePeopleWrapperProps> = ({
mutationSpy,
}) => {
return (
<ThemeProvider theme={theme}>
<TestRouter>
<GqlMockedProvider<{
GetPersonDuplicates: GetPersonDuplicatesQuery;
}>
mocks={getPersonDuplicatesMocks}
onCall={mutationSpy}
>
<ContactsProvider
activeFilters={{}}
setActiveFilters={() => {}}
starredFilter={{}}
setStarredFilter={() => {}}
filterPanelOpen={false}
setFilterPanelOpen={() => {}}
contactId={[]}
searchTerm={''}
>
<MergePeople
accountListId={accountListId}
setContactFocus={setContactFocus}
/>
</ContactsProvider>
</GqlMockedProvider>
</TestRouter>
</ThemeProvider>
);
};

describe('Tools - MergePeople', () => {
it('should render', async () => {
const { findByText, getByTestId } = render(<MergePeopleWrapper />);

expect(await findByText('Merge People')).toBeInTheDocument();
expect(getByTestId('PeopleMergeDescription').textContent).toMatch(
'You have 55 possible duplicate people',
);
});

it('should merge people', async () => {
const mutationSpy = jest.fn();

const { getByText, queryAllByTestId, findByText, getByRole } = render(
<SnackbarProvider>
<MergePeopleWrapper mutationSpy={mutationSpy} />
</SnackbarProvider>,
);

await waitFor(() =>
expect(queryAllByTestId('MergeContactPair')).toHaveLength(2),
);
expect(getByText('(Siebel)')).toBeInTheDocument();

expect(
getByRole('button', { name: 'Confirm and Continue' }),
).toBeDisabled();
userEvent.click(getByText('555-555-5555'));
expect(await findByText('Use this one')).toBeInTheDocument();
expect(
getByRole('button', { name: 'Confirm and Continue' }),
).not.toBeDisabled();

userEvent.click(getByRole('button', { name: 'Confirm and Continue' }));
await waitFor(() =>
expect(mockEnqueue).toHaveBeenCalledWith('Success!', {
variant: 'success',
}),
);

const mergeCalls = mutationSpy.mock.calls
.map(([{ operation }]) => operation)
.filter(({ operationName }) => operationName === 'MergePeopleBulk');
expect(mergeCalls).toHaveLength(1);
expect(mergeCalls[0].variables).toEqual({
input: {
winnersAndLosers: [
{
loserId: 'person-1.5',
winnerId: 'person-1',
},
],
},
});
});

it('should ignore contacts', async () => {
const mutationSpy = jest.fn();

const { queryByText, queryAllByTestId, findByText, getByRole } = render(
<SnackbarProvider>
<MergePeopleWrapper mutationSpy={mutationSpy} />
</SnackbarProvider>,
);

await waitFor(() =>
expect(queryAllByTestId('MergeContactPair')).toHaveLength(2),
);
const confirmButton = getByRole('button', { name: 'Confirm and Continue' });

expect(confirmButton).toBeDisabled();
userEvent.click(queryAllByTestId('rightButton')[0]);
expect(await findByText('Use this one')).toBeInTheDocument();
userEvent.click(queryAllByTestId('ignoreButton')[0]);
expect(queryByText('Use this one')).not.toBeInTheDocument();
expect(
getByRole('button', { name: 'Confirm and Continue' }),
).not.toBeDisabled();
});

describe('setContactFocus()', () => {
it('should open up contact details', async () => {
const mutationSpy = jest.fn();
const { findByText, queryByTestId } = render(
<MergePeopleWrapper mutationSpy={mutationSpy} />,
);
await waitFor(() =>
expect(queryByTestId('loading')).not.toBeInTheDocument(),
);
expect(setContactFocus).not.toHaveBeenCalled();

const contactName = await findByText('Ellie Francisco');

expect(contactName).toBeInTheDocument();
userEvent.click(contactName);
expect(setContactFocus).toHaveBeenCalledWith('contact-2');
});
});
});
13 changes: 7 additions & 6 deletions src/components/Tool/MergePeople/MergePeople.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useMemo, useState } from 'react';
import React, { memo, useMemo, useState } from 'react';
import {
Box,
CircularProgress,
Expand Down Expand Up @@ -68,14 +68,15 @@ const MergePeople: React.FC<Props> = ({
});
const { appName } = useGetAppSettings();
const [peopleMerge, { loading: updating }] = useMergePeopleBulkMutation();
const actionsLength = useMemo(
() => Object.entries(actions).length,
[actions],
const disabled = useMemo(
() => updating || Object.entries(actions).length === 0,
[actions, updating],
);
const disabled = updating || !actionsLength;
const totalCount = data?.personDuplicates.totalCount || 0;
const showing = data?.personDuplicates.nodes.length || 0;

const MemoizedStickyConfirmButtons = memo(StickyConfirmButtons);

const updateActions = (id1: string, id2: string, action: string): void => {
if (!updating) {
if (action === 'cancel') {
Expand Down Expand Up @@ -166,7 +167,7 @@ const MergePeople: React.FC<Props> = ({
</Typography>
</Box>
</Grid>
<StickyConfirmButtons
<MemoizedStickyConfirmButtons
accountListId={accountListId}
loading={loading}
updating={updating}
Expand Down
Loading

0 comments on commit 6a5db31

Please sign in to comment.