PageRenderTime 29ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/phpunit/tests/widgets/custom-html-widget.php

https://gitlab.com/morganestes/wordpress-develop
PHP | 304 lines | 175 code | 29 blank | 100 comment | 2 complexity | 61923d33162e754d6a4746fd01132d70 MD5 | raw file
  1. <?php
  2. /**
  3. * Unit tests covering WP_Widget_Custom_HTML functionality.
  4. *
  5. * @package WordPress
  6. * @subpackage widgets
  7. */
  8. /**
  9. * Test wp-includes/widgets/class-wp-widget-custom-html.php
  10. *
  11. * @group widgets
  12. */
  13. class Test_WP_Widget_Custom_HTML extends WP_UnitTestCase {
  14. /**
  15. * Args passed to the widget_custom_html_content filter.
  16. *
  17. * @var array
  18. */
  19. protected $widget_custom_html_content_args;
  20. /**
  21. * Args passed to the widget_text filter.
  22. *
  23. * @var array
  24. */
  25. protected $widget_text_args;
  26. /**
  27. * Clean up global scope.
  28. *
  29. * @global WP_Scripts $wp_scripts
  30. * @global WP_Styles $wp_style
  31. */
  32. public function clean_up_global_scope() {
  33. global $wp_scripts, $wp_styles;
  34. parent::clean_up_global_scope();
  35. $wp_scripts = null;
  36. $wp_styles = null;
  37. }
  38. /**
  39. * Test construct.
  40. *
  41. * @covers WP_Widget_Custom_HTML::__construct
  42. */
  43. public function test_construct() {
  44. $widget = new WP_Widget_Custom_HTML();
  45. $this->assertEquals( 'custom_html', $widget->id_base );
  46. $this->assertEquals( 'widget_custom_html', $widget->widget_options['classname'] );
  47. $this->assertEquals( 400, $widget->control_options['width'] );
  48. $this->assertEquals( 350, $widget->control_options['height'] );
  49. $this->assertTrue( $widget->widget_options['customize_selective_refresh'] );
  50. }
  51. /**
  52. * Test enqueue_admin_scripts method.
  53. *
  54. * @covers WP_Widget_Custom_HTML::_register
  55. */
  56. public function test__register() {
  57. set_current_screen( 'widgets.php' );
  58. $widget = new WP_Widget_Custom_HTML();
  59. $widget->_register();
  60. $this->assertEquals( 10, has_action( 'admin_print_scripts-widgets.php', array( $widget, 'enqueue_admin_scripts' ) ) );
  61. $this->assertEquals( 10, has_action( 'admin_footer-widgets.php', array( 'WP_Widget_Custom_HTML', 'render_control_template_scripts' ) ) );
  62. $this->assertEquals( 10, has_action( 'admin_head-widgets.php', array( 'WP_Widget_Custom_HTML', 'add_help_text' ) ) );
  63. $this->assertContains( 'wp.customHtmlWidgets.idBases.push( "custom_html" );', wp_scripts()->registered['custom-html-widgets']->extra['after'] );
  64. }
  65. /**
  66. * Test widget method.
  67. *
  68. * @covers WP_Widget_Custom_HTML::widget
  69. */
  70. public function test_widget() {
  71. $widget = new WP_Widget_Custom_HTML();
  72. $content = "<i>Custom HTML</i>\n\n<b>CODE</b>\nLast line.<u>unclosed";
  73. $args = array(
  74. 'before_title' => '<h2>',
  75. 'after_title' => "</h2>\n",
  76. 'before_widget' => '<section id="custom_html-5" class="widget widget_custom_html">',
  77. 'after_widget' => "</section>\n",
  78. );
  79. $instance = array(
  80. 'title' => 'Foo',
  81. 'content' => $content,
  82. );
  83. // Convert Custom HTML widget instance into Text widget instance data.
  84. $text_widget_instance = array_merge(
  85. $instance, array(
  86. 'text' => $instance['content'],
  87. 'filter' => false,
  88. 'visual' => false,
  89. )
  90. );
  91. unset( $text_widget_instance['content'] );
  92. update_option( 'use_balanceTags', 0 );
  93. add_filter( 'widget_custom_html_content', array( $this, 'filter_widget_custom_html_content' ), 5, 3 );
  94. add_filter( 'widget_text', array( $this, 'filter_widget_text' ), 10, 3 );
  95. ob_start();
  96. $this->widget_custom_html_content_args = null;
  97. $this->widget_text_args = null;
  98. $widget->widget( $args, $instance );
  99. $output = ob_get_clean();
  100. $this->assertNotEmpty( $this->widget_custom_html_content_args );
  101. $this->assertNotEmpty( $this->widget_text_args );
  102. $this->assertContains( '[filter:widget_text][filter:widget_custom_html_content]', $output );
  103. $this->assertContains( '<section id="custom_html-5" class="widget_text widget widget_custom_html">', $output );
  104. $this->assertContains( '<div class="textwidget custom-html-widget">', $output );
  105. $this->assertNotContains( '<p>', $output );
  106. $this->assertNotContains( '<br>', $output );
  107. $this->assertNotContains( '</u>', $output );
  108. $this->assertEquals( $text_widget_instance, $this->widget_text_args[1] );
  109. $this->assertEquals( $instance, $this->widget_custom_html_content_args[1] );
  110. $this->assertSame( $widget, $this->widget_text_args[2] );
  111. $this->assertSame( $widget, $this->widget_custom_html_content_args[2] );
  112. remove_filter( 'widget_custom_html_content', array( $this, 'filter_widget_custom_html_content' ), 5 );
  113. remove_filter( 'widget_text', array( $this, 'filter_widget_text' ), 10 );
  114. update_option( 'use_balanceTags', 1 );
  115. ob_start();
  116. $widget->widget( $args, $instance );
  117. $output = ob_get_clean();
  118. $this->assertContains( '</u>', $output );
  119. }
  120. /**
  121. * Filters the content of the Custom HTML widget using the legacy widget_text filter.
  122. *
  123. * @param string $text The widget content.
  124. * @param array $instance Array of settings for the current widget.
  125. * @param WP_Widget_Custom_HTML $widget Current widget instance.
  126. * @return string Widget content.
  127. */
  128. public function filter_widget_text( $text, $instance, $widget ) {
  129. $this->widget_text_args = array( $text, $instance, $widget );
  130. $text .= '[filter:widget_text]';
  131. return $text;
  132. }
  133. /**
  134. * Filters the content of the Custom HTML widget using the dedicated widget_custom_html_content filter.
  135. *
  136. * @param string $widget_content The widget content.
  137. * @param array $instance Array of settings for the current widget.
  138. * @param WP_Widget_Custom_HTML $widget Current Custom HTML widget instance.
  139. * @return string Widget content.
  140. */
  141. public function filter_widget_custom_html_content( $widget_content, $instance, $widget ) {
  142. $this->widget_custom_html_content_args = array( $widget_content, $instance, $widget );
  143. $widget_content .= '[filter:widget_custom_html_content]';
  144. return $widget_content;
  145. }
  146. /**
  147. * Test update method.
  148. *
  149. * @covers WP_Widget_Custom_HTML::update
  150. */
  151. public function test_update() {
  152. $widget = new WP_Widget_Custom_HTML();
  153. $instance = array(
  154. 'title' => "The\n<b>Title</b>",
  155. 'content' => "The\n\n<b>Code</b>",
  156. );
  157. wp_set_current_user(
  158. $this->factory()->user->create(
  159. array(
  160. 'role' => 'administrator',
  161. )
  162. )
  163. );
  164. // Should return valid instance.
  165. $expected = array(
  166. 'title' => sanitize_text_field( $instance['title'] ),
  167. 'content' => $instance['content'],
  168. );
  169. $result = $widget->update( $instance, array() );
  170. $this->assertEquals( $result, $expected );
  171. // Make sure KSES is applying as expected.
  172. add_filter( 'map_meta_cap', array( $this, 'grant_unfiltered_html_cap' ), 10, 2 );
  173. $this->assertTrue( current_user_can( 'unfiltered_html' ) );
  174. $instance['content'] = '<script>alert( "Howdy!" );</script>';
  175. $expected['content'] = $instance['content'];
  176. $result = $widget->update( $instance, array() );
  177. $this->assertEquals( $result, $expected );
  178. remove_filter( 'map_meta_cap', array( $this, 'grant_unfiltered_html_cap' ) );
  179. add_filter( 'map_meta_cap', array( $this, 'revoke_unfiltered_html_cap' ), 10, 2 );
  180. $this->assertFalse( current_user_can( 'unfiltered_html' ) );
  181. $instance['content'] = '<script>alert( "Howdy!" );</script>';
  182. $expected['content'] = wp_kses_post( $instance['content'] );
  183. $result = $widget->update( $instance, array() );
  184. $this->assertEquals( $result, $expected );
  185. remove_filter( 'map_meta_cap', array( $this, 'revoke_unfiltered_html_cap' ), 10 );
  186. }
  187. /**
  188. * Grant unfiltered_html cap via map_meta_cap.
  189. *
  190. * @param array $caps Returns the user's actual capabilities.
  191. * @param string $cap Capability name.
  192. * @return array Caps.
  193. */
  194. public function grant_unfiltered_html_cap( $caps, $cap ) {
  195. if ( 'unfiltered_html' === $cap ) {
  196. $caps = array_diff( $caps, array( 'do_not_allow' ) );
  197. $caps[] = 'unfiltered_html';
  198. }
  199. return $caps;
  200. }
  201. /**
  202. * Revoke unfiltered_html cap via map_meta_cap.
  203. *
  204. * @param array $caps Returns the user's actual capabilities.
  205. * @param string $cap Capability name.
  206. * @return array Caps.
  207. */
  208. public function revoke_unfiltered_html_cap( $caps, $cap ) {
  209. if ( 'unfiltered_html' === $cap ) {
  210. $caps = array_diff( $caps, array( 'unfiltered_html' ) );
  211. $caps[] = 'do_not_allow';
  212. }
  213. return $caps;
  214. }
  215. /**
  216. * Test enqueue_admin_scripts method. Condition: logged_in, syntax_highlighting is on.
  217. *
  218. * @covers WP_Widget_Custom_HTML::enqueue_admin_scripts
  219. */
  220. public function test_enqueue_admin_scripts_when_logged_in_and_syntax_highlighting_on() {
  221. $user = $this->factory()->user->create();
  222. wp_set_current_user( $user );
  223. wp_get_current_user()->syntax_highlighting = 'true';
  224. set_current_screen( 'widgets.php' );
  225. $widget = new WP_Widget_Custom_HTML();
  226. $widget->enqueue_admin_scripts();
  227. $this->assertTrue( wp_script_is( 'custom-html-widgets', 'enqueued' ) );
  228. $this->assertTrue( wp_script_is( 'code-editor', 'enqueued' ) );
  229. $this->assertTrue( wp_script_is( 'wp-codemirror', 'enqueued' ) );
  230. $this->assertTrue( wp_script_is( 'csslint', 'enqueued' ) );
  231. $this->assertTrue( wp_script_is( 'jshint', 'enqueued' ) );
  232. $this->assertTrue( wp_script_is( 'htmlhint', 'enqueued' ) );
  233. }
  234. /**
  235. * Test enqueue_admin_scripts method. Condition: logged_in, syntax_highlighting is off.
  236. *
  237. * @covers WP_Widget_Custom_HTML::enqueue_admin_scripts
  238. */
  239. public function test_enqueue_admin_scripts_when_logged_in_and_syntax_highlighting_off() {
  240. $user = $this->factory()->user->create();
  241. wp_set_current_user( $user );
  242. update_user_meta( $user, 'syntax_highlighting', 'false' );
  243. set_current_screen( 'widgets.php' );
  244. $widget = new WP_Widget_Custom_HTML();
  245. $widget->enqueue_admin_scripts();
  246. $this->assertTrue( wp_script_is( 'custom-html-widgets', 'enqueued' ) );
  247. $this->assertFalse( wp_script_is( 'code-editor', 'enqueued' ) );
  248. $this->assertFalse( wp_script_is( 'wp-codemirror', 'enqueued' ) );
  249. $this->assertFalse( wp_script_is( 'csslint', 'enqueued' ) );
  250. $this->assertFalse( wp_script_is( 'jshint', 'enqueued' ) );
  251. $this->assertFalse( wp_script_is( 'htmlhint', 'enqueued' ) );
  252. }
  253. /**
  254. * Test render_control_template_scripts method.
  255. *
  256. * @covers WP_Widget_Custom_HTML::render_control_template_scripts
  257. */
  258. public function test_render_control_template_scripts() {
  259. ob_start();
  260. WP_Widget_Custom_HTML::render_control_template_scripts();
  261. $output = ob_get_clean();
  262. $this->assertContains( '<script type="text/html" id="tmpl-widget-custom-html-control-fields">', $output );
  263. }
  264. /**
  265. * Test add_help_text method.
  266. *
  267. * @covers WP_Widget_Custom_HTML::add_help_text
  268. */
  269. public function test_add_help_text() {
  270. set_current_screen( 'widgets.php' );
  271. WP_Widget_Custom_HTML::add_help_text();
  272. $help_tab = get_current_screen()->get_help_tab( 'custom_html_widget' );
  273. $this->assertContains( 'Use the Custom HTML widget to add arbitrary HTML code to your widget areas.', $help_tab['content'] );
  274. }
  275. }