diff --git a/CHANGELOG.md b/CHANGELOG.md index 773d0fd5..6a109361 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * Add more reusable hooks and utilities. Refs UISACQCOMP-228. * Move reusable version history components to the ACQ lib. Refs UISACQCOMP-230. * Move reusable helper function to support version history functionality. Refs UISACQCOMP-232. +* Move reusable version history hook useVersionHistoryValueResolvers to the ACQ lib. Refs UISACQCOMP-235. ## [6.0.2](https://github.com/folio-org/stripes-acq-components/tree/v6.0.2) (2024-12-04) [Full Changelog](https://github.com/folio-org/stripes-acq-components/compare/v6.0.1...v6.0.2) diff --git a/lib/VersionHistory/hooks/index.js b/lib/VersionHistory/hooks/index.js index 9f8aaabe..5fae4281 100644 --- a/lib/VersionHistory/hooks/index.js +++ b/lib/VersionHistory/hooks/index.js @@ -1,2 +1,3 @@ export { useVersionsDifference } from './useVersionsDifference'; export { useVersionWrappedFormatter } from './useVersionWrappedFormatter'; +export { useVersionHistoryValueResolvers } from './useVersionHistoryValueResolvers'; diff --git a/lib/VersionHistory/hooks/useVersionHistoryValueResolvers/index.js b/lib/VersionHistory/hooks/useVersionHistoryValueResolvers/index.js new file mode 100644 index 00000000..eb0b0fb7 --- /dev/null +++ b/lib/VersionHistory/hooks/useVersionHistoryValueResolvers/index.js @@ -0,0 +1 @@ +export { useVersionHistoryValueResolvers } from './useVersionHistoryValueResolvers'; diff --git a/lib/VersionHistory/hooks/useVersionHistoryValueResolvers/useVersionHistoryValueResolvers.js b/lib/VersionHistory/hooks/useVersionHistoryValueResolvers/useVersionHistoryValueResolvers.js new file mode 100644 index 00000000..a74fb7f0 --- /dev/null +++ b/lib/VersionHistory/hooks/useVersionHistoryValueResolvers/useVersionHistoryValueResolvers.js @@ -0,0 +1,42 @@ +/* Developed collaboratively using AI (Chat GPT) */ + +import { useIntl } from 'react-intl'; + +import { getFullName } from '@folio/stripes/util'; + +export const useVersionHistoryValueResolvers = () => { + const intl = useIntl(); + const deletedRecordLabel = intl.formatMessage({ id: 'stripes-acq-components.versionHistory.deletedRecord' }); + + /** + * Resolves a value from a map by ID and property. + * @param {string} id - The ID to resolve. + * @param {string} property - The property to retrieve from the map entry. + * @param {Object} obj - The map object containing items. + * @returns {string | null} - Resolved value or fallback label. + */ + const getObjectPropertyById = (id, property, obj = {}) => { + if (!id) return null; + if (id in obj) { + return obj[id]?.[property] || null; + } + + return deletedRecordLabel; + }; + + /** + * Resolves a user's full name by ID using a users map. + * @param {string} id - The user ID to resolve. + * @param {Object} usersMap - The map of user objects. + * @returns {string | null} - Full name of the user or fallback label. + */ + const getUserFullNameById = (id, usersMap = {}) => { + if (!id) return null; + + return id in usersMap + ? getFullName(usersMap[id]) + : deletedRecordLabel; + }; + + return { getObjectPropertyById, getUserFullNameById }; +}; diff --git a/lib/VersionHistory/hooks/useVersionHistoryValueResolvers/useVersionHistoryValueResolvers.test.js b/lib/VersionHistory/hooks/useVersionHistoryValueResolvers/useVersionHistoryValueResolvers.test.js new file mode 100644 index 00000000..38c88091 --- /dev/null +++ b/lib/VersionHistory/hooks/useVersionHistoryValueResolvers/useVersionHistoryValueResolvers.test.js @@ -0,0 +1,91 @@ +/* Developed collaboratively using AI (Chat GPT) */ + +import { renderHook } from '@testing-library/react-hooks'; +import { useIntl } from 'react-intl'; + +import { getFullName } from '@folio/stripes/util'; + +import { useVersionHistoryValueResolvers } from './useVersionHistoryValueResolvers'; + +jest.mock('react-intl', () => ({ + useIntl: jest.fn(), +})); + +jest.mock('@folio/stripes/util', () => ({ + getFullName: jest.fn(), +})); + +describe('useVersionHistoryValueResolvers', () => { + let intlMock; + + beforeEach(() => { + intlMock = { + formatMessage: jest.fn(({ id }) => id), + }; + useIntl.mockReturnValue(intlMock); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should return object property by ID if ID and property exist in the map', () => { + const { result } = renderHook(() => useVersionHistoryValueResolvers()); + + const obj = { + id1: { property1: 'value1', property2: 'value2' }, + id2: { property1: 'value3' }, + }; + + const value = result.current.getObjectPropertyById('id1', 'property1', obj); + + expect(value).toBe('value1'); + }); + + it('should return null when ID is not provided', () => { + const { result } = renderHook(() => useVersionHistoryValueResolvers()); + const obj = { id1: { property1: 'value1' } }; + + const value = result.current.getObjectPropertyById(null, 'property1', obj); + + expect(value).toBeNull(); + }); + + it('should return deletedRecordLabel when ID is not found in the object', () => { + const { result } = renderHook(() => useVersionHistoryValueResolvers()); + + const obj = { id1: { property1: 'value1' } }; + const value = result.current.getObjectPropertyById('id2', 'property1', obj); + + expect(value).toBe('stripes-acq-components.versionHistory.deletedRecord'); + }); + + it('should return null when ID is not provided for getUserFullNameById', () => { + const { result } = renderHook(() => useVersionHistoryValueResolvers()); + const usersMap = { user1: { firstName: 'John', lastName: 'Doe' } }; + + const value = result.current.getUserFullNameById(null, usersMap); + + expect(value).toBeNull(); + }); + + it('should return user full name by ID using the users map', () => { + getFullName.mockReturnValue('John Doe'); + const { result } = renderHook(() => useVersionHistoryValueResolvers()); + + const usersMap = { user1: { firstName: 'John', lastName: 'Doe' } }; + const value = result.current.getUserFullNameById('user1', usersMap); + + expect(getFullName).toHaveBeenCalledWith(usersMap.user1); + expect(value).toBe('John Doe'); + }); + + it('should return deletedRecordLabel when ID is not found in the users map', () => { + const { result } = renderHook(() => useVersionHistoryValueResolvers()); + + const usersMap = { user1: { firstName: 'John', lastName: 'Doe' } }; + const value = result.current.getUserFullNameById('user2', usersMap); + + expect(value).toBe('stripes-acq-components.versionHistory.deletedRecord'); + }); +});