Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
274 changes: 76 additions & 198 deletions tests/phpunit/tests/block-bindings/render.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,31 @@ public static function wpSetUpBeforeClass() {
),
),
'render_callback' => function ( $attributes ) {
return '<p>' . esc_html( $attributes['myAttribute'] ) . '</p>';
if ( isset( $attributes['myAttribute'] ) ) {
return '<p>' . esc_html( $attributes['myAttribute'] ) . '</p>';
}
},
)
);
}

/**
* Sets up the test fixture.
*
* @since 6.9.0
*/
public function set_up() {
parent::set_up();

add_filter(
'block_bindings_supported_attributes_test/block',
function ( $supported_attributes ) {
$supported_attributes[] = 'myAttribute';
return $supported_attributes;
}
);
}

/**
* Tear down after each test.
*
Expand Down Expand Up @@ -83,6 +102,16 @@ public function data_update_block_with_value_from_source() {
,
'<div class="wp-block-button"><a class="wp-block-button__link wp-element-button">test source value</a></div>',
),
'test block' => array(
'myAttribute',
<<<HTML
<!-- wp:test/block -->
<p>This should not appear</p>
<!-- /wp:test/block -->
HTML
,
'<p>test source value</p>',
),
);
}

Expand Down Expand Up @@ -133,66 +162,42 @@ public function test_update_block_with_value_from_source( $bound_attribute, $blo
);
}

/**
* Test if the block_bindings_supported_attributes_{$block_type} filter is applied correctly.
*
* @ticket 62090
*/
public function test_filter_block_bindings_supported_attributes() {
$get_value_callback = function () {
return 'test source value';
};

register_block_bindings_source(
self::SOURCE_NAME,
array(
'label' => self::SOURCE_LABEL,
'get_value_callback' => $get_value_callback,
)
);

add_filter(
'block_bindings_supported_attributes_test/block',
function ( $supported_attributes ) {
$supported_attributes[] = 'myAttribute';
return $supported_attributes;
}
);

$block_content = <<<HTML
<!-- wp:test/block {"metadata":{"bindings":{"myAttribute":{"source":"test/source"}}}} -->
<p>This should not appear</p>
<!-- /wp:test/block -->
HTML;
$parsed_blocks = parse_blocks( $block_content );
$block = new WP_Block( $parsed_blocks[0] );
$result = $block->render();

$this->assertSame(
'test source value',
$block->attributes['myAttribute'],
"The 'myAttribute' attribute should be updated with the value returned by the source."
);
$this->assertSame(
'<p>test source value</p>',
trim( $result ),
'The block content should be updated with the value returned by the source.'
public function data_different_get_value_callbacks() {
return array(
'pass arguments to source' => array(
function ( $source_args, $block_instance, $attribute_name ) {
$value = $source_args['key'];
return "The attribute name is '$attribute_name' and its binding has argument 'key' with value '$value'.";
},
"<p>The attribute name is 'content' and its binding has argument 'key' with value 'test'.</p>",
),
'unsafe HTML should be sanitized' => array(
function () {
return '<script>alert("Unsafe HTML")</script>';
},
'<p>alert("Unsafe HTML")</p>',
),
'symbols and numbers should be rendered correctly' => array(
function () {
return '$12.50';
},
'<p>$12.50</p>',
),
);
}

/**
* Test passing arguments to the source.
*
* @ticket 60282
* @ticket 60651
* @ticket 61385
*
* @covers ::register_block_bindings_source
*
* @dataProvider data_different_get_value_callbacks
*/
public function test_passing_arguments_to_source() {
$get_value_callback = function ( $source_args, $block_instance, $attribute_name ) {
$value = $source_args['key'];
return "The attribute name is '$attribute_name' and its binding has argument 'key' with value '$value'.";
};

public function test_different_get_value_callbacks( $get_value_callback, $expected ) {
register_block_bindings_source(
self::SOURCE_NAME,
array(
Expand All @@ -211,12 +216,7 @@ public function test_passing_arguments_to_source() {
$result = $block->render();

$this->assertSame(
"The attribute name is 'content' and its binding has argument 'key' with value 'test'.",
$block->attributes['content'],
"The 'content' attribute should be updated with the value returned by the source."
);
$this->assertSame(
"<p>The attribute name is 'content' and its binding has argument 'key' with value 'test'.</p>",
$expected,
trim( $result ),
'The block content should be updated with the value returned by the source.'
);
Expand All @@ -226,11 +226,17 @@ public function test_passing_arguments_to_source() {
* Tests passing `uses_context` as argument to the source.
*
* @ticket 60525
* @ticket 61642
*
* @covers ::register_block_bindings_source
*/
public function test_passing_uses_context_to_source() {
$get_value_callback = function ( $source_args, $block_instance, $attribute_name ) {
$get_value_callback = function ( $source_args, $block_instance ) {
$this->assertArrayNotHasKey(
'forbiddenSourceContext',
$block_instance->context,
"Only context that was made available through the source's uses_context property should be accessible."
);
$value = $block_instance->context['sourceContext'];
return "Value: $value";
};
Expand All @@ -245,83 +251,27 @@ public function test_passing_uses_context_to_source() {
);

$block_content = <<<HTML
<!-- wp:paragraph {"metadata":{"bindings":{"content":{"source":"test/source", "args": {"key": "test"}}}}} -->
<!-- wp:test/block {"metadata":{"bindings":{"myAttribute":{"source":"test/source", "args": {"key": "test"}}}}} -->
<p>This should not appear</p>
<!-- /wp:paragraph -->
HTML;
$parsed_blocks = parse_blocks( $block_content );
$block = new WP_Block( $parsed_blocks[0], array( 'sourceContext' => 'source context value' ) );
$result = $block->render();

$this->assertSame(
'Value: source context value',
$block->attributes['content'],
"The 'content' should be updated with the value of the source context."
);
$this->assertSame(
'<p>Value: source context value</p>',
trim( $result ),
'The block content should be updated with the value of the source context.'
);
}

/**
* Tests that blocks can only access the context from the specific source.
*
* @ticket 61642
*
* @covers ::register_block_bindings_source
*/
public function test_blocks_can_just_access_the_specific_uses_context() {
register_block_bindings_source(
'test/source-one',
array(
'label' => 'Test Source One',
'get_value_callback' => function () {
return;
},
'uses_context' => array( 'contextOne' ),
)
);

register_block_bindings_source(
'test/source-two',
array(
'label' => 'Test Source Two',
'get_value_callback' => function ( $source_args, $block_instance, $attribute_name ) {
$value = $block_instance->context['contextTwo'];
// Try to use the context from source one, which shouldn't be available.
if ( ! empty( $block_instance->context['contextOne'] ) ) {
$value = $block_instance->context['contextOne'];
}
return "Value: $value";
},
'uses_context' => array( 'contextTwo' ),
)
);

$block_content = <<<HTML
<!-- wp:paragraph {"metadata":{"bindings":{"content":{"source":"test/source-two", "args": {"key": "test"}}}}} -->
<p>Default content</p>
<!-- /wp:paragraph -->
<!-- /wp:test/block -->
HTML;
$parsed_blocks = parse_blocks( $block_content );
$block = new WP_Block(
$parsed_blocks[0],
array(
'contextOne' => 'source one context value',
'contextTwo' => 'source two context value',
'sourceContext' => 'source context value',
'forbiddenSourceContext' => 'forbidden donut',
)
);
$result = $block->render();

$this->assertSame(
'Value: source two context value',
$block->attributes['content'],
"The 'content' should be updated with the value of the second source context value."
'Value: source context value',
$block->attributes['myAttribute'],
"The 'myAttribute' should be updated with the value of the source context."
);
$this->assertSame(
'<p>Value: source two context value</p>',
'<p>Value: source context value</p>',
trim( $result ),
'The block content should be updated with the value of the source context.'
);
Expand Down Expand Up @@ -369,78 +319,6 @@ public function test_update_block_with_value_from_source_image_placeholder() {
);
}

/**
* Tests if the block content is sanitized when unsafe HTML is passed.
*
* @ticket 60651
*
* @covers ::register_block_bindings_source
*/
public function test_source_value_with_unsafe_html_is_sanitized() {
$get_value_callback = function () {
return '<script>alert("Unsafe HTML")</script>';
};

register_block_bindings_source(
self::SOURCE_NAME,
array(
'label' => self::SOURCE_LABEL,
'get_value_callback' => $get_value_callback,
)
);

$block_content = <<<HTML
<!-- wp:paragraph {"metadata":{"bindings":{"content":{"source":"test/source"}}}} -->
<p>This should not appear</p>
<!-- /wp:paragraph -->
HTML;
$parsed_blocks = parse_blocks( $block_content );
$block = new WP_Block( $parsed_blocks[0] );
$result = $block->render();

$this->assertSame(
'<p>alert("Unsafe HTML")</p>',
trim( $result ),
'The block content should be updated with the value returned by the source.'
);
}

/**
* Tests that including symbols and numbers works well with bound attributes.
*
* @ticket 61385
*
* @covers WP_Block::process_block_bindings
*/
public function test_using_symbols_in_block_bindings_value() {
$get_value_callback = function () {
return '$12.50';
};

register_block_bindings_source(
self::SOURCE_NAME,
array(
'label' => self::SOURCE_LABEL,
'get_value_callback' => $get_value_callback,
)
);

$block_content = <<<HTML
<!-- wp:paragraph {"metadata":{"bindings":{"content":{"source":"test/source"}}}} -->
<p>Default content</p>
<!-- /wp:paragraph -->
HTML;
$parsed_blocks = parse_blocks( $block_content );
$block = new WP_Block( $parsed_blocks[0] );
$result = $block->render();

$this->assertSame(
'<p>$12.50</p>',
trim( $result ),
'The block content should properly show the symbol and numbers.'
);
}

/**
* Tests if the `__default` attribute is replaced with real attributes for
* pattern overrides.
Expand All @@ -452,14 +330,14 @@ public function test_using_symbols_in_block_bindings_value() {
*/
public function test_default_binding_for_pattern_overrides() {
$block_content = <<<HTML
<!-- wp:paragraph {"metadata":{"bindings":{"__default":{"source":"core/pattern-overrides"}},"name":"Test"}} -->
<!-- wp:test/block {"metadata":{"bindings":{"__default":{"source":"core/pattern-overrides"}},"name":"Test"}} -->
<p>This should not appear</p>
<!-- /wp:paragraph -->
<!-- /wp:test/block -->
HTML;

$expected_content = 'This is the content value';
$parsed_blocks = parse_blocks( $block_content );
$block = new WP_Block( $parsed_blocks[0], array( 'pattern/overrides' => array( 'Test' => array( 'content' => $expected_content ) ) ) );
$block = new WP_Block( $parsed_blocks[0], array( 'pattern/overrides' => array( 'Test' => array( 'myAttribute' => $expected_content ) ) ) );

$result = $block->render();

Expand All @@ -470,7 +348,7 @@ public function test_default_binding_for_pattern_overrides() {
);

$expected_bindings_metadata = array(
'content' => array( 'source' => 'core/pattern-overrides' ),
'myAttribute' => array( 'source' => 'core/pattern-overrides' ),
);
$this->assertSame(
$expected_bindings_metadata,
Expand Down
Loading