From 13eefbd6d79241a2bd60ed3127942aaeab62e45a Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Thu, 20 May 2021 13:07:49 +0200 Subject: [PATCH 01/22] Add helpers for integration tests --- test/native/helpers.js | 74 ++++++++++++++++++++++++++++++++++++++ test/native/jest.config.js | 1 + test/native/setup.js | 19 +++++++++- 3 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 test/native/helpers.js diff --git a/test/native/helpers.js b/test/native/helpers.js new file mode 100644 index 00000000000000..a9ad08f8d5b90c --- /dev/null +++ b/test/native/helpers.js @@ -0,0 +1,74 @@ +/** + * External dependencies + */ +import { render, fireEvent } from '@testing-library/react-native'; + +export async function initializeEditor( { initialHtml } ) { + const Editor = require( '@wordpress/edit-post/src/editor' ).default; + const renderResult = render( + + ); + const { findByLabelText } = renderResult; + const blockListWrapper = await findByLabelText( 'block-list-wrapper' ); + // onLayout event has to be explicitly dispatched in BlockList component, + // otherwise the inner blocks are not rendered. + fireEvent( blockListWrapper, 'layout', { + nativeEvent: { + layout: { + width: 100, + }, + }, + } ); + + const extraMethods = [ + getByTextInAztec, + getBlockAtPosition, + addBlock, + ].reduce( ( carry, func ) => { + return { + ...carry, + [ func.name ]: ( ...props ) => func( renderResult, ...props ), + }; + }, {} ); + + return { + ...renderResult, + ...extraMethods, + }; +} + +async function getBlockAtPosition( + { findAllByRole }, + blockName, + position = 1 +) { + const instances = await findAllByRole( 'button' ); + const result = instances.filter( ( instance ) => + instance.props.accessibilityLabel.startsWith( + `${ blockName } Block. Row ${ position }` + ) + ); + return result.length ? result[ 0 ] : undefined; +} + +async function addBlock( { findByLabelText }, blockName ) { + const button = await findByLabelText( 'Add block' ); + fireEvent.press( button ); + const blockButton = await findByLabelText( `${ blockName } block` ); + fireEvent.press( blockButton ); +} + +// eslint-disable-next-line camelcase +async function getByTextInAztec( { UNSAFE_queryAllByType }, value ) { + const instances = await UNSAFE_queryAllByType( 'RCTAztecView' ); + const result = instances.filter( ( instance ) => { + const text = instance.props.text.text; + return text === value; + } ); + return result.length ? result[ 0 ] : undefined; +} diff --git a/test/native/jest.config.js b/test/native/jest.config.js index 2da93faad1859e..a2d3e7d047bf37 100644 --- a/test/native/jest.config.js +++ b/test/native/jest.config.js @@ -55,6 +55,7 @@ module.exports = { [ `@wordpress\\/(${ transpiledPackageNames.join( '|' ) })$` ]: '/packages/$1/src', + 'test/helpers$': '/test/native/helpers.js', }, modulePathIgnorePatterns: [ '/packages/react-native-editor/node_modules', diff --git a/test/native/setup.js b/test/native/setup.js index 9c89c8845d999a..04d07a6faa2b76 100644 --- a/test/native/setup.js +++ b/test/native/setup.js @@ -20,13 +20,17 @@ jest.mock( '@wordpress/element', () => { }; } ); +let triggerHtmlSerialization = () => {}; +let serializedHtml; jest.mock( '@wordpress/react-native-bridge', () => { return { addEventListener: jest.fn(), mediaUploadSync: jest.fn(), removeEventListener: jest.fn(), requestFocalPointPickerTooltipShown: jest.fn( () => true ), - subscribeParentGetHtml: jest.fn(), + subscribeParentGetHtml: jest.fn( ( callback ) => { + triggerHtmlSerialization = callback; + } ), subscribeParentToggleHTMLMode: jest.fn(), subscribeSetTitle: jest.fn(), subscribeSetFocusOnTitle: jest.fn(), @@ -47,11 +51,15 @@ jest.mock( '@wordpress/react-native-bridge', () => { requestMediaPicker: jest.fn(), requestUnsupportedBlockFallback: jest.fn(), subscribeReplaceBlock: jest.fn(), + provideToNative_Html: jest.fn( ( html ) => { + serializedHtml = html; + } ), mediaSources: { deviceLibrary: 'DEVICE_MEDIA_LIBRARY', deviceCamera: 'DEVICE_CAMERA', siteMediaLibrary: 'SITE_MEDIA_LIBRARY', }, + fetchRequest: jest.fn(), }; } ); @@ -156,5 +164,14 @@ jest.mock( announceForAccessibility: jest.fn(), removeEventListener: jest.fn(), isScreenReaderEnabled: jest.fn( () => Promise.resolve( false ) ), + fetch: jest.fn( () => ( { + done: jest.fn(), + } ) ), } ) ); + +// Helpers for integration tests +global.getEditorHtml = () => { + triggerHtmlSerialization(); + return serializedHtml; +}; From 1e592ee2dcd0362fab8a1fe0d91c23158538b162 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Thu, 20 May 2021 13:09:29 +0200 Subject: [PATCH 02/22] Add fixes for running integration tests --- .../src/components/block-list/index.native.js | 1 + .../src/mobile/bottom-sheet/index.native.js | 12 +++++++----- test/native/__mocks__/styleMock.js | 6 ++++++ 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/packages/block-editor/src/components/block-list/index.native.js b/packages/block-editor/src/components/block-list/index.native.js index c60163cf9a3bee..45cf4133bef85e 100644 --- a/packages/block-editor/src/components/block-list/index.native.js +++ b/packages/block-editor/src/components/block-list/index.native.js @@ -230,6 +230,7 @@ export class BlockList extends Component { return ( { @@ -185,6 +184,8 @@ class BottomSheet extends Component { ); } + Dimensions.addEventListener( 'change', this.onDimensionsChange ); + // 'Will' keyboard events are not available on Android. // Reference: https://reactnative.dev/docs/0.61/keyboard#addlistener this.keyboardShowListener = Keyboard.addListener( @@ -204,6 +205,7 @@ class BottomSheet extends Component { } componentWillUnmount() { + Dimensions.removeEventListener( 'change', this.onDimensionsChange ); this.keyboardShowListener.remove(); this.keyboardHideListener.remove(); if ( this.androidModalClosedSubscription ) { diff --git a/test/native/__mocks__/styleMock.js b/test/native/__mocks__/styleMock.js index f01d424bb9d162..46f0d1a2b41079 100644 --- a/test/native/__mocks__/styleMock.js +++ b/test/native/__mocks__/styleMock.js @@ -106,4 +106,10 @@ module.exports = { paddingLeft: 10, paddingRight: 10, }, + 'block-types-list__column': { + padding: 10, + }, + floatingToolbar: { + height: 10, + }, }; From f6f4cb7433e9b283c369719549267d137460be30 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Thu, 20 May 2021 13:12:29 +0200 Subject: [PATCH 03/22] Add reusable block integration tests --- .../src/block/test/edit.native.js | 115 ++++++++++++++++++ .../block-library/src/block/test/fixture.js | 24 ++++ 2 files changed, 139 insertions(+) create mode 100644 packages/block-library/src/block/test/edit.native.js create mode 100644 packages/block-library/src/block/test/fixture.js diff --git a/packages/block-library/src/block/test/edit.native.js b/packages/block-library/src/block/test/edit.native.js new file mode 100644 index 00000000000000..292da758086b69 --- /dev/null +++ b/packages/block-library/src/block/test/edit.native.js @@ -0,0 +1,115 @@ +/** + * External dependencies + */ +import { cleanup, fireEvent, waitFor } from '@testing-library/react-native'; + +/** + * WordPress dependencies + */ +import { getBlockTypes, unregisterBlockType } from '@wordpress/blocks'; +import { fetchRequest } from '@wordpress/react-native-bridge'; + +/** + * Internal dependencies + */ +import { initializeEditor } from 'test/helpers'; +import { getReusableBlock } from './fixture'; + +beforeAll( () => { + // Setup API fetch as it's done when initializing the editor + require( '@wordpress/react-native-editor/src/api-fetch-setup' ).default(); + // Register all core blocks + require( '@wordpress/block-library' ).registerCoreBlocks(); +} ); + +afterAll( () => { + // Clean up registered blocks + getBlockTypes().forEach( ( block ) => { + unregisterBlockType( block.name ); + } ); +} ); + +afterEach( cleanup ); + +describe( 'Reusable block', () => { + // The skipped tests below pass but are currently skipped because multiple + // async findBy* queries currently cause errors in test output + // https://git.io/JYYGE + // eslint-disable-next-line jest/no-disabled-tests + 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 initialHtml = ``; + const endpoint = `/wp/v2/blocks/${ id }`; + + const result = await initializeEditor( { initialHtml } ); + const { getBlockAtPosition, getByText } = result; + + // Wait for the block to be fetched. + await waitFor( () => { + const isBlockFetched = fetchRequest.mock.calls.find( ( call ) => + call[ 0 ].startsWith( endpoint ) + ); + expect( isBlockFetched ).toBeTruthy(); + } ); + + expect( getBlockAtPosition( 'Reusable block' ) ).toBeDefined(); + expect( + getByText( 'Block has been deleted or is unavailable.' ) + ).toBeDefined(); + + expect( global.getEditorHtml() ).toBe( initialHtml ); + } ); + + // The skipped tests below pass but are currently skipped because multiple + // async findBy* queries currently cause errors in test output + // https://git.io/JYYGE + // eslint-disable-next-line jest/no-disabled-tests + it( 'renders block content', async () => { + // We have to use different ids because entities are cached in memory. + const id = 2; + const initialHtml = ``; + const endpoint = `/wp/v2/blocks/${ id }`; + + fetchRequest.mockImplementation( ( path ) => { + if ( path.startsWith( endpoint ) ) { + return Promise.resolve( + JSON.stringify( getReusableBlock( id ) ) + ); + } + } ); + + const result = await initializeEditor( { initialHtml } ); + const { getBlockAtPosition } = result; + + // Wait for the block to be fetched. + await waitFor( () => { + const hasFetchedBlock = fetchRequest.mock.calls.find( ( call ) => + call[ 0 ].startsWith( endpoint ) + ); + expect( hasFetchedBlock ).toBeTruthy(); + } ); + + const reusableBlock = await getBlockAtPosition( 'Reusable block' ); + const innerBlockListWrapper = reusableBlock.findByProps( { + accessibilityLabel: 'block-list-wrapper', + } ); + // onLayout event has to be explicitly dispatched in BlockList component, + // otherwise the inner blocks are not rendered. + fireEvent( innerBlockListWrapper, 'layout', { + nativeEvent: { + layout: { + width: 100, + }, + }, + } ); + + const headingInnerBlock = reusableBlock.findByProps( { + accessibilityLabel: + 'Heading Block. Row 1. Level 2. First Reusable block', + } ); + expect( headingInnerBlock ).toBeDefined(); + + expect( global.getEditorHtml() ).toBe( initialHtml ); + } ); +} ); diff --git a/packages/block-library/src/block/test/fixture.js b/packages/block-library/src/block/test/fixture.js new file mode 100644 index 00000000000000..4408a441e73d25 --- /dev/null +++ b/packages/block-library/src/block/test/fixture.js @@ -0,0 +1,24 @@ +export const getReusableBlock = ( id ) => ( { + content: { + raw: ` + +

First Reusable block

+ + + +

Bold Italic Striked Superscript(1) Subscript(2) Link

+ + + !-- wp:heading {"level":4} --> +

List

+ + + +
  • First Item
  • Second Item
  • Third Item
+ +`, + }, + id, + title: { raw: `Reusable block - ${ id }` }, + type: 'wp_block', +} ); From 85feaeb0b153f3cd69a219f46fa669cb18d6844b Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Thu, 20 May 2021 13:46:09 +0200 Subject: [PATCH 04/22] Disable reusable block integration tests --- .../block-library/src/block/test/edit.native.js | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/packages/block-library/src/block/test/edit.native.js b/packages/block-library/src/block/test/edit.native.js index 292da758086b69..a2e14f883846b3 100644 --- a/packages/block-library/src/block/test/edit.native.js +++ b/packages/block-library/src/block/test/edit.native.js @@ -31,11 +31,11 @@ afterAll( () => { afterEach( cleanup ); -describe( 'Reusable block', () => { - // The skipped tests below pass but are currently skipped because multiple - // async findBy* queries currently cause errors in test output - // https://git.io/JYYGE - // eslint-disable-next-line jest/no-disabled-tests +// The skipped tests below pass but are currently skipped because multiple +// async findBy* queries currently cause errors in test output +// https://git.io/JYYGE +// eslint-disable-next-line jest/no-disabled-tests +describe.skip( 'Reusable block', () => { 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; @@ -61,10 +61,6 @@ describe( 'Reusable block', () => { expect( global.getEditorHtml() ).toBe( initialHtml ); } ); - // The skipped tests below pass but are currently skipped because multiple - // async findBy* queries currently cause errors in test output - // https://git.io/JYYGE - // eslint-disable-next-line jest/no-disabled-tests it( 'renders block content', async () => { // We have to use different ids because entities are cached in memory. const id = 2; From ca954834020d6928e6ce5dc39848a74b48aa8baa Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Wed, 2 Jun 2021 11:30:50 +0200 Subject: [PATCH 05/22] Change a11y label for testID in block list component --- packages/block-editor/src/components/block-list/index.native.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/block-list/index.native.js b/packages/block-editor/src/components/block-list/index.native.js index 45cf4133bef85e..0fdde48756c784 100644 --- a/packages/block-editor/src/components/block-list/index.native.js +++ b/packages/block-editor/src/components/block-list/index.native.js @@ -230,10 +230,10 @@ export class BlockList extends Component { return ( Date: Wed, 2 Jun 2021 11:31:40 +0200 Subject: [PATCH 06/22] Rename reusable block fixture --- packages/block-library/src/block/test/fixture.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/block/test/fixture.js b/packages/block-library/src/block/test/fixture.js index 4408a441e73d25..028e380cb88747 100644 --- a/packages/block-library/src/block/test/fixture.js +++ b/packages/block-library/src/block/test/fixture.js @@ -1,4 +1,4 @@ -export const getReusableBlock = ( id ) => ( { +export const getMockedReusableBlock = ( id ) => ( { content: { raw: ` From e99d7cf2a7c577596171f77b6c658ea6dd2581d8 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Wed, 2 Jun 2021 11:35:38 +0200 Subject: [PATCH 07/22] Refactor native helpers and update reusable block tests --- .../src/block/test/edit.native.js | 112 ++++++++++-------- test/native/helpers.js | 94 ++++++++------- test/native/setup.js | 16 +-- 3 files changed, 114 insertions(+), 108 deletions(-) diff --git a/packages/block-library/src/block/test/edit.native.js b/packages/block-library/src/block/test/edit.native.js index a2e14f883846b3..ee8e6d74f8a539 100644 --- a/packages/block-library/src/block/test/edit.native.js +++ b/packages/block-library/src/block/test/edit.native.js @@ -1,25 +1,29 @@ /** * External dependencies */ -import { cleanup, fireEvent, waitFor } from '@testing-library/react-native'; +import { + getEditorHtml, + initializeEditor, + fireEvent, + waitFor, + within, +} from 'test/helpers'; /** * WordPress dependencies */ import { getBlockTypes, unregisterBlockType } from '@wordpress/blocks'; -import { fetchRequest } from '@wordpress/react-native-bridge'; +import fetchRequest from '@wordpress/api-fetch'; /** * Internal dependencies */ -import { initializeEditor } from 'test/helpers'; -import { getReusableBlock } from './fixture'; +import { getMockedReusableBlock } from './fixture'; +import { registerCoreBlocks } from '../..'; beforeAll( () => { - // Setup API fetch as it's done when initializing the editor - require( '@wordpress/react-native-editor/src/api-fetch-setup' ).default(); // Register all core blocks - require( '@wordpress/block-library' ).registerCoreBlocks(); + registerCoreBlocks(); } ); afterAll( () => { @@ -29,36 +33,38 @@ afterAll( () => { } ); } ); -afterEach( cleanup ); - -// The skipped tests below pass but are currently skipped because multiple -// async findBy* queries currently cause errors in test output -// https://git.io/JYYGE -// eslint-disable-next-line jest/no-disabled-tests -describe.skip( 'Reusable block', () => { +describe( 'Reusable block', () => { 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 initialHtml = ``; const endpoint = `/wp/v2/blocks/${ id }`; - const result = await initializeEditor( { initialHtml } ); - const { getBlockAtPosition, getByText } = result; - - // Wait for the block to be fetched. - await waitFor( () => { - const isBlockFetched = fetchRequest.mock.calls.find( ( call ) => - call[ 0 ].startsWith( endpoint ) - ); - expect( isBlockFetched ).toBeTruthy(); + const { getByA11yLabel } = await initializeEditor( { + initialHtml, } ); - expect( getBlockAtPosition( 'Reusable block' ) ).toBeDefined(); - expect( - getByText( 'Block has been deleted or is unavailable.' ) - ).toBeDefined(); + const reusableBlock = await waitFor( () => + getByA11yLabel( /Reusable block Block\. Row 1/ ) + ); - expect( global.getEditorHtml() ).toBe( initialHtml ); + // Wait for the block to be fetched. + const reusableBlockRequest = await waitFor( () => + 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(); + expect( reusableBlock ).toBeDefined(); + expect( blockDeleted ).toBeDefined(); + expect( getEditorHtml() ).toBe( initialHtml ); } ); it( 'renders block content', async () => { @@ -67,29 +73,32 @@ describe.skip( 'Reusable block', () => { const initialHtml = ``; const endpoint = `/wp/v2/blocks/${ id }`; - fetchRequest.mockImplementation( ( path ) => { + // Return mocked response for the block endpoint. + fetchRequest.mockImplementation( ( { path } ) => { if ( path.startsWith( endpoint ) ) { - return Promise.resolve( - JSON.stringify( getReusableBlock( id ) ) - ); + return Promise.resolve( getMockedReusableBlock( id ) ); } } ); - const result = await initializeEditor( { initialHtml } ); - const { getBlockAtPosition } = result; + const { getByA11yLabel } = await initializeEditor( { + initialHtml, + } ); // Wait for the block to be fetched. - await waitFor( () => { - const hasFetchedBlock = fetchRequest.mock.calls.find( ( call ) => - call[ 0 ].startsWith( endpoint ) - ); - expect( hasFetchedBlock ).toBeTruthy(); - } ); + const reusableBlockRequest = await waitFor( () => + fetchRequest.mock.calls.find( ( call ) => + call[ 0 ].path.startsWith( endpoint ) + ) + ); + + const reusableBlock = await waitFor( () => + getByA11yLabel( /Reusable block Block\. Row 1/ ) + ); + + const innerBlockListWrapper = await waitFor( () => + within( reusableBlock ).getByTestId( 'block-list-wrapper' ) + ); - const reusableBlock = await getBlockAtPosition( 'Reusable block' ); - const innerBlockListWrapper = reusableBlock.findByProps( { - accessibilityLabel: 'block-list-wrapper', - } ); // onLayout event has to be explicitly dispatched in BlockList component, // otherwise the inner blocks are not rendered. fireEvent( innerBlockListWrapper, 'layout', { @@ -100,12 +109,15 @@ describe.skip( 'Reusable block', () => { }, } ); - const headingInnerBlock = reusableBlock.findByProps( { - accessibilityLabel: - 'Heading Block. Row 1. Level 2. First Reusable block', - } ); - expect( headingInnerBlock ).toBeDefined(); + const headingInnerBlock = waitFor( () => + within( reusableBlock ).getByA11yLabel( + 'Heading Block. Row 1. Level 2. First Reusable block' + ) + ); - expect( global.getEditorHtml() ).toBe( initialHtml ); + expect( reusableBlockRequest ).toBeDefined(); + expect( reusableBlock ).toBeDefined(); + expect( headingInnerBlock ).toBeDefined(); + expect( getEditorHtml() ).toBe( initialHtml ); } ); } ); diff --git a/test/native/helpers.js b/test/native/helpers.js index a9ad08f8d5b90c..627fe01de103e5 100644 --- a/test/native/helpers.js +++ b/test/native/helpers.js @@ -1,7 +1,18 @@ /** * External dependencies */ -import { render, fireEvent } from '@testing-library/react-native'; +import { act, render, fireEvent } from '@testing-library/react-native'; + +// Set up the mocks for getting the HTML output of the editor +let triggerHtmlSerialization = () => {}; +let serializedHtml; +const bridgeMock = jest.requireMock( '@wordpress/react-native-bridge' ); +bridgeMock.subscribeParentGetHtml = jest.fn( ( callback ) => { + triggerHtmlSerialization = callback; +} ); +bridgeMock.provideToNative_Html = jest.fn( ( html ) => { + serializedHtml = html; +} ); export async function initializeEditor( { initialHtml } ) { const Editor = require( '@wordpress/edit-post/src/editor' ).default; @@ -13,8 +24,12 @@ export async function initializeEditor( { initialHtml } ) { initialHtml={ initialHtml } /> ); - const { findByLabelText } = renderResult; - const blockListWrapper = await findByLabelText( 'block-list-wrapper' ); + const { getByTestId } = renderResult; + + const blockListWrapper = await waitFor( () => + getByTestId( 'block-list-wrapper' ) + ); + // onLayout event has to be explicitly dispatched in BlockList component, // otherwise the inner blocks are not rendered. fireEvent( blockListWrapper, 'layout', { @@ -25,50 +40,41 @@ export async function initializeEditor( { initialHtml } ) { }, } ); - const extraMethods = [ - getByTextInAztec, - getBlockAtPosition, - addBlock, - ].reduce( ( carry, func ) => { - return { - ...carry, - [ func.name ]: ( ...props ) => func( renderResult, ...props ), - }; - }, {} ); - - return { - ...renderResult, - ...extraMethods, - }; + return renderResult; } -async function getBlockAtPosition( - { findAllByRole }, - blockName, - position = 1 -) { - const instances = await findAllByRole( 'button' ); - const result = instances.filter( ( instance ) => - instance.props.accessibilityLabel.startsWith( - `${ blockName } Block. Row ${ position }` - ) - ); - return result.length ? result[ 0 ] : undefined; -} +export * from '@testing-library/react-native'; -async function addBlock( { findByLabelText }, blockName ) { - const button = await findByLabelText( 'Add block' ); - fireEvent.press( button ); - const blockButton = await findByLabelText( `${ blockName } block` ); - fireEvent.press( blockButton ); +// Custom implementation of the waitFor utility to prevent the issue: https://git.io/JYYGE +export function waitFor( cb, timeout = 150 ) { + let result; + const check = ( resolve, reject, times = 0 ) => { + try { + result = cb(); + } catch ( e ) { + //NOOP + } + if ( ! result && times < 5 ) { + setTimeout( () => check( resolve, reject, times + 1 ), timeout ); + return; + } + resolve( result ); + }; + return new Promise( ( resolve, reject ) => + act( + () => new Promise( ( internalResolve ) => check( internalResolve ) ) + ).then( () => { + if ( ! result ) { + reject( `waitFor timed out for callback:\n${ cb }` ); + return; + } + resolve( result ); + } ) + ); } -// eslint-disable-next-line camelcase -async function getByTextInAztec( { UNSAFE_queryAllByType }, value ) { - const instances = await UNSAFE_queryAllByType( 'RCTAztecView' ); - const result = instances.filter( ( instance ) => { - const text = instance.props.text.text; - return text === value; - } ); - return result.length ? result[ 0 ] : undefined; +// Helper for getting the current HTML output of the editor +export function getEditorHtml() { + triggerHtmlSerialization(); + return serializedHtml; } diff --git a/test/native/setup.js b/test/native/setup.js index 04d07a6faa2b76..2ee9ee39281d66 100644 --- a/test/native/setup.js +++ b/test/native/setup.js @@ -20,17 +20,14 @@ jest.mock( '@wordpress/element', () => { }; } ); -let triggerHtmlSerialization = () => {}; -let serializedHtml; +jest.mock( '@wordpress/api-fetch', () => jest.fn() ); + jest.mock( '@wordpress/react-native-bridge', () => { return { addEventListener: jest.fn(), mediaUploadSync: jest.fn(), removeEventListener: jest.fn(), requestFocalPointPickerTooltipShown: jest.fn( () => true ), - subscribeParentGetHtml: jest.fn( ( callback ) => { - triggerHtmlSerialization = callback; - } ), subscribeParentToggleHTMLMode: jest.fn(), subscribeSetTitle: jest.fn(), subscribeSetFocusOnTitle: jest.fn(), @@ -51,9 +48,6 @@ jest.mock( '@wordpress/react-native-bridge', () => { requestMediaPicker: jest.fn(), requestUnsupportedBlockFallback: jest.fn(), subscribeReplaceBlock: jest.fn(), - provideToNative_Html: jest.fn( ( html ) => { - serializedHtml = html; - } ), mediaSources: { deviceLibrary: 'DEVICE_MEDIA_LIBRARY', deviceCamera: 'DEVICE_CAMERA', @@ -169,9 +163,3 @@ jest.mock( } ) ), } ) ); - -// Helpers for integration tests -global.getEditorHtml = () => { - triggerHtmlSerialization(); - return serializedHtml; -}; From e63ed78ae716a4f442c00aee4541bd10bd31da6a Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Wed, 2 Jun 2021 19:13:01 +0200 Subject: [PATCH 08/22] Add missing mocks to react-native-bridge --- test/native/setup.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/native/setup.js b/test/native/setup.js index 2ee9ee39281d66..deaa3ed964103c 100644 --- a/test/native/setup.js +++ b/test/native/setup.js @@ -39,11 +39,13 @@ jest.mock( '@wordpress/react-native-bridge', () => { subscribePreferredColorScheme: () => 'light', subscribeUpdateCapabilities: jest.fn(), subscribeShowNotice: jest.fn(), + subscribeParentGetHtml: jest.fn(), editorDidMount: jest.fn(), editorDidAutosave: jest.fn(), subscribeMediaUpload: jest.fn(), subscribeMediaSave: jest.fn(), getOtherMediaOptions: jest.fn(), + provideToNative_Html: jest.fn(), requestMediaEditor: jest.fn(), requestMediaPicker: jest.fn(), requestUnsupportedBlockFallback: jest.fn(), From 962f87f9e29f69b553c098f429d5f56605630e69 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Wed, 2 Jun 2021 19:14:06 +0200 Subject: [PATCH 09/22] Move the reusable block fixture to unit test --- .../src/block/test/edit.native.js | 26 ++++++++++++++++++- .../block-library/src/block/test/fixture.js | 24 ----------------- 2 files changed, 25 insertions(+), 25 deletions(-) delete mode 100644 packages/block-library/src/block/test/fixture.js diff --git a/packages/block-library/src/block/test/edit.native.js b/packages/block-library/src/block/test/edit.native.js index ee8e6d74f8a539..a87c373eb05149 100644 --- a/packages/block-library/src/block/test/edit.native.js +++ b/packages/block-library/src/block/test/edit.native.js @@ -18,9 +18,33 @@ import fetchRequest from '@wordpress/api-fetch'; /** * Internal dependencies */ -import { getMockedReusableBlock } from './fixture'; import { registerCoreBlocks } from '../..'; +const getMockedReusableBlock = ( id ) => ( { + content: { + raw: ` + +

First Reusable block

+ + + +

Bold Italic Striked Superscript(1) Subscript(2) Link

+ + + !-- wp:heading {"level":4} --> +

List

+ + + +
  • First Item
  • Second Item
  • Third Item
+ +`, + }, + id, + title: { raw: `Reusable block - ${ id }` }, + type: 'wp_block', +} ); + beforeAll( () => { // Register all core blocks registerCoreBlocks(); diff --git a/packages/block-library/src/block/test/fixture.js b/packages/block-library/src/block/test/fixture.js deleted file mode 100644 index 028e380cb88747..00000000000000 --- a/packages/block-library/src/block/test/fixture.js +++ /dev/null @@ -1,24 +0,0 @@ -export const getMockedReusableBlock = ( id ) => ( { - content: { - raw: ` - -

First Reusable block

- - - -

Bold Italic Striked Superscript(1) Subscript(2) Link

- - - !-- wp:heading {"level":4} --> -

List

- - - -
  • First Item
  • Second Item
  • Third Item
- -`, - }, - id, - title: { raw: `Reusable block - ${ id }` }, - type: 'wp_block', -} ); From bbc4994e00f066de3852fa22abf3deb8c99d1a40 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Thu, 3 Jun 2021 19:03:54 +0200 Subject: [PATCH 10/22] Remove waitFor for getting reusable block request --- .../src/block/test/edit.native.js | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/packages/block-library/src/block/test/edit.native.js b/packages/block-library/src/block/test/edit.native.js index a87c373eb05149..1e4c18bcc37126 100644 --- a/packages/block-library/src/block/test/edit.native.js +++ b/packages/block-library/src/block/test/edit.native.js @@ -72,11 +72,8 @@ describe( 'Reusable block', () => { getByA11yLabel( /Reusable block Block\. Row 1/ ) ); - // Wait for the block to be fetched. - const reusableBlockRequest = await waitFor( () => - fetchRequest.mock.calls.find( ( call ) => - call[ 0 ].path.startsWith( endpoint ) - ) + const reusableBlockRequest = fetchRequest.mock.calls.find( ( call ) => + call[ 0 ].path.startsWith( endpoint ) ); const blockDeleted = await waitFor( () => @@ -108,17 +105,14 @@ describe( 'Reusable block', () => { initialHtml, } ); - // Wait for the block to be fetched. - const reusableBlockRequest = await waitFor( () => - fetchRequest.mock.calls.find( ( call ) => - call[ 0 ].path.startsWith( endpoint ) - ) - ); - const reusableBlock = await waitFor( () => 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' ) ); From cbb4a1073ef750102902fd685cdb7ec01dba6ae3 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Thu, 3 Jun 2021 19:04:55 +0200 Subject: [PATCH 11/22] Include Editor with import instead require --- test/native/helpers.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/native/helpers.js b/test/native/helpers.js index 627fe01de103e5..c471f6ed735303 100644 --- a/test/native/helpers.js +++ b/test/native/helpers.js @@ -3,6 +3,15 @@ */ import { act, render, fireEvent } from '@testing-library/react-native'; +/** + * WordPress dependencies + */ +// Editor component is not exposed in the pacakge because is meant to be consumed +// internally, however we require it for rendering the editor in integration tests, +// for this reason it's imported with path access. +// eslint-disable-next-line no-restricted-syntax +import Editor from '@wordpress/edit-post/src/editor'; + // Set up the mocks for getting the HTML output of the editor let triggerHtmlSerialization = () => {}; let serializedHtml; @@ -15,7 +24,6 @@ bridgeMock.provideToNative_Html = jest.fn( ( html ) => { } ); export async function initializeEditor( { initialHtml } ) { - const Editor = require( '@wordpress/edit-post/src/editor' ).default; const renderResult = render( Date: Thu, 3 Jun 2021 19:30:23 +0200 Subject: [PATCH 12/22] Update the mocks for getting the editor HTML --- test/native/helpers.js | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/test/native/helpers.js b/test/native/helpers.js index c471f6ed735303..42e186d6a6b209 100644 --- a/test/native/helpers.js +++ b/test/native/helpers.js @@ -6,6 +6,10 @@ import { act, render, fireEvent } from '@testing-library/react-native'; /** * WordPress dependencies */ +import { + subscribeParentGetHtml, + provideToNative_Html as provideToNativeHtml, +} from '@wordpress/react-native-bridge'; // Editor component is not exposed in the pacakge because is meant to be consumed // internally, however we require it for rendering the editor in integration tests, // for this reason it's imported with path access. @@ -13,13 +17,19 @@ import { act, render, fireEvent } from '@testing-library/react-native'; import Editor from '@wordpress/edit-post/src/editor'; // Set up the mocks for getting the HTML output of the editor -let triggerHtmlSerialization = () => {}; +let triggerHtmlSerialization; let serializedHtml; -const bridgeMock = jest.requireMock( '@wordpress/react-native-bridge' ); -bridgeMock.subscribeParentGetHtml = jest.fn( ( callback ) => { - triggerHtmlSerialization = callback; +subscribeParentGetHtml.mockImplementation( ( callback ) => { + if ( ! triggerHtmlSerialization ) { + triggerHtmlSerialization = callback; + return { + remove: () => { + triggerHtmlSerialization = undefined; + }, + }; + } } ); -bridgeMock.provideToNative_Html = jest.fn( ( html ) => { +provideToNativeHtml.mockImplementation( ( html ) => { serializedHtml = html; } ); @@ -83,6 +93,9 @@ export function waitFor( cb, timeout = 150 ) { // Helper for getting the current HTML output of the editor export function getEditorHtml() { + if ( ! triggerHtmlSerialization ) { + throw new Error( 'HTML serialization trigger is not defined.' ); + } triggerHtmlSerialization(); return serializedHtml; } From f5414224a2278126766c55a7f5abf52037ac2f3b Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Fri, 4 Jun 2021 15:21:22 +0200 Subject: [PATCH 13/22] Add mocked styles for rendering the inserter menu --- test/native/__mocks__/styleMock.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test/native/__mocks__/styleMock.js b/test/native/__mocks__/styleMock.js index 46f0d1a2b41079..d369d27b926544 100644 --- a/test/native/__mocks__/styleMock.js +++ b/test/native/__mocks__/styleMock.js @@ -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', + }, }; From 38853630aa51ffea6c991cc34bd53e308cccb198 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Fri, 4 Jun 2021 15:21:48 +0200 Subject: [PATCH 14/22] Add testID to block types list component --- .../block-editor/src/components/block-types-list/index.native.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/block-editor/src/components/block-types-list/index.native.js b/packages/block-editor/src/components/block-types-list/index.native.js index 9c330a38ac66b2..485cde15fbf1fa 100644 --- a/packages/block-editor/src/components/block-types-list/index.native.js +++ b/packages/block-editor/src/components/block-types-list/index.native.js @@ -77,6 +77,7 @@ export default function BlockTypesList( { name, items, onSelect, listProps } ) { Date: Fri, 4 Jun 2021 15:27:53 +0200 Subject: [PATCH 15/22] Update block mobile toolbar to prevent a render error We shouldn't update the state from the slot rendering because it's a different component, otherwise it fails with the following error: Warning: Cannot update a component (`BlockMobileToolbar`) while rendering a different component (`BlockSettingsFill`). To locate the bad setState() call inside `BlockSettingsFill`, follow the stack trace as described in https://fb.me/setstate-in-render --- .../block-mobile-toolbar/index.native.js | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/packages/block-editor/src/components/block-mobile-toolbar/index.native.js b/packages/block-editor/src/components/block-mobile-toolbar/index.native.js index 440137968b5d73..aacbdfc18b47f7 100644 --- a/packages/block-editor/src/components/block-mobile-toolbar/index.native.js +++ b/packages/block-editor/src/components/block-mobile-toolbar/index.native.js @@ -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 @@ -53,6 +53,11 @@ const BlockMobileToolbar = ( { blockWidth <= BREAKPOINTS.wrapMover || appenderWidth - spacingValue <= BREAKPOINTS.wrapMover; + const BlockSettingsButtonFill = ( { children, onMount } ) => { + useEffect( onMount, [] ); + return children ?? null; + }; + return ( { /* 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 ] ) => ( + // This purpose of this component is only to provide a way + // to pass data from the slot rendering to the component + setFillsLength( fills.length ) } + > + { wrapBlockSettings ? null : fills[ 0 ] } + + ) } Date: Fri, 4 Jun 2021 15:34:59 +0200 Subject: [PATCH 16/22] Add insert reusable block test case --- .../src/block/test/edit.native.js | 83 +++++++++++++++---- 1 file changed, 68 insertions(+), 15 deletions(-) diff --git a/packages/block-library/src/block/test/edit.native.js b/packages/block-library/src/block/test/edit.native.js index 1e4c18bcc37126..4767cc30880165 100644 --- a/packages/block-library/src/block/test/edit.native.js +++ b/packages/block-library/src/block/test/edit.native.js @@ -58,11 +58,76 @@ 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 } ) => { + if ( path.startsWith( '/wp/v2/blocks?' ) ) { + return Promise.resolve( [ + reusableBlockMock1, + reusableBlockMock2, + ] ); + } else if ( path.startsWith( '/wp/v2/blocks/1' ) ) { + return reusableBlockMock1; + } else if ( path.startsWith( '/wp/v2/blocks/2' ) ) { + return reusableBlockMock2; + } + } ); + + const { + getByA11yLabel, + getByTestId, + getByText, + } = await initializeEditor( { + initialHtml: '', + } ); + + // Open the inserter menu + fireEvent.press( await waitFor( () => getByA11yLabel( 'Add block' ) ) ); + + // Navigate to reusable tab + const reusableSegment = getByA11yLabel( '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( '' ); + } ); + 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 = ``; - const endpoint = `/wp/v2/blocks/${ id }`; const { getByA11yLabel } = await initializeEditor( { initialHtml, @@ -72,25 +137,19 @@ 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(); expect( reusableBlock ).toBeDefined(); expect( blockDeleted ).toBeDefined(); - expect( getEditorHtml() ).toBe( initialHtml ); } ); 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 = ``; const endpoint = `/wp/v2/blocks/${ id }`; @@ -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' ) ); @@ -133,9 +188,7 @@ describe( 'Reusable block', () => { ) ); - expect( reusableBlockRequest ).toBeDefined(); expect( reusableBlock ).toBeDefined(); expect( headingInnerBlock ).toBeDefined(); - expect( getEditorHtml() ).toBe( initialHtml ); } ); } ); From f363fd0145be9735710f5f8e20935f07f3bbb2ac Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Tue, 8 Jun 2021 10:55:13 +0200 Subject: [PATCH 17/22] Allow any prop in initializeEditor --- test/native/helpers.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/test/native/helpers.js b/test/native/helpers.js index 9033635d322481..623b5131845411 100644 --- a/test/native/helpers.js +++ b/test/native/helpers.js @@ -33,14 +33,9 @@ provideToNativeHtml.mockImplementation( ( html ) => { serializedHtml = html; } ); -export async function initializeEditor( { initialHtml } ) { +export async function initializeEditor( props ) { const renderResult = render( - + ); const { getByTestId } = renderResult; From 719e2b7d936f6002fba181a5beaae90a184777a6 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Tue, 8 Jun 2021 10:55:39 +0200 Subject: [PATCH 18/22] Add reusableBlock capability in integration test --- packages/block-library/src/block/test/edit.native.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/block-library/src/block/test/edit.native.js b/packages/block-library/src/block/test/edit.native.js index 4767cc30880165..82c915835dee0f 100644 --- a/packages/block-library/src/block/test/edit.native.js +++ b/packages/block-library/src/block/test/edit.native.js @@ -83,6 +83,7 @@ describe( 'Reusable block', () => { getByText, } = await initializeEditor( { initialHtml: '', + capabilities: { reusableBlock: true }, } ); // Open the inserter menu From 75b541673e453f22e88c3afd9e67194a69e59bbe Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Wed, 23 Jun 2021 12:58:31 +0200 Subject: [PATCH 19/22] Update block mobile toolbar fill logic --- .../block-mobile-toolbar/index.native.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/block-editor/src/components/block-mobile-toolbar/index.native.js b/packages/block-editor/src/components/block-mobile-toolbar/index.native.js index aacbdfc18b47f7..eeff33568d1d96 100644 --- a/packages/block-editor/src/components/block-mobile-toolbar/index.native.js +++ b/packages/block-editor/src/components/block-mobile-toolbar/index.native.js @@ -53,9 +53,12 @@ const BlockMobileToolbar = ( { blockWidth <= BREAKPOINTS.wrapMover || appenderWidth - spacingValue <= BREAKPOINTS.wrapMover; - const BlockSettingsButtonFill = ( { children, onMount } ) => { - useEffect( onMount, [] ); - return children ?? null; + const BlockSettingsButtonFill = ( fillProps ) => { + useEffect( + () => fillProps.onChangeFillsLength( fillProps.fillsLength ), + [ fillProps.fillsLength ] + ); + return fillProps.children ?? null; }; return ( @@ -75,10 +78,11 @@ const BlockMobileToolbar = ( { { /* Render only one settings icon even if we have more than one fill - need for hooks with controls */ } { ( fills = [ null ] ) => ( - // This purpose of this component is only to provide a way - // to pass data from the slot rendering to the component + // The purpose of BlockSettingsButtonFill component is only to provide a way + // to pass data upstream from the slot rendering setFillsLength( fills.length ) } + fillsLength={ fills.length } + onChangeFillsLength={ setFillsLength } > { wrapBlockSettings ? null : fills[ 0 ] } From 409a0740d7b0d63d32be4a956608f58208df7293 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Wed, 23 Jun 2021 13:13:37 +0200 Subject: [PATCH 20/22] Query reusable segment element by text --- packages/block-library/src/block/test/edit.native.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-library/src/block/test/edit.native.js b/packages/block-library/src/block/test/edit.native.js index 82c915835dee0f..96c9d742dbd6bc 100644 --- a/packages/block-library/src/block/test/edit.native.js +++ b/packages/block-library/src/block/test/edit.native.js @@ -90,7 +90,7 @@ describe( 'Reusable block', () => { fireEvent.press( await waitFor( () => getByA11yLabel( 'Add block' ) ) ); // Navigate to reusable tab - const reusableSegment = getByA11yLabel( 'Reusable' ); + const reusableSegment = getByText( 'Reusable' ); // onLayout event is required by Segment component fireEvent( reusableSegment, 'layout', { nativeEvent: { From 69f42f2aa1359f1df7003cdaa5399ce7bda13cf2 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Thu, 24 Jun 2021 10:43:03 +0200 Subject: [PATCH 21/22] Update fetch request mocks to return always a promise --- .../block-library/src/block/test/edit.native.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/block-library/src/block/test/edit.native.js b/packages/block-library/src/block/test/edit.native.js index 96c9d742dbd6bc..19e4101d3aea3d 100644 --- a/packages/block-library/src/block/test/edit.native.js +++ b/packages/block-library/src/block/test/edit.native.js @@ -65,16 +65,15 @@ describe( 'Reusable block', () => { // Return mocked responses for the block endpoints. fetchRequest.mockImplementation( ( { path } ) => { + let response = {}; if ( path.startsWith( '/wp/v2/blocks?' ) ) { - return Promise.resolve( [ - reusableBlockMock1, - reusableBlockMock2, - ] ); + response = [ reusableBlockMock1, reusableBlockMock2 ]; } else if ( path.startsWith( '/wp/v2/blocks/1' ) ) { - return reusableBlockMock1; + response = reusableBlockMock1; } else if ( path.startsWith( '/wp/v2/blocks/2' ) ) { - return reusableBlockMock2; + response = reusableBlockMock2; } + return Promise.resolve( response ); } ); const { @@ -156,9 +155,11 @@ describe( 'Reusable block', () => { // 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( { From da86065801fce22861b1c4bb2669a14522726fb8 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Thu, 24 Jun 2021 10:45:10 +0200 Subject: [PATCH 22/22] Remove unneeded fetch request mock --- packages/block-library/src/block/test/edit.native.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/block-library/src/block/test/edit.native.js b/packages/block-library/src/block/test/edit.native.js index 19e4101d3aea3d..de83b2fe1692ef 100644 --- a/packages/block-library/src/block/test/edit.native.js +++ b/packages/block-library/src/block/test/edit.native.js @@ -70,8 +70,6 @@ describe( 'Reusable block', () => { response = [ reusableBlockMock1, reusableBlockMock2 ]; } else if ( path.startsWith( '/wp/v2/blocks/1' ) ) { response = reusableBlockMock1; - } else if ( path.startsWith( '/wp/v2/blocks/2' ) ) { - response = reusableBlockMock2; } return Promise.resolve( response ); } );