register.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. <?php
  2. /**
  3. * Block registry tests.
  4. *
  5. * @package WordPress
  6. * @subpackage Blocks
  7. * @since 5.0.0
  8. */
  9. /**
  10. * Tests for register_block_type(), unregister_block_type(), get_dynamic_block_names()
  11. *
  12. * @since 5.0.0
  13. *
  14. * @group blocks
  15. */
  16. class WP_Test_Block_Register extends WP_UnitTestCase {
  17. /**
  18. * ID for a test post.
  19. *
  20. * @since 5.0.0
  21. * @var int
  22. */
  23. protected static $post_id;
  24. /**
  25. * Set up before class.
  26. *
  27. * @since 5.0.0
  28. */
  29. public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
  30. self::$post_id = $factory->post->create(
  31. array(
  32. 'post_content' => file_get_contents( DIR_TESTDATA . '/blocks/do-blocks-original.html' ),
  33. )
  34. );
  35. }
  36. /**
  37. * Tear down after class.
  38. *
  39. * @since 5.0.0
  40. */
  41. public static function wpTearDownAfterClass() {
  42. // Also deletes revisions.
  43. wp_delete_post( self::$post_id, true );
  44. }
  45. /**
  46. * Empty render function for tests to use.
  47. */
  48. function render_stub() {}
  49. /**
  50. * Tear down after each test.
  51. *
  52. * @since 5.0.0
  53. */
  54. function tearDown() {
  55. $registry = WP_Block_Type_Registry::get_instance();
  56. foreach ( array( 'core/test-static', 'core/test-dynamic', 'tests/notice' ) as $block_name ) {
  57. if ( $registry->is_registered( $block_name ) ) {
  58. $registry->unregister( $block_name );
  59. }
  60. }
  61. parent::tearDown();
  62. }
  63. /**
  64. * @ticket 45109
  65. */
  66. function test_register_affects_main_registry() {
  67. $name = 'core/test-static';
  68. $settings = array(
  69. 'icon' => 'text',
  70. );
  71. register_block_type( $name, $settings );
  72. $registry = WP_Block_Type_Registry::get_instance();
  73. $this->assertTrue( $registry->is_registered( $name ) );
  74. }
  75. /**
  76. * @ticket 45109
  77. */
  78. function test_unregister_affects_main_registry() {
  79. $name = 'core/test-static';
  80. $settings = array(
  81. 'icon' => 'text',
  82. );
  83. register_block_type( $name, $settings );
  84. unregister_block_type( $name );
  85. $registry = WP_Block_Type_Registry::get_instance();
  86. $this->assertFalse( $registry->is_registered( $name ) );
  87. }
  88. /**
  89. * @ticket 50263
  90. */
  91. function test_does_not_remove_block_asset_path_prefix() {
  92. $result = remove_block_asset_path_prefix( 'script-handle' );
  93. $this->assertSame( 'script-handle', $result );
  94. }
  95. /**
  96. * @ticket 50263
  97. */
  98. function test_removes_block_asset_path_prefix() {
  99. $result = remove_block_asset_path_prefix( 'file:./block.js' );
  100. $this->assertSame( './block.js', $result );
  101. }
  102. /**
  103. * @ticket 50263
  104. */
  105. function test_generate_block_asset_handle() {
  106. $block_name = 'unit-tests/my-block';
  107. $this->assertSame(
  108. 'unit-tests-my-block-editor-script',
  109. generate_block_asset_handle( $block_name, 'editorScript' )
  110. );
  111. $this->assertSame(
  112. 'unit-tests-my-block-script',
  113. generate_block_asset_handle( $block_name, 'script' )
  114. );
  115. $this->assertSame(
  116. 'unit-tests-my-block-editor-style',
  117. generate_block_asset_handle( $block_name, 'editorStyle' )
  118. );
  119. $this->assertSame(
  120. 'unit-tests-my-block-style',
  121. generate_block_asset_handle( $block_name, 'style' )
  122. );
  123. }
  124. /**
  125. * @ticket 50328
  126. */
  127. function test_generate_block_asset_handle_core_block() {
  128. $block_name = 'core/paragraph';
  129. $this->assertSame(
  130. 'wp-block-paragraph-editor',
  131. generate_block_asset_handle( $block_name, 'editorScript' )
  132. );
  133. $this->assertSame(
  134. 'wp-block-paragraph',
  135. generate_block_asset_handle( $block_name, 'script' )
  136. );
  137. $this->assertSame(
  138. 'wp-block-paragraph-editor',
  139. generate_block_asset_handle( $block_name, 'editorStyle' )
  140. );
  141. $this->assertSame(
  142. 'wp-block-paragraph',
  143. generate_block_asset_handle( $block_name, 'style' )
  144. );
  145. }
  146. /**
  147. * @ticket 50263
  148. */
  149. function test_field_not_found_register_block_script_handle() {
  150. $result = register_block_script_handle( array(), 'script' );
  151. $this->assertFalse( $result );
  152. }
  153. /**
  154. * @ticket 50263
  155. */
  156. function test_empty_value_register_block_script_handle() {
  157. $metadata = array( 'script' => '' );
  158. $result = register_block_script_handle( $metadata, 'script' );
  159. $this->assertFalse( $result );
  160. }
  161. /**
  162. * @expectedIncorrectUsage register_block_script_handle
  163. * @ticket 50263
  164. */
  165. function test_missing_asset_file_register_block_script_handle() {
  166. $metadata = array(
  167. 'file' => __FILE__,
  168. 'name' => 'unit-tests/test-block',
  169. 'script' => 'file:./blocks/notice/missing-asset.js',
  170. );
  171. $result = register_block_script_handle( $metadata, 'script' );
  172. $this->assertFalse( $result );
  173. }
  174. /**
  175. * @ticket 50263
  176. */
  177. function test_handle_passed_register_block_script_handle() {
  178. $metadata = array(
  179. 'editorScript' => 'test-script-handle',
  180. );
  181. $result = register_block_script_handle( $metadata, 'editorScript' );
  182. $this->assertSame( 'test-script-handle', $result );
  183. }
  184. /**
  185. * @ticket 50263
  186. */
  187. function test_success_register_block_script_handle() {
  188. $metadata = array(
  189. 'file' => DIR_TESTDATA . '/blocks/notice/block.json',
  190. 'name' => 'unit-tests/test-block',
  191. 'script' => 'file:./block.js',
  192. );
  193. $result = register_block_script_handle( $metadata, 'script' );
  194. $this->assertSame( 'unit-tests-test-block-script', $result );
  195. }
  196. /**
  197. * @ticket 50263
  198. */
  199. function test_field_not_found_register_block_style_handle() {
  200. $result = register_block_style_handle( array(), 'style' );
  201. $this->assertFalse( $result );
  202. }
  203. /**
  204. * @ticket 50263
  205. */
  206. function test_empty_value_found_register_block_style_handle() {
  207. $metadata = array( 'style' => '' );
  208. $result = register_block_style_handle( $metadata, 'style' );
  209. $this->assertFalse( $result );
  210. }
  211. /**
  212. * @ticket 50263
  213. */
  214. function test_handle_passed_register_block_style_handle() {
  215. $metadata = array(
  216. 'style' => 'test-style-handle',
  217. );
  218. $result = register_block_style_handle( $metadata, 'style' );
  219. $this->assertSame( 'test-style-handle', $result );
  220. }
  221. /**
  222. * @ticket 50263
  223. */
  224. function test_success_register_block_style_handle() {
  225. $metadata = array(
  226. 'file' => DIR_TESTDATA . '/blocks/notice/block.json',
  227. 'name' => 'unit-tests/test-block',
  228. 'style' => 'file:./block.css',
  229. );
  230. $result = register_block_style_handle( $metadata, 'style' );
  231. $this->assertSame( 'unit-tests-test-block-style', $result );
  232. $this->assertSame( 'replace', wp_styles()->get_data( 'unit-tests-test-block-style', 'rtl' ) );
  233. }
  234. /**
  235. * Tests that the function returns false when the `block.json` is not found
  236. * in the WordPress core.
  237. *
  238. * @ticket 50263
  239. */
  240. function test_metadata_not_found_in_wordpress_core() {
  241. $result = register_block_type_from_metadata( 'unknown' );
  242. $this->assertFalse( $result );
  243. }
  244. /**
  245. * Tests that the function returns false when the `block.json` is not found
  246. * in the current directory.
  247. *
  248. * @ticket 50263
  249. */
  250. function test_metadata_not_found_in_the_current_directory() {
  251. $result = register_block_type_from_metadata( __DIR__ );
  252. $this->assertFalse( $result );
  253. }
  254. /**
  255. * Tests that the function returns the registered block when the `block.json`
  256. * is found in the fixtures directory.
  257. *
  258. * @ticket 50263
  259. */
  260. function test_block_registers_with_metadata_fixture() {
  261. $result = register_block_type_from_metadata(
  262. DIR_TESTDATA . '/blocks/notice'
  263. );
  264. $this->assertInstanceOf( 'WP_Block_Type', $result );
  265. $this->assertSame( 2, $result->api_version );
  266. $this->assertSame( 'tests/notice', $result->name );
  267. $this->assertSame( 'Notice', $result->title );
  268. $this->assertSame( 'common', $result->category );
  269. $this->assertSameSets( array( 'core/group' ), $result->parent );
  270. $this->assertSame( 'star', $result->icon );
  271. $this->assertSame( 'Shows warning, error or success notices…', $result->description );
  272. $this->assertSameSets( array( 'alert', 'message' ), $result->keywords );
  273. $this->assertSame(
  274. array(
  275. 'message' => array(
  276. 'type' => 'string',
  277. 'source' => 'html',
  278. 'selector' => '.message',
  279. ),
  280. ),
  281. $result->attributes
  282. );
  283. $this->assertSame(
  284. array(
  285. 'tests/message' => 'message',
  286. ),
  287. $result->provides_context
  288. );
  289. $this->assertSameSets( array( 'groupId' ), $result->uses_context );
  290. $this->assertSame(
  291. array(
  292. 'align' => true,
  293. 'lightBlockWrapper' => true,
  294. ),
  295. $result->supports
  296. );
  297. $this->assertSame(
  298. array(
  299. array(
  300. 'name' => 'default',
  301. 'label' => 'Default',
  302. 'isDefault' => true,
  303. ),
  304. array(
  305. 'name' => 'other',
  306. 'label' => 'Other',
  307. ),
  308. ),
  309. $result->styles
  310. );
  311. $this->assertSame(
  312. array(
  313. 'attributes' => array(
  314. 'message' => 'This is a notice!',
  315. ),
  316. ),
  317. $result->example
  318. );
  319. $this->assertSame( 'tests-notice-editor-script', $result->editor_script );
  320. $this->assertSame( 'tests-notice-script', $result->script );
  321. $this->assertSame( 'tests-notice-editor-style', $result->editor_style );
  322. $this->assertSame( 'tests-notice-style', $result->style );
  323. }
  324. /**
  325. * @ticket 52301
  326. */
  327. function test_block_registers_with_metadata_i18n_support() {
  328. function filter_set_locale_to_polish() {
  329. return 'pl_PL';
  330. }
  331. add_filter( 'locale', 'filter_set_locale_to_polish' );
  332. load_textdomain( 'notice', WP_LANG_DIR . '/plugins/notice-pl_PL.mo' );
  333. $result = register_block_type_from_metadata(
  334. DIR_TESTDATA . '/blocks/notice'
  335. );
  336. unload_textdomain( 'notice' );
  337. remove_filter( 'locale', 'filter_set_locale_to_polish' );
  338. $this->assertInstanceOf( 'WP_Block_Type', $result );
  339. $this->assertSame( 'tests/notice', $result->name );
  340. $this->assertSame( 'Powiadomienie', $result->title );
  341. $this->assertSame( 'Wyświetla ostrzeżenie, błąd lub powiadomienie o sukcesie…', $result->description );
  342. $this->assertSameSets( array( 'ostrzeżenie', 'wiadomość' ), $result->keywords );
  343. $this->assertSame(
  344. array(
  345. array(
  346. 'name' => 'default',
  347. 'label' => 'Domyślny',
  348. 'isDefault' => true,
  349. ),
  350. array(
  351. 'name' => 'other',
  352. 'label' => 'Inny',
  353. ),
  354. ),
  355. $result->styles
  356. );
  357. }
  358. /**
  359. * @ticket 45109
  360. */
  361. function test_get_dynamic_block_names() {
  362. register_block_type( 'core/test-static', array() );
  363. register_block_type( 'core/test-dynamic', array( 'render_callback' => array( $this, 'render_stub' ) ) );
  364. $dynamic_block_names = get_dynamic_block_names();
  365. $this->assertContains( 'core/test-dynamic', $dynamic_block_names );
  366. $this->assertNotContains( 'core/test-static', $dynamic_block_names );
  367. }
  368. /**
  369. * @ticket 45109
  370. */
  371. function test_has_blocks() {
  372. // Test with passing post ID.
  373. $this->assertTrue( has_blocks( self::$post_id ) );
  374. // Test with passing WP_Post object.
  375. $this->assertTrue( has_blocks( get_post( self::$post_id ) ) );
  376. // Test with passing content string.
  377. $this->assertTrue( has_blocks( get_post( self::$post_id ) ) );
  378. // Test default.
  379. $this->assertFalse( has_blocks() );
  380. $query = new WP_Query( array( 'post__in' => array( self::$post_id ) ) );
  381. $query->the_post();
  382. $this->assertTrue( has_blocks() );
  383. // Test string (without blocks).
  384. $content = file_get_contents( DIR_TESTDATA . '/blocks/do-blocks-expected.html' );
  385. $this->assertFalse( has_blocks( $content ) );
  386. }
  387. /**
  388. * @ticket 49615
  389. */
  390. public function test_filter_block_registration() {
  391. $filter_registration = function( $args, $name ) {
  392. $args['attributes'] = array( $name => array( 'type' => 'boolean' ) );
  393. return $args;
  394. };
  395. add_filter( 'register_block_type_args', $filter_registration, 10, 2 );
  396. register_block_type( 'core/test-filtered', array() );
  397. remove_filter( 'register_block_type_args', $filter_registration );
  398. $registry = WP_Block_Type_Registry::get_instance();
  399. $block_type = $registry->get_registered( 'core/test-filtered' );
  400. $this->assertSame( 'boolean', $block_type->attributes['core/test-filtered']['type'] );
  401. }
  402. /**
  403. * @ticket 52138
  404. */
  405. public function test_filter_block_registration_metadata() {
  406. $filter_metadata_registration = function( $metadata ) {
  407. $metadata['apiVersion'] = 3;
  408. return $metadata;
  409. };
  410. add_filter( 'block_type_metadata', $filter_metadata_registration, 10, 2 );
  411. $result = register_block_type_from_metadata(
  412. DIR_TESTDATA . '/blocks/notice'
  413. );
  414. remove_filter( 'block_type_metadata', $filter_metadata_registration );
  415. $this->assertSame( 3, $result->api_version );
  416. }
  417. /**
  418. * @ticket 52138
  419. */
  420. public function test_filter_block_registration_metadata_settings() {
  421. $filter_metadata_registration = function( $settings, $metadata ) {
  422. $settings['api_version'] = $metadata['apiVersion'] + 1;
  423. return $settings;
  424. };
  425. add_filter( 'block_type_metadata_settings', $filter_metadata_registration, 10, 2 );
  426. $result = register_block_type_from_metadata(
  427. DIR_TESTDATA . '/blocks/notice'
  428. );
  429. remove_filter( 'block_type_metadata_settings', $filter_metadata_registration );
  430. $this->assertSame( 3, $result->api_version );
  431. }
  432. }