Skip to content

Commit

Permalink
Merge pull request #983 from CruGlobal/MPDX-8024-confirm-all
Browse files Browse the repository at this point in the history
MPDX-8024 - Fix Send Newsletter - Confirm All Button
  • Loading branch information
wrandall22 authored Aug 12, 2024
2 parents 0351b4f + b7da966 commit 2dd9c53
Show file tree
Hide file tree
Showing 6 changed files with 274 additions and 19 deletions.
5 changes: 5 additions & 0 deletions src/components/Tool/FixSendNewsletter/Contact.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ThemeProvider } from '@mui/material/styles';
import { render } from '@testing-library/react';
import { SendNewsletterEnum } from 'src/graphql/types.generated';
import theme from 'src/theme';
import Contact from './Contact';
import {
Expand All @@ -21,6 +22,10 @@ const TestComponent = ({
primaryPerson={primaryPerson}
status=""
primaryAddress={primaryAddress}
contactUpdates={[
{ id: '', sendNewsletter: null as unknown as SendNewsletterEnum },
]}
setContactUpdates={jest.fn()}
handleSingleConfirm={jest.fn()}
setContactFocus={jest.fn()}
/>
Expand Down
27 changes: 25 additions & 2 deletions src/components/Tool/FixSendNewsletter/Contact.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { SetContactFocus } from 'pages/accountLists/[accountListId]/tools/useToo
import { SendNewsletterEnum } from 'src/graphql/types.generated';
import theme from '../../../theme';
import { StyledInput } from '../StyledInput';
import { ContactUpdateData } from './FixSendNewsletter';
import {
ContactPrimaryAddressFragment,
ContactPrimaryPersonFragment,
Expand Down Expand Up @@ -85,6 +86,8 @@ interface Props {
status?: string;
primaryAddress?: ContactPrimaryAddressFragment;
source?: string;
contactUpdates: ContactUpdateData[];
setContactUpdates: React.Dispatch<React.SetStateAction<ContactUpdateData[]>>;
handleSingleConfirm: (
id: string,
name: string,
Expand All @@ -99,6 +102,8 @@ const Contact = ({
primaryPerson,
status,
primaryAddress,
contactUpdates,
setContactUpdates,
handleSingleConfirm,
setContactFocus,
}: Props): ReactElement => {
Expand All @@ -122,15 +127,33 @@ const Contact = ({
}
}
}
setNewsletter(newNewsletterValue);
updateNewsletterValue(newNewsletterValue);
}, [primaryAddress]);

const updateNewsletterValue = (sendNewsletter: SendNewsletterEnum): void => {
setNewsletter(sendNewsletter);
const existingItem = contactUpdates.find(
(contactData) => contactData.id === id,
);
if (existingItem) {
existingItem.sendNewsletter = sendNewsletter;
} else {
setContactUpdates([
...contactUpdates,
{
id,
sendNewsletter: sendNewsletter,
},
]);
}
};

const handleChange = (
event:
| React.ChangeEvent<HTMLSelectElement>
| React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>,
): void => {
setNewsletter(event.target.value as SendNewsletterEnum);
updateNewsletterValue(event.target.value as SendNewsletterEnum);
};

const handleContactNameClick = () => {
Expand Down
184 changes: 170 additions & 14 deletions src/components/Tool/FixSendNewsletter/FixSendNewsletter.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ import { MockLinkCallHandler } from 'graphql-ergonomock/dist/apollo/MockLink';
import { SnackbarProvider } from 'notistack';
import TestRouter from '__tests__/util/TestRouter';
import { GqlMockedProvider } from '__tests__/util/graphqlMocking';
import { MassActionsUpdateContactsMutation } from 'src/components/Contacts/MassActions/MassActionsUpdateContacts.generated';
import { SendNewsletterEnum } from 'src/graphql/types.generated';
import theme from 'src/theme';
import FixSendNewsletter from './FixSendNewsletter';
import {
mockInvalidNewslettersResponse,
mockMassActionsUpdateContactsData,
mockUploadNewsletterChange,
} from './FixSendNewsletterMock';
import { InvalidNewsletterQuery } from './InvalidNewsletter.generated';
Expand Down Expand Up @@ -49,6 +52,7 @@ const TestComponent = ({
<GqlMockedProvider<{
InvalidNewsletter: InvalidNewsletterQuery;
UpdateContactNewsletter: UpdateContactNewsletterMutation;
MassActionsUpdateContacts: MassActionsUpdateContactsMutation;
}>
mocks={mocks}
cache={cache}
Expand All @@ -65,8 +69,13 @@ const TestComponent = ({
);

describe('FixSendNewsletter', () => {
const deceasedName =
mockInvalidNewslettersResponse.InvalidNewsletter.contacts.nodes[2].name;
const contacts =
mockInvalidNewslettersResponse.InvalidNewsletter.contacts.nodes;
const deceasedName = contacts[2].name;
const firstContactName = contacts[0].name;
const secondContactName = contacts[1].name;
const initialNewsletterValue = 'None';
const newNewsletterValue = 'Physical';

beforeEach(() => {
setContactFocus.mockClear();
Expand Down Expand Up @@ -105,6 +114,22 @@ describe('FixSendNewsletter', () => {
});
});

it('should show the confirm all button', async () => {
const { getByRole } = render(
<TestComponent
mocks={{
InvalidNewsletter: {
...mockInvalidNewslettersResponse.InvalidNewsletter,
},
}}
/>,
);

await waitFor(() => {
expect(getByRole('button', { name: 'Confirm 2' })).toBeVisible();
});
});

it('should not show deceased contacts', async () => {
const { queryByRole, queryByText } = render(
<TestComponent
Expand All @@ -127,17 +152,18 @@ describe('FixSendNewsletter', () => {
});

describe('confirm single', () => {
const name =
mockInvalidNewslettersResponse.InvalidNewsletter.contacts.nodes[0].name;
const otherName =
mockInvalidNewslettersResponse.InvalidNewsletter.contacts.nodes[1].name;
const initialNewsletterValue = 'None';
const newNewsletterValue = 'Physical';

it('should successfully update the newsletter', async () => {
const cache = new InMemoryCache();
jest.spyOn(cache, 'readQuery').mockReturnValue({
...mockInvalidNewslettersResponse.InvalidNewsletter,
contacts: {
nodes: [
{
...mockInvalidNewslettersResponse.InvalidNewsletter.contacts
.nodes[1],
sendNewsletter: SendNewsletterEnum.Physical,
},
],
},
});

const { getAllByRole, queryByText, queryByRole } = render(
Expand All @@ -161,14 +187,15 @@ describe('FixSendNewsletter', () => {
await waitFor(() => {
expect(newsletterDropdown).toHaveDisplayValue([initialNewsletterValue]);
});
expect(queryByText(firstContactName)).toBeInTheDocument();
userEvent.selectOptions(newsletterDropdown, newNewsletterValue);
userEvent.click(getAllByRole('button', { name: 'Confirm' })[0]);
await waitFor(() => {
expect(mockEnqueue).toHaveBeenCalledWith('Newsletter updated!', {
variant: 'success',
});
expect(queryByText(name)).not.toBeInTheDocument();
expect(queryByText(otherName)).toBeInTheDocument();
expect(queryByText(firstContactName)).not.toBeInTheDocument();
expect(queryByText(secondContactName)).toBeInTheDocument();
});
});

Expand All @@ -194,7 +221,7 @@ describe('FixSendNewsletter', () => {

await waitFor(() => {
expect(mockEnqueue).toHaveBeenCalledWith(
`Error updating contact ${name}`,
`Error updating contact ${firstContactName}`,
{
variant: 'error',
autoHideDuration: 7000,
Expand Down Expand Up @@ -232,7 +259,7 @@ describe('FixSendNewsletter', () => {
userEvent.click(getAllByRole('button', { name: 'Confirm' })[0]);
await waitFor(() => {
expect(queryByText(deceasedName)).not.toBeInTheDocument();
expect(queryByText(otherName)).toBeInTheDocument();
expect(queryByText(secondContactName)).toBeInTheDocument();
expect(cache.writeQuery).toHaveBeenCalledWith(
expect.objectContaining({
data: {
Expand Down Expand Up @@ -272,4 +299,133 @@ describe('FixSendNewsletter', () => {
});
});
});

describe('bulk confirm', () => {
const secondContactNewNewsletterValue = 'Both';

const confirmAll = async (getAllByRole, getByRole, queryByRole) => {
await waitFor(() =>
expect(queryByRole('progressbar')).not.toBeInTheDocument(),
);

const firstNewsletterDropdown = getAllByRole('combobox')[0];
await waitFor(() => {
expect(firstNewsletterDropdown).toHaveDisplayValue([
initialNewsletterValue,
]);
});
userEvent.selectOptions(firstNewsletterDropdown, newNewsletterValue);

const secondNewsletterDropdown = getAllByRole('combobox')[1];
await waitFor(() => {
expect(secondNewsletterDropdown).toHaveDisplayValue([
initialNewsletterValue,
]);
});
userEvent.selectOptions(
secondNewsletterDropdown,
secondContactNewNewsletterValue,
);

userEvent.click(getByRole('button', { name: 'Confirm 2' }));
userEvent.click(getByRole('button', { name: 'Yes' }));
};

it('should bring up the confirmation modal', async () => {
const { getByRole, getByText, queryByRole } = render(
<TestComponent
mocks={{
InvalidNewsletter: {
...mockInvalidNewslettersResponse.InvalidNewsletter,
},
UpdateContactNewsletter: {
...mockUploadNewsletterChange.UpdateContactNewsletter,
},
}}
/>,
);

await waitFor(() =>
expect(queryByRole('progressbar')).not.toBeInTheDocument(),
);

userEvent.click(getByRole('button', { name: 'Confirm 2' }));

await waitFor(() => {
expect(
getByText(
'You are updating all contacts visible on this page, setting it to the visible newsletter selection. Are you sure you want to do this?',
),
).toBeVisible();
});
});

it('should successfully update all the contacts', async () => {
let cardinality = 0;

const { getAllByRole, getByRole, queryByText, queryByRole } = render(
<TestComponent
mocks={{
InvalidNewsletter: () => {
let queryResult;
if (cardinality === 0) {
queryResult = {
...mockInvalidNewslettersResponse.InvalidNewsletter,
};
} else {
queryResult = {
contacts: {
nodes: [
{
...mockInvalidNewslettersResponse.InvalidNewsletter
.contacts.nodes[2],
},
],
},
};
}
cardinality++;
return queryResult;
},
MassActionsUpdateContacts: {
...mockMassActionsUpdateContactsData.MassActionsUpdateContacts,
},
}}
/>,
);
confirmAll(getAllByRole, getByRole, queryByRole);
await waitFor(() => {
expect(mockEnqueue).toHaveBeenCalledWith(
'Newsletter statuses updated successfully',
{
variant: 'success',
},
);
expect(queryByText(firstContactName)).not.toBeInTheDocument();
expect(queryByText(secondContactName)).not.toBeInTheDocument();
});
});

it('should handle errors', async () => {
const { getAllByRole, getByRole, queryByRole } = render(
<TestComponent
mocks={{
InvalidNewsletter: {
...mockInvalidNewslettersResponse.InvalidNewsletter,
},
MassActionsUpdateContacts: () => {
throw new Error('Server Error');
},
}}
/>,
);
confirmAll(getAllByRole, getByRole, queryByRole);
await waitFor(() => {
expect(mockEnqueue).toHaveBeenCalledWith(`Error updating contacts`, {
variant: 'error',
autoHideDuration: 7000,
});
});
});
});
});
Loading

0 comments on commit 2dd9c53

Please sign in to comment.