Expose metadata as object from useProductMetadata hook (#43860)

* Add useParentMetadata hook

* Move functionality to existing useProductMetadata hook

* Update changelog

* Remove deleted hook from index

* Update useProductMetadata API and unit tests
This commit is contained in:
Nathan Silveira 2024-01-23 17:50:36 -03:00 committed by GitHub
parent 80b4ec13e3
commit c7d4c88270
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 113 additions and 48 deletions

View File

@ -0,0 +1,4 @@
Significance: minor
Type: add
Expose metadata as object from useProductMetadata hook

View File

@ -10,24 +10,36 @@ import useProductMetadata from '../use-product-metadata';
const mockFnMetadataProp = jest.fn();
jest.mock( '@wordpress/core-data', () => ( {
useEntityProp: jest.fn().mockImplementation( () => {
return [
[
{
key: 'field1',
value: 'value1',
},
{
key: 'field2',
value: 'value1',
},
{
key: 'existing_field',
value: 'value1',
},
],
mockFnMetadataProp,
];
useEntityId: jest.fn().mockReturnValue( 123 ),
} ) );
jest.mock( '@wordpress/data', () => ( {
useSelect: jest.fn().mockImplementation( ( callback ) => {
return callback(
jest.fn().mockReturnValue( {
getEditedEntityRecord: () => ( {
meta_data: [
{
key: 'field1',
value: 'value1',
},
{
key: 'field2',
value: 'value1',
},
{
key: 'existing_field',
value: 'value1',
},
],
} ),
} )
);
} ),
useDispatch: jest.fn().mockImplementation( () => {
return {
editEntityRecord: mockFnMetadataProp,
};
} ),
} ) );
@ -45,19 +57,36 @@ describe( 'useProductMetadata', () => {
value: 'value2',
},
] );
expect( mockFnMetadataProp ).toHaveBeenCalledWith( [
expect( mockFnMetadataProp ).toHaveBeenCalledWith(
'postType',
'product',
123,
{
key: 'existing_field',
value: 'value1',
},
{
key: 'field1',
value: 'value2',
},
{
key: 'field2',
value: 'value2',
},
] );
meta_data: [
{
key: 'existing_field',
value: 'value1',
},
{
key: 'field1',
value: 'value2',
},
{
key: 'field2',
value: 'value2',
},
],
}
);
} );
it( 'should return the metadata as an object for easy readings', async () => {
const { metadata } = renderHook( () =>
useProductMetadata( { postType: 'product', id: 123 } )
).result.current;
expect( metadata ).toEqual( {
field1: 'value1',
field2: 'value1',
existing_field: 'value1',
} );
} );
} );

View File

@ -1,30 +1,62 @@
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore No types for this exist yet.
// eslint-disable-next-line @woocommerce/dependency-group
import { useEntityId } from '@wordpress/core-data';
/**
* External dependencies
*/
import { useEntityProp } from '@wordpress/core-data';
import { useDispatch, useSelect } from '@wordpress/data';
import { Product } from '@woocommerce/data';
/**
* Internal dependencies
*/
import { Metadata } from '../types';
function useProductMetadata( postType?: string ) {
const [ metadata, setMetadata ] = useEntityProp< Metadata< string >[] >(
'postType',
postType || 'product',
'meta_data'
);
interface Options {
postType?: string;
id?: number;
}
return {
updateMetadata: ( entries: Metadata< string >[] ) => {
setMetadata( [
...metadata.filter(
( item ) =>
entries.findIndex( ( e ) => e.key === item.key ) === -1
),
...entries,
] );
function useProductMetadata( options?: Options ) {
const postType = options?.postType || 'product';
const thisId = useEntityId( 'postType', postType );
const id = options?.id || thisId;
// @ts-expect-error There are no types for this.
const { editEntityRecord } = useDispatch( 'core' );
return useSelect(
( select ) => {
// @ts-expect-error There are no types for this.
const { getEditedEntityRecord } = select( 'core' );
const { meta_data: metadata }: Product = getEditedEntityRecord(
'postType',
postType,
id
);
return {
metadata: metadata.reduce( function ( acc, cur ) {
acc[ cur.key ] = cur.value;
return acc;
}, {} as Record< string, string | undefined > ),
updateMetadata: ( entries: Metadata< string >[] ) => {
editEntityRecord( 'postType', postType, id, {
meta_data: [
...metadata.filter(
( item ) =>
entries.findIndex(
( e ) => e.key === item.key
) === -1
),
...entries,
],
} );
},
};
},
};
[ id ]
);
}
export default useProductMetadata;