Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add has_block function and unit tests for it #9058

Merged
Merged
Show file tree
Hide file tree
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
31 changes: 29 additions & 2 deletions lib/register.php
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ function has_blocks( $post = null ) {
* @see gutenberg_parse_blocks()
*
* @since 0.5.0
* @deprecated 3.6.0 Use has_block()
* @deprecated 3.6.0 Use has_blocks()
*
* @param object $post Post.
* @return bool Whether the post has blocks.
Expand All @@ -384,7 +384,7 @@ function gutenberg_post_has_blocks( $post ) {
* @see gutenberg_parse_blocks()
*
* @since 1.6.0
* @deprecated 3.6.0 Use has_block()
* @deprecated 3.6.0 Use has_blocks()
*
* @param string $content Content to test.
* @return bool Whether the content contains blocks.
Expand All @@ -394,6 +394,33 @@ function gutenberg_content_has_blocks( $content ) {
return has_blocks( $content );
}

/**
* Determine whether a $post or a string contains a specific block type.
* This test optimizes for performance rather than strict accuracy, detecting
* the block type exists but not validating its structure.
* For strict accuracy, you should use the block parser on post content.
*
* @since 3.6.0
*
* @param string $block_type Full Block type to look for.
* @param int|string|WP_Post|null $post Optional. Post content, post ID, or post object. Defaults to global $post.
* @return bool Whether the post content contains the specified block.
*/
function has_block( $block_type, $post = null ) {
if ( ! has_blocks( $post ) ) {
return false;
}

if ( ! is_string( $post ) ) {
$wp_post = get_post( $post );
if ( $wp_post instanceof WP_Post ) {
$post = $wp_post->post_content;
}
}

return false !== strpos( $post, '<!-- wp:' . $block_type . ' ' );
}

/**
* Returns the current version of the block format that the content string is using.
*
Expand Down
113 changes: 113 additions & 0 deletions phpunit/class-block-type-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,50 @@
* Tests for WP_Block_Type
*/
class Block_Type_Test extends WP_UnitTestCase {
function setUp() {
parent::setUp();
}

/**
* Editor user ID.
*
* @var int
*/
protected static $editor_user_id;

/**
* ID for a post containing blocks.
*
* @var int
*/
protected static $post_with_blocks;

/**
* ID for a post without blocks.
*
* @var int
*/
protected static $post_without_blocks;

/**
* Set up before class.
*/
public static function wpSetUpBeforeClass() {
self::$editor_user_id = self::factory()->user->create( array(
'role' => 'editor',
) );

self::$post_with_blocks = self::factory()->post->create( array(
'post_title' => 'Example',
'post_content' => "<!-- wp:core/text {\"dropCap\":true} -->\n<p class=\"has-drop-cap\">Tester</p>\n<!-- /wp:core/text -->",
) );

self::$post_without_blocks = self::factory()->post->create( array(
'post_title' => 'Example',
'post_content' => 'Tester',
) );
}

function test_set_props() {
$name = 'core/dummy';
$args = array(
Expand Down Expand Up @@ -112,6 +156,75 @@ function test_prepare_attributes() {
), $prepared_attributes );
}

function test_has_block_with_mixed_content() {
$mixed_post_content = 'before' .
'<!-- wp:core/dummy --><!-- /wp:core/dummy -->' .
'<!-- wp:core/dummy_atts {"value":"b1"} --><!-- /wp:core/dummy_atts -->' .
'<!-- wp:core/dummy-child -->
<p>testing the test</p>
<!-- /wp:core/dummy-child -->' .
'between' .
'<!-- wp:core/self-close-dummy /-->' .
'<!-- wp:custom/dummy {"value":"b2"} /-->' .
'after';

$this->assertTrue( has_block( 'core/dummy', $mixed_post_content ) );

$this->assertTrue( has_block( 'core/dummy_atts', $mixed_post_content ) );

$this->assertTrue( has_block( 'core/dummy-child', $mixed_post_content ) );

$this->assertTrue( has_block( 'core/self-close-dummy', $mixed_post_content ) );

$this->assertTrue( has_block( 'custom/dummy', $mixed_post_content ) );

// checking for a partial block name should fail.
$this->assertFalse( has_block( 'core/dumm', $mixed_post_content ) );

// checking for a wrong namespace should fail.
$this->assertFalse( has_block( 'custom/dummy_atts', $mixed_post_content ) );

// checking for namespace only should not work. Or maybe ... ?
$this->assertFalse( has_block( 'core', $mixed_post_content ) );
}

function test_has_block_with_invalid_content() {
// some content with invalid HMTL comments and a single valid block.
$invalid_content = 'before' .
'<!- - wp:core/weird-space --><!-- /wp:core/weird-space -->' .
'<!--wp:core/untrimmed-left --><!-- /wp:core/untrimmed -->' .
'<!-- wp:core/dummy --><!-- /wp:core/dummy -->' .
'<!-- wp:core/untrimmed-right--><!-- /wp:core/untrimmed2 -->' .
'after';

$this->assertFalse( has_block( 'core/text', self::$post_without_blocks ) );

$this->assertFalse( has_block( 'core/weird-space', $invalid_content ) );

$this->assertFalse( has_block( 'core/untrimmed-left', $invalid_content ) );

$this->assertFalse( has_block( 'core/untrimmed-right', $invalid_content ) );

$this->assertTrue( has_block( 'core/dummy', $invalid_content ) );
}

function test_post_has_block() {
// should fail for a non-existent block `custom/dummy`.
$this->assertFalse( has_block( 'custom/dummy', self::$post_with_blocks ) );

// this functions should not work without the second param until the $post global is set.
$this->assertFalse( has_block( 'core/text' ) );
$this->assertFalse( has_block( 'core/dummy' ) );

global $post;
$post = get_post( self::$post_with_blocks );

// check if the function correctly detects content from the $post global.
$this->assertTrue( has_block( 'core/text' ) );
// even if it detects a proper $post global it should still be false for a missing block.
$this->assertFalse( has_block( 'core/dummy' ) );
}

function render_dummy_block( $attributes ) {
return json_encode( $attributes );
}
Expand Down