diff --git a/tests/phpunit/tests/block-supports/border.php b/tests/phpunit/tests/block-supports/border.php index 31ab0ca789f9f..63103d8604a93 100644 --- a/tests/phpunit/tests/block-supports/border.php +++ b/tests/phpunit/tests/block-supports/border.php @@ -272,168 +272,4 @@ public function test_should_apply_stabilized_border_supports() { $this->assertSame( $expected, $actual ); } - - /** - * Tests that experimental border support configuration gets stabilized correctly. - * - * @ticket 61728 - */ - public function test_should_stabilize_border_supports() { - $reflection = new ReflectionClass( WP_Block_Type::class ); - $method = $reflection->getMethod( 'stabilize_supports' ); - $method->setAccessible( true ); - $block_type = new WP_Block_Type( 'test/block' ); - - $supports = array( - '__experimentalBorder' => array( - 'color' => true, - 'radius' => true, - 'style' => true, - 'width' => true, - '__experimentalSkipSerialization' => true, - '__experimentalDefaultControls' => array( - 'color' => true, - 'radius' => true, - 'style' => true, - 'width' => true, - ), - ), - ); - - $actual = $method->invoke( $block_type, $supports ); - $expected = array( - 'border' => array( - 'color' => true, - 'radius' => true, - 'style' => true, - 'width' => true, - 'skipSerialization' => true, - 'defaultControls' => array( - 'color' => true, - 'radius' => true, - 'style' => true, - 'width' => true, - ), - ), - ); - - $this->assertSame( $expected, $actual, 'Stabilized border block support config does not match.' ); - } - - /** - * Tests the merging of border support configuration when stabilizing - * experimental config. Due to the ability to filter block type args, plugins - * or themes could filter using outdated experimental keys. While not every - * permutation of filtering can be covered, the majority of use cases are - * served best by merging configs based on the order they were defined if possible. - * - * @ticket 61728 - */ - public function test_should_stabilize_border_supports_using_order_based_merge() { - $reflection = new ReflectionClass( WP_Block_Type::class ); - $method = $reflection->getMethod( 'stabilize_supports' ); - $method->setAccessible( true ); - $block_type = new WP_Block_Type( 'test/block' ); - - $experimental_border_config = array( - 'color' => true, - 'radius' => true, - 'style' => true, - 'width' => true, - '__experimentalSkipSerialization' => true, - '__experimentalDefaultControls' => array( - 'color' => true, - 'radius' => true, - 'style' => true, - 'width' => true, - ), - - /* - * The following simulates theme/plugin filtering using `__experimentalBorder` - * key but stable serialization and default control keys. - */ - 'skipSerialization' => false, - 'defaultControls' => array( - 'color' => true, - 'radius' => false, - 'style' => true, - 'width' => true, - ), - ); - $stable_border_config = array( - 'color' => true, - 'radius' => true, - 'style' => false, - 'width' => true, - 'skipSerialization' => false, - 'defaultControls' => array( - 'color' => true, - 'radius' => false, - 'style' => false, - 'width' => true, - ), - - /* - * The following simulates theme/plugin filtering using stable `border` key - * but experimental serialization and default control keys. - */ - '__experimentalSkipSerialization' => true, - '__experimentalDefaultControls' => array( - 'color' => false, - 'radius' => false, - 'style' => false, - 'width' => false, - ), - ); - - // Test with experimental config first. - $experimental_first = array( - '__experimentalBorder' => $experimental_border_config, - 'border' => $stable_border_config, - ); - - $actual = $method->invoke( $block_type, $experimental_first ); - $expected = array( - 'border' => array( - 'color' => true, - 'radius' => true, - 'style' => false, - 'width' => true, - 'skipSerialization' => true, - 'defaultControls' => array( - 'color' => false, - 'radius' => false, - 'style' => false, - 'width' => false, - ), - ), - ); - - $this->assertSame( $expected, $actual, 'Merged stabilized border block support config does not match when experimental keys are first.' ); - - // Test with stable config first. - $stable_first = array( - 'border' => $stable_border_config, - '__experimentalBorder' => $experimental_border_config, - ); - - $actual = $method->invoke( $block_type, $stable_first ); - $expected = array( - 'border' => array( - 'color' => true, - 'radius' => true, - 'style' => true, - 'width' => true, - 'skipSerialization' => false, - 'defaultControls' => array( - 'color' => true, - 'radius' => false, - 'style' => true, - 'width' => true, - ), - ), - ); - - $this->assertSame( $expected, $actual, 'Merged stabilized border block support config does not match when stable keys are first.' ); - } } diff --git a/tests/phpunit/tests/blocks/wpBlockType.php b/tests/phpunit/tests/blocks/wpBlockType.php index a73efa8ce8a7d..ebaf32f2004f8 100644 --- a/tests/phpunit/tests/blocks/wpBlockType.php +++ b/tests/phpunit/tests/blocks/wpBlockType.php @@ -586,7 +586,7 @@ public function test_variations_callback_happens_only_once() { /** * Test filter function for get_block_type_variations filter. * - * @param array $variations Block variations before filter. + * @param array $variations Block variations before filter. * @param WP_Block_Type $block_type Block type. * * @return array Block variations after filter. @@ -652,4 +652,202 @@ public function mock_variation_callback() { array( 'name' => 'var2' ), ); } + + /** + * Tests stabilization of experimental block supports. + * + * @ticket 61728 + * @covers WP_Block_Type::stabilize_supports + */ + public function test_stabilize_block_supports() { + $reflection = new ReflectionClass( WP_Block_Type::class ); + $method = $reflection->getMethod( 'stabilize_supports' ); + $method->setAccessible( true ); + $block_type = new WP_Block_Type( 'test/block' ); + + $supports = array( + '__experimentalBorder' => array( + 'color' => true, + 'radius' => true, + 'width' => true, + 'style' => true, + '__experimentalSkipSerialization' => true, + '__experimentalDefaultControls' => array( + 'color' => true, + 'radius' => true, + 'width' => true, + ), + ), + 'typography' => array( + 'fontSize' => true, + '__experimentalFontFamily' => true, + '__experimentalFontStyle' => true, + '__experimentalFontWeight' => true, + '__experimentalLetterSpacing' => true, + '__experimentalTextTransform' => true, + '__experimentalTextDecoration' => true, + '__experimentalSkipSerialization' => true, + '__experimentalDefaultControls' => array( + 'fontFamily' => true, + 'fontSize' => true, + 'letterSpacing' => true, + ), + ), + ); + + $actual = $method->invoke( $block_type, $supports ); + $expected = array( + 'border' => array( + 'color' => true, + 'radius' => true, + 'width' => true, + 'style' => true, + 'skipSerialization' => true, + 'defaultControls' => array( + 'color' => true, + 'radius' => true, + 'width' => true, + ), + ), + 'typography' => array( + 'fontSize' => true, + 'fontFamily' => true, + 'fontStyle' => true, + 'fontWeight' => true, + 'letterSpacing' => true, + 'textTransform' => true, + 'textDecoration' => true, + 'skipSerialization' => true, + 'defaultControls' => array( + 'fontFamily' => true, + 'fontSize' => true, + 'letterSpacing' => true, + ), + ), + ); + + $this->assertSameSetsWithIndex( $expected, $actual ); + } + + /** + * Tests that experimental and stable block supports can be merged based on definition order. + * + * If a plugin or theme overrides the support config with the `register_block_type_args` + * filter, both experimental and stable configs may be present. In that case, use the + * order keys are defined in to determine the final value: + * - If config is an array, merge the arrays in their order of definition. + * - If config is not an array, use the value defined last. + * + * The reason for preferring the last defined key is that after filters are applied, + * the last inserted key is likely the most up-to-date value. We cannot determine + * with certainty which value was "last modified" so the insertion order is the + * best guess. + * + * @ticket 61728 + * @covers WP_Block_Type::stabilize_supports + */ + public function test_stabilize_block_supports_merges_by_order() { + $reflection = new ReflectionClass( WP_Block_Type::class ); + $method = $reflection->getMethod( 'stabilize_supports' ); + $method->setAccessible( true ); + $block_type = new WP_Block_Type( 'test/block' ); + + // Test with experimental config first. + $experimental_first = array( + '__experimentalBorder' => array( + 'color' => true, + 'radius' => true, + 'style' => true, + 'width' => true, + 'skipSerialization' => false, + 'defaultControls' => array( + 'color' => true, + 'radius' => false, + 'style' => true, + 'width' => true, + ), + ), + 'border' => array( + 'color' => true, + 'radius' => true, + 'style' => false, + 'width' => true, + 'skipSerialization' => true, + 'defaultControls' => array( + 'color' => false, + 'radius' => false, + 'style' => false, + 'width' => false, + ), + ), + ); + + $actual = $method->invoke( $block_type, $experimental_first ); + $expected = array( + 'border' => array( + 'color' => true, + 'radius' => true, + 'style' => false, + 'width' => true, + 'skipSerialization' => true, + 'defaultControls' => array( + 'color' => false, + 'radius' => false, + 'style' => false, + 'width' => false, + ), + ), + ); + + $this->assertSameSetsWithIndex( $expected, $actual, 'Merged stabilized block support config does not match when experimental keys are first.' ); + + // Test with stable config first. + $stable_first = array( + 'border' => array( + 'color' => true, + 'radius' => true, + 'style' => false, + 'width' => true, + 'skipSerialization' => true, + 'defaultControls' => array( + 'color' => false, + 'radius' => false, + 'style' => false, + 'width' => false, + ), + ), + '__experimentalBorder' => array( + 'color' => true, + 'radius' => true, + 'style' => true, + 'width' => true, + 'skipSerialization' => false, + 'defaultControls' => array( + 'color' => true, + 'radius' => false, + 'style' => true, + 'width' => true, + ), + ), + ); + + $actual = $method->invoke( $block_type, $stable_first ); + $expected = array( + 'border' => array( + 'color' => true, + 'radius' => true, + 'style' => true, + 'width' => true, + 'skipSerialization' => false, + 'defaultControls' => array( + 'color' => true, + 'radius' => false, + 'style' => true, + 'width' => true, + ), + ), + ); + + $this->assertSameSetsWithIndex( $expected, $actual, 'Merged stabilized block support config does not match when stable keys are first.' ); + } }