From 5d566cc778cc8e70faa02c0dab982cfef9d13841 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 23 Feb 2023 11:37:04 +0000 Subject: [PATCH 1/8] Initial attempt --- packages/block-editor/src/hooks/duotone.js | 2 +- .../block-editor/src/hooks/test/duotone.js | 103 ++++++++++++++++++ 2 files changed, 104 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/hooks/duotone.js b/packages/block-editor/src/hooks/duotone.js index fef0f8de32cddc..5ca76aa58af576 100644 --- a/packages/block-editor/src/hooks/duotone.js +++ b/packages/block-editor/src/hooks/duotone.js @@ -187,7 +187,7 @@ function addDuotoneAttributes( settings ) { * * @return {Function} Wrapped component. */ -const withDuotoneControls = createHigherOrderComponent( +export const withDuotoneControls = createHigherOrderComponent( ( BlockEdit ) => ( props ) => { const hasDuotoneSupport = hasBlockSupport( props.name, diff --git a/packages/block-editor/src/hooks/test/duotone.js b/packages/block-editor/src/hooks/test/duotone.js index b97c967d212f07..78aa9ed9c43e44 100644 --- a/packages/block-editor/src/hooks/test/duotone.js +++ b/packages/block-editor/src/hooks/test/duotone.js @@ -1,11 +1,114 @@ +/** + * External dependencies + */ +import { render, screen } from '@testing-library/react'; + +/** + * WordPress dependencies + */ +import { registerBlockType, unregisterBlockType } from '@wordpress/blocks'; +import { SlotFillProvider } from '@wordpress/components'; + /** * Internal dependencies */ +import BlockEditorProvider from '../../components/provider'; +import BlockControls from '../../components/block-controls'; +// eslint-disable-next-line no-unused-vars +import BlockEdit from '../../components/block-edit'; import { + withDuotoneControls, getColorsFromDuotonePreset, getDuotonePresetFromColors, } from '../duotone'; +describe( 'withDuotoneControls', () => { + const blockName = 'core/test-block'; + + const blockSettings = { + save: () => {}, + category: 'media', + title: 'Block Title', + edit: ( { children } ) => <>{ children }, + supports: { + color: { + __experimentalDuotone: 'img', + }, + }, + }; + + const componentProps = { + name: blockName, + attributes: {}, + isSelected: true, + }; + + const settings = { + __experimentalFeatures: { + color: { + palette: { + default: [ + { + name: 'Pale pink', + slug: 'pale-pink', + color: '#f78da7', + }, + { + name: 'Vivid green cyan', + slug: 'vivid-green-cyan', + color: '#00d084', + }, + ], + }, + defaultDuotone: true, + duotone: { + default: [ + { + name: 'Black and white', + slug: 'black-and-white', + colors: [ '#000000', '#FFFFFF' ], + }, + { + name: 'Pale pink and green', + slug: 'palepink-green', + colors: [ '#f78da7', '#00d084' ], + }, + ], + }, + }, + }, + }; + + beforeEach( () => { + registerBlockType( blockName, blockSettings ); + } ); + + afterEach( () => { + unregisterBlockType( blockName ); + } ); + + it( 'should show Duotone control in toolbar', () => { + const EnhancedComponent = withDuotoneControls( ( { wrapperProps } ) => ( +
+ ) ); + + render( + + + + + + + ); + + expect( + screen.getByRole( 'button', { + name: 'Apply duotone filter"', + } ) + ).toBeInTheDocument(); + } ); +} ); + describe( 'Duotone utilities', () => { const duotonePalette = [ { From 56d14360b608366c13cca1d24cc20bc48024639e Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 28 Feb 2023 17:26:31 +1300 Subject: [PATCH 2/8] Wrap the EnhancedComponent in a BlockEdit --- packages/block-editor/src/hooks/test/duotone.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/hooks/test/duotone.js b/packages/block-editor/src/hooks/test/duotone.js index 78aa9ed9c43e44..81f52fa4676163 100644 --- a/packages/block-editor/src/hooks/test/duotone.js +++ b/packages/block-editor/src/hooks/test/duotone.js @@ -95,7 +95,9 @@ describe( 'withDuotoneControls', () => { render( - + + + @@ -103,7 +105,7 @@ describe( 'withDuotoneControls', () => { expect( screen.getByRole( 'button', { - name: 'Apply duotone filter"', + name: 'Apply duotone filter', } ) ).toBeInTheDocument(); } ); From a0143cdbecb162ecd902b813c0e42041e7fcaca8 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Tue, 28 Feb 2023 10:04:42 +0000 Subject: [PATCH 3/8] Apply correct setup state --- packages/block-editor/src/hooks/test/duotone.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/hooks/test/duotone.js b/packages/block-editor/src/hooks/test/duotone.js index 81f52fa4676163..3cbf005fbb70ec 100644 --- a/packages/block-editor/src/hooks/test/duotone.js +++ b/packages/block-editor/src/hooks/test/duotone.js @@ -96,7 +96,7 @@ describe( 'withDuotoneControls', () => { - + From 5eec7ba9998c204ffc384593421f0a6fe43ef4b0 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Tue, 28 Feb 2023 10:20:22 +0000 Subject: [PATCH 4/8] =?UTF-8?q?Fix=20Picker=20to=20give=20accessible=20lab?= =?UTF-8?q?el=20to=20=E2=80=9CUnset=E2=80=9D=20Duotone=20option?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/components/src/duotone-picker/duotone-picker.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/components/src/duotone-picker/duotone-picker.js b/packages/components/src/duotone-picker/duotone-picker.js index 4f9e5ea7b23ce6..f0b55fbdb39f47 100644 --- a/packages/components/src/duotone-picker/duotone-picker.js +++ b/packages/components/src/duotone-picker/duotone-picker.js @@ -42,6 +42,7 @@ function DuotonePicker( { key="unset" value="unset" isSelected={ isUnset } + aria-label={ __( 'Unset' ) } tooltipText={ __( 'Unset' ) } className="components-duotone-picker__color-indicator" onClick={ () => { From f1bca20183b8a029db9b3cc70ffdab16916141f1 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Tue, 28 Feb 2023 10:30:45 +0000 Subject: [PATCH 5/8] Simplify to single test asserting on presence of Duotone panel --- .../block-editor/src/hooks/test/duotone.js | 47 ++++++++++++++----- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/packages/block-editor/src/hooks/test/duotone.js b/packages/block-editor/src/hooks/test/duotone.js index 3cbf005fbb70ec..f646b83b8e028b 100644 --- a/packages/block-editor/src/hooks/test/duotone.js +++ b/packages/block-editor/src/hooks/test/duotone.js @@ -2,6 +2,7 @@ * External dependencies */ import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; /** * WordPress dependencies @@ -43,7 +44,7 @@ describe( 'withDuotoneControls', () => { isSelected: true, }; - const settings = { + const blockEditorSettings = { __experimentalFeatures: { color: { palette: { @@ -79,6 +80,13 @@ describe( 'withDuotoneControls', () => { }, }; + const duotonePresets = + blockEditorSettings.__experimentalFeatures.color.duotone.default; + + const EnhancedComponent = withDuotoneControls( ( { wrapperProps } ) => ( +
+ ) ); + beforeEach( () => { registerBlockType( blockName, blockSettings ); } ); @@ -87,13 +95,10 @@ describe( 'withDuotoneControls', () => { unregisterBlockType( blockName ); } ); - it( 'should show Duotone control in toolbar', () => { - const EnhancedComponent = withDuotoneControls( ( { wrapperProps } ) => ( -
- ) ); - + it( 'should show Duotone panel with presets in toolbar for blocks that support Duotone', async () => { + const user = userEvent.setup(); render( - + @@ -103,11 +108,29 @@ describe( 'withDuotoneControls', () => { ); - expect( - screen.getByRole( 'button', { - name: 'Apply duotone filter', - } ) - ).toBeInTheDocument(); + const duotoneToggleButton = screen.getByRole( 'button', { + name: 'Apply duotone filter', + } ); + + await user.click( duotoneToggleButton ); + + const duotonePopover = screen.queryByRole( 'group', { + name: 'Duotone', + } ); + expect( duotonePopover ).toBeInTheDocument(); + + const unsetOption = screen.queryByRole( 'button', { + name: 'Unset', + } ); + expect( unsetOption ).toBeInTheDocument(); + + duotonePresets?.forEach( ( preset ) => { + // check in document + const presetOption = screen.queryByRole( 'button', { + name: `Duotone: ${ preset.name }`, + } ); + expect( presetOption ).toBeInTheDocument(); + } ); } ); } ); From 188fae142ccad105042d28a150b6b2508512f210 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Tue, 28 Feb 2023 10:36:08 +0000 Subject: [PATCH 6/8] Add test for block that does not support Duotone --- .../block-editor/src/hooks/test/duotone.js | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/hooks/test/duotone.js b/packages/block-editor/src/hooks/test/duotone.js index f646b83b8e028b..213b255b638b34 100644 --- a/packages/block-editor/src/hooks/test/duotone.js +++ b/packages/block-editor/src/hooks/test/duotone.js @@ -38,7 +38,7 @@ describe( 'withDuotoneControls', () => { }, }; - const componentProps = { + const blockProps = { name: blockName, attributes: {}, isSelected: true, @@ -95,12 +95,42 @@ describe( 'withDuotoneControls', () => { unregisterBlockType( blockName ); } ); + it( 'should not show Duotone panel in toolbar for blocks that do not support Duotone', () => { + // A Block with no duotone support. + registerBlockType( 'test/no-duotone-support-block', { + ...blockSettings, + name: 'Block with no duotone support', + supports: {}, // no duotone support. + } ); + + const blockNoDuotoneProps = { + ...blockProps, + name: 'test/no-duotone-support-block', + }; + + render( + + + + + + + + + ); + + const duotoneToggleButton = screen.queryByRole( 'button', { + name: 'Apply duotone filter', + } ); + expect( duotoneToggleButton ).not.toBeInTheDocument(); + } ); + it( 'should show Duotone panel with presets in toolbar for blocks that support Duotone', async () => { const user = userEvent.setup(); render( - + From 750d448a9a264711a9b723b4a7ac9d3a127c1d1f Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Tue, 28 Feb 2023 10:56:05 +0000 Subject: [PATCH 7/8] Test selected Duotone preset matches with block attribute --- .../block-editor/src/hooks/test/duotone.js | 44 +++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/packages/block-editor/src/hooks/test/duotone.js b/packages/block-editor/src/hooks/test/duotone.js index 213b255b638b34..bb66b942304686 100644 --- a/packages/block-editor/src/hooks/test/duotone.js +++ b/packages/block-editor/src/hooks/test/duotone.js @@ -83,7 +83,7 @@ describe( 'withDuotoneControls', () => { const duotonePresets = blockEditorSettings.__experimentalFeatures.color.duotone.default; - const EnhancedComponent = withDuotoneControls( ( { wrapperProps } ) => ( + const WithDuotoneControls = withDuotoneControls( ( { wrapperProps } ) => (
) ); @@ -112,7 +112,7 @@ describe( 'withDuotoneControls', () => { - + @@ -131,7 +131,7 @@ describe( 'withDuotoneControls', () => { - + @@ -162,6 +162,44 @@ describe( 'withDuotoneControls', () => { expect( presetOption ).toBeInTheDocument(); } ); } ); + + it( 'should select the duotone preset in the panel when the block attribute contains a duotone preset', async () => { + const user = userEvent.setup(); + const duotonePreset = duotonePresets[ 0 ]; + const blockWithDuotoneProps = { + ...blockProps, + attributes: { + style: { + color: { + duotone: duotonePreset.slug, + }, + }, + }, + }; + + render( + + + + + + + + + ); + + const duotoneToggleButton = screen.getByRole( 'button', { + name: 'Apply duotone filter', + } ); + + await user.click( duotoneToggleButton ); + + const presetOption = screen.queryByRole( 'button', { + name: `Duotone: ${ duotonePreset.name }`, + pressed: true, // the selected preset should be pressed. + } ); + expect( presetOption ).toBeInTheDocument(); + } ); } ); describe( 'Duotone utilities', () => { From 208697efb968cbd4e691bf7d55a1267359297470 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Tue, 28 Feb 2023 11:01:03 +0000 Subject: [PATCH 8/8] Check preset not selected if Duotone is custom --- .../block-editor/src/hooks/test/duotone.js | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/packages/block-editor/src/hooks/test/duotone.js b/packages/block-editor/src/hooks/test/duotone.js index bb66b942304686..3f95d1591ae050 100644 --- a/packages/block-editor/src/hooks/test/duotone.js +++ b/packages/block-editor/src/hooks/test/duotone.js @@ -200,6 +200,52 @@ describe( 'withDuotoneControls', () => { } ); expect( presetOption ).toBeInTheDocument(); } ); + + it( 'should not show a selected Duotone preset in the panel when the block attribute contains a custom duotone', async () => { + const user = userEvent.setup(); + const blockWithDuotoneProps = { + ...blockProps, + attributes: { + style: { + color: { + duotone: [ 'rgb(0, 0, 0)', 'rgb(255, 255, 255)' ], + }, + }, + }, + }; + + render( + + + + + + + + + ); + + const duotoneToggleButton = screen.getByRole( 'button', { + name: 'Apply duotone filter', + } ); + + await user.click( duotoneToggleButton ); + + const unsetOption = screen.queryByRole( 'button', { + name: 'Unset', + pressed: false, // the unset option should not be pressed. + } ); + expect( unsetOption ).toBeInTheDocument(); + + duotonePresets?.forEach( ( preset ) => { + // check in document + const presetOption = screen.queryByRole( 'button', { + name: `Duotone: ${ preset.name }`, + pressed: false, // no preset should be pressed. + } ); + expect( presetOption ).toBeInTheDocument(); + } ); + } ); } ); describe( 'Duotone utilities', () => {