From bebb88748d36e771ea977a0e7c5be0fcddd568aa Mon Sep 17 00:00:00 2001 From: ssandupatla <58558770+ssandupatla@users.noreply.github.com> Date: Fri, 14 Apr 2023 14:32:51 +0530 Subject: [PATCH 1/5] UIIN-1688 JEST/RTL test cases for LocationSelectionWithCheck.js --- .../common/LocationSelectionWithCheck.test.js | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 src/edit/common/LocationSelectionWithCheck.test.js diff --git a/src/edit/common/LocationSelectionWithCheck.test.js b/src/edit/common/LocationSelectionWithCheck.test.js new file mode 100644 index 000000000..e2787ce98 --- /dev/null +++ b/src/edit/common/LocationSelectionWithCheck.test.js @@ -0,0 +1,93 @@ +import React from 'react'; +import { screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { QueryClient, QueryClientProvider } from 'react-query'; + +import '../../../test/jest/__mock__'; + +import { renderWithIntl, translationsProperties } from '../../../test/jest/helpers'; + +import LocationSelectionWithCheck from './LocationSelectionWithCheck'; + +jest.mock('../../RemoteStorageService', () => ({ + Check: { + useByLocation: () => jest.fn(), + }, + Confirmation: { + Heading: () =>
, + Message: () =>
, + }, +})); + + +const queryClient = new QueryClient(); + +const input = { + name: 'location', + value: '123', + onChange: jest.fn(), +}; +const meta = { + initial: '2' +}; + +const defaultProps = { + input, + meta +}; + +const renderLocationSelectionWithCheck = () => renderWithIntl( + + + , + translationsProperties +); + +describe('LocationSelectionWithCheck', () => { + afterEach(() => { + jest.clearAllMocks(); + }); + it('should render select button', () => { + renderLocationSelectionWithCheck(); + const selectBtn = screen.getByTestId('LocationSelectionSelectBtn'); + expect(selectBtn).toBeInTheDocument(); + expect(selectBtn).toHaveTextContent('Select'); + }); + it('should display location lookup when select button is clicked', () => { + renderLocationSelectionWithCheck(); + const selectBtn = screen.getByTestId('LocationSelectionSelectBtn'); + userEvent.click(selectBtn); + const locationLookup = screen.getByText('LocationLookup'); + expect(locationLookup).toBeInTheDocument(); + expect(screen.getByText('Inactive location')).toBeInTheDocument(); + expect(screen.getByText('This location has a status of inactive. Are you sure you want to select this location?')).toBeInTheDocument(); + }); + it('should display confirmation modal when confirm button is clicked', () => { + renderLocationSelectionWithCheck(); + const selectBtn = screen.getByTestId('LocationSelectionSelectBtn'); + userEvent.click(selectBtn); + const confirmBtn = screen.getByTestId('ConfirmationModalConfirmBtn'); + userEvent.click(confirmBtn); + const confirmationModalHeading = screen.getByTestId('ConfirmationModalHeading'); + const confirmationModalMessage = screen.getByTestId('ConfirmationModalMessage'); + const cancelBtn = screen.getByTestId('ConfirmationModalCancelBtn'); + expect(confirmationModalHeading).toBeInTheDocument(); + expect(confirmationModalMessage).toBeInTheDocument(); + expect(cancelBtn).toBeInTheDocument(); + }); + it('should close confirmation modal when cancel button is clicked', () => { + renderLocationSelectionWithCheck(); + const selectBtn = screen.getByTestId('LocationSelectionSelectBtn'); + userEvent.click(selectBtn); + const confirmBtn = screen.getByTestId('ConfirmationModalConfirmBtn'); + userEvent.click(confirmBtn); + const cancelBtn = screen.getByTestId('ConfirmationModalCancelBtn'); + userEvent.click(cancelBtn); + const confirmationModalHeading = screen.queryByTestId('ConfirmationModalHeading'); + const confirmationModalMessage = screen.queryByTestId('ConfirmationModalMessage'); + const cancelBtnAgain = screen.queryByTestId('ConfirmationModalCancelBtn'); + expect(confirmationModalHeading).toBeInTheDocument(); + expect(confirmationModalMessage).toBeInTheDocument(); + expect(cancelBtnAgain).toBeInTheDocument(); + }); +}); From 079914071b291e37578ed1796b5c41a134e2df64 Mon Sep 17 00:00:00 2001 From: ssandupatla <58558770+ssandupatla@users.noreply.github.com> Date: Fri, 14 Apr 2023 14:53:11 +0530 Subject: [PATCH 2/5] Supported files for UIIN-1688 --- .../__mock__/LocationSelectionWithCheck.js | 101 ++++++++++++++++++ .../__mock__/stripesSmartComponents.mock.js | 32 ++---- 2 files changed, 107 insertions(+), 26 deletions(-) create mode 100644 test/jest/__mock__/LocationSelectionWithCheck.js diff --git a/test/jest/__mock__/LocationSelectionWithCheck.js b/test/jest/__mock__/LocationSelectionWithCheck.js new file mode 100644 index 000000000..463d15b40 --- /dev/null +++ b/test/jest/__mock__/LocationSelectionWithCheck.js @@ -0,0 +1,101 @@ +import React, { useState } from 'react'; +import { useIntl } from 'react-intl'; +import { Field } from 'react-final-form'; + +import { LocationLookup, LocationSelection } from '@folio/stripes/smart-components'; +import { ConfirmationModal, MessageBanner } from '@folio/stripes/components'; + +import * as RemoteStorage from '../../RemoteStorageService'; + + +const MODAL_CLOSED = { + open: false, + heading: '', +}; + + +const LocationSelectionWithCheck = ({ input, ...rest }) => { + const { value, onChange, ...restInput } = input; + + const { formatMessage } = useIntl(); + + const checkFromRemoteToNonRemote = RemoteStorage.Check.useByLocation(); + + const [selectedValue, setSelectedValue] = useState(value); + const [rollbackValue, setRollbackValue] = useState(value); + const [modal, setModal] = useState(MODAL_CLOSED); + + const fromLocationId = rest.meta.initial; + + const handleSelect = location => { + const toLocationId = location?.id; + + setSelectedValue(toLocationId); + + const isNotSameLocation = toLocationId !== value; + const isNewLocationInactive = location && !location.isActive; + const isMovingFromRemote = checkFromRemoteToNonRemote({ fromLocationId, toLocationId }); + const isConfirmationNeeded = (isNewLocationInactive || isMovingFromRemote) && isNotSameLocation; + + if (isConfirmationNeeded) { + const heading = + (isNewLocationInactive && isMovingFromRemote && formatMessage({ id: 'ui-inventory.location.confirm.common.header' })) + || (isNewLocationInactive && formatMessage({ id: 'ui-inventory.location.confirm.inactive.header' })) + || (isMovingFromRemote && ); + + const messages = [ + isNewLocationInactive && formatMessage({ id: 'ui-inventory.location.confirm.inactive.message' }), + isMovingFromRemote && , + ]; + const message = messages.filter(Boolean).map(m => {m}); + + setRollbackValue(isMovingFromRemote ? fromLocationId : value); + setModal({ open: true, heading, message }); + + return; + } + + onChange(toLocationId); + }; + + const handleConfirm = () => { + setModal(MODAL_CLOSED); + onChange(selectedValue); + }; + + const handleCancel = () => { + setModal(MODAL_CLOSED); + setSelectedValue(rollbackValue); + }; + + return ( + <> + + + + + + + ); +}; + +LocationSelectionWithCheck.propTypes = Field.propTypes; + +export default LocationSelectionWithCheck; diff --git a/test/jest/__mock__/stripesSmartComponents.mock.js b/test/jest/__mock__/stripesSmartComponents.mock.js index bd2f50bfa..b5b0a03b2 100644 --- a/test/jest/__mock__/stripesSmartComponents.mock.js +++ b/test/jest/__mock__/stripesSmartComponents.mock.js @@ -3,32 +3,12 @@ import React from 'react'; jest.mock('@folio/stripes/smart-components', () => ({ ...jest.requireActual('@folio/stripes/smart-components'), LocationLookup: () =>
LocationLookup
, + LocationSelection: ({ onSelect }) => ( + + ), ViewMetaData: () =>
ViewMetaData
, ControlledVocab: () =>
ControlledVocab
, - ConfigManager: (props) => { - const { getInitialValues, onBeforeSave, children } = props; - const component = -
-
ConfigManager
- {children} - - -
; - return component; - }, - useRemoteStorageMappings: () => { - return ({ - 'holdings-id-1': { - 'id': 'holdings-id-1', - 'name': 'Storage A', - 'description': 'Storage A description' - }, - 'holdings-id-2': { - 'id': 'holdings-id-2', - 'name': 'Storage B', - 'description': 'Storage B description' - } - }); - } + // useRemoteStorageMappings: () =>
useRemoteStorageMappings
, }), { virtual: true }); - From e1c68404743ddaa534698c4a69ac3d185b1d46d6 Mon Sep 17 00:00:00 2001 From: ssandupatla <58558770+ssandupatla@users.noreply.github.com> Date: Fri, 14 Apr 2023 18:24:22 +0530 Subject: [PATCH 3/5] Delete LocationSelectionWithCheck.js Duplicate file --- .../__mock__/LocationSelectionWithCheck.js | 101 ------------------ 1 file changed, 101 deletions(-) delete mode 100644 test/jest/__mock__/LocationSelectionWithCheck.js diff --git a/test/jest/__mock__/LocationSelectionWithCheck.js b/test/jest/__mock__/LocationSelectionWithCheck.js deleted file mode 100644 index 463d15b40..000000000 --- a/test/jest/__mock__/LocationSelectionWithCheck.js +++ /dev/null @@ -1,101 +0,0 @@ -import React, { useState } from 'react'; -import { useIntl } from 'react-intl'; -import { Field } from 'react-final-form'; - -import { LocationLookup, LocationSelection } from '@folio/stripes/smart-components'; -import { ConfirmationModal, MessageBanner } from '@folio/stripes/components'; - -import * as RemoteStorage from '../../RemoteStorageService'; - - -const MODAL_CLOSED = { - open: false, - heading: '', -}; - - -const LocationSelectionWithCheck = ({ input, ...rest }) => { - const { value, onChange, ...restInput } = input; - - const { formatMessage } = useIntl(); - - const checkFromRemoteToNonRemote = RemoteStorage.Check.useByLocation(); - - const [selectedValue, setSelectedValue] = useState(value); - const [rollbackValue, setRollbackValue] = useState(value); - const [modal, setModal] = useState(MODAL_CLOSED); - - const fromLocationId = rest.meta.initial; - - const handleSelect = location => { - const toLocationId = location?.id; - - setSelectedValue(toLocationId); - - const isNotSameLocation = toLocationId !== value; - const isNewLocationInactive = location && !location.isActive; - const isMovingFromRemote = checkFromRemoteToNonRemote({ fromLocationId, toLocationId }); - const isConfirmationNeeded = (isNewLocationInactive || isMovingFromRemote) && isNotSameLocation; - - if (isConfirmationNeeded) { - const heading = - (isNewLocationInactive && isMovingFromRemote && formatMessage({ id: 'ui-inventory.location.confirm.common.header' })) - || (isNewLocationInactive && formatMessage({ id: 'ui-inventory.location.confirm.inactive.header' })) - || (isMovingFromRemote && ); - - const messages = [ - isNewLocationInactive && formatMessage({ id: 'ui-inventory.location.confirm.inactive.message' }), - isMovingFromRemote && , - ]; - const message = messages.filter(Boolean).map(m => {m}); - - setRollbackValue(isMovingFromRemote ? fromLocationId : value); - setModal({ open: true, heading, message }); - - return; - } - - onChange(toLocationId); - }; - - const handleConfirm = () => { - setModal(MODAL_CLOSED); - onChange(selectedValue); - }; - - const handleCancel = () => { - setModal(MODAL_CLOSED); - setSelectedValue(rollbackValue); - }; - - return ( - <> - - - - - - - ); -}; - -LocationSelectionWithCheck.propTypes = Field.propTypes; - -export default LocationSelectionWithCheck; From e5e724821c9c7a4fa1f57742938a49da2b0efcdd Mon Sep 17 00:00:00 2001 From: ssandupatla <58558770+ssandupatla@users.noreply.github.com> Date: Fri, 14 Apr 2023 18:25:02 +0530 Subject: [PATCH 4/5] Update LocationSelectionWithCheck.test.js File updated --- .../common/LocationSelectionWithCheck.test.js | 79 ++++++------------- 1 file changed, 22 insertions(+), 57 deletions(-) diff --git a/src/edit/common/LocationSelectionWithCheck.test.js b/src/edit/common/LocationSelectionWithCheck.test.js index e2787ce98..4dffa7986 100644 --- a/src/edit/common/LocationSelectionWithCheck.test.js +++ b/src/edit/common/LocationSelectionWithCheck.test.js @@ -1,27 +1,11 @@ +import '../../../test/jest/__mock__'; import React from 'react'; -import { screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { QueryClient, QueryClientProvider } from 'react-query'; - -import '../../../test/jest/__mock__'; - import { renderWithIntl, translationsProperties } from '../../../test/jest/helpers'; - -import LocationSelectionWithCheck from './LocationSelectionWithCheck'; - -jest.mock('../../RemoteStorageService', () => ({ - Check: { - useByLocation: () => jest.fn(), - }, - Confirmation: { - Heading: () =>
, - Message: () =>
, - }, -})); - +import { LocationSelectionWithCheck } from './LocationSelectionWithCheck'; const queryClient = new QueryClient(); - const input = { name: 'location', value: '123', @@ -47,47 +31,28 @@ describe('LocationSelectionWithCheck', () => { afterEach(() => { jest.clearAllMocks(); }); - it('should render select button', () => { - renderLocationSelectionWithCheck(); - const selectBtn = screen.getByTestId('LocationSelectionSelectBtn'); - expect(selectBtn).toBeInTheDocument(); - expect(selectBtn).toHaveTextContent('Select'); + it('component should render correctly', () => { + const { getByText } = renderLocationSelectionWithCheck(); + expect(getByText('LocationLookup')).toBeInTheDocument(); + expect(getByText('ConfirmationModal')).toBeInTheDocument(); }); - it('should display location lookup when select button is clicked', () => { - renderLocationSelectionWithCheck(); - const selectBtn = screen.getByTestId('LocationSelectionSelectBtn'); - userEvent.click(selectBtn); - const locationLookup = screen.getByText('LocationLookup'); - expect(locationLookup).toBeInTheDocument(); - expect(screen.getByText('Inactive location')).toBeInTheDocument(); - expect(screen.getByText('This location has a status of inactive. Are you sure you want to select this location?')).toBeInTheDocument(); + it('warning message should render on clicking select button', () => { + const { container, getByRole, getByText } = renderLocationSelectionWithCheck(); + userEvent.click(getByRole('button', { name: 'Select' })); + expect(getByRole('alert')).not.toBeEmptyDOMElement(); + expect(getByText('Inactive location')).toBeInTheDocument(); + expect(container.getElementsByClassName('inner type-warning').length).toBe(1); }); - it('should display confirmation modal when confirm button is clicked', () => { - renderLocationSelectionWithCheck(); - const selectBtn = screen.getByTestId('LocationSelectionSelectBtn'); - userEvent.click(selectBtn); - const confirmBtn = screen.getByTestId('ConfirmationModalConfirmBtn'); - userEvent.click(confirmBtn); - const confirmationModalHeading = screen.getByTestId('ConfirmationModalHeading'); - const confirmationModalMessage = screen.getByTestId('ConfirmationModalMessage'); - const cancelBtn = screen.getByTestId('ConfirmationModalCancelBtn'); - expect(confirmationModalHeading).toBeInTheDocument(); - expect(confirmationModalMessage).toBeInTheDocument(); - expect(cancelBtn).toBeInTheDocument(); + it('Warning message should disapper after clicking confin button', () => { + const { container, getByRole } = renderLocationSelectionWithCheck(); + userEvent.click(getByRole('button', { name: 'Select' })); + userEvent.click(getByRole('button', { name: 'confirm' })); + expect(container.getElementsByClassName('inner type-warning').length).toBe(0); }); - it('should close confirmation modal when cancel button is clicked', () => { - renderLocationSelectionWithCheck(); - const selectBtn = screen.getByTestId('LocationSelectionSelectBtn'); - userEvent.click(selectBtn); - const confirmBtn = screen.getByTestId('ConfirmationModalConfirmBtn'); - userEvent.click(confirmBtn); - const cancelBtn = screen.getByTestId('ConfirmationModalCancelBtn'); - userEvent.click(cancelBtn); - const confirmationModalHeading = screen.queryByTestId('ConfirmationModalHeading'); - const confirmationModalMessage = screen.queryByTestId('ConfirmationModalMessage'); - const cancelBtnAgain = screen.queryByTestId('ConfirmationModalCancelBtn'); - expect(confirmationModalHeading).toBeInTheDocument(); - expect(confirmationModalMessage).toBeInTheDocument(); - expect(cancelBtnAgain).toBeInTheDocument(); + it('Warning message should disapper after clicking cancel button', () => { + const { container, getByRole } = renderLocationSelectionWithCheck(); + userEvent.click(getByRole('button', { name: 'Select' })); + userEvent.click(getByRole('button', { name: 'cancel' })); + expect(container.getElementsByClassName('inner type-warning').length).toBe(0); }); }); From 97566cd52d41b944c177fa5750929bc32ca054ab Mon Sep 17 00:00:00 2001 From: ssandupatla <58558770+ssandupatla@users.noreply.github.com> Date: Fri, 14 Apr 2023 18:25:36 +0530 Subject: [PATCH 5/5] Update stripesSmartComponents.mock.js Updated --- .../__mock__/stripesSmartComponents.mock.js | 36 +++++++++++++++---- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/test/jest/__mock__/stripesSmartComponents.mock.js b/test/jest/__mock__/stripesSmartComponents.mock.js index b5b0a03b2..c6a5b0811 100644 --- a/test/jest/__mock__/stripesSmartComponents.mock.js +++ b/test/jest/__mock__/stripesSmartComponents.mock.js @@ -2,13 +2,35 @@ import React from 'react'; jest.mock('@folio/stripes/smart-components', () => ({ ...jest.requireActual('@folio/stripes/smart-components'), + ControlledVocab: () =>
ControlledVocab
, + ConfigManager: (props) => { + const { getInitialValues, onBeforeSave, children } = props; + const component = +
+
ConfigManager
+ {children} + + +
; + return component; + }, LocationLookup: () =>
LocationLookup
, - LocationSelection: ({ onSelect }) => ( - - ), + LocationSelection: jest.fn(({ onSelect }) => ( + + )), + useRemoteStorageMappings: () => { + return ({ + 'holdings-id-1': { + 'id': 'holdings-id-1', + 'name': 'Storage A', + 'description': 'Storage A description' + }, + 'holdings-id-2': { + 'id': 'holdings-id-2', + 'name': 'Storage B', + 'description': 'Storage B description' + } + }); + }, ViewMetaData: () =>
ViewMetaData
, - ControlledVocab: () =>
ControlledVocab
, - // useRemoteStorageMappings: () =>
useRemoteStorageMappings
, }), { virtual: true });