Template API: Conditional disabling support (#41307)

* Add disable conditions functionality to back-end

* Evaluate _templateBlockDisableConditions in registerWooBlockType

* Add 'disabled' support for number, pricing, and text

* Add disabled support for checkbox

* Add disabled for taxonomy block

* Add changelogs

* Update documentation

* Add unit tests

* Augment attribute with disabled in back-end

* Fix disabled styling

* Remove disabled from toggle since it's being added for all blocks

* Improve CSS for disabled fields

* Only add disabled attribute when it's not added on the block json and refactor

* Allow adding disable conditions in the constructor

* Fix lint issue

* Fix test

* Add disableConditions to dependencies
This commit is contained in:
Nathan Silveira 2023-11-14 13:17:34 -03:00 committed by GitHub
parent 7ec5a88573
commit 55766ac140
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 485 additions and 177 deletions

View File

@ -0,0 +1,4 @@
Significance: minor
Type: add
Use _templateBlockDisableConditions attribute to evaluate disabled attribute

View File

@ -46,31 +46,46 @@ function getEdit<
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore context is added to the block props by the block editor.
const { context } = props;
const { _templateBlockHideConditions: hideConditions } =
props.attributes;
const {
_templateBlockHideConditions: hideConditions,
_templateBlockDisableConditions: disableConditions,
} = props.attributes;
const { getEvaluationContext } = useEvaluationContext( context );
const shouldHide = useSelect(
const { shouldHide, shouldDisable } = useSelect(
( select: typeof WPSelect ) => {
if ( ! hideConditions || ! Array.isArray( hideConditions ) ) {
return false;
}
const evaluationContext = getEvaluationContext( select );
return hideConditions.some( ( condition ) =>
evaluate( condition.expression, evaluationContext )
);
return {
shouldHide:
hideConditions &&
Array.isArray( hideConditions ) &&
hideConditions.some( ( condition ) =>
evaluate( condition.expression, evaluationContext )
),
shouldDisable:
disableConditions &&
Array.isArray( disableConditions ) &&
disableConditions.some( ( condition ) =>
evaluate( condition.expression, evaluationContext )
),
};
},
[ getEvaluationContext, hideConditions ]
[ getEvaluationContext, hideConditions, disableConditions ]
);
if ( ! edit || shouldHide ) {
return null;
}
return createElement( edit, props );
return createElement( edit, {
...props,
attributes: {
...props.attributes,
disabled: props.attributes.disabled || shouldDisable,
},
} );
};
}
@ -95,6 +110,14 @@ function augmentAttributes<
type: 'array',
__experimentalRole: 'content',
},
_templateBlockDisableConditions: {
type: 'array',
__experimentalRole: 'content',
},
disabled: attributes.disabled || {
type: 'boolean',
__experimentalRole: 'content',
},
},
};
}

View File

@ -54,6 +54,14 @@ describe( 'registerWooBlockType', () => {
type: 'array',
__experimentalRole: 'content',
},
_templateBlockDisableConditions: {
__experimentalRole: 'content',
type: 'array',
},
disabled: {
__experimentalRole: 'content',
type: 'boolean',
},
},
},
{

View File

@ -0,0 +1,4 @@
Significance: minor
Type: add
Add support for disabled state in SelectTree

View File

@ -11,7 +11,17 @@
box-sizing: border-box;
&--disabled {
opacity: 0.5;
background-color: $gray-100;
border-color: $gray-400;
opacity: 1.0;
.woocommerce-experimental-select-control {
&__items-wrapper {
opacity: 0.5;
}
&__suffix {
fill: $gray-400;
}
}
}
}

View File

@ -5,6 +5,12 @@
}
}
.woocommerce-experimental-select-control {
&__input:disabled {
background-color: $gray-100;
}
}
.woocommerce-experimental-select-tree-control__dropdown {
display: block;

View File

@ -25,6 +25,7 @@ interface SelectTreeProps extends TreeControlProps {
treeRef?: React.ForwardedRef< HTMLOListElement >;
suffix?: JSX.Element | null;
isLoading?: boolean;
disabled?: boolean;
label: string | JSX.Element;
onInputChange?: ( value: string | undefined ) => void;
initialInputValue?: string | undefined;
@ -36,6 +37,7 @@ export const SelectTree = function SelectTree( {
suffix = <SuffixIcon icon={ chevronDown } />,
placeholder,
isLoading,
disabled,
initialInputValue,
onInputChange,
shouldShowCreateButton,
@ -98,6 +100,7 @@ export const SelectTree = function SelectTree( {
'aria-autocomplete': 'list',
'aria-controls': `${ props.id }-menu`,
autoComplete: 'off',
disabled,
onFocus: ( event ) => {
if ( ! isOpen ) {
setIsOpen( true );

View File

@ -0,0 +1,4 @@
Significance: minor
Type: add
Add support for disabled state for checkbox, number, pricing, taxonomy, and text blocks

View File

@ -16,8 +16,15 @@ export function Edit( {
attributes,
context: { postType },
}: ProductEditorBlockEditProps< CheckboxBlockAttributes > ) {
const { property, title, label, tooltip, checkedValue, uncheckedValue } =
attributes;
const {
property,
title,
label,
tooltip,
checkedValue,
uncheckedValue,
disabled,
} = attributes;
const blockProps = useWooBlockProps( attributes );
@ -39,6 +46,7 @@ export function Edit( {
tooltip={ tooltip }
checkedValue={ checkedValue }
uncheckedValue={ uncheckedValue }
disabled={ disabled }
/>
</div>
);

View File

@ -30,6 +30,7 @@ export function Edit( {
max,
required,
tooltip,
disabled,
} = attributes;
const [ value, setValue ] = useProductEntityProp( property, {
postType,
@ -91,6 +92,7 @@ export function Edit( {
} }
required={ required }
tooltip={ tooltip }
disabled={ disabled }
/>
</div>
);

View File

@ -27,7 +27,7 @@ export function Edit( {
context: { postType },
}: ProductEditorBlockEditProps< PricingBlockAttributes > ) {
const blockProps = useWooBlockProps( attributes );
const { property, label, help } = attributes;
const { property, label, help, disabled } = attributes;
const [ price, setPrice ] = useProductEntityProp< string >( property, {
postType,
fallbackValue: '',
@ -60,6 +60,7 @@ export function Edit( {
<BaseControl id={ priceId } help={ interpolatedHelp }>
<InputControl
{ ...inputProps }
disabled={ disabled }
id={ priceId }
name={ property }
label={ label || __( 'Price', 'woocommerce' ) }

View File

@ -51,6 +51,7 @@ export function Edit( {
createTitle,
dialogNameHelpText,
parentTaxonomyText,
disabled,
} = attributes;
const [ searchValue, setSearchValue ] = useState( '' );
const [ allEntries, setAllEntries ] = useState< Taxonomy[] >( [] );
@ -105,6 +106,7 @@ export function Edit( {
}
label={ label }
isLoading={ isResolving }
disabled={ disabled }
multiple
createValue={ searchValue }
onInputChange={ searchDelayed }

View File

@ -32,6 +32,7 @@ export function Edit( {
maxLength,
help,
tooltip,
disabled,
} = attributes;
const [ value, setValue ] = useProductEntityProp< string >( property, {
postType,
@ -87,6 +88,7 @@ export function Edit( {
<div { ...blockProps }>
<TextControl
value={ value }
disabled={ disabled }
label={ label }
onChange={ setValue }
onBlur={ () => {

View File

@ -17,6 +17,7 @@ export type CheckboxProps = {
onChange: ( selected: boolean | string | null ) => void;
checkedValue?: string | null;
uncheckedValue?: string | null;
disabled?: boolean;
};
export const Checkbox: React.FC< CheckboxProps > = ( {
@ -27,6 +28,7 @@ export const Checkbox: React.FC< CheckboxProps > = ( {
title,
checkedValue,
uncheckedValue,
disabled,
}: CheckboxProps ) => {
function isChecked() {
if ( checkedValue !== undefined ) {
@ -50,6 +52,7 @@ export const Checkbox: React.FC< CheckboxProps > = ( {
label={ label }
checked={ isChecked() }
onChange={ handleChange }
disabled={ disabled }
/>
{ tooltip && (
<Tooltip

View File

@ -1,4 +1,12 @@
.woocommerce-product-form__checkbox {
.components-checkbox-control__input:disabled {
opacity: 1;
background-color: $gray-100;
border-color: $gray-400;
}
.components-checkbox-control__input:disabled + svg {
fill: $gray-400;
}
.components-base-control__field,
.components-checkbox-control__label,
&-wrapper,

View File

@ -27,6 +27,7 @@ export type NumberProps = {
onBlur?: () => void;
required?: boolean;
tooltip?: string;
disabled?: boolean;
};
export const NumberControl: React.FC< NumberProps > = ( {
@ -40,6 +41,7 @@ export const NumberControl: React.FC< NumberProps > = ( {
required,
tooltip,
placeholder,
disabled,
}: NumberProps ) => {
const inputProps = useNumberInputProps( {
value: value || '',
@ -65,6 +67,7 @@ export const NumberControl: React.FC< NumberProps > = ( {
>
<InputControl
{ ...inputProps }
disabled={ disabled }
id={ id }
suffix={ suffix }
placeholder={ placeholder }

View File

@ -25,6 +25,7 @@ export type TextProps = {
required?: boolean;
onBlur?: () => void;
tooltip?: string;
disabled?: boolean;
};
export const TextControl: React.FC< TextProps > = ( {
@ -37,6 +38,7 @@ export const TextControl: React.FC< TextProps > = ( {
placeholder,
required,
tooltip,
disabled,
}: TextProps ) => {
const textControlId = useInstanceId(
BaseControl,
@ -59,6 +61,7 @@ export const TextControl: React.FC< TextProps > = ( {
>
<InputControl
id={ textControlId }
disabled={ disabled }
placeholder={ placeholder }
value={ value }
onChange={ onChange }

View File

@ -37,6 +37,7 @@
@import "components/product-page-skeleton/styles.scss";
@import "components/modal-editor-welcome-guide/style.scss";
@import "components/attribute-control/attribute-skeleton.scss";
@import "components/checkbox-control/style.scss";
/* Field Blocks */

View File

@ -0,0 +1,4 @@
Significance: minor
Type: add
Add API to allow adding disable conditions

View File

@ -31,6 +31,11 @@ interface BlockInterface {
*/
public const HIDE_CONDITIONS_KEY = 'hideConditions';
/**
* Key for the block disable conditions in the block configuration.
*/
public const DISABLE_CONDITIONS_KEY = 'disableConditions';
/**
* Get the block name.
*/
@ -110,6 +115,29 @@ interface BlockInterface {
*/
public function get_hide_conditions(): array;
/**
* Add a disable condition to the block.
*
* The disable condition is a JavaScript-like expression that will be evaluated on the client to determine if the block should be disabled.
* See [@woocommerce/expression-evaluation](https://github.com/woocommerce/woocommerce/blob/trunk/packages/js/expression-evaluation/README.md) for more details.
*
* @param string $expression An expression, which if true, will disable the block.
* @return string The key of the disable condition, which can be used to remove the disable condition.
*/
public function add_disable_condition( string $expression ): string;
/**
* Remove a disable condition from the block.
*
* @param string $key The key of the disable condition to remove.
*/
public function remove_disable_condition( string $key );
/**
* Get the disable conditions of the block.
*/
public function get_disable_conditions(): array;
/**
* Get the block configuration as a formatted template.
*

View File

@ -217,6 +217,18 @@ Removes a hide condition from the block, referenced by the key returned from `ad
Get the hide conditions for the block.
##### `add_disable_condition( string $expression ): string`
Adds a disable condition to the block. Similar to `add_hide_condition()`, but the block is shown as disabled instead of hidden.
##### `remove_disable_condition( string $key )`
Removes a disable condition from the block, referenced by the key returned from `add_disable_condition()`.
##### `get_disable_conditions(): array`
Get the disable conditions for the block.
##### `get_formatted_template(): array`
Get the block configuration as a formatted template.

View File

@ -23,7 +23,7 @@ class BlockRegistry {
/**
* Array of all available generic blocks.
*/
const GENERIC_BLOCKS = [
const GENERIC_BLOCKS = array(
'woocommerce/conditional',
'woocommerce/product-checkbox-field',
'woocommerce/product-collapsible',
@ -35,12 +35,12 @@ class BlockRegistry {
'woocommerce/product-taxonomy-field',
'woocommerce/product-text-field',
'woocommerce/product-number-field',
];
);
/**
* Array of all available product fields blocks.
*/
const PRODUCT_FIELDS_BLOCKS = [
const PRODUCT_FIELDS_BLOCKS = array(
'woocommerce/product-catalog-visibility-field',
'woocommerce/product-description-field',
'woocommerce/product-downloads-field',
@ -61,7 +61,7 @@ class BlockRegistry {
'woocommerce/product-password-field',
'woocommerce/product-has-variations-notice',
'woocommerce/product-single-variation-notice',
];
);
/**
* Get a file path for a given block file.
@ -136,20 +136,28 @@ class BlockRegistry {
// registerWooBlockType function in @woocommerce/block-templates.
return array_merge(
$attributes,
[
'_templateBlockId' => [
array(
'_templateBlockId' => array(
'type' => 'string',
'__experimentalRole' => 'content',
],
'_templateBlockOrder' => [
),
'_templateBlockOrder' => array(
'type' => 'integer',
'__experimentalRole' => 'content',
],
'_templateBlockHideConditions' => [
),
'_templateBlockHideConditions' => array(
'type' => 'array',
'__experimentalRole' => 'content',
],
]
),
'_templateBlockDisableConditions' => array(
'type' => 'array',
'__experimentalRole' => 'content',
),
'disabled' => isset( $attributes['disabled'] ) ? $attributes['disabled'] : array(
'type' => 'boolean',
'__experimentalRole' => 'content',
),
)
);
}
@ -162,10 +170,10 @@ class BlockRegistry {
// Note: If you modify this function, also update the client-side
// registerProductEditorBlockType function in @woocommerce/product-editor.
return array_merge(
isset( $uses_context ) ? $uses_context : [],
[
isset( $uses_context ) ? $uses_context : array(),
array(
'postType',
]
)
);
}
@ -199,10 +207,10 @@ class BlockRegistry {
return register_block_type_from_metadata(
$block_json_file,
[
'attributes' => $this->augment_attributes( isset( $metadata['attributes'] ) ? $metadata['attributes'] : [] ),
'uses_context' => $this->augment_uses_context( isset( $metadata['usesContext'] ) ? $metadata['usesContext'] : [] ),
]
array(
'attributes' => $this->augment_attributes( isset( $metadata['attributes'] ) ? $metadata['attributes'] : array() ),
'uses_context' => $this->augment_uses_context( isset( $metadata['usesContext'] ) ? $metadata['usesContext'] : array() ),
)
);
}

View File

@ -71,6 +71,7 @@ add_action( 'woocommerce_block_template_area_product-form_after_remove_block_sal
```php
use Automattic\WooCommerce\Admin\BlockTemplates\BlockInterface;
// hide sale price block if regular_price is less than 10
function YOUR_PREFIX_hide_block( BlockInterface $sale_price_block ) {
$sale_price_block->add_hide_condition( 'editedProduct.regular_price < 10' );
}
@ -78,6 +79,21 @@ function YOUR_PREFIX_hide_block( BlockInterface $sale_price_block ) {
add_action( 'woocommerce_block_template_area_product-form_after_add_block_sale-price', 'YOUR_PREFIX_hide_block' );
```
### Conditionally disabling a block in product editor templates
```php
use Automattic\WooCommerce\Admin\BlockTemplates\BlockInterface;
// disable sale price block if regular_price is not set
function YOUR_PREFIX_hide_block( BlockInterface $sale_price_block ) {
$sale_price_block->add_disable_condition( '!editedProduct.regular_price' );
}
add_action( 'woocommerce_block_template_area_product-form_after_add_block_sale-price', 'YOUR_PREFIX_hide_block' );
```
## Interfaces
### GroupInterface

View File

@ -38,14 +38,14 @@ class AbstractBlock implements BlockInterface {
*
* @var array
*/
private $attributes = [];
private $attributes = array();
/**
* The block hide conditions.
*
* @var array
*/
private $hide_conditions = [];
private $hide_conditions = array();
/**
* The block hide conditions counter.
@ -54,6 +54,20 @@ class AbstractBlock implements BlockInterface {
*/
private $hide_conditions_counter = 0;
/**
* The block disable conditions.
*
* @var array
*/
private $disable_conditions = array();
/**
* The block disable conditions counter.
*
* @var int
*/
private $disable_conditions_counter = 0;
/**
* The block template that this block belongs to.
*
@ -105,6 +119,12 @@ class AbstractBlock implements BlockInterface {
$this->add_hide_condition( $hide_condition['expression'] );
}
}
if ( isset( $config[ self::DISABLE_CONDITIONS_KEY ] ) ) {
foreach ( $config[ self::DISABLE_CONDITIONS_KEY ] as $disable_condition ) {
$this->add_disable_condition( $disable_condition['expression'] );
}
}
}
/**
@ -228,9 +248,9 @@ class AbstractBlock implements BlockInterface {
// Storing the expression in an array to allow for future expansion
// (such as adding the plugin that added the condition).
$this->hide_conditions[ $key ] = [
$this->hide_conditions[ $key ] = array(
'expression' => $expression,
];
);
return $key;
}
@ -250,4 +270,41 @@ class AbstractBlock implements BlockInterface {
public function get_hide_conditions(): array {
return $this->hide_conditions;
}
/**
* Add a disable condition to the block.
*
* The disable condition is a JavaScript-like expression that will be evaluated on the client to determine if the block should be hidden.
* See [@woocommerce/expression-evaluation](https://github.com/woocommerce/woocommerce/blob/trunk/packages/js/expression-evaluation/README.md) for more details.
*
* @param string $expression An expression, which if true, will disable the block.
*/
public function add_disable_condition( string $expression ): string {
$key = 'k' . $this->disable_conditions_counter;
$this->disable_conditions_counter++;
// Storing the expression in an array to allow for future expansion
// (such as adding the plugin that added the condition).
$this->disable_conditions[ $key ] = array(
'expression' => $expression,
);
return $key;
}
/**
* Remove a disable condition from the block.
*
* @param string $key The key of the disable condition to remove.
*/
public function remove_disable_condition( string $key ) {
unset( $this->disable_conditions[ $key ] );
}
/**
* Get the disable conditions of the block.
*/
public function get_disable_conditions(): array {
return $this->disable_conditions;
}
}

View File

@ -12,19 +12,22 @@ trait BlockFormattedTemplateTrait {
* @return array The block configuration as a formatted template.
*/
public function get_formatted_template(): array {
$arr = [
$arr = array(
$this->get_name(),
array_merge(
$this->get_attributes(),
[
array(
'_templateBlockId' => $this->get_id(),
'_templateBlockOrder' => $this->get_order(),
],
! empty( $this->get_hide_conditions() ) ? [
),
! empty( $this->get_hide_conditions() ) ? array(
'_templateBlockHideConditions' => $this->get_formatted_hide_conditions(),
] : []
) : array(),
! empty( $this->get_disable_conditions() ) ? array(
'_templateBlockDisableConditions' => $this->get_formatted_disable_conditions(),
) : array(),
),
];
);
return $arr;
}
@ -33,15 +36,31 @@ trait BlockFormattedTemplateTrait {
* Get the block hide conditions formatted for inclusion in a formatted template.
*/
private function get_formatted_hide_conditions(): array {
$formatted_hide_conditions = array_map(
function( $hide_condition ) {
return [
'expression' => $hide_condition['expression'],
];
return $this->format_conditions( $this->get_hide_conditions() );
}
/**
* Get the block disable conditions formatted for inclusion in a formatted template.
*/
private function get_formatted_disable_conditions(): array {
return $this->format_conditions( $this->get_disable_conditions() );
}
/**
* Formats conditions in the expected format to include in the template.
*
* @param array $conditions The conditions to format.
*/
private function format_conditions( $conditions ): array {
$formatted_expressions = array_map(
function( $condition ) {
return array(
'expression' => $condition['expression'],
);
},
array_values( $this->get_hide_conditions() )
array_values( $conditions )
);
return $formatted_hide_conditions;
return $formatted_expressions;
}
}

View File

@ -22,7 +22,7 @@ class BlockTest extends WC_Unit_Test_Case {
$this->expectException( \ValueError::class );
new Block( [], $template );
new Block( array(), $template );
}
/**
@ -32,9 +32,9 @@ class BlockTest extends WC_Unit_Test_Case {
$template = new BlockTemplate();
$block = new Block(
[
array(
'blockName' => 'test-block-name',
],
),
$template
);
@ -49,18 +49,18 @@ class BlockTest extends WC_Unit_Test_Case {
$template_2 = new BlockTemplate();
$parent = new Block(
[
array(
'blockName' => 'test-block-parent-name',
],
),
$template_2
);
$this->expectException( \ValueError::class );
new Block(
[
array(
'blockName' => 'test-block-name',
],
),
$template,
$parent
);
@ -74,17 +74,17 @@ class BlockTest extends WC_Unit_Test_Case {
$template = new BlockTemplate();
$block = $template->add_block(
[
array(
'id' => 'test-block-id',
'blockName' => 'test-block-name',
]
)
);
$child_block = $block->add_block(
[
array(
'id' => 'test-block-id-2',
'blockName' => 'test-block-name-2',
]
)
);
$this->assertSame(
@ -113,17 +113,17 @@ class BlockTest extends WC_Unit_Test_Case {
$template = new BlockTemplate();
$block = $template->add_block(
[
array(
'id' => 'test-block-id',
'blockName' => 'test-block-name',
]
)
);
$child_block = $block->add_block(
[
array(
'id' => 'test-block-id-2',
'blockName' => 'test-block-name-2',
]
)
);
$block->remove_block( 'test-block-id-2' );
@ -152,17 +152,17 @@ class BlockTest extends WC_Unit_Test_Case {
$template = new BlockTemplate();
$block = $template->add_block(
[
array(
'id' => 'test-block-id',
'blockName' => 'test-block-name',
]
)
);
$child_block = $block->add_block(
[
array(
'id' => 'test-block-id-2',
'blockName' => 'test-block-name-2',
]
)
);
$template->remove_block( 'test-block-id-2' );
@ -191,17 +191,17 @@ class BlockTest extends WC_Unit_Test_Case {
$template = new BlockTemplate();
$block = $template->add_block(
[
array(
'id' => 'test-block-id',
'blockName' => 'test-block-name',
]
)
);
$child_block = $block->add_block(
[
array(
'id' => 'test-block-id-2',
'blockName' => 'test-block-name-2',
]
)
);
$template->remove_block( 'test-block-id' );
@ -239,10 +239,10 @@ class BlockTest extends WC_Unit_Test_Case {
$template = new BlockTemplate();
$block = $template->add_block(
[
array(
'id' => 'test-block-id',
'blockName' => 'test-block-name',
]
)
);
$block->remove();
@ -260,27 +260,27 @@ class BlockTest extends WC_Unit_Test_Case {
$block_template = new BlockTemplate();
$block = $block_template->add_block(
[
array(
'blockName' => 'test-block-name',
]
)
);
$child_block_1 = $block->add_block(
[
array(
'blockName' => 'test-block-name',
]
)
);
$block->add_block(
[
array(
'blockName' => 'test-block-name',
]
)
);
$grandchild_block = $child_block_1->add_block(
[
array(
'blockName' => 'test-block-name',
]
)
);
$this->assertSame(
@ -317,19 +317,19 @@ class BlockTest extends WC_Unit_Test_Case {
$template = new BlockTemplate();
$block = $template->add_block(
[
array(
'id' => 'test-block-id',
'blockName' => 'test-block-name',
]
)
);
$template->remove_block( 'test-block-id' );
$child_block = $block->add_block(
[
array(
'id' => 'test-block-id-2',
'blockName' => 'test-block-name-2',
]
)
);
$this->assertNull(
@ -360,27 +360,55 @@ class BlockTest extends WC_Unit_Test_Case {
$template = new BlockTemplate();
$block = $template->add_block(
[
array(
'blockName' => 'test-block-name',
'hideConditions' => [
[
'hideConditions' => array(
array(
'expression' => 'foo === bar',
],
],
]
),
),
)
);
$this->assertSame(
[
'k0' => [
array(
'k0' => array(
'expression' => 'foo === bar',
],
],
),
),
$block->get_hide_conditions(),
'Failed asserting that the hide conditions are set correctly in the constructor.'
);
}
/**
* Test that disable conditions can be passed in when creating a block.
*/
public function test_disable_conditions_in_constructor() {
$template = new BlockTemplate();
$block = $template->add_block(
array(
'blockName' => 'test-block-name',
'disableConditions' => array(
array(
'expression' => 'foo === bar',
),
),
)
);
$this->assertSame(
array(
'k0' => array(
'expression' => 'foo === bar',
),
),
$block->get_disable_conditions(),
'Failed asserting that the disable conditions are set correctly in the constructor.'
);
}
/**
* Test that hide conditions can be added to a block.
*/
@ -388,9 +416,9 @@ class BlockTest extends WC_Unit_Test_Case {
$template = new BlockTemplate();
$block = $template->add_block(
[
array(
'blockName' => 'test-block-name',
]
)
);
$condition_1_key = $block->add_hide_condition( 'editedProduct.manage_stock === true' );
@ -402,19 +430,53 @@ class BlockTest extends WC_Unit_Test_Case {
$block->remove_hide_condition( $condition_2_key );
$this->assertSame(
[
$condition_1_key => [
array(
$condition_1_key => array(
'expression' => 'editedProduct.manage_stock === true',
],
$condition_3_key => [
),
$condition_3_key => array(
'expression' => 'foo > 10',
],
],
),
),
$block->get_hide_conditions(),
'Failed asserting that the hide conditions are added correctly.'
);
}
/**
* Test that hide conditions can be added to a block.
*/
public function test_add_disable_condition() {
$template = new BlockTemplate();
$block = $template->add_block(
array(
'blockName' => 'test-block-name',
)
);
$condition_1_key = $block->add_disable_condition( 'editedProduct.manage_stock === true' );
$condition_2_key = $block->add_disable_condition( 'true' );
$condition_3_key = $block->add_disable_condition( 'foo > 10' );
$block->remove_disable_condition( $condition_2_key );
$this->assertSame(
array(
$condition_1_key => array(
'expression' => 'editedProduct.manage_stock === true',
),
$condition_3_key => array(
'expression' => 'foo > 10',
),
),
$block->get_disable_conditions(),
'Failed asserting that the hide conditions are added correctly.'
);
}
/**
* Test that getting the block as a formatted template is structured correctly.
*/
@ -422,71 +484,78 @@ class BlockTest extends WC_Unit_Test_Case {
$template = new BlockTemplate();
$block = $template->add_block(
[
array(
'id' => 'test-block-id',
'blockName' => 'test-block-name',
'attributes' => [
'attributes' => array(
'attr-1' => 'value-1',
'attr-2' => 'value-2',
],
]
),
)
);
$block->add_hide_condition( 'foo === bar' );
$block->add_disable_condition( 'test > 100' );
$block->add_block(
[
array(
'id' => 'test-block-id-2',
'blockName' => 'test-block-name-2',
'attributes' => [
'attributes' => array(
'attr-3' => 'value-3',
'attr-4' => 'value-4',
],
]
),
)
);
$block->add_block(
[
array(
'id' => 'test-block-id-3',
'blockName' => 'test-block-name-3',
]
)
);
$formatted_template = $block->get_formatted_template();
$this->assertSame(
[
array(
'test-block-name',
[
'attr-1' => 'value-1',
'attr-2' => 'value-2',
'_templateBlockId' => 'test-block-id',
'_templateBlockOrder' => 10000,
'_templateBlockHideConditions' => [
[
array(
'attr-1' => 'value-1',
'attr-2' => 'value-2',
'_templateBlockId' => 'test-block-id',
'_templateBlockOrder' => 10000,
'_templateBlockHideConditions' => array(
array(
'expression' => 'foo === bar',
],
],
],
[
[
),
),
'_templateBlockDisableConditions' => array(
array(
'expression' => 'test > 100',
),
),
),
array(
array(
'test-block-name-2',
[
array(
'attr-3' => 'value-3',
'attr-4' => 'value-4',
'_templateBlockId' => 'test-block-id-2',
'_templateBlockOrder' => 10000,
],
],
[
),
),
array(
'test-block-name-3',
[
array(
'_templateBlockId' => 'test-block-id-3',
'_templateBlockOrder' => 10000,
],
],
],
],
),
),
),
),
$formatted_template,
'Failed asserting that the block is converted to a formatted template correctly.'
);
@ -499,91 +568,91 @@ class BlockTest extends WC_Unit_Test_Case {
$template = new BlockTemplate();
$block = $template->add_block(
[
array(
'blockName' => 'test-block-name',
]
)
);
$block->add_block(
[
array(
'blockName' => 'five',
'order' => 5,
]
)
);
$block->add_block(
[
array(
'blockName' => 'three',
'order' => 3,
]
)
);
$block->add_block(
[
array(
'blockName' => 'one',
'order' => 1,
]
)
);
$block->add_block(
[
array(
'blockName' => 'four',
'order' => 4,
]
)
);
$block->add_block(
[
array(
'blockName' => 'two',
'order' => 2,
]
)
);
$this->assertSame(
[
array(
'test-block-name',
[
array(
'_templateBlockId' => 'test-block-name-1',
'_templateBlockOrder' => 10000,
],
[
[
),
array(
array(
'one',
[
array(
'_templateBlockId' => 'one-1',
'_templateBlockOrder' => 1,
],
],
[
),
),
array(
'two',
[
array(
'_templateBlockId' => 'two-1',
'_templateBlockOrder' => 2,
],
],
[
),
),
array(
'three',
[
array(
'_templateBlockId' => 'three-1',
'_templateBlockOrder' => 3,
],
],
[
),
),
array(
'four',
[
array(
'_templateBlockId' => 'four-1',
'_templateBlockOrder' => 4,
],
],
[
),
),
array(
'five',
[
array(
'_templateBlockId' => 'five-1',
'_templateBlockOrder' => 5,
],
],
],
],
),
),
),
),
$block->get_formatted_template(),
'Failed asserting that the inner blocks are sorted by order.'
);