From 64325489291693df509595f547ca036d4b6afa0a Mon Sep 17 00:00:00 2001 From: vashjs Date: Tue, 10 Dec 2024 11:08:01 +0100 Subject: [PATCH] UIBULKED-571 Errors in response to UI calls --- CHANGELOG.md | 1 + .../BulkEditListResult.test.js | 1 - .../hooks/useAllPermissions.js | 6 +- src/constants/errorStatuses.js | 45 ++++++++++ src/constants/index.js | 2 + src/constants/moduleNames.js | 5 ++ src/hooks/api/index.js | 1 - src/hooks/api/useElectronicAccess.js | 6 +- src/hooks/api/useHoldingsNotes.js | 8 +- src/hooks/api/useInstanceNotes.js | 7 +- src/hooks/api/useItemNotes.js | 7 +- src/hooks/api/useLoanTypes.js | 6 +- src/hooks/api/usePatronGroup.js | 6 +- src/hooks/api/useRecordTypes.js | 6 +- src/hooks/api/useUserGroupsMap.js | 38 --------- src/hooks/useErrorMessages.js | 16 +++- src/hooks/useErrorMessages.test.js | 85 ++++++++++++++++++- src/hooks/usePublishCoordinator.js | 10 ++- src/hooks/usePublishCoordinator.test.js | 4 + 19 files changed, 189 insertions(+), 71 deletions(-) create mode 100644 src/constants/errorStatuses.js create mode 100644 src/constants/moduleNames.js delete mode 100644 src/hooks/api/useUserGroupsMap.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b94cd76..4611cff8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * [UIBULKED-560](https://folio-org.atlassian.net/browse/UIBULKED-560) Update actions menu. * [UIBULKED-585](https://folio-org.atlassian.net/browse/UUIBULKED-585) Adding missing translation and filters. * [UIBULKED-561](https://folio-org.atlassian.net/browse/UUIBULKED-561) Add administrative data accordion to MARC bulk edit form. +* [UIBULKED-571](https://folio-org.atlassian.net/browse/UIBULKED-571) Errors in response to UI calls. ## [4.2.2](https://github.com/folio-org/ui-bulk-edit/tree/v4.2.2) (2024-11-15) diff --git a/src/components/BulkEditPane/BulkEditListResult/BulkEditListResult.test.js b/src/components/BulkEditPane/BulkEditListResult/BulkEditListResult.test.js index be287896..49667332 100644 --- a/src/components/BulkEditPane/BulkEditListResult/BulkEditListResult.test.js +++ b/src/components/BulkEditPane/BulkEditListResult/BulkEditListResult.test.js @@ -29,7 +29,6 @@ jest.mock('../../../hooks/api', () => ({ useErrorsPreview: () => ({ errors: [], }), - useUserGroupsMap: () => ({}), })); const setCountOfRecordsMock = jest.fn(); diff --git a/src/components/PermissionsModal/hooks/useAllPermissions.js b/src/components/PermissionsModal/hooks/useAllPermissions.js index cc40c3fd..f5d2b3d5 100644 --- a/src/components/PermissionsModal/hooks/useAllPermissions.js +++ b/src/components/PermissionsModal/hooks/useAllPermissions.js @@ -2,13 +2,14 @@ import { useQuery } from 'react-query'; import { useNamespace, useOkapiKy } from '@folio/stripes/core'; import { FILTER_KEYS } from '../constants/core'; import { useErrorMessages } from '../../../hooks/useErrorMessages'; +import { MOD_PERMISSIONS } from '../../../constants'; export const ALL_PERMISSIONS_KEY = 'ALL_PERMISSIONS_KEY'; export const useAllPermissions = (options = {}) => { const ky = useOkapiKy(); const [namespaceKey] = useNamespace({ key: ALL_PERMISSIONS_KEY }); - const { showErrorMessage } = useErrorMessages(); + const { showExternalModuleError } = useErrorMessages(); const { data: permissions, isLoading: isPermissionsLoading } = useQuery( { @@ -20,8 +21,7 @@ export const useAllPermissions = (options = {}) => { ...permission, type: permission.mutable ? FILTER_KEYS.PERMISSION_SETS : FILTER_KEYS.PERMISSIONS, })), - onError: showErrorMessage, - onSuccess: showErrorMessage, + onError: (error) => showExternalModuleError(MOD_PERMISSIONS, error), ...options, }, ); diff --git a/src/constants/errorStatuses.js b/src/constants/errorStatuses.js new file mode 100644 index 00000000..13b53fbe --- /dev/null +++ b/src/constants/errorStatuses.js @@ -0,0 +1,45 @@ +export const ERROR_STATUSES = { + // 4xx Client Errors + 400: 'Bad Request', + 401: 'Unauthorized', + 402: 'Payment Required', + 403: 'Forbidden', + 404: 'Not Found', + 405: 'Method Not Allowed', + 406: 'Not Acceptable', + 407: 'Proxy Authentication Required', + 408: 'Request Timeout', + 409: 'Conflict', + 410: 'Gone', + 411: 'Length Required', + 412: 'Precondition Failed', + 413: 'Payload Too Large', + 414: 'URI Too Long', + 415: 'Unsupported Media Type', + 416: 'Range Not Satisfiable', + 417: 'Expectation Failed', + 418: "I'm a teapot", + 421: 'Misdirected Request', + 422: 'Unprocessable Content', + 423: 'Locked', + 424: 'Failed Dependency', + 425: 'Too Early', + 426: 'Upgrade Required', + 428: 'Precondition Required', + 429: 'Too Many Requests', + 431: 'Request Header Fields Too Large', + 451: 'Unavailable For Legal Reasons', + + // 5xx Server Errors + 500: 'Internal Server Error', + 501: 'Not Implemented', + 502: 'Bad Gateway', + 503: 'Service Unavailable', + 504: 'Gateway Timeout', + 505: 'HTTP Version Not Supported', + 506: 'Variant Also Negotiates', + 507: 'Insufficient Storage', + 508: 'Loop Detected', + 510: 'Not Extended', + 511: 'Network Authentication Required' +}; diff --git a/src/constants/index.js b/src/constants/index.js index a0d4c124..eea3ecfa 100644 --- a/src/constants/index.js +++ b/src/constants/index.js @@ -5,3 +5,5 @@ export * from './inAppActions'; export * from '../utils/date'; export * from './files'; export * from './logsActions'; +export * from './errorStatuses'; +export * from './moduleNames'; diff --git a/src/constants/moduleNames.js b/src/constants/moduleNames.js new file mode 100644 index 00000000..7ee3d8da --- /dev/null +++ b/src/constants/moduleNames.js @@ -0,0 +1,5 @@ +export const MOD_INVENTORY_STORAGE = 'mod-inventory-storage'; +export const MOD_USERS = 'mod-users'; +export const MOD_PERMISSIONS = 'mod-permissions'; +export const MOD_FQM_MANAGER = 'mod-fqm-manager'; +export const MOD_CONSORTIA = 'mod-consortia'; diff --git a/src/hooks/api/index.js b/src/hooks/api/index.js index 81dda79f..fd0a481d 100644 --- a/src/hooks/api/index.js +++ b/src/hooks/api/index.js @@ -5,7 +5,6 @@ export * from './useBulkOperationStart'; export * from './useUpload'; export * from './useBulkEditLogs'; export * from './useErrorsPreview'; -export * from './useUserGroupsMap'; export * from './usePatronGroup'; export * from './useLoanTypes'; export * from './useBulkOperationDetails'; diff --git a/src/hooks/api/useElectronicAccess.js b/src/hooks/api/useElectronicAccess.js index cb4003e8..d0f90da8 100644 --- a/src/hooks/api/useElectronicAccess.js +++ b/src/hooks/api/useElectronicAccess.js @@ -1,13 +1,14 @@ import { useNamespace, useOkapiKy } from '@folio/stripes/core'; import { useQuery } from 'react-query'; import { useErrorMessages } from '../useErrorMessages'; +import { MOD_INVENTORY_STORAGE } from '../../constants'; export const ELECTRONIC_ACCESS_RELATIONSHIPS_KEY = 'ELECTRONIC_ACCESS_RELATIONSHIPS_KEY'; export const useElectronicAccessRelationships = (options = {}) => { const ky = useOkapiKy(); const [namespaceKey] = useNamespace({ key: ELECTRONIC_ACCESS_RELATIONSHIPS_KEY }); - const { showErrorMessage } = useErrorMessages(); + const { showExternalModuleError } = useErrorMessages(); const { data, isLoading: isElectronicAccessLoading } = useQuery( { @@ -15,8 +16,7 @@ export const useElectronicAccessRelationships = (options = {}) => { cacheTime: Infinity, staleTime: Infinity, queryFn: () => ky.get('electronic-access-relationships?limit=1000&query=cql.allRecords=1 sortby name').json(), - onError: showErrorMessage, - onSuccess: showErrorMessage, + onError: (error) => showExternalModuleError(MOD_INVENTORY_STORAGE, error), ...options, }, ); diff --git a/src/hooks/api/useHoldingsNotes.js b/src/hooks/api/useHoldingsNotes.js index 0b818ef5..446e1996 100644 --- a/src/hooks/api/useHoldingsNotes.js +++ b/src/hooks/api/useHoldingsNotes.js @@ -2,17 +2,18 @@ import { useNamespace, useOkapiKy } from '@folio/stripes/core'; import { useQuery } from 'react-query'; import { useIntl } from 'react-intl'; import { useMemo } from 'react'; -import { OPTIONS, PARAMETERS_KEYS } from '../../constants'; +import { OPTIONS, PARAMETERS_KEYS, MOD_INVENTORY_STORAGE } from '../../constants'; import { getMappedAndSortedNotes } from '../../utils/helpers'; import { useErrorMessages } from '../useErrorMessages'; + export const HOLDINGS_NOTES_KEY = 'HOLDINGS_NOTES_KEY'; export const useHoldingsNotes = (options = {}) => { const ky = useOkapiKy(); const [namespaceKey] = useNamespace({ key: HOLDINGS_NOTES_KEY }); const { formatMessage } = useIntl(); - const { showErrorMessage } = useErrorMessages(); + const { showExternalModuleError } = useErrorMessages(); const { data, isLoading: isHoldingsNotesLoading } = useQuery( { @@ -20,8 +21,7 @@ export const useHoldingsNotes = (options = {}) => { cacheTime: Infinity, staleTime: Infinity, queryFn: () => ky.get('holdings-note-types', { searchParams: { limit: 1000 } }).json(), - onError: showErrorMessage, - onSuccess: showErrorMessage, + onError: (error) => showExternalModuleError(MOD_INVENTORY_STORAGE, error), ...options, }, ); diff --git a/src/hooks/api/useInstanceNotes.js b/src/hooks/api/useInstanceNotes.js index cc7e3c88..ebf92865 100644 --- a/src/hooks/api/useInstanceNotes.js +++ b/src/hooks/api/useInstanceNotes.js @@ -2,7 +2,7 @@ import { useNamespace, useOkapiKy } from '@folio/stripes/core'; import { useQuery } from 'react-query'; import { useIntl } from 'react-intl'; import { useMemo } from 'react'; -import { OPTIONS, PARAMETERS_KEYS } from '../../constants'; +import { MOD_INVENTORY_STORAGE, OPTIONS, PARAMETERS_KEYS } from '../../constants'; import { getMappedAndSortedNotes } from '../../utils/helpers'; import { useErrorMessages } from '../useErrorMessages'; @@ -12,7 +12,7 @@ export const useInstanceNotes = (options = {}) => { const ky = useOkapiKy(); const [namespaceKey] = useNamespace({ key: INSTANCE_NOTES_KEY }); const { formatMessage } = useIntl(); - const { showErrorMessage } = useErrorMessages(); + const { showExternalModuleError } = useErrorMessages(); const { data, isLoading: isInstanceNotesLoading } = useQuery( { @@ -20,8 +20,7 @@ export const useInstanceNotes = (options = {}) => { cacheTime: Infinity, staleTime: Infinity, queryFn: () => ky.get('instance-note-types', { searchParams: { limit: 1000 } }).json(), - onError: showErrorMessage, - onSuccess: showErrorMessage, + onError: (error) => showExternalModuleError(MOD_INVENTORY_STORAGE, error), ...options, }, ); diff --git a/src/hooks/api/useItemNotes.js b/src/hooks/api/useItemNotes.js index e6b73dc0..fd5042fc 100644 --- a/src/hooks/api/useItemNotes.js +++ b/src/hooks/api/useItemNotes.js @@ -2,7 +2,7 @@ import { useNamespace, useOkapiKy } from '@folio/stripes/core'; import { useQuery } from 'react-query'; import { useIntl } from 'react-intl'; import { useMemo } from 'react'; -import { OPTIONS, PARAMETERS_KEYS } from '../../constants'; +import { MOD_INVENTORY_STORAGE, OPTIONS, PARAMETERS_KEYS } from '../../constants'; import { getMappedAndSortedNotes } from '../../utils/helpers'; import { useErrorMessages } from '../useErrorMessages'; @@ -12,7 +12,7 @@ export const useItemNotes = (options = {}) => { const ky = useOkapiKy(); const [namespaceKey] = useNamespace({ key: ITEM_NOTES_KEY }); const { formatMessage } = useIntl(); - const { showErrorMessage } = useErrorMessages(); + const { showExternalModuleError } = useErrorMessages(); const { data, isLoading: isItemNotesLoading } = useQuery( { @@ -20,8 +20,7 @@ export const useItemNotes = (options = {}) => { cacheTime: Infinity, staleTime: Infinity, queryFn: () => ky.get('item-note-types', { searchParams: { limit: 1000 } }).json(), - onError: showErrorMessage, - onSuccess: showErrorMessage, + onError: (error) => showExternalModuleError(MOD_INVENTORY_STORAGE, error), ...options, }, ); diff --git a/src/hooks/api/useLoanTypes.js b/src/hooks/api/useLoanTypes.js index c20cac76..0f81127b 100644 --- a/src/hooks/api/useLoanTypes.js +++ b/src/hooks/api/useLoanTypes.js @@ -1,13 +1,14 @@ import { useNamespace, useOkapiKy } from '@folio/stripes/core'; import { useQuery } from 'react-query'; import { useErrorMessages } from '../useErrorMessages'; +import { MOD_INVENTORY_STORAGE } from '../../constants'; export const LOAN_TYPES_KEY = 'LOAN_TYPES_KEY'; export const useLoanTypes = (options = {}) => { const ky = useOkapiKy(); const [namespaceKey] = useNamespace({ key: LOAN_TYPES_KEY }); - const { showErrorMessage } = useErrorMessages(); + const { showExternalModuleError } = useErrorMessages(); const { data, isLoading } = useQuery( { @@ -15,8 +16,7 @@ export const useLoanTypes = (options = {}) => { cacheTime: Infinity, staleTime: Infinity, queryFn: () => ky.get('loan-types?query=cql.allRecords%3D1%20sortby%20name&limit=1000').json(), - onError: showErrorMessage, - onSuccess: showErrorMessage, + onError: (error) => showExternalModuleError(MOD_INVENTORY_STORAGE, error), ...options, }, ); diff --git a/src/hooks/api/usePatronGroup.js b/src/hooks/api/usePatronGroup.js index e87edf81..18866acd 100644 --- a/src/hooks/api/usePatronGroup.js +++ b/src/hooks/api/usePatronGroup.js @@ -4,21 +4,21 @@ import { import { useNamespace, useOkapiKy } from '@folio/stripes/core'; import { useErrorMessages } from '../useErrorMessages'; +import { MOD_USERS } from '../../constants'; export const PATRON_GROUP_KEY = 'PATRON_GROUP_KEY'; export const usePatronGroup = (options = {}) => { const ky = useOkapiKy(); const [namespaceKey] = useNamespace({ key: PATRON_GROUP_KEY }); - const { showErrorMessage } = useErrorMessages(); + const { showExternalModuleError } = useErrorMessages(); const { data, isLoading } = useQuery( { queryKey: [namespaceKey], cacheTime: Infinity, staleTime: Infinity, - onSuccess: showErrorMessage, - onError: showErrorMessage, + onError: (error) => showExternalModuleError(MOD_USERS, error), queryFn: async () => { const { usergroups } = await ky.get('groups', { searchParams: { limit: 200 } }).json(); diff --git a/src/hooks/api/useRecordTypes.js b/src/hooks/api/useRecordTypes.js index e472e12c..b3b5c394 100644 --- a/src/hooks/api/useRecordTypes.js +++ b/src/hooks/api/useRecordTypes.js @@ -1,13 +1,14 @@ import { useNamespace, useOkapiKy } from '@folio/stripes/core'; import { useQuery } from 'react-query'; import { useErrorMessages } from '../useErrorMessages'; +import { MOD_FQM_MANAGER } from '../../constants'; export const ENTITY_TYPE_KEY = 'ENTITY_TYPE_KEY'; export const useRecordTypes = ({ enabled } = {}) => { const ky = useOkapiKy(); const [namespaceKey] = useNamespace({ key: ENTITY_TYPE_KEY }); - const { showErrorMessage } = useErrorMessages(); + const { showExternalModuleError } = useErrorMessages(); const { data, isLoading, error } = useQuery({ queryKey: [namespaceKey], @@ -18,8 +19,7 @@ export const useRecordTypes = ({ enabled } = {}) => { }, cacheTime: Infinity, staleTime: Infinity, - onError: showErrorMessage, - onSuccess: showErrorMessage, + onError: (err) => showExternalModuleError(MOD_FQM_MANAGER, err), enabled }); diff --git a/src/hooks/api/useUserGroupsMap.js b/src/hooks/api/useUserGroupsMap.js deleted file mode 100644 index 50e17f68..00000000 --- a/src/hooks/api/useUserGroupsMap.js +++ /dev/null @@ -1,38 +0,0 @@ -import { - useQuery, -} from 'react-query'; - -import { useNamespace, useOkapiKy } from '@folio/stripes/core'; -import { useErrorMessages } from '../useErrorMessages'; - -export const GROUP_MAP_KEYS = 'GROUP_MAP_KEYS'; - -export const useUserGroupsMap = () => { - const ky = useOkapiKy(); - const [namespaceKey] = useNamespace({ key: GROUP_MAP_KEYS }); - const { showErrorMessage } = useErrorMessages(); - - const { data } = useQuery( - { - queryKey: [namespaceKey], - cacheTime: Infinity, - staleTime: Infinity, - onError: showErrorMessage, - onSuccess: showErrorMessage, - queryFn: async () => { - const { usergroups } = await ky.get('groups', { searchParams: { limit: 200 } }).json(); - - return usergroups.reduce((acc, curr) => ( - { - ...acc, - [curr.id]: curr.group, - } - ), {}); - }, - }, - ); - - return ({ - userGroups: data || {}, - }); -}; diff --git a/src/hooks/useErrorMessages.js b/src/hooks/useErrorMessages.js index c5c216f2..039d0a30 100644 --- a/src/hooks/useErrorMessages.js +++ b/src/hooks/useErrorMessages.js @@ -1,7 +1,7 @@ import { useIntl } from 'react-intl'; import { useShowCallout } from '@folio/stripes-acq-components'; -import { ERRORS } from '../constants'; +import { ERRORS, ERROR_STATUSES } from '../constants'; import { useSearchParams } from './useSearchParams'; @@ -41,7 +41,21 @@ export const useErrorMessages = () => { } }; + const showExternalModuleError = (moduleName, error) => { + const status = error?.status ?? 500; + const message = error?.message; + + const statusError = ERROR_STATUSES[status]; + const messageError = ERROR_STATUSES[message]; // Some modules return the error message as a known status + + // Determine message details based on priority: messageError > message > statusError + const messageDetails = messageError || message || statusError; + + showError(`${moduleName} returns status code: ${status} - ${messageDetails}.`); + }; + return { showErrorMessage, + showExternalModuleError, }; }; diff --git a/src/hooks/useErrorMessages.test.js b/src/hooks/useErrorMessages.test.js index 6926c47d..cd381eeb 100644 --- a/src/hooks/useErrorMessages.test.js +++ b/src/hooks/useErrorMessages.test.js @@ -2,7 +2,7 @@ import { renderHook } from '@testing-library/react-hooks'; import { useIntl } from 'react-intl'; import { useShowCallout } from '@folio/stripes-acq-components'; import { useErrorMessages } from './useErrorMessages'; -import { ERRORS } from '../constants'; +import { ERROR_STATUSES, ERRORS } from '../constants'; jest.mock('react-intl', () => ({ useIntl: jest.fn(), @@ -115,4 +115,87 @@ describe('useErrorMessages', () => { message: 'ui-bulk-edit.error.incorrectFormatted.testFileName', }); }); + + describe('showExternalModuleError', () => { + it('should show an error message using the status code if message not provided', () => { + const { result } = renderHook(() => useErrorMessages()); + + result.current.showExternalModuleError('TestModule', { status: 404 }); + + expect(showCalloutMock) + .toHaveBeenCalledWith({ + type: 'error', + message: `TestModule returns status code: 404 - ${ERROR_STATUSES[404]}.`, + }); + }); + + it('should show an error message using the "message" property if it exists', () => { + const { result } = renderHook(() => useErrorMessages()); + + const errorMessage = 'Something went wrong'; + result.current.showExternalModuleError('TestModule', { message: errorMessage }); + + expect(showCalloutMock) + .toHaveBeenCalledWith({ + type: 'error', + message: `TestModule returns status code: 500 - ${errorMessage}.`, + }); + }); + + it('should show an error message using the message if message corresponds to a known status string', () => { + const { result } = renderHook(() => useErrorMessages()); + + const errorMessage = 'Not Found'; + result.current.showExternalModuleError('TestModule', { + status: 403, + message: errorMessage + }); + + expect(showCalloutMock) + .toHaveBeenCalledWith({ + type: 'error', + message: 'TestModule returns status code: 403 - Not Found.', + }); + }); + + it('should show a generic status error message if neither a valid message nor a recognized message key is provided', () => { + const { result } = renderHook(() => useErrorMessages()); + + result.current.showExternalModuleError('TestModule', { status: 418 }); + + expect(showCalloutMock) + .toHaveBeenCalledWith({ + type: 'error', + message: `TestModule returns status code: 418 - ${ERROR_STATUSES[418]}.`, + }); + }); + + it('should default to 500 if no status is provided and message is empty', () => { + const { result } = renderHook(() => useErrorMessages()); + + result.current.showExternalModuleError('TestModule', {}); + + expect(showCalloutMock) + .toHaveBeenCalledWith({ + type: 'error', + message: `TestModule returns status code: 500 - ${ERROR_STATUSES[500]}.`, + }); + }); + + it('should handle a scenario where the module returns a non-standard error message', () => { + const { result } = renderHook(() => useErrorMessages()); + + const nonStandardMessage = 'Custom module error occurred'; + result.current.showExternalModuleError('TestModule', { + status: 501, + message: nonStandardMessage + }); + + expect(showCalloutMock) + .toHaveBeenCalledWith({ + type: 'error', + message: `TestModule returns status code: 501 - ${nonStandardMessage}.`, + }); + }); + }); }); diff --git a/src/hooks/usePublishCoordinator.js b/src/hooks/usePublishCoordinator.js index 60de5116..eb5b2790 100644 --- a/src/hooks/usePublishCoordinator.js +++ b/src/hooks/usePublishCoordinator.js @@ -9,6 +9,9 @@ import { useStripes, } from '@folio/stripes/core'; +import { MOD_CONSORTIA } from '../constants'; +import { useErrorMessages } from './useErrorMessages'; + export const PUBLISH_COORDINATOR_STATUSES = { COMPLETE: 'COMPLETE', ERROR: 'ERROR', @@ -44,6 +47,7 @@ export const usePublishCoordinator = (namespace, options = {}) => { const ky = useOkapiKy(); const stripes = useStripes(); const abortController = useRef(new AbortController()); + const { showExternalModuleError } = useErrorMessages(); const consortium = stripes.user?.user?.consortium; const baseApi = `${CONSORTIA_API}/${consortium?.id}/${PUBLICATIONS_API}`; @@ -51,7 +55,8 @@ export const usePublishCoordinator = (namespace, options = {}) => { const getPublicationResults = useCallback((id, { signal }) => { return ky.get(`${baseApi}/${id}/results`, { signal }) .json() - .then(formatPublicationResult); + .then(formatPublicationResult) + .catch((error) => showExternalModuleError(MOD_CONSORTIA, error)); }, [ky, baseApi]); const getPublicationDetails = useCallback(async (requestId, { signal } = {}) => { @@ -83,7 +88,8 @@ export const usePublishCoordinator = (namespace, options = {}) => { return ky.post(baseApi, { json, signal }) .json() - .then(res => getPublicationResponse(res, { signal })); + .then(res => getPublicationResponse(res, { signal })) + .catch((error) => showExternalModuleError(MOD_CONSORTIA, error)); }, [baseApi, getPublicationResponse, ky, options.signal]); return { diff --git a/src/hooks/usePublishCoordinator.test.js b/src/hooks/usePublishCoordinator.test.js index 0c8f5293..050c0cb1 100644 --- a/src/hooks/usePublishCoordinator.test.js +++ b/src/hooks/usePublishCoordinator.test.js @@ -18,6 +18,10 @@ import { PUBLISH_COORDINATOR_STATUSES } from './usePublishCoordinator'; +jest.mock('./useErrorMessages', () => ({ + useErrorMessages: jest.fn().mockReturnValue({ showExternalModuleError: jest.fn() }), +})); + const queryClient = new QueryClient(); // eslint-disable-next-line react/prop-types