From f237cbd09127e62d27816646b5a3d1525afcfcbc Mon Sep 17 00:00:00 2001 From: vashjs Date: Thu, 5 Dec 2024 10:05:43 +0100 Subject: [PATCH] update tests --- .../BulkEditInAppLayer.test.js} | 63 +++--- .../ContentUpdatesForm/helpers.js | 87 ++++---- .../ContentUpdatesForm/helpers.test.js | 191 +++++++++--------- .../BulkEditMarcForm/BulkEditMarcActionRow.js | 25 ++- .../BulkEditMarc/validation.test.js | 6 +- .../BulkEditMarcLayer.test.js | 95 ++++----- src/hooks/useConfirmChanges.test.js | 19 -- src/hooks/useInAppApproach.test.js | 2 - src/hooks/useMarcApproach.test.js | 1 - 9 files changed, 227 insertions(+), 262 deletions(-) rename src/components/BulkEditPane/{BulkEditListResult/BulkEditInApp/BulkEditInApp.test.js => BulkEditInAppLayer/BulkEditInAppLayer.test.js} (85%) diff --git a/src/components/BulkEditPane/BulkEditListResult/BulkEditInApp/BulkEditInApp.test.js b/src/components/BulkEditPane/BulkEditInAppLayer/BulkEditInAppLayer.test.js similarity index 85% rename from src/components/BulkEditPane/BulkEditListResult/BulkEditInApp/BulkEditInApp.test.js rename to src/components/BulkEditPane/BulkEditInAppLayer/BulkEditInAppLayer.test.js index 1d0f5252..6d848c69 100644 --- a/src/components/BulkEditPane/BulkEditListResult/BulkEditInApp/BulkEditInApp.test.js +++ b/src/components/BulkEditPane/BulkEditInAppLayer/BulkEditInAppLayer.test.js @@ -2,19 +2,19 @@ import { MemoryRouter } from 'react-router-dom'; import { QueryClientProvider } from 'react-query'; import { act, render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; +import noop from 'lodash/noop'; import { runAxeTest } from '@folio/stripes-testing'; -import '../../../../../test/jest/__mock__'; +import '../../../../test/jest/__mock__'; import { FormattedMessage } from 'react-intl'; import React from 'react'; -import { flushPromises } from '../../../../../test/jest/utils/fileUpload'; -import { queryClient } from '../../../../../test/jest/utils/queryClient'; +import { flushPromises } from '../../../../test/jest/utils/fileUpload'; +import { queryClient } from '../../../../test/jest/utils/queryClient'; -import { CAPABILITIES } from '../../../../constants'; +import { CAPABILITIES } from '../../../constants'; -import { BulkEditInApp } from './BulkEditInApp'; -import { RootContext } from '../../../../context/RootContext'; +import { RootContext } from '../../../context/RootContext'; import { useItemNotes, useHoldingsNotes, @@ -25,16 +25,17 @@ import { useLocationEcs, useLoanTypesEcs, useElectronicAccessEcs -} from '../../../../hooks/api'; +} from '../../../hooks/api'; +import { BulkEditInAppLayer } from './BulkEditInAppLayer'; -jest.mock('../../../../hooks', () => ({ - ...jest.requireActual('../../../../hooks'), +jest.mock('../../../hooks', () => ({ + ...jest.requireActual('../../../hooks'), useBulkPermissions: jest.fn(), })); -jest.mock('../../../../hooks/api', () => ({ - ...jest.requireActual('../../../../hooks/api'), +jest.mock('../../../hooks/api', () => ({ + ...jest.requireActual('../../../hooks/api'), useItemNotes: jest.fn(), useHoldingsNotes: jest.fn(), useInstanceNotes: jest.fn(), @@ -48,7 +49,7 @@ jest.mock('../../../../hooks/api', () => ({ const fileName = 'Mock.csv'; -const renderBulkEditInApp = ({ capability }) => { +const renderBulkEditInAppLayer = ({ capability }) => { const params = new URLSearchParams({ capabilities: capability, identifier: 'BARCODE', @@ -63,9 +64,11 @@ const renderBulkEditInApp = ({ capability }) => { title: , }} > - {}} - capabilities={capability} + @@ -117,7 +120,7 @@ describe('BulkEditInApp', () => { }); it('should display correct title', () => { - renderBulkEditInApp({ capability: CAPABILITIES.ITEM }); + renderBulkEditInAppLayer({ capability: CAPABILITIES.ITEM }); expect(screen.getByText('ui-bulk-edit.preview.file.title')).toBeVisible(); }); @@ -127,13 +130,13 @@ describe('BulkEditInApp', () => { /layer.column.options/, /layer.column.actions/, ]; - renderBulkEditInApp({ capability: CAPABILITIES.ITEM }); + renderBulkEditInAppLayer({ capability: CAPABILITIES.ITEM }); titles.forEach((el) => expect(screen.getByText(el)).toBeVisible()); }); it('should display added row after plus button click', async () => { - const { getByLabelText, getAllByLabelText } = renderBulkEditInApp({ capability: CAPABILITIES.ITEM }); + const { getByLabelText, getAllByLabelText } = renderBulkEditInAppLayer({ capability: CAPABILITIES.ITEM }); const plusButton = getByLabelText('plus-sign'); @@ -153,7 +156,7 @@ describe('BulkEditInApp', () => { }); it('should display select right select options on inventory tab', () => { - const { getByRole } = renderBulkEditInApp({ capability: CAPABILITIES.ITEM }); + const { getByRole } = renderBulkEditInAppLayer({ capability: CAPABILITIES.ITEM }); const options = [ /layer.options.permanentLocation/, @@ -178,7 +181,7 @@ describe('BulkEditInApp', () => { }); it('should display correct status options in action select', async () => { - const { getByRole, getByTestId } = renderBulkEditInApp({ capability: CAPABILITIES.ITEM }); + const { getByRole, getByTestId } = renderBulkEditInAppLayer({ capability: CAPABILITIES.ITEM }); const options = [ /layer.options.available/, @@ -225,7 +228,7 @@ describe('BulkEditInApp', () => { }); it('should display item permanent location options', async () => { - const { getByRole, getByTestId } = renderBulkEditInApp({ capability: CAPABILITIES.ITEM }); + const { getByRole, getByTestId } = renderBulkEditInAppLayer({ capability: CAPABILITIES.ITEM }); const options = [ /layer.action.replace/, @@ -256,7 +259,7 @@ describe('BulkEditInApp', () => { }); it('should display expiration date', async () => { - const { getByRole, getByTestId } = renderBulkEditInApp({ capability: CAPABILITIES.USER }); + const { getByRole, getByTestId } = renderBulkEditInAppLayer({ capability: CAPABILITIES.USER }); const selectionBtn = getByRole('button', { name: /options.placeholder/ }); userEvent.click(selectionBtn); @@ -276,7 +279,7 @@ describe('BulkEditInApp', () => { }); it('should display patron group', async () => { - const { getByRole, getByTestId } = renderBulkEditInApp({ capability: CAPABILITIES.USER }); + const { getByRole, getByTestId } = renderBulkEditInAppLayer({ capability: CAPABILITIES.USER }); const selectionBtn = getByRole('button', { name: /options.placeholder/ }); userEvent.click(selectionBtn); @@ -300,7 +303,7 @@ describe('BulkEditInApp', () => { }); it('should display holdings permanent location', async () => { - const { getByTestId, getByRole } = renderBulkEditInApp({ capability: CAPABILITIES.HOLDING }); + const { getByTestId, getByRole } = renderBulkEditInAppLayer({ capability: CAPABILITIES.HOLDING }); const selectionBtn = getByRole('button', { name: /options.placeholder/ }); userEvent.click(selectionBtn); @@ -323,7 +326,7 @@ describe('BulkEditInApp', () => { }); it('should display holdings set to true is checked by default', async () => { - const { getByRole, getByTestId } = renderBulkEditInApp({ capability: CAPABILITIES.HOLDING }); + const { getByRole, getByTestId } = renderBulkEditInAppLayer({ capability: CAPABILITIES.HOLDING }); const selectionBtn = getByRole('button', { name: /options.placeholder/ }); userEvent.click(selectionBtn); @@ -351,7 +354,7 @@ describe('BulkEditInApp', () => { }); it('should display holdings set to false is unchecked by default', async () => { - const { getByRole, getByTestId } = renderBulkEditInApp({ capability: CAPABILITIES.HOLDING }); + const { getByRole, getByTestId } = renderBulkEditInAppLayer({ capability: CAPABILITIES.HOLDING }); const selectionBtn = getByRole('button', { name: /options.placeholder/ }); userEvent.click(selectionBtn); @@ -379,7 +382,7 @@ describe('BulkEditInApp', () => { }); it('should display holding temporary location options', async () => { - const { getByTestId, getByRole } = renderBulkEditInApp({ capability: CAPABILITIES.HOLDING }); + const { getByTestId, getByRole } = renderBulkEditInAppLayer({ capability: CAPABILITIES.HOLDING }); const options = [ /layer.action.replace/, @@ -407,7 +410,7 @@ describe('BulkEditInApp', () => { }); it('should render with no axe errors in holding form', async () => { - renderBulkEditInApp({ capability: CAPABILITIES.HOLDING }); + renderBulkEditInAppLayer({ capability: CAPABILITIES.HOLDING }); await runAxeTest({ rootNode: document.body, @@ -415,7 +418,7 @@ describe('BulkEditInApp', () => { }); it('should render with no axe errors in user form', async () => { - renderBulkEditInApp({ capability: CAPABILITIES.USER }); + renderBulkEditInAppLayer({ capability: CAPABILITIES.USER }); await runAxeTest({ rootNode: document.body, @@ -423,7 +426,7 @@ describe('BulkEditInApp', () => { }); it('should render with no axe errors in item form', async () => { - renderBulkEditInApp({ capability: CAPABILITIES.ITEM }); + renderBulkEditInAppLayer({ capability: CAPABILITIES.ITEM }); await runAxeTest({ rootNode: document.body, diff --git a/src/components/BulkEditPane/BulkEditListResult/BulkEditInApp/ContentUpdatesForm/helpers.js b/src/components/BulkEditPane/BulkEditListResult/BulkEditInApp/ContentUpdatesForm/helpers.js index c362c466..be700f78 100644 --- a/src/components/BulkEditPane/BulkEditListResult/BulkEditInApp/ContentUpdatesForm/helpers.js +++ b/src/components/BulkEditPane/BulkEditListResult/BulkEditInApp/ContentUpdatesForm/helpers.js @@ -430,51 +430,50 @@ export const sortWithoutPlaceholder = (array) => { return [placeholder, ...rest.sort((a, b) => a.label.localeCompare(b.label))]; }; -export const getMappedContentUpdates = (fields, options) => fields.map( - // eslint-disable-next-line no-shadow - ({ parameters, tenants, option, actionsDetails: { actions } }) => { - const [initial, updated] = actions.map(action => action?.value ?? null); - const actionTenants = actions.map(action => action?.tenants); - const sourceOption = options.find(o => o.value === option); - const optionType = sourceOption?.type; - const mappedOption = optionType || option; // if option has type, use it, otherwise use option value (required for ITEM_NOTE cases) - // generate action type key with '_' delimiter - const typeKey = actions - .filter(Boolean) - .map(action => action?.name ?? null).join('_'); - - const actionParameters = actions.find(action => Boolean(action?.parameters))?.parameters; - const filteredTenants = actionTenants.filter(Boolean); - // final action is the action which doesn't require any additional data after it - const isSecondActionFinal = FINAL_ACTIONS.includes(actions[1]?.name); - - const activeTenants = isSecondActionFinal || filteredTenants.length === 1 - ? filteredTenants.flat() - : filteredTenants - .flat() - .filter((tenant, index, array) => array.indexOf(tenant) !== index); - - // That tenants array need when we use find and replace action with two different action values - const updatedTenants = filteredTenants[1] || []; - const type = ACTIONS[typeKey]; +export const getMappedContentUpdates = (fields, options) => fields.map(({ + parameters, tenants, option, actionsDetails: { actions } +}) => { + const [initial, updated] = actions.map(action => action?.value ?? null); + const actionTenants = actions.map(action => action?.tenants); + const sourceOption = options.find(o => o.value === option); + const optionType = sourceOption?.type; + const mappedOption = optionType || option; // if option has type, use it, otherwise use option value (required for ITEM_NOTE cases) + // generate action type key with '_' delimiter + const typeKey = actions + .filter(Boolean) + .map(action => action?.name ?? null).join('_'); + + const actionParameters = actions.find(action => Boolean(action?.parameters))?.parameters; + const filteredTenants = actionTenants.filter(Boolean); + // final action is the action which doesn't require any additional data after it + const isSecondActionFinal = FINAL_ACTIONS.includes(actions[1]?.name); + + const activeTenants = isSecondActionFinal || filteredTenants.length === 1 + ? filteredTenants.flat() + : filteredTenants + .flat() + .filter((tenant, index, array) => array.indexOf(tenant) !== index); + + // That tenants array need when we use find and replace action with two different action values + const updatedTenants = filteredTenants[1] || []; + const type = ACTIONS[typeKey]; - return { - option: mappedOption, - tenants: tenants?.filter(Boolean), - actions: [{ - type, - initial, - updated, - tenants: activeTenants, - updated_tenants: updatedTenants, - parameters: [ - ...(parameters || []), - ...(actionParameters || []), - ], - }], - }; - }, -); + return { + option: mappedOption, + tenants: tenants?.filter(Boolean), + actions: [{ + type, + initial, + updated, + tenants: activeTenants, + updated_tenants: updatedTenants, + parameters: [ + ...(parameters || []), + ...(actionParameters || []), + ], + }], + }; +}); export const getFieldTemplate = (options, capability) => { return ({ diff --git a/src/components/BulkEditPane/BulkEditListResult/BulkEditInApp/ContentUpdatesForm/helpers.test.js b/src/components/BulkEditPane/BulkEditListResult/BulkEditInApp/ContentUpdatesForm/helpers.test.js index 62401110..277e8fd2 100644 --- a/src/components/BulkEditPane/BulkEditListResult/BulkEditInApp/ContentUpdatesForm/helpers.test.js +++ b/src/components/BulkEditPane/BulkEditListResult/BulkEditInApp/ContentUpdatesForm/helpers.test.js @@ -1,3 +1,4 @@ +import { FormattedMessage } from 'react-intl'; import { ACTIONS, CONTROL_TYPES, @@ -207,8 +208,8 @@ describe('ContentUpdatesForm helpers', () => { { actionsList: [{ value: ACTIONS.FIND, - disabled: false, - label: undefined + label: , + disabled: false }], controlType, [ACTION_VALUE_KEY]: ACTIONS.FIND, @@ -217,8 +218,8 @@ describe('ContentUpdatesForm helpers', () => { { actionsList: [{ value: ACTIONS.REPLACE_WITH, + label: , disabled: false, - label: undefined }], controlType, [ACTION_VALUE_KEY]: ACTIONS.REPLACE_WITH, @@ -242,7 +243,7 @@ describe('ContentUpdatesForm helpers', () => { { actionsList: [{ value: ACTIONS.REPLACE_WITH, - label: undefined, + label: , disabled: false }], controlType: () => CONTROL_TYPES.PATRON_GROUP_SELECT, @@ -268,7 +269,8 @@ describe('ContentUpdatesForm helpers', () => { { actionsList: [{ value: ACTIONS.REPLACE_WITH, - disabled: false + label: , + disabled: false, }], [ACTION_VALUE_KEY]: ACTIONS.REPLACE_WITH, [FIELD_VALUE_KEY]: '', @@ -294,18 +296,18 @@ describe('ContentUpdatesForm helpers', () => { { actionsList: [{ value: '', + label: , disabled: true, - label: undefined }, { value: ACTIONS.REPLACE_WITH, + label: , disabled: false, - label: undefined, }, { value: ACTIONS.CLEAR_FIELD, + label: , disabled: false, - label: undefined, }, ], controlType, @@ -333,8 +335,8 @@ describe('ContentUpdatesForm helpers', () => { { actionsList: [{ value: ACTIONS.REPLACE_WITH, + label: , disabled: false, - label: undefined }], controlType, [ACTION_VALUE_KEY]: ACTIONS.REPLACE_WITH, @@ -359,18 +361,18 @@ describe('ContentUpdatesForm helpers', () => { { actionsList: [{ value: '', + label: , disabled: true, - label: undefined }, { value: ACTIONS.REPLACE_WITH, + label: , disabled: false, - label: undefined, }, { value: ACTIONS.CLEAR_FIELD, + label: , disabled: false, - label: undefined, }, ], controlType: () => CONTROL_TYPES.LOCATION, @@ -396,16 +398,16 @@ describe('ContentUpdatesForm helpers', () => { { actionsList: [{ value: '', + label: , disabled: true, - label: undefined }, { value: ACTIONS.SET_TO_TRUE, + label: , disabled: false, - label: undefined }, { value: ACTIONS.SET_TO_FALSE, + label: , disabled: false, - label: undefined }], [ACTION_VALUE_KEY]: '', [FIELD_VALUE_KEY]: '', @@ -433,16 +435,16 @@ describe('ContentUpdatesForm helpers', () => { { actionsList: [{ value: '', + label: , disabled: true, - label: undefined }, { value: ACTIONS.SET_TO_TRUE, + label: , disabled: false, - label: undefined }, { value: ACTIONS.SET_TO_FALSE, + label: , disabled: false, - label: undefined }], [ACTION_VALUE_KEY]: '', [FIELD_VALUE_KEY]: '', @@ -473,18 +475,18 @@ describe('ContentUpdatesForm helpers', () => { { actionsList: [{ value: '', + label: , disabled: true, - label: undefined }, { value: ACTIONS.REPLACE_WITH, + label: , disabled: false, - label: undefined, }, { value: ACTIONS.CLEAR_FIELD, + label: , disabled: false, - label: undefined, }, ], controlType, @@ -512,8 +514,8 @@ describe('ContentUpdatesForm helpers', () => { { actionsList: [{ value: ACTIONS.REPLACE_WITH, + label: , disabled: false, - label: undefined }], controlType, [ACTION_VALUE_KEY]: ACTIONS.REPLACE_WITH, @@ -540,18 +542,18 @@ describe('ContentUpdatesForm helpers', () => { { actionsList: [{ value: '', + label: , disabled: true, - label: undefined, }, { value: ACTIONS.REPLACE_WITH, + label: , disabled: false, - label: undefined, }, { value: ACTIONS.CLEAR_FIELD, + label: , disabled: false, - label: undefined, }, ], controlType, @@ -579,8 +581,8 @@ describe('ContentUpdatesForm helpers', () => { { actionsList: [{ value: ACTIONS.REPLACE_WITH, + label: , disabled: false, - label: undefined }], controlType, [ACTION_VALUE_KEY]: ACTIONS.REPLACE_WITH, @@ -613,43 +615,43 @@ describe('ContentUpdatesForm helpers', () => { actionsList: [ { value: '', + label: , disabled: true, - label: undefined }, { value: ACTIONS.MARK_AS_STAFF_ONLY, + label: , disabled: false, - label: undefined }, { value: ACTIONS.REMOVE_MARK_AS_STAFF_ONLY, + label: , disabled: false, - label: undefined }, { value: ACTIONS.ADD_TO_EXISTING, + label: , disabled: false, - label: undefined }, { value: ACTIONS.REMOVE_ALL, + label: , disabled: false, - label: undefined }, { value: ACTIONS.FIND, + label: , disabled: false, - label: undefined }, { value: ACTIONS.CHANGE_TYPE, + label: , disabled: false, - label: undefined, }, { value: ACTIONS.DUPLICATE, + label: , disabled: false, - label: undefined, }, ], controlType: () => CONTROL_TYPES.TEXTAREA, @@ -685,40 +687,39 @@ describe('ContentUpdatesForm helpers', () => { { actionsList: [{ value: '', + label: , disabled: true, - label: undefined, }, { value: ACTIONS.MARK_AS_STAFF_ONLY, + label: , disabled: false, - label: undefined }, { value: ACTIONS.REMOVE_MARK_AS_STAFF_ONLY, + label: , disabled: false, - label: undefined }, { value: ACTIONS.ADD_TO_EXISTING, + label: , disabled: false, - label: undefined }, { value: ACTIONS.REMOVE_ALL, + label: , disabled: false, - label: undefined }, { value: ACTIONS.FIND, + label: , disabled: false, - label: undefined }, { value: ACTIONS.CHANGE_TYPE, + label: , disabled: false, - label: undefined, - }, - ], + }], controlType: (action) => { return action === ACTIONS.CHANGE_TYPE ? CONTROL_TYPES.NOTE_SELECT @@ -755,23 +756,23 @@ describe('ContentUpdatesForm helpers', () => { actionsList: [ { value: '', + label: , disabled: true, - label: undefined }, { value: ACTIONS.CLEAR_FIELD, + label: , disabled: false, - label: undefined, }, { value: ACTIONS.FIND, + label: , disabled: false, - label: undefined, }, { value: ACTIONS.REPLACE_WITH, + label: , disabled: false, - label: undefined, }, ], controlType: () => CONTROL_TYPES.ELECTRONIC_ACCESS_RELATIONSHIP_SELECT, @@ -803,26 +804,27 @@ describe('ContentUpdatesForm helpers', () => { actions: [ null, { - actionsList: [{ - value: '', - disabled: true, - label: undefined, - }, - { - value: ACTIONS.CLEAR_FIELD, - disabled: false, - label: undefined - }, - { - value: ACTIONS.FIND, - disabled: false, - label: undefined - }, - { - value: ACTIONS.REPLACE_WITH, - disabled: false, - label: undefined - }, + actionsList: [ + { + value: '', + label: , + disabled: true, + }, + { + value: ACTIONS.CLEAR_FIELD, + label: , + disabled: false, + }, + { + value: ACTIONS.FIND, + label: , + disabled: false, + }, + { + value: ACTIONS.REPLACE_WITH, + label: , + disabled: false, + }, ], controlType: () => CONTROL_TYPES.TEXTAREA, [ACTION_VALUE_KEY]: '', @@ -846,26 +848,27 @@ describe('ContentUpdatesForm helpers', () => { actions: [ null, { - actionsList: [{ - value: '', - disabled: true, - label: undefined, - }, - { - value: ACTIONS.CLEAR_FIELD, - disabled: false, - label: undefined - }, - { - value: ACTIONS.FIND, - disabled: false, - label: undefined - }, - { - value: ACTIONS.REPLACE_WITH, - disabled: false, - label: undefined - }, + actionsList: [ + { + value: '', + label: , + disabled: true, + }, + { + value: ACTIONS.CLEAR_FIELD, + label: , + disabled: false, + }, + { + value: ACTIONS.FIND, + label: , + disabled: false, + }, + { + value: ACTIONS.REPLACE_WITH, + label: , + disabled: false, + }, ], controlType: () => CONTROL_TYPES.TEXTAREA, [ACTION_VALUE_KEY]: '', @@ -967,35 +970,35 @@ describe('ContentUpdatesForm helpers', () => { { actionsList: [{ value: '', + label: , disabled: true, - label: undefined }, { value: ACTIONS.MARK_AS_STAFF_ONLY, + label: , disabled: false, - label: undefined }, { value: ACTIONS.REMOVE_MARK_AS_STAFF_ONLY, + label: , disabled: false, - label: undefined }, { value: ACTIONS.ADD_TO_EXISTING, + label: , disabled: false, - label: undefined }, { value: ACTIONS.REMOVE_ALL, + label: , disabled: false, - label: undefined }, { value: ACTIONS.FIND, + label: , disabled: false, - label: undefined }, { value: ACTIONS.CHANGE_TYPE, + label: , disabled: false, - label: undefined, }], [ACTION_VALUE_KEY]: '', [FIELD_VALUE_KEY]: '', diff --git a/src/components/BulkEditPane/BulkEditListResult/BulkEditMarc/BulkEditMarcForm/BulkEditMarcActionRow.js b/src/components/BulkEditPane/BulkEditListResult/BulkEditMarc/BulkEditMarcForm/BulkEditMarcActionRow.js index 2880fc97..f867948c 100644 --- a/src/components/BulkEditPane/BulkEditListResult/BulkEditMarc/BulkEditMarcForm/BulkEditMarcActionRow.js +++ b/src/components/BulkEditPane/BulkEditListResult/BulkEditMarc/BulkEditMarcForm/BulkEditMarcActionRow.js @@ -34,10 +34,9 @@ const BulkEditMarcActionRow = ({ const errors = getMarcFormErrors(fields); const subFieldErrorId = get(errors, `[${rowIndex}].actions[${actionIndex}].data[${dataIndex}].value`); - const subfieldErrorMessage = subFieldErrorId && data.value.length === SUBFIELD_MAX_LENGTH ? - formatMessage({ id: subFieldErrorId }) - : - ''; + const subfieldErrorMessage = subFieldErrorId && data.value.length === SUBFIELD_MAX_LENGTH + ? formatMessage({ id: subFieldErrorId }) + : ''; switch (data.key) { case DATA_KEYS.VALUE: @@ -94,10 +93,8 @@ const BulkEditMarcActionRow = ({ maxLength={SUBFIELD_MAX_LENGTH} /> {data.meta.required && ( - - * - ) - } + * + )} ); @@ -126,12 +123,14 @@ const BulkEditMarcActionRow = ({ fullWidth /> {(action.meta.required && actionIndex > 0) && ( - - * - ) - } + * + )} - {action.data.map((data, dataIndex) => renderDataControl(data, actionIndex, dataIndex))} + {action.data.map((data, dataIndex) => ( + + {renderDataControl(data, actionIndex, dataIndex)} + + ))} )); }; diff --git a/src/components/BulkEditPane/BulkEditListResult/BulkEditMarc/validation.test.js b/src/components/BulkEditPane/BulkEditListResult/BulkEditMarc/validation.test.js index a6ec7656..16e6bf25 100644 --- a/src/components/BulkEditPane/BulkEditListResult/BulkEditMarc/validation.test.js +++ b/src/components/BulkEditPane/BulkEditListResult/BulkEditMarc/validation.test.js @@ -41,7 +41,7 @@ describe('getMarcFormErrors', () => { const invalidInput = [ { 'id': '202', - 'tag': '111', + 'tag': '005', 'ind1': '\\', 'ind2': '\\', 'subfield': '', @@ -80,7 +80,7 @@ describe('getMarcFormErrors', () => { const invalidInput = [ { id: '202', - tag: '111', + tag: '005', ind1: '\\', ind2: '\\', subfield: '', @@ -108,9 +108,9 @@ describe('getMarcFormErrors', () => { const errors = getMarcFormErrors(invalidInput); expect(errors).toEqual({ - '[0].tag': 'ui-bulk-edit.layer.marc.error', '[0].subfield': 'ui-bulk-edit.layer.marc.error.subfield', '[0].actions[0].data[0].value': 'ui-bulk-edit.layer.marc.error.subfield', + '[0].tag': 'ui-bulk-edit.layer.marc.error', }); }); }); diff --git a/src/components/BulkEditPane/BulkEditMarcLayer/BulkEditMarcLayer.test.js b/src/components/BulkEditPane/BulkEditMarcLayer/BulkEditMarcLayer.test.js index fbebfa86..db5935ec 100644 --- a/src/components/BulkEditPane/BulkEditMarcLayer/BulkEditMarcLayer.test.js +++ b/src/components/BulkEditPane/BulkEditMarcLayer/BulkEditMarcLayer.test.js @@ -20,6 +20,8 @@ import { getMarcFieldTemplate } from '../BulkEditListResult/BulkEditMarc/helpers import { ACTIONS } from '../../../constants/marcActions'; const mockConfirmChanges = jest.fn(); +const mockMarcContentUpdate = jest.fn().mockReturnValue('marcContentUpdate'); +const mockContentUpdate = jest.fn(); jest.mock('../../../hooks/useConfirmChanges', () => ({ useConfirmChanges: jest.fn(() => ({ @@ -28,6 +30,18 @@ jest.mock('../../../hooks/useConfirmChanges', () => ({ })), })); +jest.mock('../../../hooks/api/useMarcContentUpdate', () => ({ + useMarcContentUpdate: jest.fn(() => ({ + marcContentUpdate: mockMarcContentUpdate, + })), +})); + +jest.mock('../../../hooks/api/useContentUpdate', () => ({ + useContentUpdate: jest.fn(() => ({ + contentUpdate: mockContentUpdate, + })), +})); + const closeMarcLayerFn = jest.fn(); const setCountOfRecordsMockFn = jest.fn(); const title = 'Title'; @@ -46,9 +60,9 @@ const renderBulkEditMarcLayer = ({ criteria }) => { const params = new URLSearchParams({ criteria, approach: APPROACHES.MARC, - capabilities: CAPABILITIES.USER, - identifier: IDENTIFIERS.ID, - fileName: 'barcodes.csv', + capabilities: CAPABILITIES.INSTANCE_MARC, + identifier: IDENTIFIERS.INSTANCE_HRID, + fileName: 'instances.csv', }).toString(); return render( @@ -64,9 +78,9 @@ const renderBulkEditMarcLayer = ({ criteria }) => { > { expect(getByText('ui-bulk-edit.layer.column.subfield')) .toBeVisible(); expect(getAllByText('ui-bulk-edit.layer.column.actions').length) - .toBe(3); + .toBe(4); // 3 actions for MarcField + 1 for Administrative data // tooltips expect(getByText('ui-bulk-edit.layer.marc.error.limited')) @@ -146,23 +160,7 @@ describe('BulkEditMarcLayer', () => { }); }); - it('should show error message if value is not between 5xx and 9xx ', async () => { - const { getByRole } = renderBulkEditMarcLayer({ criteria: CRITERIA.IDENTIFIER }); - - const inputField = getByRole('textbox', { name: /ui-bulk-edit.layer.column.field/i }); - - expect(inputField) - .toHaveValue(''); - - userEvent.type(inputField, '123'); - - await waitFor(() => { - expect(screen.getByText('ui-bulk-edit.layer.marc.error')) - .toBeVisible(); - }); - }); - - it('should show error message if value is not between 5xx and 9xx ', async () => { + it('should show error message if value is 00x', async () => { const { getByRole } = renderBulkEditMarcLayer({ criteria: CRITERIA.IDENTIFIER }); const inputField = getByRole('textbox', { name: /ui-bulk-edit.layer.column.field/i }); @@ -170,7 +168,7 @@ describe('BulkEditMarcLayer', () => { expect(inputField) .toHaveValue(''); - userEvent.type(inputField, '123'); + userEvent.type(inputField, '002'); await waitFor(() => { expect(screen.getByText('ui-bulk-edit.layer.marc.error')) @@ -197,28 +195,27 @@ describe('BulkEditMarcLayer', () => { }); it('should add and remove rows when + or trash buttons clicked', async () => { - const { - getByRole, - getAllByRole - } = renderBulkEditMarcLayer({ criteria: CRITERIA.IDENTIFIER }); + const { getAllByRole } = renderBulkEditMarcLayer({ criteria: CRITERIA.IDENTIFIER }); + + const marcAccordion = getAllByRole('region')[2]; - const addBtn = getByRole('button', { name: /plus-sign/i }); - const trashBtn = getByRole('button', { name: /trash/i }); + const addBtn = within(marcAccordion).getByRole('button', { name: /plus-sign/i }); + const trashBtn = within(marcAccordion).getByRole('button', { name: /trash/i }); - expect(getAllByRole('button', { name: /plus-sign/i }).length) + expect(within(marcAccordion).getAllByRole('button', { name: /plus-sign/i }).length) .toBe(1); userEvent.click(addBtn); await waitFor(() => { - expect(getAllByRole('button', { name: /plus-sign/i }).length) + expect(within(marcAccordion).getAllByRole('button', { name: /plus-sign/i }).length) .toBe(2); }); userEvent.click(trashBtn); await waitFor(() => { - expect(getAllByRole('button', { name: /plus-sign/i }).length) + expect(within(marcAccordion).getAllByRole('button', { name: /plus-sign/i }).length) .toBe(1); }); }); @@ -317,11 +314,17 @@ describe('BulkEditMarcLayer', () => { it('should call "confirm changes" function', async () => { const { getByRole, + getAllByRole, } = renderBulkEditMarcLayer({ criteria: CRITERIA.IDENTIFIER }); - const actionSelect = getByRole('combobox', { name: /ui-bulk-edit.layer.column.action/i }); + const marcAccordion = getAllByRole('region')[2]; - // select first action + const actionSelect = within(marcAccordion).getByRole('combobox', { name: /ui-bulk-edit.layer.column.action/i }); + const inputField = within(marcAccordion).getByRole('textbox', { name: /ui-bulk-edit.layer.column.field/i }); + const inputSubField = within(marcAccordion).getByRole('textbox', { name: /ui-bulk-edit.layer.column.subfield/i }); + + userEvent.type(inputField, '555'); + userEvent.type(inputSubField, 'a'); userEvent.selectOptions(actionSelect, ACTIONS.REMOVE_ALL); const confirmChangesBtn = getByRole('button', { name: /ui-bulk-edit.layer.confirmChanges/i }); @@ -329,27 +332,7 @@ describe('BulkEditMarcLayer', () => { userEvent.click(confirmChangesBtn); await waitFor(() => { - expect(mockConfirmChanges).toHaveBeenCalledWith({ - bulkOperationMarcRules: [ - { - actions: [ - { - data: [], - name: 'REMOVE_ALL', - }, - ], - bulkOperationId: undefined, - id: expect.anything(), - ind1: '\\', - ind2: '\\', - parameters: [], - subfield: '', - subfields: [], - tag: '', - }, - ], - totalRecords: 1, - }); + expect(mockConfirmChanges).toHaveBeenCalledWith(['marcContentUpdate']); }); }); diff --git a/src/hooks/useConfirmChanges.test.js b/src/hooks/useConfirmChanges.test.js index 9849706f..c163c231 100644 --- a/src/hooks/useConfirmChanges.test.js +++ b/src/hooks/useConfirmChanges.test.js @@ -46,7 +46,6 @@ describe('useConfirmChanges', () => { }; const mockBulkOperationDetails = { bulkDetails: { totalNumOfRecords: 100 } }; const mockBulkOperationStart = jest.fn(); - const mockUpdateFn = jest.fn(() => Promise.resolve()); const mockDownloadFile = jest.fn(); beforeEach(() => { @@ -63,7 +62,6 @@ describe('useConfirmChanges', () => { it('should initialize hook state correctly', () => { const { result } = renderHook(() => useConfirmChanges({ - updateFn: mockUpdateFn, queryDownloadKey: 'testKey', bulkOperationId: '123', })); @@ -75,7 +73,6 @@ describe('useConfirmChanges', () => { it('should open and close the preview modal', () => { const { result } = renderHook(() => useConfirmChanges({ - updateFn: mockUpdateFn, queryDownloadKey: 'testKey', bulkOperationId: '123', })); @@ -93,7 +90,6 @@ describe('useConfirmChanges', () => { it('should handle confirmChanges function correctly', async () => { const { result, waitForNextUpdate } = renderHook(() => useConfirmChanges({ - updateFn: mockUpdateFn, queryDownloadKey: 'testKey', bulkOperationId: '123', })); @@ -109,26 +105,12 @@ describe('useConfirmChanges', () => { // Wait for the next update after the async calls await waitForNextUpdate(); // Wait for the polling to start - // Verify that the update function is called - expect(mockUpdateFn).toHaveBeenCalled(); - - // Verify that the bulkOperationStart function is called with the correct parameters - expect(mockBulkOperationStart).toHaveBeenCalledWith({ - id: '123', - approach: 'IN_APP', - step: 'EDIT', - }); - // Finally, check if loading state is set back to false expect(result.current.isPreviewLoading).toBe(false); }); it('should handle error in confirmChanges function', async () => { - // Mock the update function to throw an error - mockUpdateFn.mockImplementationOnce(() => Promise.reject(new Error('Update failed'))); - const { result, waitForNextUpdate } = renderHook(() => useConfirmChanges({ - updateFn: mockUpdateFn, queryDownloadKey: 'testKey', bulkOperationId: '123', })); @@ -150,7 +132,6 @@ describe('useConfirmChanges', () => { it('should call downloadFile from useFileDownload', () => { const { result } = renderHook(() => useConfirmChanges({ - updateFn: mockUpdateFn, queryDownloadKey: 'testKey', bulkOperationId: '123', })); diff --git a/src/hooks/useInAppApproach.test.js b/src/hooks/useInAppApproach.test.js index afd02d91..8bce94ea 100644 --- a/src/hooks/useInAppApproach.test.js +++ b/src/hooks/useInAppApproach.test.js @@ -33,10 +33,8 @@ describe('useInAppApproach', () => { it('should initialize with default values', () => { const { result } = renderHook(() => useInAppApproach()); - expect(result.current.contentUpdates).toBe(null); expect(result.current.isInAppLayerOpen).toBe(false); expect(result.current.isPreviewModalOpened).toBe(false); - expect(result.current.isInAppFormValid).toBe(true); }); it('should open in-app layer and set param', () => { diff --git a/src/hooks/useMarcApproach.test.js b/src/hooks/useMarcApproach.test.js index 9b43c08e..c6e306d4 100644 --- a/src/hooks/useMarcApproach.test.js +++ b/src/hooks/useMarcApproach.test.js @@ -69,7 +69,6 @@ describe('useMarcApproach', () => { const { result } = renderHook(() => useMarcApproach()); expect(result.current.isMarcLayerOpen).toBe(false); - expect(result.current.isMarcFieldsValid).toBe(true); }); test('should open marc layer and set param', () => {