diff --git a/e2e-tests/caseList.ts b/e2e-tests/caseList.ts index 9228ed3622..43f907e7eb 100644 --- a/e2e-tests/caseList.ts +++ b/e2e-tests/caseList.ts @@ -56,9 +56,9 @@ export const caseList = (page: Page) => { caseSummaryText: caseListPage.locator(`//textarea[@data-testid='Case-CaseSummary-TextArea']`), caseSummaryTextArea: caseListPage.locator(`//textarea[@data-testid='summary']`), casePrintButton: caseListPage.locator(`//button[@data-testid='CasePrint-Button']`), - casePrintCloseButton: caseListPage.locator(`//button[@data-testid='CasePrint-CloseCross']`), - caseCloseButton: caseListPage.locator(`//button[@data-testid='CaseHome-CloseButton']`), - caseEditCloseButton: caseListPage.locator(`//button[@data-testid='Case-CloseButton']`), + modalCloseButton: caseListPage.locator( + `//button[@data-testid='NavigableContainer-CloseCross']`, + ), updateCaseButton: caseListPage.locator(`//button[@data-testid='Case-EditCaseScreen-SaveItem']`), caseEditButton: caseListPage.locator(`//button[@data-testid='Case-EditButton']`), @@ -124,7 +124,7 @@ export const caseList = (page: Page) => { await openPrintButton.click(); console.log('Opened Case Print'); - const closePrintButton = selectors.casePrintCloseButton; + const closePrintButton = selectors.modalCloseButton; await closePrintButton.waitFor({ state: 'visible' }); await closePrintButton.click(); console.log('Close Case Print'); @@ -179,18 +179,9 @@ export const caseList = (page: Page) => { await updateCaseButton.waitFor({ state: 'visible' }); await expect(updateCaseButton).toContainText('Save'); await updateCaseButton.click(); - console.log('Updated Case Summary'); } - // Close Edit case - async function closeEditCase() { - const caseEditClose = selectors.caseEditCloseButton; - await caseEditClose.waitFor({ state: 'visible' }); - await expect(caseEditClose).toContainText('Cancel'); - await caseEditClose.click(); - } - // Verify case summary update async function verifyCaseSummaryUpdated() { const summaryText = selectors.caseSummaryText; @@ -205,13 +196,11 @@ export const caseList = (page: Page) => { await Promise.all(caseListIdButtons.map((l, idx) => expect(l).toContainText(ids[idx]))); } - //Close Case - async function closeCase() { - const closeCaseButton = selectors.caseCloseButton; + //Close Modal (probably can move this to more generic navigation file now we have more standardised navigation) + async function closeModal() { + const closeCaseButton = selectors.modalCloseButton; await closeCaseButton.waitFor({ state: 'visible' }); - await expect(closeCaseButton).toContainText('Close'); await closeCaseButton.click(); - console.log('Closed Case'); } return { @@ -223,9 +212,8 @@ export const caseList = (page: Page) => { addCaseSection, editCase, updateCaseSummary, - closeEditCase, verifyCaseSummaryUpdated, - closeCase, + closeModal, verifyCaseIdsAreInListInOrder, }; }; diff --git a/e2e-tests/tests/caselist.spec.ts b/e2e-tests/tests/caselist.spec.ts index 9bdcb11039..9b3267adbd 100644 --- a/e2e-tests/tests/caselist.spec.ts +++ b/e2e-tests/tests/caselist.spec.ts @@ -81,6 +81,7 @@ test.describe.serial('Open and Edit a Case in Case List page', () => { await page.verifyCaseSummaryUpdated(); - await page.closeCase(); + await page.closeModal(); + console.log('Closed Case'); }); }); diff --git a/e2e-tests/ui-tests/tests/case-list.spec.ts b/e2e-tests/ui-tests/tests/case-list.spec.ts index 739a9e1640..f4a366d108 100644 --- a/e2e-tests/ui-tests/tests/case-list.spec.ts +++ b/e2e-tests/ui-tests/tests/case-list.spec.ts @@ -19,8 +19,7 @@ import { expect, Page, test } from '@playwright/test'; import * as mockServer from '../flex-in-a-box/proxied-endpoints'; -// eslint-disable-next-line @typescript-eslint/no-unused-vars -import { preload, useUnminifiedFlex } from '../flex-in-a-box/local-resources'; +import '../flex-in-a-box/local-resources'; import hrmCases from '../aselo-service-mocks/hrm/cases'; import { caseList, Filter } from '../../caseList'; import AxeBuilder from '@axe-core/playwright'; @@ -96,6 +95,6 @@ test.describe.serial('Case List', () => { .analyze(); //expect(caseHomeAccessibilityScanResults.violations).toEqual([]); warnViolations(caseEditAccessibilityScanResults, `the case summary edit page`); - await caseListPage.closeEditCase(); + await caseListPage.closeModal(); }); }); diff --git a/plugin-hrm-form/src/___tests__/components/PreviousContactsBanner.test.tsx b/plugin-hrm-form/src/___tests__/components/PreviousContactsBanner.test.tsx index 61a2fa32a5..ddd4d6a95d 100644 --- a/plugin-hrm-form/src/___tests__/components/PreviousContactsBanner.test.tsx +++ b/plugin-hrm-form/src/___tests__/components/PreviousContactsBanner.test.tsx @@ -14,12 +14,12 @@ * along with this program. If not, see https://www.gnu.org/licenses/. */ -import React from 'react'; +import * as React from 'react'; import { render, screen } from '@testing-library/react'; import '@testing-library/jest-dom/extend-expect'; import { configureAxe, toHaveNoViolations } from 'jest-axe'; import { mount } from 'enzyme'; -import { StorelessThemeProvider, ThemeConfigProps } from '@twilio/flex-ui'; +import { StorelessThemeProvider } from '@twilio/flex-ui'; import { UnconnectedPreviousContactsBanner } from '../../components/PreviousContactsBanner'; import { channelTypes } from '../../states/DomainConstants'; @@ -155,7 +155,7 @@ test('Click View Records should redirect user to search results', () => { const searchContacts = jest.fn(); const searchCases = jest.fn(); - const changeRoute = jest.fn(); + const openModal = jest.fn(); const viewPreviousContacts = jest.fn(); render( @@ -166,8 +166,8 @@ test('Click View Records should redirect user to search results', () => { previousContacts={previousContacts} searchContacts={searchContacts} searchCases={searchCases} - changeRoute={changeRoute} viewPreviousContacts={viewPreviousContacts} + openContactSearchResults={openModal} /> , ); @@ -177,7 +177,7 @@ test('Click View Records should redirect user to search results', () => { expect(searchContacts).not.toHaveBeenCalled(); expect(searchCases).not.toHaveBeenCalled(); expect(viewPreviousContacts).toHaveBeenCalled(); - expect(changeRoute).toHaveBeenCalledWith({ route: 'tabbed-forms', subroute: 'search' }); + expect(openModal).toHaveBeenCalled(); }); test('a11y', async () => { diff --git a/plugin-hrm-form/src/___tests__/components/case/AddEditCaseItem.test.tsx b/plugin-hrm-form/src/___tests__/components/case/AddEditCaseItem.test.tsx index b43e9750ba..840d17b07a 100644 --- a/plugin-hrm-form/src/___tests__/components/case/AddEditCaseItem.test.tsx +++ b/plugin-hrm-form/src/___tests__/components/case/AddEditCaseItem.test.tsx @@ -29,7 +29,7 @@ import { RootState } from '../../../states'; import AddEditCaseItem, { AddEditCaseItemProps } from '../../../components/case/AddEditCaseItem'; import { getDefinitionVersions } from '../../../hrmConfig'; import { CustomITask } from '../../../types/types'; -import { CaseItemAction, NewCaseSubroutes } from '../../../states/routing/types'; +import { CaseItemAction } from '../../../states/routing/types'; import { householdSectionApi } from '../../../states/case/sections/household'; import { newGoBackAction } from '../../../states/routing/actions'; import { ReferralLookupStatus } from '../../../states/contacts/resourceReferral'; @@ -153,6 +153,7 @@ const hrmState: Partial = { categories: { gridView: false, expanded: {} }, recreated: false, draft: { + dialogsOpen: {}, resourceReferralList: { lookupStatus: ReferralLookupStatus.NOT_STARTED, resourceReferralIdToAdd: undefined, @@ -185,7 +186,10 @@ const state2 = { [connectedCaseBase]: addingNewHouseholdCaseState, routing: { tasks: { - task1: [{ route: 'case', subroute: 'household', action: CaseItemAction.Add }], + task1: [ + { route: 'case', subroute: 'household', action: CaseItemAction.View }, + { route: 'case', subroute: 'household', action: CaseItemAction.Add }, + ], }, }, }, @@ -221,11 +225,6 @@ describe('Test AddHousehold', () => { counselor: 'Someone', sectionApi: householdSectionApi, definitionVersion: mockV1, - routing: { - route: 'case', - subroute: NewCaseSubroutes.Household, - action: CaseItemAction.Add, - }, }), ); test('Test close functionality', async () => { @@ -239,15 +238,8 @@ describe('Test AddHousehold', () => { expect(store2.dispatch).not.toHaveBeenCalledWith(newGoBackAction('task1')); - expect(screen.getByTestId('Case-CloseCross')).toBeInTheDocument(); - screen.getByTestId('Case-CloseCross').click(); - - expect(store2.dispatch).toHaveBeenCalledWith(newGoBackAction('task1')); - - store2.dispatch.mockClear(); - - expect(screen.getByTestId('Case-CloseButton')).toBeInTheDocument(); - screen.getByTestId('Case-CloseButton').click(); + expect(screen.getByTestId('NavigableContainer-BackButton')).toBeInTheDocument(); + screen.getByTestId('NavigableContainer-BackButton').click(); expect(store2.dispatch).toHaveBeenCalledWith(newGoBackAction('task1')); }); diff --git a/plugin-hrm-form/src/___tests__/components/case/Case.test.tsx b/plugin-hrm-form/src/___tests__/components/case/Case.test.tsx index 7ce0af4633..e515415cb1 100644 --- a/plugin-hrm-form/src/___tests__/components/case/Case.test.tsx +++ b/plugin-hrm-form/src/___tests__/components/case/Case.test.tsx @@ -244,7 +244,7 @@ describe('useState mocked', () => { expect(screen.getByTestId('Case-DetailsHeaderCounselor').innerHTML).toContain('worker1 name'); expect(screen.getByTestId('Case-Details_DateOpened').getAttribute('value')).toBe('6/29/2020'); expect(screen.getByTestId('Case-Details_DateLastUpdated').getAttribute('value')).toBe('—'); - expect(screen.getByTestId('Case-DetailsHeaderChildName').innerHTML).toContain('first last'); + expect(screen.getByTestId('NavigableContainer-Title').innerHTML).toContain('first last'); }); test('Case (should render, after update)', async () => { diff --git a/plugin-hrm-form/src/___tests__/components/case/CaseHome.test.tsx b/plugin-hrm-form/src/___tests__/components/case/CaseHome.test.tsx index 286ba1ff44..d4ad48157b 100644 --- a/plugin-hrm-form/src/___tests__/components/case/CaseHome.test.tsx +++ b/plugin-hrm-form/src/___tests__/components/case/CaseHome.test.tsx @@ -24,18 +24,14 @@ import configureMockStore from 'redux-mock-store'; import { mockGetDefinitionsResponse } from '../../mockGetConfig'; import CaseHome, { CaseHomeProps } from '../../../components/case/CaseHome'; -import { HouseholdEntry, PerpetratorEntry, StandaloneITask } from '../../../types/types'; +import { CustomITask, HouseholdEntry, PerpetratorEntry } from '../../../types/types'; import { CaseDetails } from '../../../states/case/types'; import { getDefinitionVersions } from '../../../hrmConfig'; import { CaseItemAction, NewCaseSubroutes } from '../../../states/routing/types'; import { VALID_EMPTY_CONTACT } from '../../testContacts'; -import { - configurationBase, - connectedCaseBase, - contactFormsBase, - namespace, - routingBase, -} from '../../../states/storeNamespaces'; +import { namespace } from '../../../states/storeNamespaces'; +import { RecursivePartial } from '../../RecursivePartial'; +import { RootState } from '../../../states'; // eslint-disable-next-line react-hooks/rules-of-hooks const { mockFetchImplementation, mockReset, buildBaseURL } = useFetchDefinitions(); @@ -72,7 +68,7 @@ const householdEntry: HouseholdEntry = { twilioWorkerId: 'worker1', }; -function createState(state) { +function createState(state: RecursivePartial) { return { [namespace]: state, }; @@ -81,7 +77,7 @@ function createState(state) { let ownProps: CaseHomeProps; let mockV1; -let initialState; +let initialState: RecursivePartial; let caseDetails: CaseDetails; describe('useState mocked', () => { @@ -96,7 +92,7 @@ describe('useState mocked', () => { beforeEach(() => { mockReset(); initialState = createState({ - [configurationBase]: { + configuration: { counselors: { list: [], hash: { worker1: 'worker1 name' }, @@ -104,11 +100,11 @@ describe('useState mocked', () => { definitionVersions: { v1: mockV1 }, currentDefinitionVersion: mockV1, }, - [contactFormsBase]: { - tasks: { - task1: { + activeContacts: { + existingContacts: { + contact1: { metadata: {}, - contact: { + savedContact: { ...VALID_EMPTY_CONTACT, rawJson: { ...VALID_EMPTY_CONTACT.rawJson, @@ -121,27 +117,32 @@ describe('useState mocked', () => { }, categories: {}, }, - taskSid: 'task1', + taskId: 'task1', }, }, }, }, - [connectedCaseBase]: { + connectedCase: { tasks: { task1: { - taskSid: 'task1', connectedCase: { id: 123, createdAt: '2020-06-29T22:26:00.208Z', twilioWorkerId: 'worker1', status: 'open', - info: { definitionVersion: 'v1' }, + info: { definitionVersion: DefinitionVersionId.v1 }, connectedContacts: [], }, }, }, }, - [routingBase]: { tasks: { task1: [{ route: 'case', subroute: 'home' }] } }, + routing: { + tasks: { + task1: [ + { route: 'tabbed-forms', subroute: 'categories', activeModal: [{ route: 'case', subroute: 'home' }] }, + ], + }, + }, }); const setState = jest.fn(); @@ -173,7 +174,7 @@ describe('useState mocked', () => { }; ownProps = { - task: initialState[namespace][connectedCaseBase].tasks.task1 as StandaloneITask, + task: { taskSid: 'task1' } as CustomITask, definitionVersion: mockV1, can: () => true, caseDetails, @@ -209,8 +210,7 @@ describe('useState mocked', () => { action: CaseItemAction.Add, }, taskId: 'task1', - replace: false, - type: 'routing/change-route', + type: 'routing/open-modal', }); }); @@ -234,8 +234,7 @@ describe('useState mocked', () => { action: CaseItemAction.Add, }, taskId: 'task1', - replace: false, - type: 'routing/change-route', + type: 'routing/open-modal', }); }); @@ -259,8 +258,7 @@ describe('useState mocked', () => { action: CaseItemAction.Add, }, taskId: 'task1', - replace: false, - type: 'routing/change-route', + type: 'routing/open-modal', }); }); @@ -284,8 +282,7 @@ describe('useState mocked', () => { action: CaseItemAction.Add, }, taskId: 'task1', - replace: false, - type: 'routing/change-route', + type: 'routing/open-modal', }); }); @@ -312,8 +309,7 @@ describe('useState mocked', () => { id: 'HOUSEHOLD_ID', }, taskId: 'task1', - replace: false, - type: 'routing/change-route', + type: 'routing/open-modal', }); }); @@ -340,8 +336,7 @@ describe('useState mocked', () => { id: 'PERPETRATOR_ID', }, taskId: 'task1', - replace: false, - type: 'routing/change-route', + type: 'routing/open-modal', }); }); @@ -367,8 +362,7 @@ describe('useState mocked', () => { id: '', }, taskId: 'task1', - replace: false, - type: 'routing/change-route', + type: 'routing/open-modal', }); }); @@ -402,7 +396,7 @@ describe('useState mocked', () => { , ); - screen.getByTestId('CaseHome-CloseButton').click(); + screen.getByTestId('NavigableContainer-CloseCross').click(); expect(ownProps.handleCancelNewCaseAndClose).not.toHaveBeenCalled(); expect(ownProps.handleClose).toHaveBeenCalled(); diff --git a/plugin-hrm-form/src/___tests__/components/case/EditCaseSummary.test.tsx b/plugin-hrm-form/src/___tests__/components/case/EditCaseSummary.test.tsx index f45b87ae99..d307c13737 100644 --- a/plugin-hrm-form/src/___tests__/components/case/EditCaseSummary.test.tsx +++ b/plugin-hrm-form/src/___tests__/components/case/EditCaseSummary.test.tsx @@ -28,9 +28,11 @@ import { mockGetDefinitionsResponse } from '../../mockGetConfig'; import EditCaseSummary, { EditCaseSummaryProps } from '../../../components/case/EditCaseSummary'; import { getDefinitionVersions } from '../../../hrmConfig'; import { StandaloneITask } from '../../../types/types'; -import { AppRoutes } from '../../../states/routing/types'; +import { CaseRoute } from '../../../states/routing/types'; import { changeRoute } from '../../../states/routing/actions'; -import { configurationBase, connectedCaseBase, contactFormsBase, namespace } from '../../../states/storeNamespaces'; +import { namespace } from '../../../states/storeNamespaces'; +import { RecursivePartial } from '../../RecursivePartial'; +import { RootState } from '../../../states'; // eslint-disable-next-line react-hooks/rules-of-hooks const { mockFetchImplementation, mockReset, buildBaseURL } = useFetchDefinitions(); @@ -40,30 +42,35 @@ let mockV1: DefinitionVersion; expect.extend(toHaveNoViolations); const mockStore = configureMockStore([]); -const state = { +const state: RecursivePartial = { [namespace]: { - [configurationBase]: { + configuration: { counselors: { list: [], hash: { worker1: 'worker1 name' }, }, }, - [contactFormsBase]: { - tasks: { - task1: { - childInformation: { - name: { firstName: { value: 'first' }, lastName: { value: 'last' } }, + activeContacts: { + existingContacts: { + contact1: { + savedContact: { + rawJson: { + childInformation: { + firstName: 'first', + lastName: 'last', + }, + }, }, metadata: {}, }, }, }, - [connectedCaseBase]: { + connectedCase: { tasks: { task1: { caseWorkingCopy: { sections: {} }, connectedCase: { - createdAt: 1593469560208, + createdAt: new Date().toISOString(), twilioWorkerId: 'worker1', status: 'open', info: {}, @@ -73,11 +80,17 @@ const state = { }, }, routing: { - route: 'new-case', tasks: { - task1: { - route: 'new-case', - }, + task1: [ + { + route: 'case', + subroute: 'home', + }, + { + route: 'case', + subroute: 'caseSummary', + }, + ], }, }, }, @@ -92,7 +105,7 @@ const task = { describe('Test EditCaseSummary', () => { let ownProps: EditCaseSummaryProps; - const exitRoute: AppRoutes = { route: 'new-case' }; + const exitRoute: CaseRoute = { route: 'case', subroute: 'home' }; beforeAll(async () => { const formDefinitionsBaseUrl = buildBaseURL(DefinitionVersionId.v1); @@ -106,7 +119,6 @@ describe('Test EditCaseSummary', () => { mockReset(); ownProps = { task: task as StandaloneITask, - exitRoute, definitionVersion: mockV1, can: () => true, }; @@ -123,14 +135,8 @@ describe('Test EditCaseSummary', () => { expect(store.dispatch).not.toHaveBeenCalledWith(changeRoute(exitRoute, 'task1')); - expect(screen.getByTestId('Case-CloseCross')).toBeInTheDocument(); - screen.getByTestId('Case-CloseCross').click(); - expect(store.dispatch).not.toHaveBeenCalledWith(changeRoute(exitRoute, 'task1')); - - store.dispatch.mockClear(); - - expect(screen.getByTestId('Case-CloseButton')).toBeInTheDocument(); - screen.getByTestId('Case-CloseButton').click(); + expect(screen.getByTestId('NavigableContainer-BackButton')).toBeInTheDocument(); + screen.getByTestId('NavigableContainer-BackButton').click(); expect(store.dispatch).not.toHaveBeenCalledWith(changeRoute(exitRoute, 'task1')); }); diff --git a/plugin-hrm-form/src/___tests__/components/case/ViewCaseItem.test.tsx b/plugin-hrm-form/src/___tests__/components/case/ViewCaseItem.test.tsx index 5ffe783a62..e8cb66e4ac 100644 --- a/plugin-hrm-form/src/___tests__/components/case/ViewCaseItem.test.tsx +++ b/plugin-hrm-form/src/___tests__/components/case/ViewCaseItem.test.tsx @@ -141,12 +141,6 @@ describe('Test ViewHousehold', () => { definitionVersion: mockV1, task: task as StandaloneITask, sectionApi: householdSectionApi, - routing: { - route: 'case', - subroute: NewCaseSubroutes.Household, - action: CaseItemAction.View, - id: 'HOUSEHOLD_2', - }, canEdit: () => true, }; }); @@ -160,17 +154,9 @@ describe('Test ViewHousehold', () => { , ); - expect(screen.getByTestId('Case-CloseCross')).toBeInTheDocument(); + expect(screen.getByTestId('NavigableContainer-BackButton')).toBeInTheDocument(); expect(screen.getByTestId('Case-EditButton')).toBeInTheDocument(); - screen.getByTestId('Case-CloseCross').click(); - - expect(store.dispatch).toHaveBeenCalledWith(newGoBackAction(task.taskSid)); - - store.dispatch.mockClear(); - expect(store.dispatch).not.toHaveBeenCalled(); - - expect(screen.getByTestId('Case-CloseButton')).toBeInTheDocument(); - screen.getByTestId('Case-CloseButton').click(); + screen.getByTestId('NavigableContainer-BackButton').click(); expect(store.dispatch).toHaveBeenCalledWith(newGoBackAction(task.taskSid)); }); @@ -182,7 +168,7 @@ describe('Test ViewHousehold', () => { , ); - expect(screen.getByTestId('Case-CloseCross')).toBeInTheDocument(); + expect(screen.getByTestId('NavigableContainer-BackButton')).toBeInTheDocument(); expect(screen.queryByTestId('Case-EditButton')).toBeNull(); }); diff --git a/plugin-hrm-form/src/___tests__/components/case/ViewContact.test.tsx b/plugin-hrm-form/src/___tests__/components/case/ViewContact.test.tsx index ff76830f81..bab4f6b8ce 100644 --- a/plugin-hrm-form/src/___tests__/components/case/ViewContact.test.tsx +++ b/plugin-hrm-form/src/___tests__/components/case/ViewContact.test.tsx @@ -28,10 +28,12 @@ import { mockGetDefinitionsResponse } from '../../mockGetConfig'; import ViewContact from '../../../components/case/ViewContact'; import { ContactDetailsSections } from '../../../components/common/ContactDetails'; import { getDefinitionVersions } from '../../../hrmConfig'; -import { Contact } from '../../../types/types'; +import { Case, Contact } from '../../../types/types'; import { RootState } from '../../../states'; import { DetailsContext, TOGGLE_DETAIL_EXPANDED_ACTION } from '../../../states/contacts/contactDetails'; -import { connectedCaseBase, contactFormsBase, csamReportBase } from '../../../states/storeNamespaces'; +import { connectedCaseBase, csamReportBase } from '../../../states/storeNamespaces'; +import { VALID_EMPTY_CONTACT, VALID_EMPTY_METADATA } from '../../testContacts'; +import { newCloseModalAction } from '../../../states/routing/actions'; jest.mock('@twilio/flex-ui', () => ({ ...jest.requireActual('@twilio/flex-ui'), @@ -115,7 +117,7 @@ const contact: Contact = { stateOrCounty: '', streetAddress: '', }, - contactlessTask: { channel: 'voice' }, + contactlessTask: { ...VALID_EMPTY_CONTACT.rawJson.contactlessTask, channel: 'voice' }, categories: { category1: ['Tag1', 'Tag2'] }, }, }; @@ -147,6 +149,14 @@ describe('View Contact', () => { }, } as any, 'plugin-hrm-form': { + routing: { + tasks: { + 'task-id': [ + { route: 'case', subroute: 'home', activeModal: [{ route: 'contact', subroute: 'view', id: 'TEST_ID' }] }, + ], + }, + isAddingOfflineContact: false, + }, configuration: { language: '', workerInfo: { chatChannelCapacity: 1 }, @@ -157,18 +167,23 @@ describe('View Contact', () => { [connectedCaseBase]: { tasks: { 'task-id': { - connectedCase: {}, - timelineActivities: [], + connectedCase: {} as Case, + availableStatusTransitions: [], + caseWorkingCopy: { sections: {} }, }, }, }, - [contactFormsBase]: { - tasks: {}, + activeContacts: { + editingContact: false, + isCallTypeCaller: false, existingContacts: { TEST_ID: { savedContact: contact, references: new Set(['task-id']), - categories: { gridView: false, expanded: {} }, + metadata: { + ...VALID_EMPTY_METADATA, + categories: { gridView: false, expanded: {} }, + }, }, }, contactDetails: { @@ -177,7 +192,6 @@ describe('View Contact', () => { }, }, [csamReportBase]: { - tasks: {}, contacts: {}, }, }, @@ -190,45 +204,43 @@ describe('View Contact', () => { render( - + , ); // TODO: Verify interpolated translations contain the expected data await waitFor(() => expect(screen.getByTestId('ContactDetails-Container')).toBeInTheDocument()); - expect(screen.getByText('#TEST_ID')).toBeInTheDocument(); - expect(screen.getByText('Jill Smith')).toBeInTheDocument(); + expect(screen.getByText('#TEST_ID Jill Smith')).toBeInTheDocument(); }); test('click on close button', async () => { - const onClickClose = jest.fn(); const store = mockStore(initialState); render( - + , ); - await waitFor(() => expect(screen.getByTestId('Case-ViewContactScreen-CloseButton')).toBeInTheDocument()); + await waitFor(() => expect(screen.getByTestId('NavigableContainer-CloseCross')).toBeInTheDocument()); - screen.getByTestId('Case-ViewContactScreen-CloseButton').click(); - - expect(onClickClose).toHaveBeenCalled(); + screen.getByTestId('NavigableContainer-CloseCross').click(); + const actions = store.getActions(); + expect(actions[actions.length - 1]).toStrictEqual(newCloseModalAction(task.taskSid)); }); test('click on expand section sends toggle action', async () => { const store = mockStore(initialState); render( - - - - - , + + + + + , ); await waitFor(() => expect(screen.getByTestId('ContactDetails-Section-ChildInformation')).toBeInTheDocument()); @@ -247,7 +259,7 @@ describe('View Contact', () => { const wrapper = mount( - + , ); diff --git a/plugin-hrm-form/src/___tests__/components/caseList/CaseList.test.tsx b/plugin-hrm-form/src/___tests__/components/caseList/CaseList.test.tsx index f6a7619ee5..44510eefb6 100644 --- a/plugin-hrm-form/src/___tests__/components/caseList/CaseList.test.tsx +++ b/plugin-hrm-form/src/___tests__/components/caseList/CaseList.test.tsx @@ -36,7 +36,7 @@ import { fetchCaseListSuccess, } from '../../../states/caseList/listContent'; import { caseListSettingsInitialState } from '../../../states/caseList/settings'; -import { Case, ContactRawJson, Contact } from '../../../types/types'; +import { Case, ContactRawJson, Contact, standaloneTaskSid } from '../../../types/types'; import { caseListBase, configurationBase, namespace } from '../../../states/storeNamespaces'; // eslint-disable-next-line react-hooks/rules-of-hooks @@ -140,7 +140,11 @@ test('Should dispatch fetchStarted and fetchSuccess actions if case lists return currentDefinitionVersion: mockV1, }, [caseListBase]: blankCaseListState, - routing: { tasks: {} }, + routing: { + tasks: { + [standaloneTaskSid]: [{ route: 'case-list', subroute: 'case-list' }], + }, + }, }); const store = mockStore(initialState); @@ -187,7 +191,11 @@ test('Should render list if it is populated', async () => { listLoading: false, }, }, - routing: { tasks: {} }, + routing: { + tasks: { + [standaloneTaskSid]: [{ route: 'case-list', subroute: 'case-list' }], + }, + }, }); const store = mockStore(initialState); @@ -237,7 +245,11 @@ test('Should render no cases and show No Cases Found row', async () => { listLoading: false, }, }, - routing: { tasks: {} }, + routing: { + tasks: { + [standaloneTaskSid]: [{ route: 'case-list', subroute: 'case-list' }], + }, + }, }); const store = mockStore(initialState); @@ -276,7 +288,11 @@ test('Should dispatch fetchStarted and fetchError actions if case lists error', currentDefinitionVersion: mockV1, }, [caseListBase]: blankCaseListState, - routing: { tasks: {} }, + routing: { + tasks: { + [standaloneTaskSid]: [{ route: 'case-list', subroute: 'case-list' }], + }, + }, }); const store = mockStore(initialState); @@ -313,7 +329,11 @@ test('Should render error page if fetchError set in store', async () => { ...blankCaseListState, content: { ...blankCaseListState.content, fetchError: new Error('Some error') }, }, - routing: { tasks: {} }, + routing: { + tasks: { + [standaloneTaskSid]: [{ route: 'case-list', subroute: 'case-list' }], + }, + }, }); const store = mockStore(initialState); @@ -352,7 +372,11 @@ test('Should render loading page if listLoading set in store', async () => { ...blankCaseListState, content: { ...blankCaseListState.content, listLoading: true }, }, - routing: { tasks: {} }, + routing: { + tasks: { + [standaloneTaskSid]: [{ route: 'case-list', subroute: 'case-list' }], + }, + }, }); const store = mockStore(initialState); @@ -384,7 +408,11 @@ test('a11y', async () => { currentDefinitionVersion: mockV1, }, [caseListBase]: blankCaseListState, - routing: { tasks: {} }, + routing: { + tasks: { + [standaloneTaskSid]: [{ route: 'case-list', subroute: 'case-list' }], + }, + }, }); const store = mockStore(initialState); diff --git a/plugin-hrm-form/src/___tests__/search/ContactDetails.test.tsx b/plugin-hrm-form/src/___tests__/search/ContactDetails.test.tsx index d47a9032dc..2dcab47351 100644 --- a/plugin-hrm-form/src/___tests__/search/ContactDetails.test.tsx +++ b/plugin-hrm-form/src/___tests__/search/ContactDetails.test.tsx @@ -27,7 +27,7 @@ import ContactDetails from '../../components/search/ContactDetails'; import { channelTypes } from '../../states/DomainConstants'; import { getDefinitionVersions } from '../../hrmConfig'; import { DetailsContext } from '../../states/contacts/contactDetails'; -import { Contact } from '../../types/types'; +import { Contact, CustomITask } from '../../types/types'; import { csamReportBase } from '../../states/storeNamespaces'; jest.mock('@twilio/flex-ui', () => ({ @@ -155,6 +155,11 @@ beforeAll(async () => { tasks: {}, contacts: {}, }, + routing: { + tasks: { + TEST_TASK_ID: [{ route: 'contact', subroute: 'view', id: 'TEST CONTACT ID' }], + }, + }, }, flex: { worker: { @@ -207,7 +212,7 @@ test(` with contact of type ${callTypes.caller}`, async () => { currentIsCaller={true} handleBack={handleBack} handleSelectSearchResult={handleSelectSearchResult} - task={{ taskSid: 'TEST_TASK_ID' }} + task={{ taskSid: 'TEST_TASK_ID' } as CustomITask} showActionIcons={false} /> diff --git a/plugin-hrm-form/src/___tests__/search/Search.test.tsx b/plugin-hrm-form/src/___tests__/search/Search.test.tsx index 7299c92877..3048f7e002 100644 --- a/plugin-hrm-form/src/___tests__/search/Search.test.tsx +++ b/plugin-hrm-form/src/___tests__/search/Search.test.tsx @@ -24,11 +24,15 @@ import { StorelessThemeProvider } from '@twilio/flex-ui'; import { mockGetDefinitionsResponse } from '../mockGetConfig'; import Search from '../../components/search'; -import { SearchPages } from '../../states/search/types'; -import { channelTypes } from '../../states/DomainConstants'; import { getDefinitionVersions } from '../../hrmConfig'; import { DetailsContext } from '../../states/contacts/contactDetails'; import { csamReportBase } from '../../states/storeNamespaces'; +import { RecursivePartial } from '../RecursivePartial'; +import { RootState } from '../../states'; +import { Contact, SearchCaseResult } from '../../types/types'; +import { VALID_EMPTY_CONTACT } from '../testContacts'; +import { DetailedSearchContactsResult, SearchFormValues } from '../../states/search/types'; +import { AppRoutes } from '../../states/routing/types'; // eslint-disable-next-line react-hooks/rules-of-hooks const { mockFetchImplementation, mockReset, buildBaseURL } = useFetchDefinitions(); @@ -40,10 +44,31 @@ jest.mock('../../services/ServerlessService', () => ({ populateCounselors: async () => [], })); +jest.mock('@twilio/flex-ui', () => ({ + ...(jest.requireActual('@twilio/flex-ui') as any), + Actions: { + invokeAction: jest.fn(), + }, +})); + function createState( taskId, - { currentPage, searchFormValues, currentContact, searchResult, detailsExpanded, previousContacts }, -) { + { + searchFormValues, + currentContact, + detailsExpanded, + previousContacts, + route, + searchContactsResult, + }: { + searchFormValues: SearchFormValues; + currentContact: Contact; + detailsExpanded: any; + previousContacts: { contacts?: DetailedSearchContactsResult; cases?: SearchCaseResult }; + route: AppRoutes; + searchContactsResult?: DetailedSearchContactsResult; + }, +): RecursivePartial { return { 'plugin-hrm-form': { configuration: { @@ -56,14 +81,13 @@ function createState( }, routing: { tasks: { - 'standalone-task-sid': 'some-id', + 'standalone-task-sid': [route], + [taskId]: [route], }, }, searchContacts: { tasks: { [taskId]: { - currentPage: currentPage || SearchPages.form, - currentContact: currentContact || null, form: searchFormValues || { firstName: '', lastName: '', @@ -72,24 +96,19 @@ function createState( dateFrom: '', dateTo: '', }, - searchResult: searchResult || [], previousContacts, detailsExpanded: detailsExpanded || {}, isRequesting: false, error: null, + searchContactsResult, }, }, }, activeContacts: { - tasks: { - [taskId]: { - helpline: 'helpline', - }, - }, existingContacts: { 'TEST CONTACT ID': { - refCount: 1, - contact: currentContact, + references: ['1'], + savedContact: currentContact, }, }, contactDetails: { @@ -99,10 +118,16 @@ function createState( }, }, [csamReportBase]: { - tasks: {}, contacts: {}, }, }, + flex: { + worker: { + attributes: { + roles: [] as any, + }, + }, + }, }; } @@ -127,24 +152,23 @@ afterEach(() => { }); test(' should display ', async () => { - const currentPage = SearchPages.form; - const searchFormValues = { + const searchFormValues: SearchFormValues = { firstName: 'Jill', lastName: 'Smith', counselor: { label: 'Counselor Name', value: 'counselor-id' }, phoneNumber: 'Anonymous', dateFrom: '2020-03-10', dateTo: '2020-03-15', + contactNumber: undefined, }; const task = { taskSid: 'WT123', attributes: { preEngagementData: {} } }; const initialState = createState(task.taskSid, { - currentPage, searchFormValues, detailsExpanded, previousContacts: undefined, currentContact: undefined, - searchResult: undefined, + route: { route: 'search', subroute: 'form' }, }); const store = mockStore(initialState); @@ -165,14 +189,14 @@ test(' should display ', async () => { }); test(' should display with previous contacts checkbox', async () => { - const currentPage = SearchPages.form; - const searchFormValues = { + const searchFormValues: SearchFormValues = { firstName: 'Jill', lastName: 'Smith', counselor: { label: 'Counselor Name', value: 'counselor-id' }, phoneNumber: 'Anonymous', dateFrom: '2020-03-10', dateTo: '2020-03-15', + contactNumber: undefined, }; const task = { taskSid: 'WT123', @@ -185,16 +209,15 @@ test(' should display with previous contacts checkbox', a const previousContacts = { contacts: { count: 3, contacts: [] }, - casesCount: { count: 1, cases: [] }, + cases: { count: 1, cases: [] }, }; const initialState = createState(task.taskSid, { - currentPage, searchFormValues, detailsExpanded, previousContacts, currentContact: undefined, - searchResult: undefined, + route: { route: 'search', subroute: 'form' }, }); const store = mockStore(initialState); @@ -214,36 +237,34 @@ test(' should display with previous contacts checkbox', a }); test(' should display ', async () => { - const currentPage = SearchPages.details; - const currentContact = { - contactId: 'TEST CONTACT ID', - details: { - definitionVersion: 'v1', + const currentContact: Contact = { + ...VALID_EMPTY_CONTACT, + id: 'TEST CONTACT ID', + timeOfContact: new Date().toISOString(), + rawJson: { + callType: 'Child calling about self', + categories: {}, + contactlessTask: VALID_EMPTY_CONTACT.rawJson.contactlessTask, + definitionVersion: DefinitionVersionId.v1, childInformation: { - name: { - firstName: 'Jill', - lastName: 'Smith', - }, + firstName: 'Jill', + lastName: 'Smith', gender: 'Other', age: '18-25', language: 'Language 1', nationality: 'Nationality 1', ethnicity: 'Ethnicity 1', - location: { - streetAddress: '', - city: '', - stateOrCounty: '', - postalCode: '', - phone1: '', - phone2: '', - }, + streetAddress: '', + city: '', + stateOrCounty: '', + postalCode: '', + phone1: '', + phone2: '', refugee: false, disabledOrSpecialNeeds: false, hiv: false, - school: { - name: 'school', - gradeLevel: 'some', - }, + name: 'school', + gradeLevel: 'some', }, caseInformation: { callSummary: 'Child calling about self', @@ -257,48 +278,32 @@ test(' should display ', async () => { wouldTheChildRecommendUsToAFriend: false, }, callerInformation: { - name: { - firstName: '', - lastName: '', - }, + firstName: '', + lastName: '', relationshipToChild: '', gender: '', age: '', language: '', nationality: '', ethnicity: '', - location: { - city: '', - phone1: '', - phone2: '', - postalCode: '', - stateOrCounty: '', - streetAddress: '', - }, + city: '', + phone1: '', + phone2: '', + postalCode: '', + stateOrCounty: '', + streetAddress: '', }, }, - overview: { - dateTime: '2020-03-10', - name: 'Jill Smith', - customerNumber: 'Anonymous', - callType: 'Child calling about self', - categories: { category1: ['Tag1', 'Tag2'] }, - counselor: 'counselor-id', - notes: 'Jill Smith Notes', - channel: channelTypes.web, - conversationDuration: 10, - }, - counselor: 'Counselor', }; const task = { taskSid: 'WT123' }; const initialState = createState(task.taskSid, { - currentPage, currentContact, detailsExpanded, searchFormValues: undefined, previousContacts: undefined, - searchResult: undefined, + searchContactsResult: { contacts: [currentContact], count: 1 }, + route: { route: 'contact', subroute: 'view', id: currentContact.id }, }); const store = mockStore(initialState); diff --git a/plugin-hrm-form/src/___tests__/search/SearchResults.test.js b/plugin-hrm-form/src/___tests__/search/SearchResults.test.tsx similarity index 92% rename from plugin-hrm-form/src/___tests__/search/SearchResults.test.js rename to plugin-hrm-form/src/___tests__/search/SearchResults.test.tsx index b9213d2442..70a4aa8852 100644 --- a/plugin-hrm-form/src/___tests__/search/SearchResults.test.js +++ b/plugin-hrm-form/src/___tests__/search/SearchResults.test.tsx @@ -14,7 +14,7 @@ * along with this program. If not, see https://www.gnu.org/licenses/. */ -import React from 'react'; +import * as React from 'react'; import { render, screen } from '@testing-library/react'; import '@testing-library/jest-dom/extend-expect'; import { Provider } from 'react-redux'; @@ -22,9 +22,7 @@ import configureMockStore from 'redux-mock-store'; import { StorelessThemeProvider } from '@twilio/flex-ui'; import { DefinitionVersionId, loadDefinition, useFetchDefinitions } from 'hrm-form-definitions'; -import HrmTheme from '../../styles/HrmTheme'; import { mockGetDefinitionsResponse } from '../mockGetConfig'; -import { SearchPages } from '../../states/search/types'; import SearchResults from '../../components/search/SearchResults'; import { getDefinitionVersions } from '../../hrmConfig'; import { @@ -34,6 +32,9 @@ import { namespace, searchContactsBase, } from '../../states/storeNamespaces'; +import { RootState } from '../../states'; +import { RecursivePartial } from '../RecursivePartial'; +import { VALID_EMPTY_METADATA } from '../testContacts'; jest.mock('../../permissions', () => ({ getPermissionsForCase: jest.fn(() => ({ @@ -51,15 +52,13 @@ jest.mock('../../permissions', () => ({ // eslint-disable-next-line react-hooks/rules-of-hooks const { mockFetchImplementation, mockReset, buildBaseURL } = useFetchDefinitions(); -const themeConf = { - colorTheme: HrmTheme, -}; +const themeConf = {}; const mockStore = configureMockStore([]); const task = { taskSid: 'task1' }; -let state1; -let stateOnCasesTab; +let state1: RecursivePartial; +let stateOnCasesTab: RecursivePartial; let store1; let storeOnCasesTab; @@ -88,21 +87,26 @@ describe('Search Results', () => { currentDefinitionVersion: mockV1, }, [contactFormsBase]: { - tasks: { - task1: { - childInformation: { - name: { firstName: { value: 'first' }, lastName: { value: 'last' } }, + existingContacts: { + contact1: { + savedContact: { + rawJson: { + childInformation: { + firstName: 'first', + lastName: 'last', + }, + }, }, - metadata: {}, + references: [], + metadata: { ...VALID_EMPTY_METADATA }, }, }, }, [connectedCaseBase]: { tasks: { task1: { - temporaryCaseInfo: null, connectedCase: { - createdAt: 1593469560208, + createdAt: new Date(1593469560208).toISOString(), twilioWorkerId: 'worker1', status: 'open', info: null, @@ -112,16 +116,12 @@ describe('Search Results', () => { }, [searchContactsBase]: { tasks: { - task1: { - currentPage: SearchPages.resultsContacts, - temporaryCaseInfo: null, - connectedCase: { - createdAt: 1593469560208, - twilioWorkerId: 'worker1', - status: 'open', - info: null, - }, - }, + task1: {}, + }, + }, + routing: { + tasks: { + task1: [{ route: 'search', subroute: 'contact-results' }], }, }, }, @@ -130,12 +130,10 @@ describe('Search Results', () => { stateOnCasesTab = { [namespace]: { ...state1[namespace], - [searchContactsBase]: { + + routing: { tasks: { - task1: { - ...state1[namespace][searchContactsBase].tasks.task1, - currentPage: SearchPages.resultsCases, - }, + task1: [{ route: 'search', subroute: 'case-results' }], }, }, }, diff --git a/plugin-hrm-form/src/___tests__/states/routing/actions.test.ts b/plugin-hrm-form/src/___tests__/states/routing/actions.test.ts index 7a529c6779..df956fc1b8 100644 --- a/plugin-hrm-form/src/___tests__/states/routing/actions.test.ts +++ b/plugin-hrm-form/src/___tests__/states/routing/actions.test.ts @@ -15,7 +15,7 @@ */ import * as types from '../../../states/routing/types'; -import { CaseItemAction } from '../../../states/routing/types'; +import { CaseItemAction, ChangeRouteMode } from '../../../states/routing/types'; import * as actions from '../../../states/routing/actions'; const task = { taskSid: 'task1' }; @@ -26,7 +26,7 @@ describe('test action creators', () => { type: types.CHANGE_ROUTE, routing: { route: 'case', subroute: 'home' }, taskId: task.taskSid, - replace: false, + mode: ChangeRouteMode.Push, }); expect( @@ -35,7 +35,7 @@ describe('test action creators', () => { type: types.CHANGE_ROUTE, routing: { route: 'case', subroute: 'note', action: CaseItemAction.Add }, - replace: false, + mode: ChangeRouteMode.Push, taskId: task.taskSid, }); }); @@ -45,7 +45,7 @@ describe('test action creators', () => { type: types.CHANGE_ROUTE, routing: { route: 'select-call-type' }, taskId: task.taskSid, - replace: false, + mode: ChangeRouteMode.Push, }); }); @@ -54,7 +54,7 @@ describe('test action creators', () => { type: types.CHANGE_ROUTE, routing: { route: 'tabbed-forms' }, taskId: task.taskSid, - replace: false, + mode: ChangeRouteMode.Push, }); }); @@ -68,15 +68,17 @@ describe('test action creators', () => { type: types.CHANGE_ROUTE, routing: { route: 'csam-report', subroute: 'form', previousRoute: { route: 'case', subroute: 'home' } }, taskId: task.taskSid, - replace: false, + mode: ChangeRouteMode.Push, }); }); test('changeRoute (replace flag set)', async () => { - expect(actions.changeRoute({ route: 'case', subroute: 'home' }, task.taskSid, true)).toStrictEqual({ + expect( + actions.changeRoute({ route: 'case', subroute: 'home' }, task.taskSid, ChangeRouteMode.Replace), + ).toStrictEqual({ type: types.CHANGE_ROUTE, routing: { route: 'case', subroute: 'home' }, taskId: task.taskSid, - replace: true, + mode: ChangeRouteMode.Replace, }); }); }); diff --git a/plugin-hrm-form/src/___tests__/states/routing/reducer.test.ts b/plugin-hrm-form/src/___tests__/states/routing/reducer.test.ts index d19bee0e6b..6cfe6e6367 100644 --- a/plugin-hrm-form/src/___tests__/states/routing/reducer.test.ts +++ b/plugin-hrm-form/src/___tests__/states/routing/reducer.test.ts @@ -18,7 +18,7 @@ import { DefinitionVersion, DefinitionVersionId, loadDefinition, useFetchDefinit import { mockGetDefinitionsResponse, mockPartialConfiguration } from '../../mockGetConfig'; import { getDefinitionVersions } from '../../../hrmConfig'; -import { reduce, initialState, newTaskEntry } from '../../../states/routing/reducer'; +import { initialState, newTaskEntry, reduce } from '../../../states/routing/reducer'; import * as actions from '../../../states/routing/actions'; import * as GeneralActions from '../../../states/actions'; import { standaloneTaskSid } from '../../../types/types'; @@ -27,7 +27,7 @@ import { CREATE_CONTACT_ACTION_FULFILLED, LOAD_CONTACT_FROM_HRM_BY_TASK_ID_ACTION_FULFILLED, } from '../../../states/contacts/types'; -import { RoutingState } from '../../../states/routing/types'; +import { ChangeRouteMode, RoutingState } from '../../../states/routing/types'; // eslint-disable-next-line react-hooks/rules-of-hooks const { mockFetchImplementation, mockReset, buildBaseURL } = useFetchDefinitions(); @@ -111,7 +111,10 @@ describe('test reducer (specific actions)', () => { isAddingOfflineContact: false, }; - const result = reduce(stateWithTask, actions.changeRoute({ route: 'tabbed-forms' }, task.taskSid, true)); + const result = reduce( + stateWithTask, + actions.changeRoute({ route: 'tabbed-forms' }, task.taskSid, ChangeRouteMode.Replace), + ); expect(result).toStrictEqual(expected); }); @@ -150,7 +153,10 @@ describe('test reducer (specific actions)', () => { isAddingOfflineContact: false, }; - const result1 = reduce(stateWithTask, actions.changeRoute({ route: 'case', subroute: 'home' }, task.taskSid, true)); + const result1 = reduce( + stateWithTask, + actions.changeRoute({ route: 'case', subroute: 'home' }, task.taskSid, ChangeRouteMode.Replace), + ); const result2 = reduce(result1, { type: LOAD_CONTACT_FROM_HRM_BY_TASK_ID_ACTION_FULFILLED, diff --git a/plugin-hrm-form/src/___tests__/states/search/actions.test.ts b/plugin-hrm-form/src/___tests__/states/search/actions.test.ts index 95c1f1baa9..82d954f6b2 100644 --- a/plugin-hrm-form/src/___tests__/states/search/actions.test.ts +++ b/plugin-hrm-form/src/___tests__/states/search/actions.test.ts @@ -24,8 +24,6 @@ import { searchContacts } from '../../../services/ContactService'; import { searchCases } from '../../../services/CaseService'; import { CASES_PER_PAGE, CONTACTS_PER_PAGE } from '../../../components/search/SearchResults'; import { getDefinitionVersions } from '../../../hrmConfig'; -import { Contact } from '../../../types/types'; -import { VALID_EMPTY_CONTACT } from '../../testContacts'; jest.mock('../../../services/ContactService', () => ({ searchContacts: jest.fn() })); jest.mock('../../../services/CaseService', () => ({ searchCases: jest.fn() })); @@ -51,28 +49,6 @@ describe('test action creators', () => { await loadDefinition(formDefinitionsBaseUrl), ); }); - test('changeSearchPage', () => { - expect(actions.changeSearchPage(taskId)('details')).toStrictEqual({ - type: t.CHANGE_SEARCH_PAGE, - taskId, - page: t.SearchPages.details, - }); - expect(actions.changeSearchPage(task.taskSid)('form')).toStrictEqual({ - type: t.CHANGE_SEARCH_PAGE, - taskId, - page: t.SearchPages.form, - }); - expect(actions.changeSearchPage(task.taskSid)('results.contacts')).toStrictEqual({ - type: t.CHANGE_SEARCH_PAGE, - taskId, - page: t.SearchPages.resultsContacts, - }); - expect(actions.changeSearchPage(task.taskSid)('results.cases')).toStrictEqual({ - type: t.CHANGE_SEARCH_PAGE, - taskId, - page: t.SearchPages.resultsCases, - }); - }); test('handleSearchFormChange', () => { expect(actions.handleSearchFormChange(taskId)('firstName', 'Some name')).toStrictEqual({ @@ -83,16 +59,6 @@ describe('test action creators', () => { }); }); - test('viewContactDetails', () => { - const contact: Contact = { ...VALID_EMPTY_CONTACT, id: 'fake contact' }; - - expect(actions.viewContactDetails(taskId)(contact)).toStrictEqual({ - type: t.VIEW_CONTACT_DETAILS, - taskId, - contact, - }); - }); - test('searchContacts (success)', async () => { const contact = { id: 'fake contact', diff --git a/plugin-hrm-form/src/___tests__/states/search/reducer.test.ts b/plugin-hrm-form/src/___tests__/states/search/reducer.test.ts index db3d269b8d..a8947459ca 100644 --- a/plugin-hrm-form/src/___tests__/states/search/reducer.test.ts +++ b/plugin-hrm-form/src/___tests__/states/search/reducer.test.ts @@ -18,7 +18,7 @@ import fromentries from 'fromentries'; import * as t from '../../../states/search/types'; import { handleSearchFormChange } from '../../../states/search/actions'; -import { Contact, SearchCaseResult } from '../../../types/types'; +import { SearchCaseResult } from '../../../types/types'; import { REMOVE_CONTACT_STATE, RemoveContactStateAction } from '../../../states/types'; import { reduce, newTaskEntry } from '../../../states/search/reducer'; import { VALID_EMPTY_CONTACT, VALID_EMPTY_METADATA } from '../../testContacts'; @@ -128,34 +128,6 @@ describe('search reducer', () => { state = result; }); - test('CHANGE_SEARCH_PAGE action', () => { - const action: t.SearchActionType = { - type: t.CHANGE_SEARCH_PAGE, - taskId: task.taskSid, - page: t.SearchPages.results, - }; - const result = reduce(state, action); - - const { tasks } = result; - expect(tasks[task.taskSid].currentPage).toEqual(t.SearchPages.results); - state = result; - }); - - test('VIEW_CONTACT_DETAILS action', () => { - const contact: Contact = { ...VALID_EMPTY_CONTACT, id: 'fake contact' }; - const action: t.SearchActionType = { - type: t.VIEW_CONTACT_DETAILS, - contact, - taskId: task.taskSid, - }; - const result = reduce(state, action); - - const { tasks } = result; - expect(tasks[task.taskSid].currentPage).toEqual(t.SearchPages.details); - expect(tasks[task.taskSid].currentContact).toEqual(contact); - state = result; - }); - test('SEARCH_CONTACTS_REQUEST action', () => { expect(state.tasks[task.taskSid].isRequesting).toBeFalsy(); const action: t.SearchActionType = { diff --git a/plugin-hrm-form/src/___tests__/testContacts.ts b/plugin-hrm-form/src/___tests__/testContacts.ts index 36114b9d23..f090795af9 100644 --- a/plugin-hrm-form/src/___tests__/testContacts.ts +++ b/plugin-hrm-form/src/___tests__/testContacts.ts @@ -62,5 +62,6 @@ export const VALID_EMPTY_METADATA: ContactMetadata = { recreated: false, draft: { resourceReferralList: { resourceReferralIdToAdd: undefined, lookupStatus: ReferralLookupStatus.NOT_STARTED }, + dialogsOpen: {}, }, }; diff --git a/plugin-hrm-form/src/components/CSAMReport/CSAMReportChildForm.tsx b/plugin-hrm-form/src/components/CSAMReport/CSAMReportChildForm.tsx index fa75e3c916..f6eb470dab 100644 --- a/plugin-hrm-form/src/components/CSAMReport/CSAMReportChildForm.tsx +++ b/plugin-hrm-form/src/components/CSAMReport/CSAMReportChildForm.tsx @@ -18,13 +18,16 @@ import React from 'react'; import { Template } from '@twilio/flex-ui'; import { useForm } from 'react-hook-form'; +import Close from '@material-ui/icons/Close'; import ActionHeader from '../case/ActionHeader'; -import { BottomButtonBar, Box, StyledNextStepButton } from '../../styles/HrmStyles'; +import { BottomButtonBar, Box, HeaderCloseButton, HiddenText, Row, StyledNextStepButton } from '../../styles/HrmStyles'; import { BoldDescriptionText, CSAMReportContainer, CSAMReportLayout } from '../../styles/CSAMReport'; import { childDefinitionObject, childInitialValues, generateCSAMFormElement } from './CSAMReportFormDefinition'; import { RequiredAsterisk } from '../common/forms/formGenerators'; import { ChildCSAMReportForm } from '../../states/csam-report/types'; +import useFocus from '../../utils/useFocus'; +import { CaseActionTitle } from '../../styles/case'; type Props = { counselor: string; @@ -44,14 +47,32 @@ const CSAMReportChildForm: React.FC = ({ methods, }) => { const generateChildFormElement = generateCSAMFormElement(childInitialValues, formValues, update, methods); + + const focusElementRef = useFocus(); + return ( + + +