From 0cca59f75f529ffc5151550946d202ab266d805a Mon Sep 17 00:00:00 2001 From: Caleb Cox Date: Mon, 7 Oct 2024 14:07:54 -0500 Subject: [PATCH 1/5] Memoize contactStatuses It is part of a dependency array in SuggestedContactStatus --- src/hooks/useContactPartnershipStatuses.ts | 33 +++++++++++++--------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/hooks/useContactPartnershipStatuses.ts b/src/hooks/useContactPartnershipStatuses.ts index d1c7bbb48..e35f674f0 100644 --- a/src/hooks/useContactPartnershipStatuses.ts +++ b/src/hooks/useContactPartnershipStatuses.ts @@ -1,3 +1,4 @@ +import { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { useApiConstants } from 'src/components/Constants/UseApiConstants'; import { PhaseEnum, StatusEnum } from 'src/graphql/types.generated'; @@ -50,19 +51,25 @@ export const useContactPartnershipStatuses = () => { // translated: "Appointment Scheduled" // } // } - const contactStatuses: ContactStatuses = phases - ? phases?.reduce((acc, phase) => { - phase?.contactStatuses?.map((status) => { - const statusName = statuses?.find(({ id }) => status === id)?.value; - acc[status] = { - name: statusName, - translated: getLocalizedContactStatus(t, status), - phase: phase.id, - }; - }); - return acc; - }, otherStatuses) - : otherStatuses; + const contactStatuses: ContactStatuses = useMemo( + () => + phases + ? phases?.reduce((acc, phase) => { + phase?.contactStatuses?.map((status) => { + const statusName = statuses?.find( + ({ id }) => status === id, + )?.value; + acc[status] = { + name: statusName, + translated: getLocalizedContactStatus(t, status), + phase: phase.id, + }; + }); + return acc; + }, otherStatuses) + : otherStatuses, + [phases], + ); // statusMap: { // "Never Ask": "NEVER_ASK", From cae30a993818c239e5b470b6d68ae9a34d2325e7 Mon Sep 17 00:00:00 2001 From: Caleb Cox Date: Mon, 7 Oct 2024 16:16:18 -0500 Subject: [PATCH 2/5] Fix contact status mocking --- .../Form/Complete/TaskModalCompleteForm.test.tsx | 7 +++++++ .../SuggestedContactStatus.test.tsx | 13 ++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/components/Task/Modal/Form/Complete/TaskModalCompleteForm.test.tsx b/src/components/Task/Modal/Form/Complete/TaskModalCompleteForm.test.tsx index 4dfbe13c9..5382acc62 100644 --- a/src/components/Task/Modal/Form/Complete/TaskModalCompleteForm.test.tsx +++ b/src/components/Task/Modal/Form/Complete/TaskModalCompleteForm.test.tsx @@ -20,6 +20,7 @@ import { dispatch } from 'src/lib/analytics'; import theme from 'src/theme'; import useTaskModal from '../../../../../hooks/useTaskModal'; import { TaskModalEnum } from '../../TaskModal'; +import { ContactStatusQuery } from '../Inputs/SuggestedContactStatus/SuggestedContactStatus.generated'; import { taskModalTests } from '../TaskModalTests'; import TaskModalCompleteForm from './TaskModalCompleteForm'; @@ -76,9 +77,15 @@ const Components = ({ mocks = {}, taskOverrides, props }: ComponentsProps) => ( mocks={{ LoadConstants: loadConstantsMockData, + ContactStatus: { + contact: { + status: null, + }, + }, ...mocks, }} onCall={mutationSpy} diff --git a/src/components/Task/Modal/Form/Inputs/SuggestedContactStatus/SuggestedContactStatus.test.tsx b/src/components/Task/Modal/Form/Inputs/SuggestedContactStatus/SuggestedContactStatus.test.tsx index 12dbcd51a..a04b848e6 100644 --- a/src/components/Task/Modal/Form/Inputs/SuggestedContactStatus/SuggestedContactStatus.test.tsx +++ b/src/components/Task/Modal/Form/Inputs/SuggestedContactStatus/SuggestedContactStatus.test.tsx @@ -3,6 +3,7 @@ import { ThemeProvider } from '@emotion/react'; import { render, waitFor } from '@testing-library/react'; import { I18nextProvider } from 'react-i18next'; import { GqlMockedProvider } from '__tests__/util/graphqlMocking'; +import { LoadConstantsQuery } from 'src/components/Constants/LoadConstants.generated'; import { loadConstantsMockData } from 'src/components/Constants/LoadConstantsMock'; import { StatusEnum } from 'src/graphql/types.generated'; import i18n from 'src/lib/i18n'; @@ -11,6 +12,7 @@ import { FormikHandleChange, SuggestedContactStatus, } from './SuggestedContactStatus'; +import { ContactStatusQuery } from './SuggestedContactStatus.generated'; const handleChange: FormikHandleChange = jest.fn(); const accountListId = 'abc'; @@ -31,14 +33,15 @@ const Components = ({ }: ComponentsProps) => ( - mocks={{ LoadConstants: loadConstantsMockData, ContactStatus: { - data: { - contact: { - status: contactStatusQueryMock || null, - }, + contact: { + status: contactStatusQueryMock || null, }, }, }} From 08fe2d87388179ddf4ba5e6d479b76416a74a8f2 Mon Sep 17 00:00:00 2001 From: Caleb Cox Date: Mon, 7 Oct 2024 16:16:34 -0500 Subject: [PATCH 3/5] Add contact id to query --- .../Inputs/SuggestedContactStatus/SuggestedContactStatus.graphql | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/Task/Modal/Form/Inputs/SuggestedContactStatus/SuggestedContactStatus.graphql b/src/components/Task/Modal/Form/Inputs/SuggestedContactStatus/SuggestedContactStatus.graphql index 576df89f9..e76e9c1a3 100644 --- a/src/components/Task/Modal/Form/Inputs/SuggestedContactStatus/SuggestedContactStatus.graphql +++ b/src/components/Task/Modal/Form/Inputs/SuggestedContactStatus/SuggestedContactStatus.graphql @@ -1,5 +1,6 @@ query ContactStatus($accountListId: ID!, $contactId: ID!) { contact(accountListId: $accountListId, id: $contactId) { + id status } } From 76e30c1ad974025010a78fbcb817bd65c1988974 Mon Sep 17 00:00:00 2001 From: Caleb Cox Date: Mon, 7 Oct 2024 16:16:56 -0500 Subject: [PATCH 4/5] Clean up tests --- .../Complete/TaskModalCompleteForm.test.tsx | 18 +++---- .../SuggestedContactStatus.test.tsx | 47 ++++++------------- 2 files changed, 20 insertions(+), 45 deletions(-) diff --git a/src/components/Task/Modal/Form/Complete/TaskModalCompleteForm.test.tsx b/src/components/Task/Modal/Form/Complete/TaskModalCompleteForm.test.tsx index 5382acc62..56b2cba57 100644 --- a/src/components/Task/Modal/Form/Complete/TaskModalCompleteForm.test.tsx +++ b/src/components/Task/Modal/Form/Complete/TaskModalCompleteForm.test.tsx @@ -149,15 +149,13 @@ describe('TaskModalCompleteForm', () => { await waitFor(() => { expect( - queryByText( - "Change the contact's status to: CONTACT_FOR_APPOINTMENT", - ), + queryByText("Change the contact's status to:"), ).not.toBeInTheDocument(); }); }); it('renders suggested status when single contact', async () => { - const { getByRole, getByText, findByRole } = render( + const { getByRole, getByText, findByRole, findByText } = render( { ); }); - await waitFor(() => { - expect( - getByText("Change the contact's status to:"), - ).toBeInTheDocument(); - expect(getByText('Initiate for Appointment')).toBeInTheDocument(); - }); + expect(await findByText('Initiate for Appointment')).toBeInTheDocument(); + expect(getByText("Change the contact's status to:")).toBeInTheDocument(); }); it('does not render suggested status when the Phase Constant does not provide a suggested status', async () => { @@ -407,8 +401,8 @@ describe('TaskModalCompleteForm', () => { userEvent.click(await findByRole('combobox', { name: 'Next Action' })); userEvent.click(await findByRole('option', { name: 'Thank You Note' })); - userEvent.click(await findByText("Change the contact's status to:")); - expect(getByText('Partner - Special')).toBeInTheDocument(); + expect(await findByText('Partner - Special')).toBeInTheDocument(); + userEvent.click(getByText("Change the contact's status to:")); userEvent.click(getByText('Save')); await waitFor(() => diff --git a/src/components/Task/Modal/Form/Inputs/SuggestedContactStatus/SuggestedContactStatus.test.tsx b/src/components/Task/Modal/Form/Inputs/SuggestedContactStatus/SuggestedContactStatus.test.tsx index a04b848e6..428dfccde 100644 --- a/src/components/Task/Modal/Form/Inputs/SuggestedContactStatus/SuggestedContactStatus.test.tsx +++ b/src/components/Task/Modal/Form/Inputs/SuggestedContactStatus/SuggestedContactStatus.test.tsx @@ -108,29 +108,27 @@ describe('SuggestedContactStatus', () => { }); it('renders suggested status when single contact and checks contact status with gql call', async () => { - const { getByText } = render( + const { findByText } = render( , ); - await waitFor(() => { - expect(mutationSpy).toHaveBeenCalledTimes(2); + + await waitFor(() => expect(mutationSpy).toHaveGraphqlOperation('ContactStatus', { accountListId: accountListId, contactId: 'contact-1', - }); - }); - - await waitFor( - () => expect(getByText('Initiate for Appointment')).toBeInTheDocument(), - { timeout: 3000 }, + }), ); + expect( + await findByText("Change the contact's status to:"), + ).toBeInTheDocument(); }); it('does not send a ContactStatus graphql request when the current contacts status is provided', async () => { - const { getByText } = render( + const { findByText, getByText } = render( { />, ); - await waitFor(() => { - expect(mutationSpy).toHaveBeenCalledTimes(1); - expect(mutationSpy).toHaveGraphqlOperation('LoadConstants', {}); - }); - await waitFor( - () => { - expect( - getByText("Change the contact's status to:"), - ).toBeInTheDocument(); - expect(getByText('Initiate for Appointment')).toBeInTheDocument(); - }, - { timeout: 3000 }, - ); + expect(await findByText('Initiate for Appointment')).toBeInTheDocument(); + expect(getByText("Change the contact's status to:")).toBeInTheDocument(); + expect(mutationSpy).not.toHaveGraphqlOperation('ContactStatus'); }); it('renders suggested status when the contact has no status', async () => { - const { getByText } = render( + const { findByText, getByText } = render( { />, ); - await waitFor( - () => { - expect( - getByText("Change the contact's status to:"), - ).toBeInTheDocument(); - expect(getByText('Initiate for Appointment')).toBeInTheDocument(); - }, - { timeout: 3000 }, - ); + expect(await findByText('Initiate for Appointment')).toBeInTheDocument(); + expect(getByText("Change the contact's status to:")).toBeInTheDocument(); }); }); From d3008c4856ed9cb8fb64b3d80bc4ae127a7e38f7 Mon Sep 17 00:00:00 2001 From: Caleb Cox Date: Tue, 8 Oct 2024 06:58:20 -0500 Subject: [PATCH 5/5] Find suggested status checkbox with one role query --- .../Complete/TaskModalCompleteForm.test.tsx | 26 ++++++++------ .../SuggestedContactStatus.test.tsx | 36 +++++++++++-------- .../SuggestedContactStatus.tsx | 2 +- 3 files changed, 39 insertions(+), 25 deletions(-) diff --git a/src/components/Task/Modal/Form/Complete/TaskModalCompleteForm.test.tsx b/src/components/Task/Modal/Form/Complete/TaskModalCompleteForm.test.tsx index 56b2cba57..263885c87 100644 --- a/src/components/Task/Modal/Form/Complete/TaskModalCompleteForm.test.tsx +++ b/src/components/Task/Modal/Form/Complete/TaskModalCompleteForm.test.tsx @@ -134,7 +134,7 @@ describe('TaskModalCompleteForm', () => { }); it("doesn't render suggested contact status when multiple contacts", async () => { - const { queryByText, findByRole } = render( + const { queryByRole, findByRole } = render( , @@ -149,13 +149,13 @@ describe('TaskModalCompleteForm', () => { await waitFor(() => { expect( - queryByText("Change the contact's status to:"), + queryByRole('checkbox', { name: /^Change the contact's status/ }), ).not.toBeInTheDocument(); }); }); it('renders suggested status when single contact', async () => { - const { getByRole, getByText, findByRole, findByText } = render( + const { getByRole, findByRole } = render( { ); }); - expect(await findByText('Initiate for Appointment')).toBeInTheDocument(); - expect(getByText("Change the contact's status to:")).toBeInTheDocument(); + expect( + await findByRole('checkbox', { + name: "Change the contact's status to: Initiate for Appointment", + }), + ).toBeInTheDocument(); }); it('does not render suggested status when the Phase Constant does not provide a suggested status', async () => { - const { getByRole, queryByText, findByRole } = render( + const { getByRole, queryByRole, findByRole } = render( { await waitFor(() => { expect( - queryByText("Change the contact's status to:"), + queryByRole('checkbox', { name: /^Change the contact's status/ }), ).not.toBeInTheDocument(); }); }); @@ -384,7 +387,7 @@ describe('TaskModalCompleteForm', () => { it('saves contacts new status', async () => { const completedAt = DateTime.local(2015, 1, 5, 1, 2).toISO(); - const { findByRole, getByText, findByText } = render( + const { findByRole, getByText } = render( { userEvent.click(await findByRole('combobox', { name: 'Next Action' })); userEvent.click(await findByRole('option', { name: 'Thank You Note' })); - expect(await findByText('Partner - Special')).toBeInTheDocument(); - userEvent.click(getByText("Change the contact's status to:")); + userEvent.click( + await findByRole('checkbox', { + name: "Change the contact's status to: Partner - Special", + }), + ); userEvent.click(getByText('Save')); await waitFor(() => diff --git a/src/components/Task/Modal/Form/Inputs/SuggestedContactStatus/SuggestedContactStatus.test.tsx b/src/components/Task/Modal/Form/Inputs/SuggestedContactStatus/SuggestedContactStatus.test.tsx index 428dfccde..1507c7213 100644 --- a/src/components/Task/Modal/Form/Inputs/SuggestedContactStatus/SuggestedContactStatus.test.tsx +++ b/src/components/Task/Modal/Form/Inputs/SuggestedContactStatus/SuggestedContactStatus.test.tsx @@ -62,7 +62,7 @@ const Components = ({ describe('SuggestedContactStatus', () => { it("doesn't render suggested contact status when there are multiple contacts", async () => { - const { queryByText } = render( + const { queryByRole } = render( { ); await waitFor(() => { expect( - queryByText("Change the contact's status to:"), + queryByRole('checkbox', { name: /^Change the contact's status/ }), ).not.toBeInTheDocument(); }); }); it("doesn't render suggested contact status when suggested status is the same as the current status", async () => { const sameStatus = StatusEnum.ContactForAppointment; - const { queryByText } = render( + const { queryByRole } = render( { ); await waitFor(() => { expect( - queryByText("Change the contact's status to:"), + queryByRole('checkbox', { name: /^Change the contact's status/ }), ).not.toBeInTheDocument(); }); }); it("doesn't render suggested contact status when the current contact is a Prayer, Special or Financial Partner", async () => { - const { queryByText } = render( + const { queryByRole } = render( { ); await waitFor(() => { expect( - queryByText("Change the contact's status to:"), + queryByRole('checkbox', { name: /^Change the contact's status/ }), ).not.toBeInTheDocument(); }); }); it('renders suggested status when single contact and checks contact status with gql call', async () => { - const { findByText } = render( + const { findByRole } = render( { }), ); expect( - await findByText("Change the contact's status to:"), + await findByRole('checkbox', { + name: "Change the contact's status to: Initiate for Appointment", + }), ).toBeInTheDocument(); }); it('does not send a ContactStatus graphql request when the current contacts status is provided', async () => { - const { findByText, getByText } = render( + const { findByRole } = render( { />, ); - expect(await findByText('Initiate for Appointment')).toBeInTheDocument(); - expect(getByText("Change the contact's status to:")).toBeInTheDocument(); + expect( + await findByRole('checkbox', { + name: "Change the contact's status to: Initiate for Appointment", + }), + ).toBeInTheDocument(); expect(mutationSpy).not.toHaveGraphqlOperation('ContactStatus'); }); it('renders suggested status when the contact has no status', async () => { - const { findByText, getByText } = render( + const { findByRole } = render( { />, ); - expect(await findByText('Initiate for Appointment')).toBeInTheDocument(); - expect(getByText("Change the contact's status to:")).toBeInTheDocument(); + expect( + await findByRole('checkbox', { + name: "Change the contact's status to: Initiate for Appointment", + }), + ).toBeInTheDocument(); }); }); diff --git a/src/components/Task/Modal/Form/Inputs/SuggestedContactStatus/SuggestedContactStatus.tsx b/src/components/Task/Modal/Form/Inputs/SuggestedContactStatus/SuggestedContactStatus.tsx index 237bd7b96..59d9271cc 100644 --- a/src/components/Task/Modal/Form/Inputs/SuggestedContactStatus/SuggestedContactStatus.tsx +++ b/src/components/Task/Modal/Form/Inputs/SuggestedContactStatus/SuggestedContactStatus.tsx @@ -84,7 +84,7 @@ export const SuggestedContactStatus: React.FC = ({ values={{ status: contactStatuses[suggestedContactStatus]?.translated, }} - components={{ italic: , bold: }} + components={{ bold: }} /> } />