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: Store refactor #22388

Merged
merged 31 commits into from
May 25, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
48264f9
Pass along action parameter
ryelle May 13, 2020
d919284
Fix up comments
ryelle May 13, 2020
ba7f537
Use shared package `data-controls`
ryelle May 13, 2020
effc1d9
Remove `uninstallBlock`, `removeInstalledBlockType`
ryelle May 14, 2020
bcf7ffa
Update controls to return promises
ryelle May 15, 2020
9262fbb
Update response format from API
ryelle May 15, 2020
8b8df1f
Refactor install & download into one single, multi-step action generator
ryelle May 15, 2020
54d41d6
Switch to new action generator for installation
ryelle May 15, 2020
4ea7785
Update Notice reducer to store the notice text
ryelle May 15, 2020
d08fd13
Bring `onSelect` functionality back
ryelle May 15, 2020
b2b9733
Fix notice description
ryelle May 15, 2020
6a509b9
Switch to `useDispatch` hook
ryelle May 15, 2020
335fb87
Update packages/block-directory/src/store/controls.js
ryelle May 18, 2020
0cc38e2
Remove extra export
ryelle May 19, 2020
4bbf4a4
Remove unnecessary resets
ryelle May 19, 2020
ebb5406
Update variable name to reflect value
ryelle May 19, 2020
25a035b
Add test to block list item
ryelle May 19, 2020
4c42c45
Remove unused props
ryelle May 19, 2020
04966be
Remove behavior test, update to use snapshot testing
ryelle May 19, 2020
84024be
Update notice block to use `useSelect`
ryelle May 19, 2020
69bd598
Update package-lock
ryelle May 19, 2020
b635202
Check file extension before trying to load scripts & styles
ryelle May 19, 2020
f0c2790
Fix class name
ryelle May 19, 2020
966e2fc
Bring back `setIsInstalling`
ryelle May 19, 2020
f7aca00
Add i18n & punctuation to error messages
ryelle May 20, 2020
4dddbe0
Add a default error message
ryelle May 20, 2020
35d65e7
Return a success/failure indicator for installation
ryelle May 20, 2020
884a473
Remove unused state property, update tests
ryelle May 22, 2020
01cb9b4
Add selector tests for `getDownloadableBlocks`
ryelle May 22, 2020
4c406fc
Update mocked API response
ryelle May 22, 2020
4dee597
Add default message for installation failures
ryelle May 25, 2020
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
2 changes: 1 addition & 1 deletion lib/class-wp-rest-block-directory-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ public function install_block( $request ) {
return WP_Error( $activate_result->get_error_code(), $activate_result->get_error_message() );
}

return rest_ensure_response( true );
return rest_ensure_response( array( 'success' => true ) );
}

/**
Expand Down
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 @@ -31,6 +31,7 @@
"@wordpress/components": "file:../components",
"@wordpress/compose": "file:../compose",
"@wordpress/data": "file:../data",
"@wordpress/data-controls": "file:../data-controls",
"@wordpress/element": "file:../element",
"@wordpress/i18n": "file:../i18n",
"@wordpress/icons": "file:../icons",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`DownloadableBlockListItem should render a block item 1`] = `
<li
className="block-directory-downloadable-block-list-item"
>
<article
className="block-directory-downloadable-block-list-item__panel"
>
<header
className="block-directory-downloadable-block-list-item__header"
>
<WithSelect(DownloadableBlockHeader)
icon="block-default"
onClick={[MockFunction]}
rating={5}
title="Boxer"
/>
</header>
<section
className="block-directory-downloadable-block-list-item__body"
>
<DownloadableBlockNotice
block={
Object {
"active_installs": 0,
"assets": Array [
"http://plugins.svn.wordpress.org/boxer-block/trunk/build/index.js",
"http://plugins.svn.wordpress.org/boxer-block/trunk/build/view.js",
],
"author": "CK Lee",
"author_block_count": "1",
"author_block_rating": 5,
"description": "Boxer is a Block that puts your WordPress posts into boxes on a page.",
"humanized_updated": "3 months ago",
"icon": "block-default",
"id": "boxer-block",
"name": "boxer/boxer",
"rating": 5,
"rating_count": 1,
"title": "Boxer",
}
}
onClick={[MockFunction]}
/>
<DownloadableBlockInfo
description="Boxer is a Block that puts your WordPress posts into boxes on a page."
/>
</section>
<footer
className="block-directory-downloadable-block-list-item__footer"
>
<DownloadableBlockAuthorInfo
author="CK Lee"
/>
</footer>
</article>
</li>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export const item = {
name: 'boxer/boxer',
title: 'Boxer',
description:
'Boxer is a Block that puts your WordPress posts into boxes on a page.',
id: 'boxer-block',
icon: 'block-default',
rating: 5,
rating_count: 1,
active_installs: 0,
author_block_rating: 5,
author_block_count: '1',
author: 'CK Lee',
assets: [
'http://plugins.svn.wordpress.org/boxer-block/trunk/build/index.js',
'http://plugins.svn.wordpress.org/boxer-block/trunk/build/view.js',
],
humanized_updated: '3 months ago',
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* External dependencies
*/
import { shallow } from 'enzyme';

/**
* Internal dependencies
*/
import DownloadableBlockListItem from '../index';
import DownloadableBlockHeader from '../../downloadable-block-header';
import { item } from './fixtures';

describe( 'DownloadableBlockListItem', () => {
it( 'should render a block item', () => {
const wrapper = shallow(
<DownloadableBlockListItem onClick={ jest.fn() } item={ item } />
);

expect( wrapper ).toMatchSnapshot();
} );

it( 'should try to install the block plugin', () => {
const onClick = jest.fn();
const wrapper = shallow(
<DownloadableBlockListItem onClick={ onClick } item={ item } />
);

wrapper
.find( DownloadableBlockHeader )
.simulate( 'click', { event: {} } );

expect( onClick ).toHaveBeenCalledTimes( 1 );
} );
} );
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,27 @@
*/
import { __ } from '@wordpress/i18n';
import { Button, Notice } from '@wordpress/components';
import { withSelect } from '@wordpress/data';
import { useSelect } from '@wordpress/data';

/**
* Internal dependencies
*/
import { DOWNLOAD_ERROR_NOTICE_ID } from '../../store/constants';
export const DownloadableBlockNotice = ( { block, onClick } ) => {
const errorNotice = useSelect(
( select ) =>
select( 'core/block-directory' ).getErrorNoticeForBlock( block.id ),
[ block ]
);

export const DownloadableBlockNotice = ( { block, errorNotices, onClick } ) => {
if ( ! errorNotices[ block.id ] ) {
if ( ! errorNotice ) {
return null;
}

// A Failed install is the default error as its the first step
let copy = __( 'Block could not be added.' );

if ( errorNotices[ block.id ] === DOWNLOAD_ERROR_NOTICE_ID ) {
copy = __(
'Block could not be added. There is a problem with the block.'
);
}

return (
<Notice
status="error"
isDismissible={ false }
className="block-directory-downloadable-blocks__notice"
className="block-directory-downloadable-block-notice"
>
<div className="block-directory-downloadable-blocks__notice-content">
{ copy }
<div className="block-directory-downloadable-block-notice__content">
{ errorNotice }
</div>
<Button
isSmall
Expand All @@ -46,8 +38,4 @@ export const DownloadableBlockNotice = ( { block, errorNotices, onClick } ) => {
);
};

export default withSelect( ( select ) => {
return {
errorNotices: select( 'core/block-directory' ).getErrorNotices(),
};
} )( DownloadableBlockNotice );
export default DownloadableBlockNotice;
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
.block-directory-downloadable-blocks__notice {
.block-directory-downloadable-block-notice {
margin: 0 0 16px;
}

.block-directory-downloadable-blocks__notice-content {
.block-directory-downloadable-block-notice__content {
padding-right: 12px;
margin-bottom: 8px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`DownloadableBlockNotice Rendering should return something when there are error notices 1`] = `
<Notice
className="block-directory-downloadable-block-notice"
isDismissible={false}
status="error"
>
<div
className="block-directory-downloadable-block-notice__content"
>
Plugin not found.
</div>
<ForwardRef(Button)
isPrimary={true}
isSmall={true}
onClick={[Function]}
>
Retry
</ForwardRef(Button)>
</Notice>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -7,53 +7,52 @@ import { shallow } from 'enzyme';
* WordPress dependencies
*/
import { Button } from '@wordpress/components';
import { useSelect } from '@wordpress/data';

/**
* Internal dependencies
*/
import { DownloadableBlockNotice } from '../index';
import { plugin } from './fixtures';

import { INSTALL_ERROR_NOTICE_ID } from '../../../store/constants';

const getContainer = ( { block, onClick = jest.fn(), errorNotices = {} } ) => {
return shallow(
<DownloadableBlockNotice
block={ block }
onClick={ onClick }
errorNotices={ errorNotices }
/>
);
};
jest.mock( '@wordpress/data/src/components/use-select', () => {
// This allows us to tweak the returned value on each test
const mock = jest.fn();
return mock;
} );

describe( 'DownloadableBlockNotice', () => {
describe( 'Rendering', () => {
it( 'should return null when there are no error notices', () => {
const wrapper = getContainer( { block: plugin } );
useSelect.mockImplementation( () => false );
const wrapper = shallow(
<DownloadableBlockNotice
block={ plugin }
onClick={ jest.fn() }
/>
);
expect( wrapper.isEmptyRender() ).toBe( true );
} );

it( 'should return something when there are error notices', () => {
const errorNotices = {
[ plugin.id ]: INSTALL_ERROR_NOTICE_ID,
};
const wrapper = getContainer( { block: plugin, errorNotices } );
expect( wrapper.length ).toBeGreaterThan( 0 );
useSelect.mockImplementation( () => 'Plugin not found.' );
const wrapper = shallow(
<DownloadableBlockNotice
block={ plugin }
onClick={ jest.fn() }
/>
);
expect( wrapper ).toMatchSnapshot();
} );
} );

describe( 'Behavior', () => {
it( 'should trigger the callback on button click', () => {
const errorNotices = {
[ plugin.id ]: INSTALL_ERROR_NOTICE_ID,
};

useSelect.mockImplementation( () => 'Plugin not found.' );
const onClick = jest.fn();
const wrapper = getContainer( {
block: plugin,
onClick,
errorNotices,
} );
const wrapper = shallow(
<DownloadableBlockNotice block={ plugin } onClick={ onClick } />
);

wrapper.find( Button ).simulate( 'click', { event: {} } );

Expand Down
Loading