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

"Multiple use" block validation logic improvement [with Playwright] #57576

Merged
merged 10 commits into from Feb 9, 2024
31 changes: 28 additions & 3 deletions packages/edit-post/src/hooks/validate-multiple-use/index.js
Expand Up @@ -15,6 +15,33 @@ import { addFilter } from '@wordpress/hooks';
import { __ } from '@wordpress/i18n';
import { compose, createHigherOrderComponent } from '@wordpress/compose';

/**
* Recursively find very first block of an specific block type.
*
* @param {Object[]} blocks List of blocks.
* @param {string} name Block name to search.
*
* @return {Object|undefined} Return block object or undefined.
*/
function findFirstOfSameType( blocks, name ) {
if ( ! Array.isArray( blocks ) || ! blocks.length ) {
return;
}

for ( const block of blocks ) {
if ( block.name === name ) {
return block;
}

// Search inside innerBlocks.
const firstBlock = findFirstOfSameType( block.innerBlocks, name );

if ( firstBlock ) {
return firstBlock;
}
}
}

const enhance = compose(
/**
* For blocks whose block type doesn't support `multiple`, provides the
Expand All @@ -39,9 +66,7 @@ const enhance = compose(
// Otherwise, only pass `originalBlockClientId` if it refers to a different
// block from the current one.
const blocks = select( blockEditorStore ).getBlocks();
const firstOfSameType = blocks.find(
( { name } ) => block.name === name
);
const firstOfSameType = findFirstOfSameType( blocks, block.name );
const isInvalid =
firstOfSameType && firstOfSameType.clientId !== block.clientId;
return {
Expand Down
38 changes: 38 additions & 0 deletions test/e2e/specs/editor/various/validate-multiple-use.spec.js
@@ -0,0 +1,38 @@
/**
* WordPress dependencies
*/

const { test, expect } = require( '@wordpress/e2e-test-utils-playwright' );

test.describe( 'Validate multiple use', () => {
test.beforeEach( async ( { admin } ) => {
await admin.createNewPost();
} );

test( 'should display correct amount of warning message', async ( {
getdave marked this conversation as resolved.
Show resolved Hide resolved
editor,
page,
} ) => {
// Insert a block with `multiple` feature enabled, such as `core/more`
getdave marked this conversation as resolved.
Show resolved Hide resolved
await editor.insertBlock( {
name: 'core/more',
} );

const optionButton = page.locator(
".components-dropdown-menu__toggle[data-toolbar-item='true'][aria-label='Options']"
);
fai-sal marked this conversation as resolved.
Show resolved Hide resolved

// Group the block
await optionButton.click();
await page.getByText( 'Group' ).click();
fai-sal marked this conversation as resolved.
Show resolved Hide resolved

// Duplicate the block
await optionButton.click();
await page.getByText( 'Duplicate' ).click();
fai-sal marked this conversation as resolved.
Show resolved Hide resolved

// Check if warnings is visible
getdave marked this conversation as resolved.
Show resolved Hide resolved
await expect(
page.frameLocator( 'iFrame' ).locator( '.block-editor-warning' )
fai-sal marked this conversation as resolved.
Show resolved Hide resolved
).toBeVisible();
} );
} );