Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
13eefbd
Add helpers for integration tests
fluiddot May 20, 2021
1e592ee
Add fixes for running integration tests
fluiddot May 20, 2021
f6f4cb7
Add reusable block integration tests
fluiddot May 20, 2021
85feaeb
Disable reusable block integration tests
fluiddot May 20, 2021
ca95483
Change a11y label for testID in block list component
fluiddot Jun 2, 2021
de6bff0
Rename reusable block fixture
fluiddot Jun 2, 2021
e99d7cf
Refactor native helpers and update reusable block tests
fluiddot Jun 2, 2021
e63ed78
Add missing mocks to react-native-bridge
fluiddot Jun 2, 2021
962f87f
Move the reusable block fixture to unit test
fluiddot Jun 2, 2021
bbc4994
Remove waitFor for getting reusable block request
fluiddot Jun 3, 2021
cbb4a10
Include Editor with import instead require
fluiddot Jun 3, 2021
abcc235
Update the mocks for getting the editor HTML
fluiddot Jun 3, 2021
f541422
Add mocked styles for rendering the inserter menu
fluiddot Jun 4, 2021
3885363
Add testID to block types list component
fluiddot Jun 4, 2021
85dc86c
Update block mobile toolbar to prevent a render error
fluiddot Jun 4, 2021
7be11c6
Add insert reusable block test case
fluiddot Jun 4, 2021
a24919e
Merge branch 'trunk' into rnmobile/add/add-reusable-block-integration…
fluiddot Jun 8, 2021
f363fd0
Allow any prop in initializeEditor
fluiddot Jun 8, 2021
719e2b7
Add reusableBlock capability in integration test
fluiddot Jun 8, 2021
38e4132
Merge branch 'trunk' into rnmobile/add/add-reusable-block-integration…
fluiddot Jun 23, 2021
75b5416
Update block mobile toolbar fill logic
fluiddot Jun 23, 2021
409a074
Query reusable segment element by text
fluiddot Jun 23, 2021
69f42f2
Update fetch request mocks to return always a promise
fluiddot Jun 24, 2021
da86065
Remove unneeded fetch request mock
fluiddot Jun 24, 2021
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
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { View } from 'react-native';
*/
import { withDispatch, withSelect } from '@wordpress/data';
import { compose } from '@wordpress/compose';
import { useState } from '@wordpress/element';
import { useState, useEffect } from '@wordpress/element';

/**
* Internal dependencies
Expand Down Expand Up @@ -53,6 +53,14 @@ const BlockMobileToolbar = ( {
blockWidth <= BREAKPOINTS.wrapMover ||
appenderWidth - spacingValue <= BREAKPOINTS.wrapMover;

const BlockSettingsButtonFill = ( fillProps ) => {
useEffect(
() => fillProps.onChangeFillsLength( fillProps.fillsLength ),
[ fillProps.fillsLength ]
);
return fillProps.children ?? null;
};

return (
<View
style={ [ styles.toolbar, isFullWidth && styles.toolbarFullWidth ] }
Expand All @@ -69,10 +77,16 @@ const BlockMobileToolbar = ( {

<BlockSettingsButton.Slot>
{ /* Render only one settings icon even if we have more than one fill - need for hooks with controls */ }
{ ( fills = [ null ] ) => {
setFillsLength( fills.length );
return wrapBlockSettings ? null : fills[ 0 ];
} }
{ ( fills = [ null ] ) => (
// The purpose of BlockSettingsButtonFill component is only to provide a way
// to pass data upstream from the slot rendering
<BlockSettingsButtonFill
fillsLength={ fills.length }
onChangeFillsLength={ setFillsLength }
>
{ wrapBlockSettings ? null : fills[ 0 ] }
</BlockSettingsButtonFill>
) }
</BlockSettingsButton.Slot>

<BlockActionsMenu
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export default function BlockTypesList( { name, items, onSelect, listProps } ) {
<FlatList
onLayout={ onLayout }
key={ `InserterUI-${ name }-${ numberOfColumns }` } //re-render when numberOfColumns changes
testID={ `InserterUI-${ name }` }
keyboardShouldPersistTaps="always"
numColumns={ numberOfColumns }
data={ items }
Expand Down
85 changes: 69 additions & 16 deletions packages/block-library/src/block/test/edit.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,74 @@ afterAll( () => {
} );

describe( 'Reusable block', () => {
it( 'inserts a reusable block', async () => {
// We have to use different ids because entities are cached in memory.
const reusableBlockMock1 = getMockedReusableBlock( 1 );
const reusableBlockMock2 = getMockedReusableBlock( 2 );

// Return mocked responses for the block endpoints.
fetchRequest.mockImplementation( ( { path } ) => {
let response = {};
if ( path.startsWith( '/wp/v2/blocks?' ) ) {
response = [ reusableBlockMock1, reusableBlockMock2 ];
} else if ( path.startsWith( '/wp/v2/blocks/1' ) ) {
response = reusableBlockMock1;
}
return Promise.resolve( response );
} );

const {
getByA11yLabel,
getByTestId,
getByText,
} = await initializeEditor( {
initialHtml: '',
capabilities: { reusableBlock: true },
} );

// Open the inserter menu
fireEvent.press( await waitFor( () => getByA11yLabel( 'Add block' ) ) );

// Navigate to reusable tab
const reusableSegment = getByText( 'Reusable' );
// onLayout event is required by Segment component
fireEvent( reusableSegment, 'layout', {
nativeEvent: {
layout: {
width: 100,
},
},
} );
fireEvent.press( reusableSegment );

const reusableBlockList = getByTestId( 'InserterUI-ReusableBlocks' );
// onScroll event used to force the FlatList to render all items
fireEvent.scroll( reusableBlockList, {
nativeEvent: {
contentOffset: { y: 0, x: 0 },
contentSize: { width: 100, height: 100 },
layoutMeasurement: { width: 100, height: 100 },
},
} );

// Insert a reusable block
fireEvent.press(
await waitFor( () => getByText( `Reusable block - 1` ) )
);

// Get the reusable block
const reusableBlock = await waitFor( () =>
getByA11yLabel( /Reusable block Block\. Row 1/ )
);

expect( reusableBlock ).toBeDefined();
expect( getEditorHtml() ).toBe( '<!-- wp:block {"ref":1} /-->' );
} );

it( 'renders warning when the block does not exist', async () => {
// We have to use different ids because entities are cached in memory.
const id = 1;
const id = 3;
const initialHtml = `<!-- wp:block {"ref":${ id }} /-->`;
const endpoint = `/wp/v2/blocks/${ id }`;

const { getByA11yLabel } = await initializeEditor( {
initialHtml,
Expand All @@ -72,33 +135,29 @@ describe( 'Reusable block', () => {
getByA11yLabel( /Reusable block Block\. Row 1/ )
);

const reusableBlockRequest = fetchRequest.mock.calls.find( ( call ) =>
call[ 0 ].path.startsWith( endpoint )
);

const blockDeleted = await waitFor( () =>
within( reusableBlock ).getByText(
'Block has been deleted or is unavailable.'
)
);

expect( reusableBlockRequest ).toBeDefined();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to remove this check because it's already covered when verifying the existence of the reusable block.

expect( reusableBlock ).toBeDefined();
expect( blockDeleted ).toBeDefined();
expect( getEditorHtml() ).toBe( initialHtml );

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're not making modifications to the content so this check is not really necessary.

} );

it( 'renders block content', async () => {
// We have to use different ids because entities are cached in memory.
const id = 2;
const id = 4;
const initialHtml = `<!-- wp:block {"ref":${ id }} /-->`;
const endpoint = `/wp/v2/blocks/${ id }`;

// Return mocked response for the block endpoint.
fetchRequest.mockImplementation( ( { path } ) => {
let response = {};
if ( path.startsWith( endpoint ) ) {
return Promise.resolve( getMockedReusableBlock( id ) );
response = getMockedReusableBlock( id );
}
return Promise.resolve( response );
} );

const { getByA11yLabel } = await initializeEditor( {
Expand All @@ -109,10 +168,6 @@ describe( 'Reusable block', () => {
getByA11yLabel( /Reusable block Block\. Row 1/ )
);

const reusableBlockRequest = fetchRequest.mock.calls.find( ( call ) =>
call[ 0 ].path.startsWith( endpoint )
);

const innerBlockListWrapper = await waitFor( () =>
within( reusableBlock ).getByTestId( 'block-list-wrapper' )
);
Expand All @@ -133,9 +188,7 @@ describe( 'Reusable block', () => {
)
);

expect( reusableBlockRequest ).toBeDefined();
expect( reusableBlock ).toBeDefined();
expect( headingInnerBlock ).toBeDefined();
expect( getEditorHtml() ).toBe( initialHtml );
} );
} );
9 changes: 8 additions & 1 deletion test/native/__mocks__/styleMock.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,16 @@ module.exports = {
paddingRight: 10,
},
'block-types-list__column': {
padding: 10,
paddingLeft: 10,
paddingRight: 10,
},
floatingToolbar: {
height: 10,
},
searchFormPlaceholder: {
color: 'gray',
},
ripple: {
backgroundColor: 'white',
},
Comment on lines +116 to +121

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These styles are required to render the inserter menu.

};
9 changes: 2 additions & 7 deletions test/native/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,9 @@ provideToNativeHtml.mockImplementation( ( html ) => {
serializedHtml = html;
} );

export async function initializeEditor( { initialHtml } ) {
export async function initializeEditor( props ) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change allows us to pass any Editor prop on the initialization like the capabilities object.

const renderResult = render(
<Editor
postId={ 0 }
postType="post"
initialTitle="test"
initialHtml={ initialHtml }
/>
<Editor postId={ 0 } postType="post" initialTitle="test" { ...props } />
);
const { getByTestId } = renderResult;

Expand Down