Skip to content

Commit

Permalink
Block Directory: Fix the block activation when metadata registered on…
Browse files Browse the repository at this point in the history
… server (#38697)

* Block Directory: Fix the block activation when metadata registered only on server

* Add proper mocking for Block Directory unit tests

* Handle the case when the block is not registered on the server

* Use `_fields` with REST API call and `pick` to filter response
  • Loading branch information
gziolo committed Feb 11, 2022
1 parent 64abb70 commit 8c1c614
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 11 deletions.
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/block-directory/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"@wordpress/icons": "file:../icons",
"@wordpress/notices": "file:../notices",
"@wordpress/plugins": "file:../plugins",
"@wordpress/url": "file:../url",
"lodash": "^4.17.21"
},
"publishConfig": {
Expand Down
48 changes: 45 additions & 3 deletions packages/block-directory/src/store/actions.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
/**
* External dependencies
*/
import { pick } from 'lodash';

/**
* WordPress dependencies
*/
import { store as blocksStore } from '@wordpress/blocks';
import {
store as blocksStore,
unstable__bootstrapServerSideBlockDefinitions, // eslint-disable-line camelcase
} from '@wordpress/blocks';
import { __, sprintf } from '@wordpress/i18n';
import apiFetch from '@wordpress/api-fetch';
import { store as noticesStore } from '@wordpress/notices';
import { addQueryArgs } from '@wordpress/url';

/**
* Internal dependencies
Expand Down Expand Up @@ -52,7 +61,7 @@ export const installBlockType = ( block ) => async ( {
registry,
dispatch,
} ) => {
const { id } = block;
const { id, name } = block;
let success = false;
dispatch.clearErrorNotice( id );
try {
Expand Down Expand Up @@ -82,9 +91,42 @@ export const installBlockType = ( block ) => async ( {
links: { ...block.links, ...links },
} );

// Ensures that the block metadata is propagated to the editor when registered on the server.
const metadataFields = [
'api_version',
'title',
'category',
'parent',
'icon',
'description',
'keywords',
'attributes',
'provides_context',
'uses_context',
'supports',
'styles',
'example',
'variations',
];
await apiFetch( {
path: addQueryArgs( `/wp/v2/block-types/${ name }`, {
_fields: metadataFields,
} ),
} )
// Ignore when the block is not registered on the server.
.catch( () => {} )
.then( ( response ) => {
if ( ! response ) {
return;
}
unstable__bootstrapServerSideBlockDefinitions( {
[ name ]: pick( response, metadataFields ),
} );
} );

await loadAssets();
const registeredBlocks = registry.select( blocksStore ).getBlockTypes();
if ( ! registeredBlocks.some( ( i ) => i.name === block.name ) ) {
if ( ! registeredBlocks.some( ( i ) => i.name === name ) ) {
throw new Error(
__( 'Error registering block. Try reloading the page.' )
);
Expand Down
22 changes: 15 additions & 7 deletions packages/block-directory/src/store/test/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ describe( 'actions', () => {
},
};

const blockTypePath = '/wp/v2/block-types/block/block';
const blockTypeResponse = {
name: 'block/block',
title: 'Test Block',
};

describe( 'installBlockType', () => {
it( 'should install a block successfully', async () => {
const registry = createRegistryWithStores();
Expand All @@ -84,6 +90,8 @@ describe( 'actions', () => {
switch ( path ) {
case 'wp/v2/plugins':
return pluginResponse;
case blockTypePath:
return blockTypeResponse;
default:
throw new Error( `unexpected API endpoint: ${ path }` );
}
Expand Down Expand Up @@ -121,14 +129,14 @@ describe( 'actions', () => {
const registry = createRegistryWithStores();

// mock the api-fetch and load-assets modules
apiFetch.mockImplementation( async ( p ) => {
const { url } = p;
switch ( url ) {
case pluginEndpoint:
return pluginResponse;
default:
throw new Error( `unexpected API endpoint: ${ url }` );
apiFetch.mockImplementation( async ( { path, url } ) => {
if ( path === blockTypePath ) {
return blockTypeResponse;
}
if ( url === pluginEndpoint ) {
return pluginResponse;
}
throw new Error( `unexpected API endpoint: ${ url }` );
} );

loadAssets.mockImplementation( loadAssetsMock( registry ) );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,29 @@ import {
createJSONResponse,
} from '@wordpress/e2e-test-utils';

const BLOCK1_NAME = 'block-directory-test-block/main-block';

// Urls to mock
const SEARCH_URLS = [
'/wp/v2/block-directory/search',
`rest_route=${ encodeURIComponent( '/wp/v2/block-directory/search' ) }`,
];

const BLOCK_TYPE_URLS = [
`/wp/v2/block-types/${ BLOCK1_NAME }`,
`rest_route=${ encodeURIComponent(
`/wp/v2/block-types/${ BLOCK1_NAME }`
) }`,
];

const INSTALL_URLS = [
'/wp/v2/plugins',
`rest_route=${ encodeURIComponent( '/wp/v2/plugins' ) }`,
];

// Example Blocks
const MOCK_BLOCK1 = {
name: 'block-directory-test-block/main-block',
name: BLOCK1_NAME,
title: 'Block Directory Test Block',
description: 'This plugin is useful for the block.',
id: 'block-directory-test-block',
Expand Down Expand Up @@ -109,6 +118,11 @@ const MOCK_BLOCKS_RESPONSES = [
request.method() === 'GET',
onRequestMatch: createJSONResponse( [ MOCK_BLOCK1, MOCK_BLOCK2 ] ),
},
{
// Mock response for block type
match: ( request ) => matchUrl( request.url(), BLOCK_TYPE_URLS ),
onRequestMatch: createJSONResponse( {} ),
},
{
// Mock response for install
match: ( request ) => matchUrl( request.url(), INSTALL_URLS ),
Expand Down

0 comments on commit 8c1c614

Please sign in to comment.