Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block Directory: Fix the block activation when metadata registered on server #38697

Merged
merged 4 commits into from
Feb 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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