Skip to content

Commit

Permalink
[RNMobile] Add WP hook for registering non-core blocks (#52791)
Browse files Browse the repository at this point in the history
* Add WP hook action for registering non-core blocks

The idea of this hook is to allow non-core blocks to be registered right after the core blocks.

* Remove unused `native.render` WP hook

* Add test case to cover WP hook `post-register-core-blocks`
  • Loading branch information
fluiddot committed Jul 20, 2023
1 parent f45e825 commit 6b1a268
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 30 deletions.
5 changes: 0 additions & 5 deletions packages/react-native-editor/src/index.js
Expand Up @@ -60,11 +60,6 @@ const registerGutenberg = ( {
);
}

componentDidMount() {
// Dispatch post-render hooks.
doAction( 'native.render', this.filteredProps );
}

render() {
return cloneElement( this.editorComponent, this.filteredProps );
}
Expand Down
4 changes: 3 additions & 1 deletion packages/react-native-editor/src/setup.js
Expand Up @@ -7,7 +7,7 @@ import { I18nManager, LogBox } from 'react-native';
* WordPress dependencies
*/
import { unregisterBlockType, getBlockType } from '@wordpress/blocks';
import { addAction, addFilter } from '@wordpress/hooks';
import { addAction, addFilter, doAction } from '@wordpress/hooks';
import * as wpData from '@wordpress/data';
import { registerCoreBlocks } from '@wordpress/block-library';
// eslint-disable-next-line no-restricted-imports
Expand Down Expand Up @@ -70,6 +70,8 @@ const setupInitHooks = () => {
) {
unregisterBlockType( 'core/block' );
}

doAction( 'native.post-register-core-blocks', props );
} );

// Map native props to Editor props
Expand Down
62 changes: 38 additions & 24 deletions packages/react-native-editor/src/test/index.test.js
Expand Up @@ -8,6 +8,9 @@ import { initializeEditor, render } from 'test/helpers';
* WordPress dependencies
*/
import * as wpHooks from '@wordpress/hooks';
import { registerCoreBlocks } from '@wordpress/block-library';
// eslint-disable-next-line no-restricted-imports
import * as wpEditPost from '@wordpress/edit-post';
import '@wordpress/jest-console';

/**
Expand All @@ -18,6 +21,11 @@ import setupLocale from '../setup-locale';

jest.mock( 'react-native/Libraries/ReactNative/AppRegistry' );
jest.mock( '../setup-locale' );
jest.mock( '@wordpress/block-library', () => ( {
__esModule: true,
registerCoreBlocks: jest.fn(),
NEW_BLOCK_TYPES: {},
} ) );

const getEditorComponent = ( registerParams ) => {
let EditorComponent;
Expand Down Expand Up @@ -150,50 +158,56 @@ describe( 'Register Gutenberg', () => {
expect( hookCallOrder ).toBeLessThan( onRenderEditorCallOrder );
} );

it( 'dispatches "native.render" hook after the editor is rendered', () => {
const doAction = jest.spyOn( wpHooks, 'doAction' );

it( 'dispatches "native.post-register-core-blocks" hook after core blocks are registered', async () => {
// An empty component is provided in order to listen for render calls of the editor component.
const onRenderEditor = jest.fn();
const MockEditor = () => {
onRenderEditor();
return null;
};
jest.mock( '../setup', () => ( {
__esModule: true,
default: jest.fn().mockReturnValue( <MockEditor /> ),
} ) );

// Unmock setup module to render the above mocked editor component.
jest.unmock( '../setup' );

// The mocked editor component is provided via `initializeEditor` function of
// `@wordpress/edit-post` package, instead of via the setup as above test cases.
const initializeEditorMock = jest
.spyOn( wpEditPost, 'initializeEditor' )
.mockReturnValue( <MockEditor /> );

// Listen to WP hook
const callback = jest.fn();
wpHooks.addAction(
'native.post-register-core-blocks',
'test',
callback
);

const EditorComponent = getEditorComponent();
// Modules are isolated upon editor rendering in order to guarantee that the setup module is imported on every test.
jest.isolateModules( () => render( <EditorComponent /> ) );
render( <EditorComponent /> );

const hookCallIndex = 1;
// "invocationCallOrder" can be used to compare call orders between different mocks.
// Reference: https://github.com/facebook/jest/issues/4402#issuecomment-534516219
const hookCallOrder =
doAction.mock.invocationCallOrder[ hookCallIndex ];
const callbackCallOrder = callback.mock.invocationCallOrder[ 0 ];
const registerCoreBlocksCallOrder =
registerCoreBlocks.mock.invocationCallOrder[ 0 ];
const onRenderEditorCallOrder =
onRenderEditor.mock.invocationCallOrder[ 0 ];
const hookName = doAction.mock.calls[ hookCallIndex ][ 0 ];

expect( hookName ).toBe( 'native.render' );
expect( hookCallOrder ).toBeGreaterThan( onRenderEditorCallOrder );
expect( callbackCallOrder ).toBeGreaterThan(
registerCoreBlocksCallOrder
);
expect( callbackCallOrder ).toBeLessThan( onRenderEditorCallOrder );
expect( console ).toHaveLoggedWith( 'Hermes is: true' );

initializeEditorMock.mockRestore();
} );

it( 'initializes the editor', async () => {
// Unmock setup module to render the actual editor component.
jest.unmock( '../setup' );

const EditorComponent = getEditorComponent();
const screen = await initializeEditor(
{},
{ component: EditorComponent }
);
const screen = await initializeEditor();
// Inner blocks create BlockLists so let's take into account selecting the main one
const blockList = screen.getAllByTestId( 'block-list-wrapper' )[ 0 ];

expect( blockList ).toBeVisible();
expect( console ).toHaveLoggedWith( 'Hermes is: true' );
} );
} );

0 comments on commit 6b1a268

Please sign in to comment.