Make WordPress Core

Changeset 60720


Ignore:
Timestamp:
09/08/2025 11:27:57 AM (2 months ago)
Author:
gziolo
Message:

Tests: Update rendering test cases for Block Bindings

Refactoring covered:

  • Use the newly introduced block_bindings_supported_attributes_{$block_name} filter to register a test/block's attribute as supported by Block Bindings, rather than using an actual block (Paragraph) for most tests.
  • Merge three test cases that check if get_value_callback works correctly (accepts arguments; correctly includes symbols and numbers; return value is sanitized when rendered) into one, by using a dataProvider.
  • Merge two test cases that check if block context is correctly evaluated, and that access is only given to context included in a source's uses_context property.

Follow-up to [60684].

Props bernhard-reiter, gziolo.
See #63840.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/block-bindings/render.php

    r60684 r60720  
    3232                ),
    3333                'render_callback' => function ( $attributes ) {
    34                     return '<p>' . esc_html( $attributes['myAttribute'] ) . '</p>';
     34                    if ( isset( $attributes['myAttribute'] ) ) {
     35                        return '<p>' . esc_html( $attributes['myAttribute'] ) . '</p>';
     36                    }
    3537                },
    3638            )
     39        );
     40    }
     41
     42    /**
     43     * Sets up the test fixture.
     44     *
     45     * @since 6.9.0
     46     */
     47    public function set_up() {
     48        parent::set_up();
     49
     50        add_filter(
     51            'block_bindings_supported_attributes_test/block',
     52            function ( $supported_attributes ) {
     53                $supported_attributes[] = 'myAttribute';
     54                return $supported_attributes;
     55            }
    3756        );
    3857    }
     
    84103                '<div class="wp-block-button"><a class="wp-block-button__link wp-element-button">test source value</a></div>',
    85104            ),
     105            'test block'      => array(
     106                'myAttribute',
     107                <<<HTML
     108<!-- wp:test/block -->
     109<p>This should not appear</p>
     110<!-- /wp:test/block -->
     111HTML
     112                ,
     113                '<p>test source value</p>',
     114            ),
    86115        );
    87116    }
     
    134163    }
    135164
    136     /**
    137      * Test if the block_bindings_supported_attributes_{$block_type} filter is applied correctly.
    138      *
    139      * @ticket 62090
    140      */
    141     public function test_filter_block_bindings_supported_attributes() {
    142         $get_value_callback = function () {
    143             return 'test source value';
    144         };
    145 
    146         register_block_bindings_source(
    147             self::SOURCE_NAME,
    148             array(
    149                 'label'              => self::SOURCE_LABEL,
    150                 'get_value_callback' => $get_value_callback,
    151             )
    152         );
    153 
    154         add_filter(
    155             'block_bindings_supported_attributes_test/block',
    156             function ( $supported_attributes ) {
    157                 $supported_attributes[] = 'myAttribute';
    158                 return $supported_attributes;
    159             }
    160         );
    161 
    162         $block_content = <<<HTML
    163 <!-- wp:test/block {"metadata":{"bindings":{"myAttribute":{"source":"test/source"}}}} -->
    164 <p>This should not appear</p>
    165 <!-- /wp:test/block -->
    166 HTML;
    167         $parsed_blocks = parse_blocks( $block_content );
    168         $block         = new WP_Block( $parsed_blocks[0] );
    169         $result        = $block->render();
    170 
    171         $this->assertSame(
    172             'test source value',
    173             $block->attributes['myAttribute'],
    174             "The 'myAttribute' attribute should be updated with the value returned by the source."
    175         );
    176         $this->assertSame(
    177             '<p>test source value</p>',
    178             trim( $result ),
    179             'The block content should be updated with the value returned by the source.'
     165    public function data_different_get_value_callbacks() {
     166        return array(
     167            'pass arguments to source'        => array(
     168                function ( $source_args, $block_instance, $attribute_name ) {
     169                    $value = $source_args['key'];
     170                    return "The attribute name is '$attribute_name' and its binding has argument 'key' with value '$value'.";
     171                },
     172                "<p>The attribute name is 'content' and its binding has argument 'key' with value 'test'.</p>",
     173            ),
     174            'unsafe HTML should be sanitized' => array(
     175                function () {
     176                    return '<script>alert("Unsafe HTML")</script>';
     177                },
     178                '<p>alert("Unsafe HTML")</p>',
     179            ),
     180            'symbols and numbers should be rendered correctly' => array(
     181                function () {
     182                    return '$12.50';
     183                },
     184                '<p>$12.50</p>',
     185            ),
    180186        );
    181187    }
     
    185191     *
    186192     * @ticket 60282
     193     * @ticket 60651
     194     * @ticket 61385
     195     * @ticket 63840
    187196     *
    188197     * @covers ::register_block_bindings_source
    189      */
    190     public function test_passing_arguments_to_source() {
    191         $get_value_callback = function ( $source_args, $block_instance, $attribute_name ) {
    192             $value = $source_args['key'];
    193             return "The attribute name is '$attribute_name' and its binding has argument 'key' with value '$value'.";
    194         };
    195 
     198     *
     199     * @dataProvider data_different_get_value_callbacks
     200     */
     201    public function test_different_get_value_callbacks( $get_value_callback, $expected ) {
    196202        register_block_bindings_source(
    197203            self::SOURCE_NAME,
     
    212218
    213219        $this->assertSame(
    214             "The attribute name is 'content' and its binding has argument 'key' with value 'test'.",
    215             $block->attributes['content'],
    216             "The 'content' attribute should be updated with the value returned by the source."
    217         );
    218         $this->assertSame(
    219             "<p>The attribute name is 'content' and its binding has argument 'key' with value 'test'.</p>",
     220            $expected,
    220221            trim( $result ),
    221222            'The block content should be updated with the value returned by the source.'
     
    227228     *
    228229     * @ticket 60525
     230     * @ticket 61642
    229231     *
    230232     * @covers ::register_block_bindings_source
    231233     */
    232234    public function test_passing_uses_context_to_source() {
    233         $get_value_callback = function ( $source_args, $block_instance, $attribute_name ) {
     235        $get_value_callback = function ( $source_args, $block_instance ) {
     236            $this->assertArrayNotHasKey(
     237                'forbiddenSourceContext',
     238                $block_instance->context,
     239                "Only context that was made available through the source's uses_context property should be accessible."
     240            );
    234241            $value = $block_instance->context['sourceContext'];
    235242            return "Value: $value";
     
    246253
    247254        $block_content = <<<HTML
    248 <!-- wp:paragraph {"metadata":{"bindings":{"content":{"source":"test/source", "args": {"key": "test"}}}}} -->
     255<!-- wp:test/block {"metadata":{"bindings":{"myAttribute":{"source":"test/source", "args": {"key": "test"}}}}} -->
    249256<p>This should not appear</p>
    250 <!-- /wp:paragraph -->
    251 HTML;
    252         $parsed_blocks = parse_blocks( $block_content );
    253         $block         = new WP_Block( $parsed_blocks[0], array( 'sourceContext' => 'source context value' ) );
    254         $result        = $block->render();
    255 
    256         $this->assertSame(
    257             'Value: source context value',
    258             $block->attributes['content'],
    259             "The 'content' should be updated with the value of the source context."
    260         );
    261         $this->assertSame(
    262             '<p>Value: source context value</p>',
    263             trim( $result ),
    264             'The block content should be updated with the value of the source context.'
    265         );
    266     }
    267 
    268     /**
    269      * Tests that blocks can only access the context from the specific source.
    270      *
    271      * @ticket 61642
    272      *
    273      * @covers ::register_block_bindings_source
    274      */
    275     public function test_blocks_can_just_access_the_specific_uses_context() {
    276         register_block_bindings_source(
    277             'test/source-one',
    278             array(
    279                 'label'              => 'Test Source One',
    280                 'get_value_callback' => function () {
    281                     return;
    282                 },
    283                 'uses_context'       => array( 'contextOne' ),
    284             )
    285         );
    286 
    287         register_block_bindings_source(
    288             'test/source-two',
    289             array(
    290                 'label'              => 'Test Source Two',
    291                 'get_value_callback' => function ( $source_args, $block_instance, $attribute_name ) {
    292                     $value = $block_instance->context['contextTwo'];
    293                     // Try to use the context from source one, which shouldn't be available.
    294                     if ( ! empty( $block_instance->context['contextOne'] ) ) {
    295                         $value = $block_instance->context['contextOne'];
    296                     }
    297                     return "Value: $value";
    298                 },
    299                 'uses_context'       => array( 'contextTwo' ),
    300             )
    301         );
    302 
    303         $block_content = <<<HTML
    304 <!-- wp:paragraph {"metadata":{"bindings":{"content":{"source":"test/source-two", "args": {"key": "test"}}}}} -->
    305 <p>Default content</p>
    306 <!-- /wp:paragraph -->
     257<!-- /wp:test/block -->
    307258HTML;
    308259        $parsed_blocks = parse_blocks( $block_content );
     
    310261            $parsed_blocks[0],
    311262            array(
    312                 'contextOne' => 'source one context value',
    313                 'contextTwo' => 'source two context value',
     263                'sourceContext'          => 'source context value',
     264                'forbiddenSourceContext' => 'forbidden donut',
    314265            )
    315266        );
     
    317268
    318269        $this->assertSame(
    319             'Value: source two context value',
    320             $block->attributes['content'],
    321             "The 'content' should be updated with the value of the second source context value."
    322         );
    323         $this->assertSame(
    324             '<p>Value: source two context value</p>',
     270            'Value: source context value',
     271            $block->attributes['myAttribute'],
     272            "The 'myAttribute' should be updated with the value of the source context."
     273        );
     274        $this->assertSame(
     275            '<p>Value: source context value</p>',
    325276            trim( $result ),
    326277            'The block content should be updated with the value of the source context.'
     
    371322
    372323    /**
    373      * Tests if the block content is sanitized when unsafe HTML is passed.
    374      *
    375      * @ticket 60651
    376      *
    377      * @covers ::register_block_bindings_source
    378      */
    379     public function test_source_value_with_unsafe_html_is_sanitized() {
    380         $get_value_callback = function () {
    381             return '<script>alert("Unsafe HTML")</script>';
    382         };
    383 
    384         register_block_bindings_source(
    385             self::SOURCE_NAME,
    386             array(
    387                 'label'              => self::SOURCE_LABEL,
    388                 'get_value_callback' => $get_value_callback,
    389             )
    390         );
    391 
    392         $block_content = <<<HTML
    393 <!-- wp:paragraph {"metadata":{"bindings":{"content":{"source":"test/source"}}}} -->
    394 <p>This should not appear</p>
    395 <!-- /wp:paragraph -->
    396 HTML;
    397         $parsed_blocks = parse_blocks( $block_content );
    398         $block         = new WP_Block( $parsed_blocks[0] );
    399         $result        = $block->render();
    400 
    401         $this->assertSame(
    402             '<p>alert("Unsafe HTML")</p>',
    403             trim( $result ),
    404             'The block content should be updated with the value returned by the source.'
    405         );
    406     }
    407 
    408     /**
    409      * Tests that including symbols and numbers works well with bound attributes.
    410      *
    411      * @ticket 61385
    412      *
    413      * @covers WP_Block::process_block_bindings
    414      */
    415     public function test_using_symbols_in_block_bindings_value() {
    416         $get_value_callback = function () {
    417             return '$12.50';
    418         };
    419 
    420         register_block_bindings_source(
    421             self::SOURCE_NAME,
    422             array(
    423                 'label'              => self::SOURCE_LABEL,
    424                 'get_value_callback' => $get_value_callback,
    425             )
    426         );
    427 
    428         $block_content = <<<HTML
    429 <!-- wp:paragraph {"metadata":{"bindings":{"content":{"source":"test/source"}}}} -->
    430 <p>Default content</p>
    431 <!-- /wp:paragraph -->
    432 HTML;
    433         $parsed_blocks = parse_blocks( $block_content );
    434         $block         = new WP_Block( $parsed_blocks[0] );
    435         $result        = $block->render();
    436 
    437         $this->assertSame(
    438             '<p>$12.50</p>',
    439             trim( $result ),
    440             'The block content should properly show the symbol and numbers.'
    441         );
    442     }
    443 
    444     /**
    445324     * Tests if the `__default` attribute is replaced with real attributes for
    446325     * pattern overrides.
     
    453332    public function test_default_binding_for_pattern_overrides() {
    454333        $block_content = <<<HTML
    455 <!-- wp:paragraph {"metadata":{"bindings":{"__default":{"source":"core/pattern-overrides"}},"name":"Test"}} -->
     334<!-- wp:test/block {"metadata":{"bindings":{"__default":{"source":"core/pattern-overrides"}},"name":"Test"}} -->
    456335<p>This should not appear</p>
    457 <!-- /wp:paragraph -->
     336<!-- /wp:test/block -->
    458337HTML;
    459338
    460339        $expected_content = 'This is the content value';
    461340        $parsed_blocks    = parse_blocks( $block_content );
    462         $block            = new WP_Block( $parsed_blocks[0], array( 'pattern/overrides' => array( 'Test' => array( 'content' => $expected_content ) ) ) );
     341        $block            = new WP_Block( $parsed_blocks[0], array( 'pattern/overrides' => array( 'Test' => array( 'myAttribute' => $expected_content ) ) ) );
    463342
    464343        $result = $block->render();
     
    471350
    472351        $expected_bindings_metadata = array(
    473             'content' => array( 'source' => 'core/pattern-overrides' ),
     352            'myAttribute' => array( 'source' => 'core/pattern-overrides' ),
    474353        );
    475354        $this->assertSame(
Note: See TracChangeset for help on using the changeset viewer.