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: Add error messages inline. #20001

Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
/**
* WordPress dependencies
*/
import { Button } from '@wordpress/components';
import { __, sprintf } from '@wordpress/i18n';
import { Button } from '@wordpress/components';
import { withSelect } from '@wordpress/data';

/**
* Internal dependencies
*/
import { BlockIcon } from '@wordpress/block-editor';
import BlockRatings from '../block-ratings';

function DownloadableBlockHeader( {
export function DownloadableBlockHeader( {
icon,
title,
rating,
ratingCount,
isLoading,
onClick,
} ) {
return (
Expand Down Expand Up @@ -45,15 +47,23 @@ function DownloadableBlockHeader( {
</div>
<Button
isSecondary
isBusy={ isLoading }
disabled={ isLoading }
onClick={ ( event ) => {
event.preventDefault();
onClick();
if ( ! isLoading ) {
onClick();
}
} }
>
{ __( 'Add block' ) }
{ isLoading ? __( 'Adding…' ) : __( 'Add block' ) }
</Button>
</div>
);
}

export default DownloadableBlockHeader;
export default withSelect( ( select ) => {
return {
isLoading: select( 'core/block-directory' ).isInstalling(),
};
} )( DownloadableBlockHeader );
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,27 @@ import { shallow } from 'enzyme';
* WordPress dependencies
*/
import { BlockIcon } from '@wordpress/block-editor';
import { Button } from '@wordpress/components';

/**
* Internal dependencies
*/
import DownloadableBlockHeader from '../index';
import { DownloadableBlockHeader } from '../index';
import { pluginWithImg, pluginWithIcon } from './fixtures';

const getContainer = ( { icon, title, rating, ratingCount } ) => {
const getContainer = (
{ icon, title, rating, ratingCount },
onClick = jest.fn(),
isLoading = false
) => {
return shallow(
<DownloadableBlockHeader
icon={ icon }
onClick={ () => {} }
onClick={ onClick }
title={ title }
rating={ rating }
ratingCount={ ratingCount }
isLoading={ isLoading }
/>
);
};
Expand Down Expand Up @@ -50,4 +56,28 @@ describe( 'DownloadableBlockHeader', () => {
expect( wrapper.find( BlockIcon ) ).toHaveLength( 1 );
} );
} );

describe( 'user interaction', () => {
test( 'should trigger the onClick function', () => {
const onClickMock = jest.fn();
const wrapper = getContainer( pluginWithIcon, onClickMock );
const event = {
preventDefault: jest.fn(),
};
wrapper.find( Button ).simulate( 'click', event );
expect( onClickMock ).toHaveBeenCalledTimes( 1 );
expect( event.preventDefault ).toHaveBeenCalled();
} );

test( 'should not trigger the onClick function if loading', () => {
const onClickMock = jest.fn();
const wrapper = getContainer( pluginWithIcon, onClickMock, true );
const event = {
preventDefault: jest.fn(),
};
wrapper.find( Button ).simulate( 'click', event );
expect( event.preventDefault ).toHaveBeenCalled();
expect( onClickMock ).toHaveBeenCalledTimes( 0 );
} );
} );
} );
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
/**
* Internal dependencies
*/
import DownloadableBlockHeader from '../downloadable-block-header';
import DownloadableBlockAuthorInfo from '../downloadable-block-author-info';
import DownloadableBlockHeader from '../downloadable-block-header';
import DownloadableBlockInfo from '../downloadable-block-info';
import DownloadableBlockNotice from '../downloadable-block-notice';

function DownloadableBlockListItem( { item, onClick } ) {
const {
Expand Down Expand Up @@ -32,6 +33,10 @@ function DownloadableBlockListItem( { item, onClick } ) {
/>
</header>
<section className="block-directory-downloadable-block-list-item__body">
<DownloadableBlockNotice
onClick={ onClick }
block={ item }
/>
<DownloadableBlockInfo
activeInstalls={ activeInstalls }
description={ description }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { Button, Notice } from '@wordpress/components';
import { withSelect } from '@wordpress/data';

/**
* Internal dependencies
*/
import { DOWNLOAD_ERROR_NOTICE_ID } from '../../store/constants';

export const DownloadableBlockNotice = ( { block, errorNotices, onClick } ) => {
if ( ! errorNotices[ block.id ] ) {
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"
>
<div className="block-directory-downloadable-blocks__notice-content">
{ copy }
</div>
<Button
isSmall
isPrimary
onClick={ () => {
onClick( block );
} }
>
{ __( 'Retry' ) }
</Button>
</Notice>
);
};

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

.block-directory-downloadable-blocks__notice-content {
padding-right: 12px;
margin-bottom: 8px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const plugin = {
id: 'boxer-block',
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* External dependencies
*/
import { shallow } from 'enzyme';

/**
* WordPress dependencies
*/
import { Button } from '@wordpress/components';

/**
* 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 }
/>
);
};

describe( 'DownloadableBlockNotice', () => {
describe( 'Rendering', () => {
it( 'should return null when there are no error notices', () => {
const wrapper = getContainer( { block: plugin } );
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 );
} );
} );

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

const onClick = jest.fn();
const wrapper = getContainer( {
block: plugin,
onClick,
errorNotices,
} );

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

expect( onClick ).toHaveBeenCalledTimes( 1 );
} );
} );
} );
Loading