Skip to content

Commit

Permalink
Add reusable custom hook useVersionHistoryValueResolvers (#839)
Browse files Browse the repository at this point in the history
* Add reusable custom hook useVersionHistoryValueResolvers to display proper object property and user full name

* Use testing-library/react-hooks

* Add change log

* Move useVersionHistoryValueResolvers to VersionHistory hooks

* Move comment to the bottom of the list
  • Loading branch information
azizjonnurov authored Dec 6, 2024
1 parent 03b5d13 commit a6b569e
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions lib/VersionHistory/hooks/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { useVersionsDifference } from './useVersionsDifference';
export { useVersionWrappedFormatter } from './useVersionWrappedFormatter';
export { useVersionHistoryValueResolvers } from './useVersionHistoryValueResolvers';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { useVersionHistoryValueResolvers } from './useVersionHistoryValueResolvers';
Original file line number Diff line number Diff line change
@@ -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 };
};
Original file line number Diff line number Diff line change
@@ -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');
});
});

0 comments on commit a6b569e

Please sign in to comment.