Skip to content

Commit

Permalink
Block Locking: Fix regression in selectors (#51541)
Browse files Browse the repository at this point in the history
* Block Locking: Fix regression in selectors
* A minor adjustments to the e2e tests
* Add e2e tests for block locking and template lock
  • Loading branch information
Mamaduka authored Jun 16, 2023
1 parent f4f844e commit 309d762
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 63 deletions.
22 changes: 9 additions & 13 deletions packages/block-editor/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -1667,16 +1667,14 @@ export function canRemoveBlock( state, clientId, rootClientId = null ) {
if ( attributes === null ) {
return true;
}
if ( attributes.lock?.remove ) {
return false;
if ( attributes.lock?.remove !== undefined ) {
return ! attributes.lock.remove;
}
if ( getTemplateLock( state, rootClientId ) ) {
return false;
}
if ( getBlockEditingMode( state, rootClientId ) === 'disabled' ) {
return false;
}
return true;

return getBlockEditingMode( state, rootClientId ) !== 'disabled';
}

/**
Expand Down Expand Up @@ -1706,18 +1704,16 @@ export function canRemoveBlocks( state, clientIds, rootClientId = null ) {
export function canMoveBlock( state, clientId, rootClientId = null ) {
const attributes = getBlockAttributes( state, clientId );
if ( attributes === null ) {
return;
return true;
}
if ( attributes.lock?.move ) {
return false;
if ( attributes.lock?.move !== undefined ) {
return ! attributes.lock.move;
}
if ( getTemplateLock( state, rootClientId ) === 'all' ) {
return false;
}
if ( getBlockEditingMode( state, rootClientId ) === 'disabled' ) {
return false;
}
return true;

return getBlockEditingMode( state, rootClientId ) !== 'disabled';
}

/**
Expand Down
156 changes: 106 additions & 50 deletions test/e2e/specs/editor/various/block-locking.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,79 +8,135 @@ test.describe( 'Block Locking', () => {
await admin.createNewPost();
} );

test.describe( 'General', () => {
test( 'can prevent removal', async ( { editor, page } ) => {
await editor.insertBlock( { name: 'core/paragraph' } );
await page.keyboard.type( 'Some paragraph' );
test( 'can prevent removal', async ( { editor, page } ) => {
await editor.canvas.click( 'role=button[name="Add default block"i]' );
await page.keyboard.type( 'Some paragraph' );

await editor.clickBlockOptionsMenuItem( 'Lock' );
await editor.clickBlockOptionsMenuItem( 'Lock' );

await page.click( 'role=checkbox[name="Prevent removal"]' );
await page.click( 'role=button[name="Apply"]' );
await page.click( 'role=checkbox[name="Prevent removal"]' );
await page.click( 'role=button[name="Apply"]' );

await expect(
page.locator( 'role=menuitem[name="Delete"]' )
).not.toBeVisible();
} );
await expect(
page.locator( 'role=menuitem[name="Delete"]' )
).not.toBeVisible();
} );

test( 'can disable movement', async ( { editor, page } ) => {
await editor.insertBlock( { name: 'core/paragraph' } );
await page.keyboard.type( 'First paragraph' );
test( 'can disable movement', async ( { editor, page } ) => {
await editor.canvas.click( 'role=button[name="Add default block"i]' );
await page.keyboard.type( 'First paragraph' );

await editor.insertBlock( { name: 'core/paragraph' } );
await page.keyboard.type( 'Second paragraph' );
await page.keyboard.type( 'Enter' );
await page.keyboard.type( 'Second paragraph' );

await editor.clickBlockOptionsMenuItem( 'Lock' );
await editor.clickBlockOptionsMenuItem( 'Lock' );

await page.click( 'role=checkbox[name="Disable movement"]' );
await page.click( 'role=button[name="Apply"]' );
await page.click( 'role=checkbox[name="Disable movement"]' );
await page.click( 'role=button[name="Apply"]' );

// Hide options.
await editor.clickBlockToolbarButton( 'Options' );
// Hide options.
await editor.clickBlockToolbarButton( 'Options' );

// Drag handle is hidden.
await expect(
page.locator( 'role=button[name="Drag"]' )
).not.toBeVisible();
// Drag handle is hidden.
await expect(
page.locator( 'role=button[name="Drag"]' )
).not.toBeVisible();

// Movers are hidden. No need to check for both.
await expect(
page.locator( 'role=button[name="Move up"]' )
).not.toBeVisible();
} );
// Movers are hidden. No need to check for both.
await expect(
page.locator( 'role=button[name="Move up"]' )
).not.toBeVisible();
} );

test( 'can lock everything', async ( { editor, page } ) => {
await editor.insertBlock( { name: 'core/paragraph' } );
await page.keyboard.type( 'Some paragraph' );
test( 'can lock everything', async ( { editor, page } ) => {
await editor.canvas.click( 'role=button[name="Add default block"i]' );
await page.keyboard.type( 'Some paragraph' );

await editor.clickBlockOptionsMenuItem( 'Lock' );
await editor.clickBlockOptionsMenuItem( 'Lock' );

await page.click( 'role=checkbox[name="Lock all"]' );
await page.click( 'role=button[name="Apply"]' );
await page.click( 'role=checkbox[name="Lock all"]' );
await page.click( 'role=button[name="Apply"]' );

expect( await editor.getEditedPostContent() )
.toBe( `<!-- wp:paragraph {"lock":{"move":true,"remove":true}} -->
expect( await editor.getEditedPostContent() )
.toBe( `<!-- wp:paragraph {"lock":{"move":true,"remove":true}} -->
<p>Some paragraph</p>
<!-- /wp:paragraph -->` );
} );
} );

test( 'can unlock from toolbar', async ( { editor, page } ) => {
await editor.insertBlock( { name: 'core/paragraph' } );
await page.keyboard.type( 'Some paragraph' );
test( 'can unlock from toolbar', async ( { editor, page } ) => {
await editor.canvas.click( 'role=button[name="Add default block"i]' );
await page.keyboard.type( 'Some paragraph' );

await editor.clickBlockOptionsMenuItem( 'Lock' );
await editor.clickBlockOptionsMenuItem( 'Lock' );

await page.click( 'role=checkbox[name="Lock all"]' );
await page.click( 'role=button[name="Apply"]' );
await page.click( 'role=checkbox[name="Lock all"]' );
await page.click( 'role=button[name="Apply"]' );

await editor.clickBlockToolbarButton( 'Unlock' );
await page.click( 'role=checkbox[name="Lock all"]' );
await page.click( 'role=button[name="Apply"]' );
await editor.clickBlockToolbarButton( 'Unlock' );
await page.click( 'role=checkbox[name="Lock all"]' );
await page.click( 'role=button[name="Apply"]' );

expect( await editor.getEditedPostContent() )
.toBe( `<!-- wp:paragraph {"lock":{"move":false,"remove":false}} -->
expect( await editor.getEditedPostContent() )
.toBe( `<!-- wp:paragraph {"lock":{"move":false,"remove":false}} -->
<p>Some paragraph</p>
<!-- /wp:paragraph -->` );
} );

test( 'block locking supersedes template locking', async ( {
editor,
page,
pageUtils,
} ) => {
await editor.insertBlock( {
name: 'core/group',
attributes: {
layout: { type: 'constrained' },
templateLock: 'all',
},
innerBlocks: [
{
name: 'core/heading',
attributes: { content: 'Hello, hello' },
},
{
name: 'core/paragraph',
attributes: { content: 'WordPress' },
},
],
} );

const paragraph = editor.canvas.getByRole( 'document', {
name: 'Paragraph block',
} );
await paragraph.click();

await editor.clickBlockToolbarButton( 'Unlock' );
await page.click( 'role=checkbox[name="Lock all"]' );
await page.click( 'role=button[name="Apply"]' );

await expect(
page
.getByRole( 'toolbar', { name: 'Block tools' } )
.getByRole( 'button', { name: 'Move up' } )
).toBeVisible();

await paragraph.click();
await pageUtils.pressKeys( 'access+z' );

await expect.poll( editor.getBlocks ).toMatchObject( [
{
name: 'core/group',
attributes: {
layout: { type: 'constrained' },
templateLock: 'all',
},
innerBlocks: [
{
name: 'core/heading',
attributes: { content: 'Hello, hello' },
},
],
},
] );
} );
} );

1 comment on commit 309d762

@github-actions
Copy link

Choose a reason for hiding this comment

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

Flaky tests detected in 309d762.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/5286981104
📝 Reported issues:

Please sign in to comment.