diff --git a/plugins/woocommerce-admin/packages/data/src/user-preferences/test/use-user-preferences.js b/plugins/woocommerce-admin/packages/data/src/user-preferences/test/use-user-preferences.js index c892c11599b..6f4e210b40d 100644 --- a/plugins/woocommerce-admin/packages/data/src/user-preferences/test/use-user-preferences.js +++ b/plugins/woocommerce-admin/packages/data/src/user-preferences/test/use-user-preferences.js @@ -213,4 +213,95 @@ describe( 'useUserPreferences() hook', () => { } ); } ); } ); + + it( 'Polyfills saveUser() on older versions of WordPress', async () => { + const receiveCurrentUser = jest.fn().mockReturnValue( { + type: 'RECEIVE_CURRENT_USER', + currentUser: { + id: 1, + woocommerce_meta: { + revenue_report_columns: '["shipping"]', + }, + }, + } ); + const addEntities = jest.fn().mockReturnValue( { + type: 'BOGUG_ADD_ENTITIES', + } ); + const saveEntityRecord = jest.fn().mockReturnValue( { + type: 'BOGUG_SAVE_ENTITY_RECORD', + } ); + registerStore( 'core', { + reducer: () => ( {} ), + selectors: { + getCurrentUser: jest.fn().mockReturnValue( { + id: 1, + } ), + getEntity: jest + .fn() + .mockReturnValueOnce( undefined ) + .mockReturnValueOnce( { name: 'user', kind: 'root' } ), + getEntityRecord: jest.fn().mockReturnValue( { + id: 1, + woocommerce_meta: { + revenue_report_columns: '["shipping"]', + }, + } ), + getLastEntitySaveError: jest.fn().mockReturnValue( {} ), + hasStartedResolution: jest.fn().mockReturnValue( true ), + hasFinishedResolution: jest.fn().mockReturnValue( true ), + }, + actions: { + addEntities, + receiveCurrentUser, + saveEntityRecord, + // saveUser() left undefined to simulate WP 5.3.x. + }, + } ); + + const { result } = renderHook( () => useUserPreferences() ); + + await act( async () => { + const firstResult = await result.current.updateUserPreferences( { + revenue_report_columns: [ 'shipping' ], + } ); + + // First calls should register the User entity. + expect( addEntities ).toHaveBeenCalledWith( [ + { + name: 'user', + kind: 'root', + baseURL: '/wp/v2/users', + plural: 'users', + }, + ] ); + + expect( saveEntityRecord ).toHaveBeenCalledWith( 'root', 'user', { + id: 1, + woocommerce_meta: { revenue_report_columns: '["shipping"]' }, + } ); + expect( receiveCurrentUser ).toHaveBeenCalled(); + expect( firstResult ).toMatchObject( { + updatedUser: { + id: 1, + woocommerce_meta: { + revenue_report_columns: [ 'shipping' ], + }, + }, + } ); + + await result.current.updateUserPreferences( { + revenue_report_columns: [ 'shipping', 'taxes' ], + } ); + + // Subsequent calls should NOT register the User entity. + expect( addEntities ).toHaveBeenCalledTimes( 1 ); + + expect( saveEntityRecord ).toHaveBeenCalledWith( 'root', 'user', { + id: 1, + woocommerce_meta: { + revenue_report_columns: '["shipping","taxes"]', + }, + } ); + } ); + } ); } ); diff --git a/plugins/woocommerce-admin/packages/data/src/user-preferences/use-user-preferences.js b/plugins/woocommerce-admin/packages/data/src/user-preferences/use-user-preferences.js index 33d3981615c..3551670af85 100644 --- a/plugins/woocommerce-admin/packages/data/src/user-preferences/use-user-preferences.js +++ b/plugins/woocommerce-admin/packages/data/src/user-preferences/use-user-preferences.js @@ -35,17 +35,49 @@ const getWooCommerceMeta = ( user ) => { */ export const useUserPreferences = () => { // Get our dispatch methods now - this can't happen inside the callback below. - const { receiveCurrentUser, saveUser } = useDispatch( STORE_NAME ); + const dispatch = useDispatch( STORE_NAME ); + const { addEntities, receiveCurrentUser, saveEntityRecord } = dispatch; + let { saveUser } = dispatch; const { isRequesting, userPreferences, updateUserPreferences } = useSelect( ( select ) => { const { getCurrentUser, + getEntity, + getEntityRecord, getLastEntitySaveError, hasStartedResolution, hasFinishedResolution, } = select( STORE_NAME ); + // WP 5.3.x doesn't have the User entity defined. + if ( typeof saveUser !== 'function' ) { + // Polyfill saveUser() - wrapper of saveEntityRecord. + saveUser = async ( userToSave ) => { + const entityDefined = Boolean( + getEntity( 'root', 'user' ) + ); + + if ( ! entityDefined ) { + // Add the User entity so saveEntityRecord works. + await addEntities( [ + { + name: 'user', + kind: 'root', + baseURL: '/wp/v2/users', + plural: 'users', + }, + ] ); + } + + // Fire off the save action. + await saveEntityRecord( 'root', 'user', userToSave ); + + // Respond with the updated user. + return getEntityRecord( 'root', 'user', userToSave.id ); + }; + } + // Use getCurrentUser() to get WooCommerce meta values. const user = getCurrentUser(); const userData = getWooCommerceMeta( user );