ExcerptRemoveBlocks.php 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. <?php
  2. /**
  3. * @group formatting
  4. * @covers ::excerpt_remove_blocks
  5. * @ticket 46133
  6. */
  7. class Tests_Formatting_ExcerptRemoveBlocks extends WP_UnitTestCase {
  8. public static $post_id;
  9. public $content = '
  10. <!-- wp:paragraph -->
  11. <p>paragraph</p>
  12. <!-- /wp:paragraph -->
  13. <!-- wp:latest-posts {"postsToShow":3,"displayPostDate":true,"order":"asc","orderBy":"title"} /-->
  14. <!-- wp:spacer -->
  15. <div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>
  16. <!-- /wp:spacer -->
  17. <!-- wp:columns {"columns":1} -->
  18. <div class="wp-block-columns has-1-columns">
  19. <!-- wp:column -->
  20. <div class="wp-block-column">
  21. <!-- wp:archives {"displayAsDropdown":false,"showPostCounts":false} /-->
  22. <!-- wp:paragraph -->
  23. <p>paragraph inside column</p>
  24. <!-- /wp:paragraph -->
  25. </div>
  26. <!-- /wp:column -->
  27. </div>
  28. <!-- /wp:columns -->
  29. ';
  30. public $filtered_content = '
  31. <p>paragraph</p>
  32. <p>paragraph inside column</p>
  33. ';
  34. /**
  35. * Fake block rendering function.
  36. *
  37. * @since 5.2.0
  38. *
  39. * @return string Block output.
  40. */
  41. function render_fake_block() {
  42. return get_the_excerpt( self::$post_id );
  43. }
  44. /**
  45. * Set up.
  46. *
  47. * @since 5.2.0
  48. */
  49. function setUp() {
  50. parent::setUp();
  51. self::$post_id = $this->factory()->post->create(
  52. array(
  53. 'post_excerpt' => '', // Empty excerpt, so it has to be generated.
  54. 'post_content' => '<!-- wp:core/fake /-->',
  55. )
  56. );
  57. register_block_type(
  58. 'core/fake',
  59. array(
  60. 'render_callback' => array( $this, 'render_fake_block' ),
  61. )
  62. );
  63. }
  64. /**
  65. * Tear down.
  66. *
  67. * @since 5.2.0
  68. */
  69. function tearDown() {
  70. $registry = WP_Block_Type_Registry::get_instance();
  71. $registry->unregister( 'core/fake' );
  72. parent::tearDown();
  73. }
  74. /**
  75. * Tests excerpt_remove_blocks().
  76. *
  77. * @ticket 46133
  78. */
  79. function test_excerpt_remove_blocks() {
  80. // Simple dynamic block..
  81. $content = '<!-- wp:core/block /-->';
  82. $this->assertEmpty( excerpt_remove_blocks( $content ) );
  83. // Dynamic block with options, embedded in other content.
  84. $this->assertSame( $this->filtered_content, excerpt_remove_blocks( $this->content ) );
  85. }
  86. /**
  87. * Tests that dynamic blocks don't cause an out-of-memory error.
  88. *
  89. * When dynamic blocks happen to generate an excerpt, they can cause an
  90. * infinite loop if that block is part of the post's content.
  91. *
  92. * `wp_trim_excerpt()` applies the `the_content` filter, which has
  93. * `do_blocks` attached to it, trying to render the block which again will
  94. * attempt to return an excerpt of that post.
  95. *
  96. * This infinite loop can be avoided by stripping dynamic blocks before
  97. * `the_content` gets applied, just like shortcodes.
  98. *
  99. * @ticket 46133
  100. */
  101. function test_excerpt_infinite_loop() {
  102. $query = new WP_Query(
  103. array(
  104. 'post__in' => array( self::$post_id ),
  105. )
  106. );
  107. $query->the_post();
  108. $this->assertEmpty( do_blocks( '<!-- wp:core/fake /-->' ) );
  109. }
  110. }