<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[51493] trunk/tests/phpunit/tests/widgets: Tests: Rename classes in `phpunit/tests/widgets/` per the naming conventions.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/51493">51493</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/51493","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>SergeyBiryukov</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2021-07-26 19:25:09 +0000 (Mon, 26 Jul 2021)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Tests: Rename classes in `phpunit/tests/widgets/` per the naming conventions.

https://make.wordpress.org/core/handbook/testing/automated-testing/writing-phpunit-tests/#naming-and-organization

Follow-up to <a href="https://core.trac.wordpress.org/changeset/47780">[47780]</a>, <a href="https://core.trac.wordpress.org/changeset/48911">[48911]</a>, <a href="https://core.trac.wordpress.org/changeset/49327">[49327]</a>, <a href="https://core.trac.wordpress.org/changeset/50291">[50291]</a>, <a href="https://core.trac.wordpress.org/changeset/50292">[50292]</a>, <a href="https://core.trac.wordpress.org/changeset/50342">[50342]</a>, <a href="https://core.trac.wordpress.org/changeset/50452">[50452]</a>, <a href="https://core.trac.wordpress.org/changeset/50453">[50453]</a>, <a href="https://core.trac.wordpress.org/changeset/50456">[50456]</a>, <a href="https://core.trac.wordpress.org/changeset/50967">[50967]</a>, <a href="https://core.trac.wordpress.org/changeset/50968">[50968]</a>, <a href="https://core.trac.wordpress.org/changeset/50969">[50969]</a>, <a href="https://core.trac.wordpress.org/changeset/51491">[51491]</a>, <a href="https://core.trac.wordpress.org/changeset/51492">[514
 92]</a>.

See <a href="https://core.trac.wordpress.org/ticket/53363">#53363</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunktestsphpunittestswidgetswpWidgetRssphp">trunk/tests/phpunit/tests/widgets/wpWidgetRss.php</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunktestsphpunittestswidgetswpWidgetCustomHtmlphp">trunk/tests/phpunit/tests/widgets/wpWidgetCustomHtml.php</a></li>
<li><a href="#trunktestsphpunittestswidgetswpWidgetMediaphp">trunk/tests/phpunit/tests/widgets/wpWidgetMedia.php</a></li>
<li><a href="#trunktestsphpunittestswidgetswpWidgetMediaAudiophp">trunk/tests/phpunit/tests/widgets/wpWidgetMediaAudio.php</a></li>
<li><a href="#trunktestsphpunittestswidgetswpWidgetMediaGalleryphp">trunk/tests/phpunit/tests/widgets/wpWidgetMediaGallery.php</a></li>
<li><a href="#trunktestsphpunittestswidgetswpWidgetMediaImagephp">trunk/tests/phpunit/tests/widgets/wpWidgetMediaImage.php</a></li>
<li><a href="#trunktestsphpunittestswidgetswpWidgetMediaVideophp">trunk/tests/phpunit/tests/widgets/wpWidgetMediaVideo.php</a></li>
<li><a href="#trunktestsphpunittestswidgetswpWidgetTextphp">trunk/tests/phpunit/tests/widgets/wpWidgetText.php</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunktestsphpunittestswidgetscustomhtmlwidgetphp">trunk/tests/phpunit/tests/widgets/custom-html-widget.php</a></li>
<li><a href="#trunktestsphpunittestswidgetsmediaaudiowidgetphp">trunk/tests/phpunit/tests/widgets/media-audio-widget.php</a></li>
<li><a href="#trunktestsphpunittestswidgetsmediagallerywidgetphp">trunk/tests/phpunit/tests/widgets/media-gallery-widget.php</a></li>
<li><a href="#trunktestsphpunittestswidgetsmediaimagewidgetphp">trunk/tests/phpunit/tests/widgets/media-image-widget.php</a></li>
<li><a href="#trunktestsphpunittestswidgetsmediavideowidgetphp">trunk/tests/phpunit/tests/widgets/media-video-widget.php</a></li>
<li><a href="#trunktestsphpunittestswidgetsmediawidgetphp">trunk/tests/phpunit/tests/widgets/media-widget.php</a></li>
<li><a href="#trunktestsphpunittestswidgetstextwidgetphp">trunk/tests/phpunit/tests/widgets/text-widget.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunktestsphpunittestswidgetscustomhtmlwidgetphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/tests/phpunit/tests/widgets/custom-html-widget.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/widgets/custom-html-widget.php  2021-07-26 19:09:41 UTC (rev 51492)
+++ trunk/tests/phpunit/tests/widgets/custom-html-widget.php    2021-07-26 19:25:09 UTC (rev 51493)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,358 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-/**
- * Unit tests covering WP_Widget_Custom_HTML functionality.
- *
- * @package    WordPress
- * @subpackage widgets
- */
-
-/**
- * Test wp-includes/widgets/class-wp-widget-custom-html.php
- *
- * @group widgets
- */
-class Test_WP_Widget_Custom_HTML extends WP_UnitTestCase {
-
-       /**
-        * Args passed to the widget_custom_html_content filter.
-        *
-        * @var array
-        */
-       protected $widget_custom_html_content_args;
-
-       /**
-        * Args passed to the widget_text filter.
-        *
-        * @var array
-        */
-       protected $widget_text_args;
-
-       /**
-        * Clean up global scope.
-        *
-        * @global WP_Scripts $wp_scripts
-        * @global WP_Styles  $wp_style
-        */
-       public function clean_up_global_scope() {
-               global $wp_scripts, $wp_styles;
-               parent::clean_up_global_scope();
-               $wp_scripts = null;
-               $wp_styles  = null;
-       }
-
-       /**
-        * Test construct.
-        *
-        * @covers WP_Widget_Custom_HTML::__construct
-        */
-       public function test_construct() {
-               $widget = new WP_Widget_Custom_HTML();
-               $this->assertSame( 'custom_html', $widget->id_base );
-               $this->assertSame( 'widget_custom_html', $widget->widget_options['classname'] );
-               $this->assertSame( 400, $widget->control_options['width'] );
-               $this->assertSame( 350, $widget->control_options['height'] );
-               $this->assertTrue( $widget->widget_options['customize_selective_refresh'] );
-       }
-
-       /**
-        * Test enqueue_admin_scripts method.
-        *
-        * @covers WP_Widget_Custom_HTML::_register
-        */
-       public function test__register() {
-               set_current_screen( 'widgets.php' );
-               $widget = new WP_Widget_Custom_HTML();
-               $widget->_register();
-
-               $this->assertSame( 10, has_action( 'admin_print_scripts-widgets.php', array( $widget, 'enqueue_admin_scripts' ) ) );
-               $this->assertSame( 10, has_action( 'admin_footer-widgets.php', array( 'WP_Widget_Custom_HTML', 'render_control_template_scripts' ) ) );
-               $this->assertSame( 10, has_action( 'admin_head-widgets.php', array( 'WP_Widget_Custom_HTML', 'add_help_text' ) ) );
-               $this->assertContains( 'wp.customHtmlWidgets.idBases.push( "custom_html" );', wp_scripts()->registered['custom-html-widgets']->extra['after'] );
-       }
-
-       /**
-        * Test widget method.
-        *
-        * @covers WP_Widget_Custom_HTML::widget
-        */
-       public function test_widget() {
-               $widget  = new WP_Widget_Custom_HTML();
-               $content = "<i>Custom HTML</i>\n\n<b>CODE</b>\nLast line.<u>unclosed";
-
-               $args     = array(
-                       'before_title'  => '<h2>',
-                       'after_title'   => "</h2>\n",
-                       'before_widget' => '<section id="custom_html-5" class="widget widget_custom_html">',
-                       'after_widget'  => "</section>\n",
-               );
-               $instance = array(
-                       'title'   => 'Foo',
-                       'content' => $content,
-               );
-
-               // Convert Custom HTML widget instance into Text widget instance data.
-               $text_widget_instance = array_merge(
-                       $instance,
-                       array(
-                               'text'   => $instance['content'],
-                               'filter' => false,
-                               'visual' => false,
-                       )
-               );
-               unset( $text_widget_instance['content'] );
-
-               update_option( 'use_balanceTags', 0 );
-               add_filter( 'widget_custom_html_content', array( $this, 'filter_widget_custom_html_content' ), 5, 3 );
-               add_filter( 'widget_text', array( $this, 'filter_widget_text' ), 10, 3 );
-               ob_start();
-               $this->widget_custom_html_content_args = null;
-               $this->widget_text_args                = null;
-               $widget->widget( $args, $instance );
-               $output = ob_get_clean();
-               $this->assertNotEmpty( $this->widget_custom_html_content_args );
-               $this->assertNotEmpty( $this->widget_text_args );
-               $this->assertStringContainsString( '[filter:widget_text][filter:widget_custom_html_content]', $output );
-               $this->assertStringContainsString( '<section id="custom_html-5" class="widget_text widget widget_custom_html">', $output );
-               $this->assertStringContainsString( '<div class="textwidget custom-html-widget">', $output );
-               $this->assertStringNotContainsString( '<p>', $output );
-               $this->assertStringNotContainsString( '<br>', $output );
-               $this->assertStringNotContainsString( '</u>', $output );
-               $this->assertSame( $text_widget_instance, $this->widget_text_args[1] );
-               $this->assertSame( $instance, $this->widget_custom_html_content_args[1] );
-               $this->assertSame( $widget, $this->widget_text_args[2] );
-               $this->assertSame( $widget, $this->widget_custom_html_content_args[2] );
-               remove_filter( 'widget_custom_html_content', array( $this, 'filter_widget_custom_html_content' ), 5 );
-               remove_filter( 'widget_text', array( $this, 'filter_widget_text' ), 10 );
-
-               update_option( 'use_balanceTags', 1 );
-               ob_start();
-               $widget->widget( $args, $instance );
-               $output = ob_get_clean();
-               $this->assertStringContainsString( '</u>', $output );
-       }
-
-       /**
-        * Filters the content of the Custom HTML widget using the legacy widget_text filter.
-        *
-        * @param string                $text     The widget content.
-        * @param array                 $instance Array of settings for the current widget.
-        * @param WP_Widget_Custom_HTML $widget   Current widget instance.
-        * @return string Widget content.
-        */
-       public function filter_widget_text( $text, $instance, $widget ) {
-               $this->widget_text_args = array( $text, $instance, $widget );
-               $text                  .= '[filter:widget_text]';
-               return $text;
-       }
-
-       /**
-        * Filters the content of the Custom HTML widget using the dedicated widget_custom_html_content filter.
-        *
-        * @param string                $widget_content The widget content.
-        * @param array                 $instance       Array of settings for the current widget.
-        * @param WP_Widget_Custom_HTML $widget         Current Custom HTML widget instance.
-        * @return string Widget content.
-        */
-       public function filter_widget_custom_html_content( $widget_content, $instance, $widget ) {
-               $this->widget_custom_html_content_args = array( $widget_content, $instance, $widget );
-               $widget_content                       .= '[filter:widget_custom_html_content]';
-               return $widget_content;
-       }
-
-       /**
-        * Test update method.
-        *
-        * @covers WP_Widget_Custom_HTML::update
-        */
-       public function test_update() {
-               $widget   = new WP_Widget_Custom_HTML();
-               $instance = array(
-                       'title'   => "The\n<b>Title</b>",
-                       'content' => "The\n\n<b>Code</b>",
-               );
-
-               wp_set_current_user(
-                       $this->factory()->user->create(
-                               array(
-                                       'role' => 'administrator',
-                               )
-                       )
-               );
-
-               // Should return valid instance.
-               $expected = array(
-                       'title'   => sanitize_text_field( $instance['title'] ),
-                       'content' => $instance['content'],
-               );
-               $result   = $widget->update( $instance, array() );
-               $this->assertSame( $result, $expected );
-
-               // Make sure KSES is applying as expected.
-               add_filter( 'map_meta_cap', array( $this, 'grant_unfiltered_html_cap' ), 10, 2 );
-               $this->assertTrue( current_user_can( 'unfiltered_html' ) );
-               $instance['content'] = '<script>alert( "Howdy!" );</script>';
-               $expected['content'] = $instance['content'];
-               $result              = $widget->update( $instance, array() );
-               $this->assertSame( $result, $expected );
-               remove_filter( 'map_meta_cap', array( $this, 'grant_unfiltered_html_cap' ) );
-
-               add_filter( 'map_meta_cap', array( $this, 'revoke_unfiltered_html_cap' ), 10, 2 );
-               $this->assertFalse( current_user_can( 'unfiltered_html' ) );
-               $instance['content'] = '<script>alert( "Howdy!" );</script>';
-               $expected['content'] = wp_kses_post( $instance['content'] );
-               $result              = $widget->update( $instance, array() );
-               $this->assertSame( $result, $expected );
-               remove_filter( 'map_meta_cap', array( $this, 'revoke_unfiltered_html_cap' ), 10 );
-       }
-
-       /**
-        * Grant unfiltered_html cap via map_meta_cap.
-        *
-        * @param array  $caps    Returns the user's actual capabilities.
-        * @param string $cap     Capability name.
-        * @return array Caps.
-        */
-       public function grant_unfiltered_html_cap( $caps, $cap ) {
-               if ( 'unfiltered_html' === $cap ) {
-                       $caps   = array_diff( $caps, array( 'do_not_allow' ) );
-                       $caps[] = 'unfiltered_html';
-               }
-               return $caps;
-       }
-
-       /**
-        * Revoke unfiltered_html cap via map_meta_cap.
-        *
-        * @param array  $caps    Returns the user's actual capabilities.
-        * @param string $cap     Capability name.
-        * @return array Caps.
-        */
-       public function revoke_unfiltered_html_cap( $caps, $cap ) {
-               if ( 'unfiltered_html' === $cap ) {
-                       $caps   = array_diff( $caps, array( 'unfiltered_html' ) );
-                       $caps[] = 'do_not_allow';
-               }
-               return $caps;
-       }
-
-       /**
-        * Test enqueue_admin_scripts method. Condition: logged_in, syntax_highlighting is on.
-        *
-        * @covers WP_Widget_Custom_HTML::enqueue_admin_scripts
-        */
-       public function test_enqueue_admin_scripts_when_logged_in_and_syntax_highlighting_on() {
-               $user = $this->factory()->user->create();
-               wp_set_current_user( $user );
-               wp_get_current_user()->syntax_highlighting = 'true';
-               set_current_screen( 'widgets.php' );
-               $widget = new WP_Widget_Custom_HTML();
-               $widget->enqueue_admin_scripts();
-
-               $this->assertTrue( wp_script_is( 'custom-html-widgets', 'enqueued' ) );
-               $this->assertTrue( wp_script_is( 'code-editor', 'enqueued' ) );
-               $this->assertTrue( wp_script_is( 'wp-codemirror', 'enqueued' ) );
-               $this->assertTrue( wp_script_is( 'csslint', 'enqueued' ) );
-               $this->assertTrue( wp_script_is( 'jshint', 'enqueued' ) );
-               $this->assertTrue( wp_script_is( 'htmlhint', 'enqueued' ) );
-       }
-
-       /**
-        * Test enqueue_admin_scripts method. Condition: logged_in, syntax_highlighting is off.
-        *
-        * @covers WP_Widget_Custom_HTML::enqueue_admin_scripts
-        */
-       public function test_enqueue_admin_scripts_when_logged_in_and_syntax_highlighting_off() {
-               $user = $this->factory()->user->create();
-               wp_set_current_user( $user );
-               update_user_meta( $user, 'syntax_highlighting', 'false' );
-               set_current_screen( 'widgets.php' );
-               $widget = new WP_Widget_Custom_HTML();
-               $widget->enqueue_admin_scripts();
-
-               $this->assertTrue( wp_script_is( 'custom-html-widgets', 'enqueued' ) );
-               $this->assertFalse( wp_script_is( 'code-editor', 'enqueued' ) );
-               $this->assertFalse( wp_script_is( 'wp-codemirror', 'enqueued' ) );
-               $this->assertFalse( wp_script_is( 'csslint', 'enqueued' ) );
-               $this->assertFalse( wp_script_is( 'jshint', 'enqueued' ) );
-               $this->assertFalse( wp_script_is( 'htmlhint', 'enqueued' ) );
-       }
-
-       /**
-        * Test render_control_template_scripts method.
-        *
-        * @covers WP_Widget_Custom_HTML::render_control_template_scripts
-        */
-       public function test_render_control_template_scripts() {
-               ob_start();
-               WP_Widget_Custom_HTML::render_control_template_scripts();
-               $output = ob_get_clean();
-
-               $this->assertStringContainsString( '<script type="text/html" id="tmpl-widget-custom-html-control-fields">', $output );
-       }
-
-       /**
-        * Test add_help_text method.
-        *
-        * @covers WP_Widget_Custom_HTML::add_help_text
-        */
-       public function test_add_help_text() {
-               set_current_screen( 'widgets.php' );
-               WP_Widget_Custom_HTML::add_help_text();
-               $help_tab = get_current_screen()->get_help_tab( 'custom_html_widget' );
-
-               $this->assertStringContainsString( 'Use the Custom HTML widget to add arbitrary HTML code to your widget areas.', $help_tab['content'] );
-       }
-
-       /**
-        * Ensure that rel="noopener" is added to links with a target.
-        *
-        * @ticket 46421
-        */
-       function test_render_links_with_target() {
-               $widget = new WP_Widget_Custom_HTML();
-
-               $content = 'Test content with an external <a href="https://example.org" target="_blank">link</a>.';
-
-               $args = array(
-                       'before_title'  => '<h2>',
-                       'after_title'   => '</h2>',
-                       'before_widget' => '',
-                       'after_widget'  => '',
-               );
-
-               $instance = array(
-                       'title'   => 'Foo',
-                       'content' => $content,
-               );
-
-               $output = get_echo( array( $widget, 'widget' ), array( $args, $instance ) );
-               $this->assertStringContainsString( 'rel="noopener"', $output );
-       }
-
-       /**
-        * Ensure that rel="noopener" is not added to links without a target.
-        *
-        * @ticket 46421
-        */
-       function test_render_links_without_target() {
-               $widget = new WP_Widget_Custom_HTML();
-
-               $content = 'Test content with an internal <a href="/">link</a>.';
-
-               $args = array(
-                       'before_title'  => '<h2>',
-                       'after_title'   => '</h2>',
-                       'before_widget' => '',
-                       'after_widget'  => '',
-               );
-
-               $instance = array(
-                       'title'   => 'Foo',
-                       'content' => $content,
-               );
-
-               $output = get_echo( array( $widget, 'widget' ), array( $args, $instance ) );
-               $this->assertStringNotContainsString( 'rel="noopener"', $output );
-       }
-
-}
</del></span></pre></div>
<a id="trunktestsphpunittestswidgetsmediaaudiowidgetphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/tests/phpunit/tests/widgets/media-audio-widget.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/widgets/media-audio-widget.php  2021-07-26 19:09:41 UTC (rev 51492)
+++ trunk/tests/phpunit/tests/widgets/media-audio-widget.php    2021-07-26 19:25:09 UTC (rev 51493)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,327 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-/**
- * Unit tests covering WP_Widget_Media_Audio functionality.
- *
- * @package    WordPress
- * @subpackage widgets
- */
-
-/**
- * Test wp-includes/widgets/class-wp-widget-audio.php
- *
- * @group widgets
- */
-class Test_WP_Widget_Media_Audio extends WP_UnitTestCase {
-
-       /**
-        * Clean up global scope.
-        *
-        * @global WP_Scripts $wp_scripts
-        * @global WP_Styles $wp_styles
-        */
-       function clean_up_global_scope() {
-               global $wp_scripts, $wp_styles;
-               parent::clean_up_global_scope();
-               $wp_scripts = null;
-               $wp_styles  = null;
-       }
-
-       /**
-        * Test get_instance_schema method.
-        *
-        * @covers WP_Widget_Media_Audio::get_instance_schema
-        */
-       function test_get_instance_schema() {
-               $wp_widget_audio = new WP_Widget_Media_Audio();
-               $schema          = $wp_widget_audio->get_instance_schema();
-
-               $this->assertSameSets(
-                       array_merge(
-                               array(
-                                       'attachment_id',
-                                       'preload',
-                                       'loop',
-                                       'title',
-                                       'url',
-                               ),
-                               wp_get_audio_extensions()
-                       ),
-                       array_keys( $schema )
-               );
-       }
-
-       /**
-        * Test get_instance_schema filtering.
-        *
-        * @covers WP_Widget_Media_Audio::get_instance_schema
-        *
-        * @ticket 45029
-        */
-       function test_get_instance_schema_filtering() {
-               $wp_widget_audio = new WP_Widget_Media_Audio();
-               $schema          = $wp_widget_audio->get_instance_schema();
-
-               add_filter( 'widget_media_audio_instance_schema', array( $this, 'filter_instance_schema' ), 10, 2 );
-               $schema = $wp_widget_audio->get_instance_schema();
-
-               $this->assertTrue( $schema['loop']['default'] );
-       }
-
-       /**
-        * Filters instance schema.
-        *
-        * @since 5.2.0
-        *
-        * @param array                 $schema Schema.
-        * @param WP_Widget_Media_Audio $widget Widget.
-        * @return array
-        */
-       public function filter_instance_schema( $schema, $widget ) {
-               // Override the default loop value (false).
-               $schema['loop']['default'] = true;
-               return $schema;
-       }
-
-       /**
-        * Test constructor.
-        *
-        * @covers WP_Widget_Media_Audio::__construct
-        */
-       function test_constructor() {
-               $widget = new WP_Widget_Media_Audio();
-
-               $this->assertArrayHasKey( 'mime_type', $widget->widget_options );
-               $this->assertArrayHasKey( 'customize_selective_refresh', $widget->widget_options );
-               $this->assertArrayHasKey( 'description', $widget->widget_options );
-               $this->assertTrue( $widget->widget_options['customize_selective_refresh'] );
-               $this->assertSame( 'audio', $widget->widget_options['mime_type'] );
-               $this->assertSameSets(
-                       array(
-                               'add_to_widget',
-                               'replace_media',
-                               'edit_media',
-                               'media_library_state_multi',
-                               'media_library_state_single',
-                               'missing_attachment',
-                               'no_media_selected',
-                               'add_media',
-                               'unsupported_file_type',
-                       ),
-                       array_keys( $widget->l10n )
-               );
-       }
-
-       /**
-        * Test get_instance_schema method.
-        *
-        * @covers WP_Widget_Media_Audio::update
-        */
-       function test_update() {
-               $widget   = new WP_Widget_Media_Audio();
-               $instance = array();
-
-               // Should return valid attachment ID.
-               $expected = array(
-                       'attachment_id' => 1,
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid attachment ID.
-               $result = $widget->update(
-                       array(
-                               'attachment_id' => 'media',
-                       ),
-                       $instance
-               );
-               $this->assertSame( $result, $instance );
-
-               // Should return valid attachment url.
-               $expected = array(
-                       'url' => 'https://chickenandribs.org',
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid attachment url.
-               $result = $widget->update(
-                       array(
-                               'url' => 'not_a_url',
-                       ),
-                       $instance
-               );
-               $this->assertNotSame( $result, $instance );
-               $this->assertStringStartsWith( 'http://', $result['url'] );
-
-               // Should return loop setting.
-               $expected = array(
-                       'loop' => true,
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid loop setting.
-               $result = $widget->update(
-                       array(
-                               'loop' => 'not-boolean',
-                       ),
-                       $instance
-               );
-               $this->assertSame( $result, $instance );
-
-               // Should return valid attachment title.
-               $expected = array(
-                       'title' => 'An audio sample of parrots',
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid attachment title.
-               $result = $widget->update(
-                       array(
-                               'title' => '<h1>Cute Baby Goats</h1>',
-                       ),
-                       $instance
-               );
-               $this->assertNotSame( $result, $instance );
-
-               // Should return valid preload setting.
-               $expected = array(
-                       'preload' => 'none',
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid preload setting.
-               $result = $widget->update(
-                       array(
-                               'preload' => 'nope',
-                       ),
-                       $instance
-               );
-               $this->assertSame( $result, $instance );
-
-               // Should filter invalid key.
-               $result = $widget->update(
-                       array(
-                               'h4x' => 'value',
-                       ),
-                       $instance
-               );
-               $this->assertSame( $result, $instance );
-       }
-
-       /**
-        * Test render_media method.
-        *
-        * @covers WP_Widget_Media_Audio::render_media
-        */
-       function test_render_media() {
-               $test_audio_file = __FILE__ . '../../data/uploads/small-audio.mp3';
-               $widget          = new WP_Widget_Media_Audio();
-               $attachment_id   = self::factory()->attachment->create_object(
-                       array(
-                               'file'           => $test_audio_file,
-                               'post_parent'    => 0,
-                               'post_mime_type' => 'audio/mp3',
-                               'post_title'     => 'Test Audio',
-                       )
-               );
-               wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $test_audio_file ) );
-
-               // Should be empty when there is no attachment_id.
-               ob_start();
-               $widget->render_media( array() );
-               $output = ob_get_clean();
-               $this->assertEmpty( $output );
-
-               // Should be empty when there is an invalid attachment_id.
-               ob_start();
-               $widget->render_media(
-                       array(
-                               'attachment_id' => 777,
-                       )
-               );
-               $output = ob_get_clean();
-               $this->assertEmpty( $output );
-
-               // Tests with audio from library.
-               ob_start();
-               $widget->render_media(
-                       array(
-                               'attachment_id' => $attachment_id,
-                       )
-               );
-               $output = ob_get_clean();
-
-               // Check default outputs.
-               $this->assertStringContainsString( 'preload="none"', $output );
-               $this->assertStringContainsString( 'class="wp-audio-shortcode"', $output );
-               $this->assertStringContainsString( 'small-audio.mp3', $output );
-
-               ob_start();
-               $widget->render_media(
-                       array(
-                               'attachment_id' => $attachment_id,
-                               'title'         => 'Funny',
-                               'preload'       => 'auto',
-                               'loop'          => true,
-                       )
-               );
-               $output = ob_get_clean();
-
-               // Custom attributes.
-               $this->assertStringContainsString( 'preload="auto"', $output );
-               $this->assertStringContainsString( 'loop="1"', $output );
-       }
-
-       /**
-        * Test enqueue_preview_scripts method.
-        *
-        * @global WP_Scripts $wp_scripts
-        * @global WP_Styles $wp_styles
-        * @covers WP_Widget_Media_Audio::enqueue_preview_scripts
-        */
-       function test_enqueue_preview_scripts() {
-               global $wp_scripts, $wp_styles;
-               $wp_scripts = null;
-               $wp_styles  = null;
-               $widget     = new WP_Widget_Media_Audio();
-
-               $this->assertFalse( wp_script_is( 'wp-mediaelement' ) );
-               $this->assertFalse( wp_style_is( 'wp-mediaelement' ) );
-
-               $widget->enqueue_preview_scripts();
-
-               $this->assertTrue( wp_script_is( 'wp-mediaelement' ) );
-               $this->assertTrue( wp_style_is( 'wp-mediaelement' ) );
-       }
-
-       /**
-        * Test enqueue_admin_scripts method.
-        *
-        * @covers WP_Widget_Media_Audio::enqueue_admin_scripts
-        */
-       function test_enqueue_admin_scripts() {
-               set_current_screen( 'widgets.php' );
-               $widget = new WP_Widget_Media_Audio();
-               $widget->enqueue_admin_scripts();
-
-               $this->assertTrue( wp_script_is( 'media-audio-widget' ) );
-       }
-
-       /**
-        * Test render_control_template_scripts method.
-        *
-        * @covers WP_Widget_Media_Audio::render_control_template_scripts
-        */
-       function test_render_control_template_scripts() {
-               $widget = new WP_Widget_Media_Audio();
-
-               ob_start();
-               $widget->render_control_template_scripts();
-               $output = ob_get_clean();
-
-               $this->assertStringContainsString( '<script type="text/html" id="tmpl-wp-media-widget-audio-preview">', $output );
-       }
-}
</del></span></pre></div>
<a id="trunktestsphpunittestswidgetsmediagallerywidgetphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/tests/phpunit/tests/widgets/media-gallery-widget.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/widgets/media-gallery-widget.php        2021-07-26 19:09:41 UTC (rev 51492)
+++ trunk/tests/phpunit/tests/widgets/media-gallery-widget.php  2021-07-26 19:25:09 UTC (rev 51493)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,204 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-/**
- * Unit tests covering WP_Widget_Media_Gallery functionality.
- *
- * @package    WordPress
- * @subpackage widgets
- */
-
-/**
- * Test wp-includes/widgets/class-wp-widget-gallery.php
- *
- * @group widgets
- */
-class Test_WP_Widget_Media_Gallery extends WP_UnitTestCase {
-
-       /**
-        * Clean up global scope.
-        *
-        * @global WP_Scripts $wp_scripts
-        * @global WP_Styles $wp_styles
-        */
-       public function clean_up_global_scope() {
-               global $wp_scripts, $wp_styles;
-               parent::clean_up_global_scope();
-               $wp_scripts = null;
-               $wp_styles  = null;
-       }
-
-       /**
-        * Test get_instance_schema method.
-        *
-        * @covers WP_Widget_Media_Gallery::get_instance_schema
-        */
-       public function test_get_instance_schema() {
-               $widget = new WP_Widget_Media_Gallery();
-               $schema = $widget->get_instance_schema();
-
-               $this->assertSameSets(
-                       array(
-                               'title',
-                               'ids',
-                               'columns',
-                               'size',
-                               'link_type',
-                               'orderby_random',
-                       ),
-                       array_keys( $schema )
-               );
-       }
-
-       /**
-        * Test update() method.
-        *
-        * @covers WP_Widget_Media_Gallery::render_media
-        * @requires function imagejpeg
-        */
-       public function test_render_media() {
-               $widget = new WP_Widget_Media_Gallery();
-
-               $attachments = array();
-               foreach ( array( 'canola.jpg', 'waffles.jpg' ) as $filename ) {
-                       $test_image = get_temp_dir() . $filename;
-                       copy( DIR_TESTDATA . '/images/canola.jpg', $test_image );
-                       $attachment_id = self::factory()->attachment->create_object(
-                               array(
-                                       'file'           => $test_image,
-                                       'post_parent'    => 0,
-                                       'post_mime_type' => 'image/jpeg',
-                                       'post_title'     => 'Canola',
-                               )
-                       );
-                       wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $test_image ) );
-                       $attachments[ $filename ] = $attachment_id;
-               }
-
-               $instance            = wp_list_pluck( $widget->get_instance_schema(), 'default' );
-               $instance['size']    = 'thumbnail';
-               $instance['columns'] = 3;
-               $instance['ids']     = array_values( $attachments );
-               ob_start();
-               $widget->render_media( $instance );
-               $output = ob_get_clean();
-
-               $this->assertStringContainsString( 'gallery-columns-3', $output );
-               $this->assertStringContainsString( 'gallery-size-thumbnail', $output );
-               $this->assertStringContainsString( 'canola', $output );
-               $this->assertStringContainsString( 'waffles', $output );
-       }
-
-       /**
-        * Test enqueue_admin_scripts() method.
-        *
-        * @covers WP_Widget_Media_Gallery::enqueue_admin_scripts
-        */
-       public function test_enqueue_admin_scripts() {
-               set_current_screen( 'widgets.php' );
-               $widget = new WP_Widget_Media_Gallery();
-
-               $this->assertFalse( wp_script_is( 'media-gallery-widget' ) );
-
-               $widget->enqueue_admin_scripts();
-
-               $this->assertTrue( wp_script_is( 'media-gallery-widget' ) );
-
-               $after = implode( '', wp_scripts()->registered['media-gallery-widget']->extra['after'] );
-               $this->assertStringContainsString( 'wp.mediaWidgets.modelConstructors[ "media_gallery" ].prototype', $after );
-       }
-
-       /**
-        * Test update() method.
-        *
-        * @covers WP_Widget_Media_Gallery::update
-        */
-       public function test_update() {
-               $widget   = new WP_Widget_Media_Gallery();
-               $schema   = $widget->get_instance_schema();
-               $instance = wp_list_pluck( $schema, 'default' );
-
-               // Field: title.
-               $instance['title'] = 'Hello <b>World</b> ';
-               $instance          = $widget->update( $instance, array() );
-               $this->assertSame( 'Hello World', $instance['title'] );
-
-               // Field: ids.
-               $instance['ids'] = '1,2,3';
-               $instance        = $widget->update( $instance, array() );
-               $this->assertSame( array( 1, 2, 3 ), $instance['ids'] );
-
-               $instance['ids'] = array( 1, 2, '3' );
-               $instance        = $widget->update( $instance, array() );
-               $this->assertSame( array( 1, 2, 3 ), $instance['ids'] );
-
-               $instance['ids'] = array( 'too', 'bad' );
-               $instance        = $widget->update( $instance, array( 'ids' => array( 2, 3 ) ) );
-               $this->assertSame( array( 2, 3 ), $instance['ids'] );
-
-               // Field: columns.
-               $instance['columns'] = 4;
-               $instance            = $widget->update( $instance, array() );
-               $this->assertSame( 4, $instance['columns'] );
-
-               $instance['columns'] = '2';
-               $instance            = $widget->update( $instance, array() );
-               $this->assertSame( 2, $instance['columns'] );
-
-               $instance['columns'] = -1; // Under min of 1.
-               $instance            = $widget->update( $instance, array( 'columns' => 3 ) );
-               $this->assertSame( 3, $instance['columns'] );
-
-               $instance['columns'] = 10; // Over max of 9.
-               $instance            = $widget->update( $instance, array( 'columns' => 3 ) );
-               $this->assertSame( 3, $instance['columns'] );
-
-               // Field: size.
-               $instance['size'] = 'large';
-               $instance         = $widget->update( $instance, array() );
-               $this->assertSame( 'large', $instance['size'] );
-
-               $instance['size'] = 'bad';
-               $instance         = $widget->update( $instance, array( 'size' => 'thumbnail' ) );
-               $this->assertSame( 'thumbnail', $instance['size'] );
-
-               // Field: link_type.
-               $instance['link_type'] = 'none';
-               $instance              = $widget->update( $instance, array() );
-               $this->assertSame( 'none', $instance['link_type'] );
-
-               $instance['link_type'] = 'unknown';
-               $instance              = $widget->update( $instance, array( 'link_type' => 'file' ) );
-               $this->assertSame( 'file', $instance['link_type'] );
-
-               // Field: orderby_random.
-               $instance['orderby_random'] = '1';
-               $instance                   = $widget->update( $instance, array() );
-               $this->assertTrue( $instance['orderby_random'] );
-
-               $instance['orderby_random'] = true;
-               $instance                   = $widget->update( $instance, array() );
-               $this->assertTrue( $instance['orderby_random'] );
-
-               $instance['orderby_random'] = '';
-               $instance                   = $widget->update( $instance, array() );
-               $this->assertFalse( $instance['orderby_random'] );
-
-               $instance['orderby_random'] = false;
-               $instance                   = $widget->update( $instance, array() );
-               $this->assertFalse( $instance['orderby_random'] );
-       }
-
-       /**
-        * Test render_control_template_scripts() method.
-        *
-        * @covers WP_Widget_Media_Gallery::render_control_template_scripts
-        */
-       public function test_render_control_template_scripts() {
-               $widget = new WP_Widget_Media_Gallery();
-
-               ob_start();
-               $widget->render_control_template_scripts();
-               $output = ob_get_clean();
-
-               $this->assertStringContainsString( '<script type="text/html" id="tmpl-wp-media-widget-gallery-preview">', $output );
-       }
-}
</del></span></pre></div>
<a id="trunktestsphpunittestswidgetsmediaimagewidgetphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/tests/phpunit/tests/widgets/media-image-widget.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/widgets/media-image-widget.php  2021-07-26 19:09:41 UTC (rev 51492)
+++ trunk/tests/phpunit/tests/widgets/media-image-widget.php    2021-07-26 19:25:09 UTC (rev 51493)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,633 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-/**
- * Unit tests covering WP_Widget_Media_Image functionality.
- *
- * @package    WordPress
- * @subpackage widgets
- */
-
-/**
- * Test wp-includes/widgets/class-wp-widget-image.php
- *
- * @group widgets
- */
-class Test_WP_Widget_Media_Image extends WP_UnitTestCase {
-
-       /**
-        * Clean up global scope.
-        *
-        * @global WP_Scripts $wp_scripts
-        * @global WP_Styles $wp_styles
-        */
-       function clean_up_global_scope() {
-               global $wp_scripts, $wp_styles;
-               parent::clean_up_global_scope();
-               $wp_scripts = null;
-               $wp_styles  = null;
-       }
-
-       /**
-        * Test get_instance_schema method.
-        *
-        * @covers WP_Widget_Media_Image::get_instance_schema
-        */
-       function test_get_instance_schema() {
-               $widget = new WP_Widget_Media_Image();
-               $schema = $widget->get_instance_schema();
-
-               $this->assertSameSets(
-                       array(
-                               'alt',
-                               'attachment_id',
-                               'caption',
-                               'height',
-                               'image_classes',
-                               'image_title',
-                               'link_classes',
-                               'link_rel',
-                               'link_target_blank',
-                               'link_type',
-                               'link_url',
-                               'size',
-                               'title',
-                               'url',
-                               'width',
-                       ),
-                       array_keys( $schema )
-               );
-       }
-
-       /**
-        * Test schema filtering.
-        *
-        * @covers WP_Widget_Media_Image::get_instance_schema
-        *
-        * @ticket 45029
-        */
-       function test_get_instance_schema_filtering() {
-               $widget = new WP_Widget_Media_Image();
-               $schema = $widget->get_instance_schema();
-
-               add_filter( 'widget_media_image_instance_schema', array( $this, 'filter_instance_schema' ), 10, 2 );
-               $schema = $widget->get_instance_schema();
-
-               $this->assertSame( 'large', $schema['size']['default'] );
-       }
-
-       /**
-        * Filters instance schema.
-        *
-        * @since 5.2.0
-        *
-        * @param array                 $schema Schema.
-        * @param WP_Widget_Media_Image $widget Widget.
-        * @return array
-        */
-       public function filter_instance_schema( $schema, $widget ) {
-               // Override the default size value ('medium').
-               $schema['size']['default'] = 'large';
-               return $schema;
-       }
-
-       /**
-        * Test constructor.
-        *
-        * @covers WP_Widget_Media_Image::__construct
-        */
-       function test_constructor() {
-               $widget = new WP_Widget_Media_Image();
-
-               $this->assertArrayHasKey( 'mime_type', $widget->widget_options );
-               $this->assertArrayHasKey( 'customize_selective_refresh', $widget->widget_options );
-               $this->assertArrayHasKey( 'description', $widget->widget_options );
-               $this->assertTrue( $widget->widget_options['customize_selective_refresh'] );
-               $this->assertSame( 'image', $widget->widget_options['mime_type'] );
-               $this->assertSameSets(
-                       array(
-                               'add_to_widget',
-                               'replace_media',
-                               'edit_media',
-                               'media_library_state_multi',
-                               'media_library_state_single',
-                               'missing_attachment',
-                               'no_media_selected',
-                               'add_media',
-                               'unsupported_file_type',
-                       ),
-                       array_keys( $widget->l10n )
-               );
-       }
-
-       /**
-        * Test get_instance_schema method.
-        *
-        * @covers WP_Widget_Media_Image::update
-        */
-       function test_update() {
-               $widget   = new WP_Widget_Media_Image();
-               $instance = array();
-
-               // Should return valid attachment ID.
-               $expected = array(
-                       'attachment_id' => 1,
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid attachment ID.
-               $result = $widget->update(
-                       array(
-                               'attachment_id' => 'media',
-                       ),
-                       $instance
-               );
-               $this->assertSame( $result, $instance );
-
-               // Should return valid attachment url.
-               $expected = array(
-                       'url' => 'https://example.org',
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid attachment url.
-               $result = $widget->update(
-                       array(
-                               'url' => 'not_a_url',
-                       ),
-                       $instance
-               );
-               $this->assertNotSame( $result, $instance );
-               $this->assertStringStartsWith( 'http://', $result['url'] );
-
-               // Should return valid attachment title.
-               $expected = array(
-                       'title' => 'What a title',
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid attachment title.
-               $result = $widget->update(
-                       array(
-                               'title' => '<h1>W00t!</h1>',
-                       ),
-                       $instance
-               );
-               $this->assertNotSame( $result, $instance );
-
-               // Should return valid image size.
-               $expected = array(
-                       'size' => 'thumbnail',
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid image size.
-               $result = $widget->update(
-                       array(
-                               'size' => 'big league',
-                       ),
-                       $instance
-               );
-               $this->assertSame( $result, $instance );
-
-               // Should return valid image width.
-               $expected = array(
-                       'width' => 300,
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid image width.
-               $result = $widget->update(
-                       array(
-                               'width' => 'wide',
-                       ),
-                       $instance
-               );
-               $this->assertSame( $result, $instance );
-
-               // Should return valid image height.
-               $expected = array(
-                       'height' => 200,
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid image height.
-               $result = $widget->update(
-                       array(
-                               'height' => 'high',
-                       ),
-                       $instance
-               );
-               $this->assertSame( $result, $instance );
-
-               // Should return valid image caption.
-               $expected = array(
-                       'caption' => 'A caption with <a href="#">link</a>',
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid image caption.
-               $result = $widget->update(
-                       array(
-                               'caption' => '"><i onload="alert(\'hello\')" />',
-                       ),
-                       $instance
-               );
-               $this->assertSame(
-                       $result,
-                       array(
-                               'caption' => '"&gt;<i />',
-                       )
-               );
-
-               // Should return valid alt text.
-               $expected = array(
-                       'alt' => 'A water tower',
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid alt text.
-               $result = $widget->update(
-                       array(
-                               'alt' => '"><i onload="alert(\'hello\')" />',
-                       ),
-                       $instance
-               );
-               $this->assertSame(
-                       $result,
-                       array(
-                               'alt' => '">',
-                       )
-               );
-
-               // Should return valid link type.
-               $expected = array(
-                       'link_type' => 'file',
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid link type.
-               $result = $widget->update(
-                       array(
-                               'link_type' => 'interesting',
-                       ),
-                       $instance
-               );
-               $this->assertSame( $result, $instance );
-
-               // Should return valid link url.
-               $expected = array(
-                       'link_url' => 'https://example.org',
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid link url.
-               $result = $widget->update(
-                       array(
-                               'link_url' => 'not_a_url',
-                       ),
-                       $instance
-               );
-               $this->assertNotSame( $result, $instance );
-               $this->assertStringStartsWith( 'http://', $result['link_url'] );
-
-               // Should return valid image classes.
-               $expected = array(
-                       'image_classes' => 'A water tower',
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid image classes.
-               $result = $widget->update(
-                       array(
-                               'image_classes' => '"><i onload="alert(\'hello\')" />',
-                       ),
-                       $instance
-               );
-               $this->assertSame(
-                       $result,
-                       array(
-                               'image_classes' => 'i onloadalerthello',
-                       )
-               );
-
-               // Should return valid link classes.
-               $expected = array(
-                       'link_classes' => 'A water tower',
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid link classes.
-               $result = $widget->update(
-                       array(
-                               'link_classes' => '"><i onload="alert(\'hello\')" />',
-                       ),
-                       $instance
-               );
-               $this->assertSame(
-                       $result,
-                       array(
-                               'link_classes' => 'i onloadalerthello',
-                       )
-               );
-
-               // Should return valid rel text.
-               $expected = array(
-                       'link_rel' => 'previous',
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid rel text.
-               $result = $widget->update(
-                       array(
-                               'link_rel' => '"><i onload="alert(\'hello\')" />',
-                       ),
-                       $instance
-               );
-               $this->assertSame(
-                       $result,
-                       array(
-                               'link_rel' => 'i onloadalerthello',
-                       )
-               );
-
-               // Should return valid link target.
-               $expected = array(
-                       'link_target_blank' => false,
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid  link target.
-               $result = $widget->update(
-                       array(
-                               'link_target_blank' => 'top',
-                       ),
-                       $instance
-               );
-               $this->assertSame( $result, $instance );
-
-               // Should return valid image title.
-               $expected = array(
-                       'image_title' => 'What a title',
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid image title.
-               $result = $widget->update(
-                       array(
-                               'image_title' => '<h1>W00t!</h1>',
-                       ),
-                       $instance
-               );
-               $this->assertNotSame( $result, $instance );
-
-               // Should filter invalid key.
-               $result = $widget->update(
-                       array(
-                               'imaginary_key' => 'value',
-                       ),
-                       $instance
-               );
-               $this->assertSame( $result, $instance );
-       }
-
-       /**
-        * Test render_media method.
-        *
-        * @covers WP_Widget_Media_Image::render_media
-        * @requires function imagejpeg
-        */
-       function test_render_media() {
-               $widget = new WP_Widget_Media_Image();
-
-               $test_image = get_temp_dir() . 'canola.jpg';
-               copy( DIR_TESTDATA . '/images/canola.jpg', $test_image );
-               $attachment_id = self::factory()->attachment->create_object(
-                       array(
-                               'file'           => $test_image,
-                               'post_parent'    => 0,
-                               'post_mime_type' => 'image/jpeg',
-                               'post_title'     => 'Canola',
-                       )
-               );
-               wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $test_image ) );
-
-               // Should be empty when there is no attachment_id.
-               ob_start();
-               $widget->render_media( array() );
-               $output = ob_get_clean();
-               $this->assertEmpty( $output );
-
-               // Should be empty when there is an invalid attachment_id.
-               ob_start();
-               $widget->render_media(
-                       array(
-                               'attachment_id' => 666,
-                       )
-               );
-               $output = ob_get_clean();
-               $this->assertEmpty( $output );
-
-               ob_start();
-               $widget->render_media(
-                       array(
-                               'attachment_id' => $attachment_id,
-                       )
-               );
-               $output = ob_get_clean();
-
-               // No default title.
-               $this->assertStringNotContainsString( 'title="', $output );
-               // Default image classes.
-               $this->assertStringContainsString( 'class="image wp-image-' . $attachment_id, $output );
-               $this->assertStringContainsString( 'style="max-width: 100%; height: auto;"', $output );
-               $this->assertStringContainsString( 'alt=""', $output );
-
-               ob_start();
-               $widget->render_media(
-                       array(
-                               'attachment_id' => $attachment_id,
-                               'image_title'   => 'Custom Title',
-                               'image_classes' => 'custom-class',
-                               'alt'           => 'A flower',
-                               'size'          => 'custom',
-                               'width'         => 100,
-                               'height'        => 100,
-                       )
-               );
-               $output = ob_get_clean();
-
-               // Custom image title.
-               $this->assertStringContainsString( 'title="Custom Title"', $output );
-               // Custom image class.
-               $this->assertStringContainsString( 'class="image wp-image-' . $attachment_id . ' custom-class', $output );
-               $this->assertStringContainsString( 'alt="A flower"', $output );
-               $this->assertStringContainsString( 'width="100"', $output );
-               $this->assertStringContainsString( 'height="100"', $output );
-
-               // Embeded images.
-               ob_start();
-               $widget->render_media(
-                       array(
-                               'attachment_id' => null,
-                               'caption'       => 'With caption',
-                               'height'        => 100,
-                               'link_type'     => 'file',
-                               'url'           => 'http://example.org/url/to/image.jpg',
-                               'width'         => 100,
-                       )
-               );
-               $output = ob_get_clean();
-
-               // Custom image class.
-               $this->assertStringContainsString( 'src="http://example.org/url/to/image.jpg"', $output );
-
-               // Link settings.
-               ob_start();
-               $widget->render_media(
-                       array(
-                               'attachment_id' => $attachment_id,
-                               'link_type'     => 'file',
-                       )
-               );
-               $output = ob_get_clean();
-
-               $link = '<a href="' . wp_get_attachment_url( $attachment_id ) . '"';
-               $this->assertStringContainsString( $link, $output );
-               $this->assertTrue( (bool) preg_match( '#<a href.*?>#', $output, $matches ) );
-               $this->assertStringNotContainsString( ' class="', $matches[0] );
-               $this->assertStringNotContainsString( ' rel="', $matches[0] );
-               $this->assertStringNotContainsString( ' target="', $matches[0] );
-
-               ob_start();
-               $widget->render_media(
-                       array(
-                               'attachment_id'     => $attachment_id,
-                               'link_type'         => 'post',
-                               'link_classes'      => 'custom-link-class',
-                               'link_rel'          => 'attachment',
-                               'link_target_blank' => false,
-                       )
-               );
-               $output = ob_get_clean();
-
-               $this->assertStringContainsString( '<a href="' . get_attachment_link( $attachment_id ) . '"', $output );
-               $this->assertStringContainsString( 'class="custom-link-class"', $output );
-               $this->assertStringContainsString( 'rel="attachment"', $output );
-               $this->assertStringNotContainsString( 'target=""', $output );
-
-               ob_start();
-               $widget->render_media(
-                       array(
-                               'attachment_id'     => $attachment_id,
-                               'link_type'         => 'custom',
-                               'link_url'          => 'https://example.org',
-                               'link_target_blank' => true,
-                       )
-               );
-               $output = ob_get_clean();
-
-               $this->assertStringContainsString( '<a href="https://example.org"', $output );
-               $this->assertStringContainsString( 'target="_blank"', $output );
-               $this->assertStringContainsString( 'rel="noopener"', $output );
-
-               // Populate caption in attachment.
-               wp_update_post(
-                       array(
-                               'ID'           => $attachment_id,
-                               'post_excerpt' => 'Default caption',
-                       )
-               );
-
-               // If no caption is supplied, then the default is '', and so the caption will not be displayed.
-               ob_start();
-               $widget->render_media(
-                       array(
-                               'attachment_id' => $attachment_id,
-                       )
-               );
-               $output = ob_get_clean();
-               $this->assertStringNotContainsString( 'wp-caption', $output );
-               $this->assertStringNotContainsString( '<p class="wp-caption-text">', $output );
-
-               // If the caption is explicitly null, then the caption of the underlying attachment will be displayed.
-               ob_start();
-               $widget->render_media(
-                       array(
-                               'attachment_id' => $attachment_id,
-                               'caption'       => null,
-                       )
-               );
-               $output = ob_get_clean();
-               $this->assertStringContainsString( 'class="wp-caption alignnone"', $output );
-               $this->assertStringContainsString( '<p class="wp-caption-text">Default caption</p>', $output );
-
-               // If caption is provided, then it will be displayed.
-               ob_start();
-               $widget->render_media(
-                       array(
-                               'attachment_id' => $attachment_id,
-                               'caption'       => 'Custom caption',
-                       )
-               );
-               $output = ob_get_clean();
-               $this->assertStringContainsString( 'class="wp-caption alignnone"', $output );
-               $this->assertStringContainsString( '<p class="wp-caption-text">Custom caption</p>', $output );
-
-               // Attachments with custom sizes can render captions.
-               ob_start();
-               $widget->render_media(
-                       array(
-                               'attachment_id' => $attachment_id,
-                               'size'          => 'custom',
-                               'width'         => '300',
-                               'height'        => '200',
-                               'caption'       => 'Caption for an image with custom size',
-                       )
-               );
-               $output = ob_get_clean();
-               $this->assertStringContainsString( 'style="width: 310px"', $output );
-               $this->assertStringContainsString( '<p class="wp-caption-text">Caption for an image with custom size</p>', $output );
-       }
-
-       /**
-        * Test enqueue_admin_scripts method.
-        *
-        * @covers WP_Widget_Media_Image::enqueue_admin_scripts
-        */
-       function test_enqueue_admin_scripts() {
-               set_current_screen( 'widgets.php' );
-               $widget = new WP_Widget_Media_Image();
-               $widget->enqueue_admin_scripts();
-
-               $this->assertTrue( wp_script_is( 'media-image-widget' ) );
-       }
-
-       /**
-        * Test render_control_template_scripts method.
-        *
-        * @covers WP_Widget_Media_Image::render_control_template_scripts
-        */
-       function test_render_control_template_scripts() {
-               $widget = new WP_Widget_Media_Image();
-
-               ob_start();
-               $widget->render_control_template_scripts();
-               $output = ob_get_clean();
-
-               $this->assertStringContainsString( '<script type="text/html" id="tmpl-wp-media-widget-image-preview">', $output );
-       }
-}
</del></span></pre></div>
<a id="trunktestsphpunittestswidgetsmediavideowidgetphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/tests/phpunit/tests/widgets/media-video-widget.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/widgets/media-video-widget.php  2021-07-26 19:09:41 UTC (rev 51492)
+++ trunk/tests/phpunit/tests/widgets/media-video-widget.php    2021-07-26 19:25:09 UTC (rev 51493)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,355 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-/**
- * Unit tests covering WP_Widget_Media_Video functionality.
- *
- * @package    WordPress
- * @subpackage widgets
- */
-
-/**
- * Test wp-includes/widgets/class-wp-widget-video.php
- *
- * @group widgets
- */
-class Test_WP_Widget_Media_Video extends WP_UnitTestCase {
-
-       /**
-        * Clean up global scope.
-        *
-        * @global WP_Scripts $wp_scripts
-        * @global WP_Styles $wp_styles
-        */
-       function clean_up_global_scope() {
-               global $wp_scripts, $wp_styles;
-               parent::clean_up_global_scope();
-               $wp_scripts = null;
-               $wp_styles  = null;
-       }
-
-       /**
-        * Test get_instance_schema method.
-        *
-        * @covers WP_Widget_Media_Video::get_instance_schema
-        */
-       function test_get_instance_schema() {
-               $widget = new WP_Widget_Media_Video();
-               $schema = $widget->get_instance_schema();
-
-               $this->assertSameSets(
-                       array_merge(
-                               array(
-                                       'attachment_id',
-                                       'preload',
-                                       'loop',
-                                       'title',
-                                       'url',
-                                       'content',
-                               ),
-                               wp_get_video_extensions()
-                       ),
-                       array_keys( $schema )
-               );
-       }
-
-       /**
-        * Test schema filtering.
-        *
-        * @covers WP_Widget_Media_Video::get_instance_schema
-        *
-        * @ticket 45029
-        */
-       function test_get_instance_schema_filtering() {
-               $widget = new WP_Widget_Media_Video();
-               $schema = $widget->get_instance_schema();
-
-               add_filter( 'widget_media_video_instance_schema', array( $this, 'filter_instance_schema' ), 10, 2 );
-               $schema = $widget->get_instance_schema();
-
-               $this->assertTrue( $schema['loop']['default'] );
-       }
-
-       /**
-        * Filters instance schema.
-        *
-        * @since 5.2.0
-        *
-        * @param array                 $schema Schema.
-        * @param WP_Widget_Media_Video $widget Widget.
-        * @return array
-        */
-       public function filter_instance_schema( $schema, $widget ) {
-               // Override the default loop value (false).
-               $schema['loop']['default'] = true;
-               return $schema;
-       }
-
-       /**
-        * Test constructor.
-        *
-        * @covers WP_Widget_Media_Video::__construct
-        */
-       function test_constructor() {
-               $widget = new WP_Widget_Media_Video();
-
-               $this->assertArrayHasKey( 'mime_type', $widget->widget_options );
-               $this->assertArrayHasKey( 'customize_selective_refresh', $widget->widget_options );
-               $this->assertArrayHasKey( 'description', $widget->widget_options );
-               $this->assertTrue( $widget->widget_options['customize_selective_refresh'] );
-               $this->assertSame( 'video', $widget->widget_options['mime_type'] );
-               $this->assertSameSets(
-                       array(
-                               'add_to_widget',
-                               'replace_media',
-                               'unsupported_file_type',
-                               'edit_media',
-                               'media_library_state_multi',
-                               'media_library_state_single',
-                               'missing_attachment',
-                               'no_media_selected',
-                               'add_media',
-                       ),
-                       array_keys( $widget->l10n )
-               );
-       }
-
-       /**
-        * Test get_instance_schema method.
-        *
-        * @covers WP_Widget_Media_Video::update
-        */
-       function test_update() {
-               $widget   = new WP_Widget_Media_Video();
-               $instance = array();
-
-               // Should return valid attachment ID.
-               $expected = array(
-                       'attachment_id' => 1,
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid attachment ID.
-               $result = $widget->update(
-                       array(
-                               'attachment_id' => 'media',
-                       ),
-                       $instance
-               );
-               $this->assertSame( $result, $instance );
-
-               // Should return valid attachment url.
-               $expected = array(
-                       'url' => 'https://chickenandribs.org',
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid attachment url.
-               $result = $widget->update(
-                       array(
-                               'url' => 'not_a_url',
-                       ),
-                       $instance
-               );
-               $this->assertNotSame( $result, $instance );
-               $this->assertStringStartsWith( 'http://', $result['url'] );
-
-               // Should return loop setting.
-               $expected = array(
-                       'loop' => true,
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid loop setting.
-               $result = $widget->update(
-                       array(
-                               'loop' => 'not-boolean',
-                       ),
-                       $instance
-               );
-               $this->assertSame( $result, $instance );
-
-               // Should return valid attachment title.
-               $expected = array(
-                       'title' => 'A video of goats',
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid attachment title.
-               $result = $widget->update(
-                       array(
-                               'title' => '<h1>Cute Baby Goats</h1>',
-                       ),
-                       $instance
-               );
-               $this->assertNotSame( $result, $instance );
-
-               // Should return valid preload setting.
-               $expected = array(
-                       'preload' => 'none',
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid preload setting.
-               $result = $widget->update(
-                       array(
-                               'preload' => 'nope',
-                       ),
-                       $instance
-               );
-               $this->assertSame( $result, $instance );
-
-               // Should filter invalid key.
-               $result = $widget->update(
-                       array(
-                               'h4x' => 'value',
-                       ),
-                       $instance
-               );
-               $this->assertSame( $result, $instance );
-       }
-
-       /**
-        * Test render_media method.
-        *
-        * @covers WP_Widget_Media_Video::render_media
-        * @covers WP_Widget_Media_Video::inject_video_max_width_style
-        */
-       function test_render_media() {
-               $test_movie_file = __FILE__ . '../../data/uploads/small-video.m4v';
-               $widget          = new WP_Widget_Media_Video();
-               $attachment_id   = self::factory()->attachment->create_object(
-                       array(
-                               'file'           => $test_movie_file,
-                               'post_parent'    => 0,
-                               'post_mime_type' => 'video/mp4',
-                               'post_title'     => 'Test Video',
-                       )
-               );
-               wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $test_movie_file ) );
-
-               // Should be empty when there is no attachment_id.
-               ob_start();
-               $widget->render_media( array() );
-               $output = ob_get_clean();
-               $this->assertEmpty( $output );
-
-               // Should be empty when there is an invalid attachment_id.
-               ob_start();
-               $widget->render_media(
-                       array(
-                               'attachment_id' => 777,
-                       )
-               );
-               $output = ob_get_clean();
-               $this->assertEmpty( $output );
-
-               // Tests with video from library.
-               ob_start();
-               $widget->render_media(
-                       array(
-                               'attachment_id' => $attachment_id,
-                       )
-               );
-               $output = ob_get_clean();
-
-               // Check default outputs.
-               $this->assertStringContainsString( 'preload="metadata"', $output );
-               $this->assertStringContainsString( 'class="wp-video"', $output );
-               $this->assertStringContainsString( 'width:100%', $output );
-               $this->assertStringNotContainsString( 'height=', $output );
-               $this->assertStringNotContainsString( 'width="', $output );
-               $this->assertStringContainsString( 'small-video.m4v', $output );// Auto parses dimensions.
-
-               ob_start();
-               $widget->render_media(
-                       array(
-                               'attachment_id' => $attachment_id,
-                               'title'         => 'Open Source Cartoon',
-                               'preload'       => 'metadata',
-                               'loop'          => true,
-                       )
-               );
-               $output = ob_get_clean();
-
-               // Custom attributes.
-               $this->assertStringContainsString( 'preload="metadata"', $output );
-               $this->assertStringContainsString( 'loop="1"', $output );
-
-               // Externally hosted video.
-               ob_start();
-               $content = '<track srclang="en" label="English" kind="subtitles" src="http://example.com/wp-content/uploads/2017/04/subtitles-en.vtt">';
-               $widget->render_media(
-                       array(
-                               'attachment_id' => null,
-                               'loop'          => false,
-                               'url'           => 'https://www.youtube.com/watch?v=72xdCU__XCk',
-                               'content'       => $content,
-                       )
-               );
-               $output = ob_get_clean();
-
-               // Custom attributes.
-               $this->assertStringContainsString( 'preload="metadata"', $output );
-               $this->assertStringContainsString( 'src="https://www.youtube.com/watch?v=72xdCU__XCk', $output );
-               $this->assertStringContainsString( $content, $output );
-       }
-
-       /**
-        * Test enqueue_preview_scripts method.
-        *
-        * @global WP_Scripts $wp_scripts
-        * @global WP_Styles $wp_styles
-        * @covers WP_Widget_Media_Video::enqueue_preview_scripts
-        */
-       function test_enqueue_preview_scripts() {
-               global $wp_scripts, $wp_styles;
-               $widget = new WP_Widget_Media_Video();
-
-               $wp_scripts = null;
-               $wp_styles  = null;
-               $widget->enqueue_preview_scripts();
-               $this->assertTrue( wp_script_is( 'wp-mediaelement' ) );
-               $this->assertTrue( wp_style_is( 'wp-mediaelement' ) );
-               $this->assertTrue( wp_script_is( 'mediaelement-vimeo' ) );
-
-               $wp_scripts = null;
-               $wp_styles  = null;
-               add_filter( 'wp_video_shortcode_library', '__return_empty_string' );
-               $widget->enqueue_preview_scripts();
-               $this->assertFalse( wp_script_is( 'wp-mediaelement' ) );
-               $this->assertFalse( wp_style_is( 'wp-mediaelement' ) );
-               $this->assertFalse( wp_script_is( 'mediaelement-vimeo' ) );
-       }
-
-       /**
-        * Test enqueue_admin_scripts method.
-        *
-        * @covers WP_Widget_Media_Video::enqueue_admin_scripts
-        */
-       function test_enqueue_admin_scripts() {
-               set_current_screen( 'widgets.php' );
-               $widget = new WP_Widget_Media_Video();
-               $widget->enqueue_admin_scripts();
-
-               $this->assertTrue( wp_script_is( 'media-video-widget' ) );
-       }
-
-       /**
-        * Test render_control_template_scripts method.
-        *
-        * @covers WP_Widget_Media_Video::render_control_template_scripts
-        */
-       function test_render_control_template_scripts() {
-               $widget = new WP_Widget_Media_Video();
-
-               ob_start();
-               $widget->render_control_template_scripts();
-               $output = ob_get_clean();
-
-               $this->assertStringContainsString( '<script type="text/html" id="tmpl-wp-media-widget-video-preview">', $output );
-       }
-}
</del></span></pre></div>
<a id="trunktestsphpunittestswidgetsmediawidgetphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/tests/phpunit/tests/widgets/media-widget.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/widgets/media-widget.php        2021-07-26 19:09:41 UTC (rev 51492)
+++ trunk/tests/phpunit/tests/widgets/media-widget.php  2021-07-26 19:25:09 UTC (rev 51493)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,525 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-/**
- * Unit tests covering WP_Widget_Media functionality.
- *
- * @package    WordPress
- * @subpackage widgets
- */
-
-/**
- * Class Test_WP_Widget_Media
- *
- * @group widgets
- */
-class Test_WP_Widget_Media extends WP_UnitTestCase {
-
-       /**
-        * Clean up global scope.
-        *
-        * @global WP_Scripts $wp_scripts
-        * @global WP_Styles $wp_styles
-        */
-       function clean_up_global_scope() {
-               global $wp_scripts, $wp_styles;
-               parent::clean_up_global_scope();
-               $wp_scripts = null;
-               $wp_styles  = null;
-       }
-
-       /**
-        * Get instance for mocked media widget class.
-        *
-        * @param string $id_base         Base ID for the widget, lowercase and unique.
-        * @param string $name            Name for the widget displayed on the configuration page.
-        * @param array  $widget_options  Optional. Widget options.
-        * @param array  $control_options Optional. Widget control options.
-        * @return PHPUnit_Framework_MockObject_MockObject|WP_Widget_Media Mocked instance.
-        */
-       function get_mocked_class_instance( $id_base = 'mocked', $name = 'Mocked', $widget_options = array(), $control_options = array() ) {
-               $original_class_name       = 'WP_Widget_Media';
-               $arguments                 = array( $id_base, $name, $widget_options, $control_options );
-               $mock_class_name           = '';
-               $call_original_constructor = true;
-               $call_original_clone       = true;
-               $call_autoload             = true;
-               $mocked_methods            = array( 'render_media' );
-
-               return $this->getMockForAbstractClass( $original_class_name, $arguments, $mock_class_name, $call_original_constructor, $call_original_clone, $call_autoload, $mocked_methods );
-       }
-
-       /**
-        * Test constructor.
-        *
-        * @covers WP_Widget_Media::__construct
-        * @covers WP_Widget_Media::_register
-        */
-       function test_constructor() {
-               $widget = $this->get_mocked_class_instance();
-               $widget->_register();
-
-               $this->assertArrayHasKey( 'mime_type', $widget->widget_options );
-               $this->assertArrayHasKey( 'customize_selective_refresh', $widget->widget_options );
-               $this->assertArrayHasKey( 'description', $widget->widget_options );
-               $this->assertTrue( $widget->widget_options['customize_selective_refresh'] );
-               $this->assertEmpty( $widget->widget_options['mime_type'] );
-               $this->assertSameSets(
-                       array(
-                               'add_to_widget',
-                               'replace_media',
-                               'edit_media',
-                               'media_library_state_multi',
-                               'media_library_state_single',
-                               'missing_attachment',
-                               'no_media_selected',
-                               'add_media',
-                               'unsupported_file_type',
-                       ),
-                       array_keys( $widget->l10n )
-               );
-               $this->assertSame( count( $widget->l10n ), count( array_filter( $widget->l10n ) ), 'Expected all translation strings to be defined.' );
-               $this->assertSame( 10, has_action( 'admin_print_scripts-widgets.php', array( $widget, 'enqueue_admin_scripts' ) ) );
-               $this->assertFalse( has_action( 'wp_enqueue_scripts', array( $widget, 'enqueue_preview_scripts' ) ), 'Did not expect preview scripts to be enqueued when not in customize preview context.' );
-               $this->assertSame( 10, has_action( 'admin_footer-widgets.php', array( $widget, 'render_control_template_scripts' ) ) );
-
-               // With non-default args.
-               $id_base         = 'media_pdf';
-               $name            = 'PDF';
-               $widget_options  = array(
-                       'mime_type' => 'application/pdf',
-               );
-               $control_options = array(
-                       'width'  => 850,
-                       'height' => 1100,
-               );
-               $widget          = $this->get_mocked_class_instance( $id_base, $name, $widget_options, $control_options );
-               $this->assertSame( $id_base, $widget->id_base );
-               $this->assertSame( $name, $widget->name );
-
-               $this->assertArraySubset( $widget_options, $widget->widget_options );
-               $this->assertArraySubset( $control_options, $widget->control_options );
-       }
-
-       /**
-        * Test constructor in customize preview.
-        *
-        * @global WP_Customize_Manager $wp_customize
-        * @covers WP_Widget_Media::__construct
-        * @covers WP_Widget_Media::_register
-        */
-       function test_constructor_in_customize_preview() {
-               global $wp_customize;
-               wp_set_current_user(
-                       $this->factory()->user->create(
-                               array(
-                                       'role' => 'administrator',
-                               )
-                       )
-               );
-               require_once ABSPATH . WPINC . '/class-wp-customize-manager.php';
-               $wp_customize = new WP_Customize_Manager(
-                       array(
-                               'changeset_uuid' => wp_generate_uuid4(),
-                       )
-               );
-               $wp_customize->start_previewing_theme();
-
-               $widget = $this->get_mocked_class_instance();
-               $widget->_register();
-               $this->assertSame( 10, has_action( 'wp_enqueue_scripts', array( $widget, 'enqueue_preview_scripts' ) ) );
-       }
-
-       /**
-        * Test is_attachment_with_mime_type method.
-        *
-        * @covers WP_Widget_Media::is_attachment_with_mime_type
-        * @requires function imagejpeg
-        */
-       function test_is_attachment_with_mime_type() {
-
-               $test_image = get_temp_dir() . 'canola.jpg';
-               copy( DIR_TESTDATA . '/images/canola.jpg', $test_image );
-               $attachment_id = self::factory()->attachment->create_object(
-                       array(
-                               'file'           => $test_image,
-                               'post_parent'    => 0,
-                               'post_mime_type' => 'image/jpeg',
-                               'post_title'     => 'Canola',
-                       )
-               );
-               wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $test_image ) );
-               $widget = $this->get_mocked_class_instance();
-
-               $this->assertFalse( $widget->is_attachment_with_mime_type( 0, 'image' ) );
-               $this->assertFalse( $widget->is_attachment_with_mime_type( -123, 'image' ) );
-
-               $post_id = $this->factory()->post->create();
-               $this->assertFalse( $widget->is_attachment_with_mime_type( $post_id, 'image' ) );
-               $this->assertFalse( $widget->is_attachment_with_mime_type( $attachment_id, 'video' ) );
-               $this->assertTrue( $widget->is_attachment_with_mime_type( $attachment_id, 'image' ) );
-       }
-
-       /**
-        * Test sanitize_token_list method.
-        *
-        * @covers WP_Widget_Media::sanitize_token_list
-        */
-       function test_sanitize_token_list_string() {
-               $widget = $this->get_mocked_class_instance();
-
-               $result = $widget->sanitize_token_list( 'What A false class with-token <a href="#">and link</a>' );
-               $this->assertSame( 'What A false class with-token a hrefand linka', $result );
-
-               $result = $widget->sanitize_token_list( array( 'foo', '<i>bar', '">NO' ) );
-               $this->assertSame( $result, 'foo ibar NO' );
-       }
-
-       /**
-        * Instance schema args.
-        *
-        * @var array
-        */
-       protected $filter_instance_schema_args;
-
-       /**
-        * Filter instance schema.
-        *
-        * @param array           $schema Schema.
-        * @param WP_Widget_Media $widget Widget.
-        * @return array
-        */
-       public function filter_instance_schema( $schema, $widget ) {
-               $this->filter_instance_schema_args = compact( 'schema', 'widget' );
-               $schema['injected']                = array(
-                       'type' => 'boolean',
-               );
-               return $schema;
-       }
-
-       /**
-        * Test get_instance_schema method.
-        *
-        * @covers WP_Widget_Media::get_instance_schema
-        */
-       function test_get_instance_schema() {
-               $widget = $this->get_mocked_class_instance();
-               $schema = $widget->get_instance_schema();
-
-               $this->assertSameSets(
-                       array(
-                               'attachment_id',
-                               'title',
-                               'url',
-                       ),
-                       array_keys( $schema )
-               );
-
-               // Check filter usage.
-               $this->filter_instance_schema_args = null;
-               add_filter( 'widget_mocked_instance_schema', array( $this, 'filter_instance_schema' ), 10, 2 );
-               $schema = $widget->get_instance_schema();
-               $this->assertIsArray( $this->filter_instance_schema_args );
-               $this->assertSame( $widget, $this->filter_instance_schema_args['widget'] );
-               $this->assertSameSets( array( 'attachment_id', 'title', 'url' ), array_keys( $this->filter_instance_schema_args['schema'] ) );
-               $this->assertArrayHasKey( 'injected', $schema );
-       }
-
-       /**
-        * Test update method.
-        *
-        * @covers WP_Widget_Media::update
-        */
-       function test_update() {
-               $widget   = $this->get_mocked_class_instance();
-               $instance = array();
-
-               // Should return valid attachment ID.
-               $expected = array(
-                       'attachment_id' => 1,
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid attachment ID.
-               $result = $widget->update(
-                       array(
-                               'attachment_id' => 'media',
-                       ),
-                       $instance
-               );
-               $this->assertSame( $result, $instance );
-
-               // Should return valid attachment url.
-               $expected = array(
-                       'url' => 'https://example.org',
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid attachment url.
-               $result = $widget->update(
-                       array(
-                               'url' => 'not_a_url',
-                       ),
-                       $instance
-               );
-               $this->assertNotSame( $result, $instance );
-
-               // Should return valid attachment title.
-               $expected = array(
-                       'title' => 'What a title',
-               );
-               $result   = $widget->update( $expected, $instance );
-               $this->assertSame( $result, $expected );
-
-               // Should filter invalid attachment title.
-               $result = $widget->update(
-                       array(
-                               'title' => '<h1>W00t!</h1>',
-                       ),
-                       $instance
-               );
-               $this->assertNotSame( $result, $instance );
-
-               // Should filter invalid key.
-               $result = $widget->update(
-                       array(
-                               'imaginary_key' => 'value',
-                       ),
-                       $instance
-               );
-               $this->assertSame( $result, $instance );
-
-               add_filter( 'sanitize_text_field', array( $this, '_return_wp_error' ) );
-               $result = $widget->update(
-                       array(
-                               'title' => 'Title',
-                       ),
-                       $instance
-               );
-               remove_filter( 'sanitize_text_field', array( $this, '_return_wp_error' ) );
-               $this->assertSame( $result, $instance );
-       }
-
-       /**
-        * Helper function for Test_WP_Widget_Media::test_update().
-        *
-        * @return \WP_Error
-        */
-       function _return_wp_error() {
-               return new WP_Error( 'some-error', 'This is not valid!' );
-       }
-
-       /**
-        * Test widget method.
-        *
-        * @covers WP_Widget_Media::widget
-        * @covers WP_Widget_Media::render_media
-        */
-       function test_widget() {
-               $args     = array(
-                       'before_title'  => '<h2>',
-                       'after_title'   => "</h2>\n",
-                       'before_widget' => '<section>',
-                       'after_widget'  => "</section>\n",
-               );
-               $instance = array(
-                       'title'         => 'Foo',
-                       'url'           => 'http://example.com/image.jpg',
-                       'attachment_id' => 0,
-               );
-
-               add_filter( 'widget_mocked_instance', array( $this, 'filter_widget_mocked_instance' ), 10, 3 );
-
-               ob_start();
-               $widget = $this->get_mocked_class_instance();
-               $widget->expects( $this->atLeastOnce() )->method( 'render_media' )->with( $instance );
-               $this->widget_instance_filter_args = array();
-               $widget->widget( $args, $instance );
-               $this->assertCount( 3, $this->widget_instance_filter_args );
-               $this->assertEquals( $instance, $this->widget_instance_filter_args[0] );
-               $this->assertSame( $args, $this->widget_instance_filter_args[1] );
-               $this->assertSame( $widget, $this->widget_instance_filter_args[2] );
-               $output = ob_get_clean();
-
-               $this->assertStringContainsString( '<h2>Foo</h2>', $output );
-               $this->assertStringContainsString( '<section>', $output );
-               $this->assertStringContainsString( '</section>', $output );
-
-               // No title.
-               ob_start();
-               $widget            = $this->get_mocked_class_instance();
-               $instance['title'] = '';
-               $widget->expects( $this->atLeastOnce() )->method( 'render_media' )->with( $instance );
-               $widget->widget( $args, $instance );
-               $output = ob_get_clean();
-               $this->assertStringNotContainsString( '<h2>Foo</h2>', $output );
-
-               // No attachment_id nor url.
-               $instance['url']           = '';
-               $instance['attachment_id'] = 0;
-               ob_start();
-               $widget = $this->get_mocked_class_instance();
-               $widget->widget( $args, $instance );
-               $output = ob_get_clean();
-               $this->assertEmpty( $output );
-       }
-
-       /**
-        * Args passed to the widget_{$id_base}_instance filter.
-        *
-        * @var array
-        */
-       protected $widget_instance_filter_args = array();
-
-       /**
-        * Filters the media widget instance prior to rendering the media.
-        *
-        * @param array           $instance Instance data.
-        * @param array           $args     Widget args.
-        * @param WP_Widget_Media $object   Widget object.
-        * @return array Instance.
-        */
-       function filter_widget_mocked_instance( $instance, $args, $object ) {
-               $this->widget_instance_filter_args = func_get_args();
-               return $instance;
-       }
-
-       /**
-        * Test form method.
-        *
-        * @covers WP_Widget_Media::form
-        */
-       function test_form() {
-               $widget = $this->get_mocked_class_instance();
-
-               ob_start();
-               $widget->form( array() );
-               $output = ob_get_clean();
-
-               $this->assertStringContainsString( 'name="widget-mocked[][attachment_id]"', $output );
-               $this->assertStringContainsString( 'name="widget-mocked[][title]"', $output );
-               $this->assertStringContainsString( 'name="widget-mocked[][url]"', $output );
-       }
-
-       /**
-        * Test display_media_state method.
-        *
-        * @covers WP_Widget_Media::display_media_state
-        */
-       function test_display_media_state() {
-               $widget        = $this->get_mocked_class_instance();
-               $attachment_id = self::factory()->attachment->create_object(
-                       array(
-                               'file'           => DIR_TESTDATA . '/images/canola.jpg',
-                               'post_parent'    => 0,
-                               'post_mime_type' => 'image/jpeg',
-                       )
-               );
-
-               $result = $widget->display_media_state( array(), get_post( $attachment_id ) );
-               $this->assertSameSets( array(), $result );
-
-               $widget->save_settings(
-                       array(
-                               array(
-                                       'attachment_id' => $attachment_id,
-                               ),
-                       )
-               );
-               $result = $widget->display_media_state( array(), get_post( $attachment_id ) );
-               $this->assertSameSets( array( $widget->l10n['media_library_state_single'] ), $result );
-
-               $widget->save_settings(
-                       array(
-                               array(
-                                       'attachment_id' => $attachment_id,
-                               ),
-                               array(
-                                       'attachment_id' => $attachment_id,
-                               ),
-                       )
-               );
-               $result = $widget->display_media_state( array(), get_post( $attachment_id ) );
-               $this->assertSameSets( array( sprintf( $widget->l10n['media_library_state_multi']['singular'], 2 ) ), $result );
-       }
-
-       /**
-        * Test enqueue_admin_scripts method.
-        *
-        * @covers WP_Widget_Media::enqueue_admin_scripts
-        */
-       function test_enqueue_admin_scripts() {
-               set_current_screen( 'widgets.php' );
-               $widget = $this->get_mocked_class_instance();
-               $widget->enqueue_admin_scripts();
-
-               $this->assertTrue( wp_script_is( 'media-widgets' ) );
-       }
-
-       /**
-        * Test render_control_template_scripts method.
-        *
-        * @covers WP_Widget_Media::render_control_template_scripts
-        */
-       function test_render_control_template_scripts() {
-               $widget = $this->get_mocked_class_instance();
-
-               ob_start();
-               $widget->render_control_template_scripts();
-               $output = ob_get_clean();
-
-               $this->assertStringContainsString( '<script type="text/html" id="tmpl-widget-media-mocked-control">', $output );
-       }
-
-       /**
-        * Test has_content method.
-        *
-        * @covers WP_Widget_Media::has_content
-        */
-       function test_has_content() {
-               $attachment_id = self::factory()->attachment->create_object(
-                       array(
-                               'file'           => DIR_TESTDATA . '/images/canola.jpg',
-                               'post_parent'    => 0,
-                               'post_mime_type' => 'image/jpeg',
-                       )
-               );
-
-               $wp_widget_media = new ReflectionClass( 'WP_Widget_Media' );
-               $has_content     = $wp_widget_media->getMethod( 'has_content' );
-               $has_content->setAccessible( true );
-
-               $result = $has_content->invokeArgs(
-                       $this->get_mocked_class_instance(),
-                       array(
-                               array(
-                                       'attachment_id' => 0,
-                                       'url'           => '',
-                               ),
-                       )
-               );
-               $this->assertFalse( $result );
-
-               $result = $has_content->invokeArgs(
-                       $this->get_mocked_class_instance(),
-                       array(
-                               array(
-                                       'attachment_id' => $attachment_id,
-                                       'url'           => '',
-                               ),
-                       )
-               );
-               $this->assertTrue( $result );
-
-               $result = $has_content->invokeArgs(
-                       $this->get_mocked_class_instance(),
-                       array(
-                               array(
-                                       'attachment_id' => 0,
-                                       'url'           => 'http://example.com/image.jpg',
-                               ),
-                       )
-               );
-               $this->assertTrue( $result );
-       }
-}
</del></span></pre></div>
<a id="trunktestsphpunittestswidgetstextwidgetphp"></a>
<div class="delfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Deleted: trunk/tests/phpunit/tests/widgets/text-widget.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/widgets/text-widget.php 2021-07-26 19:09:41 UTC (rev 51492)
+++ trunk/tests/phpunit/tests/widgets/text-widget.php   2021-07-26 19:25:09 UTC (rev 51493)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,1058 +0,0 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-<?php
-/**
- * Unit tests covering WP_Widget_Text functionality.
- *
- * @package    WordPress
- * @subpackage widgets
- */
-
-/**
- * Test wp-includes/widgets/class-wp-widget-text.php
- *
- * @group widgets
- */
-class Test_WP_Widget_Text extends WP_UnitTestCase {
-       /**
-        * Args passed to the widget_text filter.
-        *
-        * @var array
-        */
-       protected $widget_text_args;
-
-       /**
-        * Args passed to the widget_text_content filter.
-        *
-        * @var array
-        */
-       protected $widget_text_content_args;
-
-       /**
-        * Clean up global scope.
-        *
-        * @global WP_Scripts           $wp_scripts
-        * @global WP_Styles            $wp_style
-        * @global WP_Customize_Manager $wp_customize
-        */
-       function clean_up_global_scope() {
-               global $wp_scripts, $wp_styles, $wp_customize;
-               parent::clean_up_global_scope();
-               $wp_scripts   = null;
-               $wp_styles    = null;
-               $wp_customize = null;
-       }
-
-       /**
-        * Test constructor method.
-        *
-        * @covers WP_Widget_Text::__construct
-        */
-       function test_construct() {
-               $widget = new WP_Widget_Text();
-               $this->assertSame( 'text', $widget->id_base );
-               $this->assertSame( 'widget_text', $widget->widget_options['classname'] );
-               $this->assertTrue( $widget->widget_options['customize_selective_refresh'] );
-               $this->assertSame( 400, $widget->control_options['width'] );
-               $this->assertSame( 350, $widget->control_options['height'] );
-       }
-
-       /**
-        * Test enqueue_admin_scripts method.
-        *
-        * @covers WP_Widget_Text::_register
-        */
-       function test__register() {
-               set_current_screen( 'widgets.php' );
-               $widget = new WP_Widget_Text();
-               $widget->_register();
-
-               $this->assertSame( 10, has_action( 'admin_print_scripts-widgets.php', array( $widget, 'enqueue_admin_scripts' ) ) );
-               $this->assertSame( 10, has_action( 'admin_footer-widgets.php', array( 'WP_Widget_Text', 'render_control_template_scripts' ) ) );
-               $this->assertContains( 'wp.textWidgets.idBases.push( "text" );', wp_scripts()->registered['text-widgets']->extra['after'] );
-               $this->assertFalse( has_action( 'wp_enqueue_scripts', array( $widget, 'enqueue_preview_scripts' ) ) );
-       }
-
-       /**
-        * Test register in customize preview.
-        *
-        * @global WP_Customize_Manager $wp_customize
-        * @covers WP_Widget_Text::__construct
-        * @covers WP_Widget_Text::_register
-        */
-       function test__register_in_customize_preview() {
-               global $wp_customize;
-               wp_set_current_user(
-                       $this->factory()->user->create(
-                               array(
-                                       'role' => 'administrator',
-                               )
-                       )
-               );
-               require_once ABSPATH . WPINC . '/class-wp-customize-manager.php';
-               $wp_customize = new WP_Customize_Manager(
-                       array(
-                               'changeset_uuid' => wp_generate_uuid4(),
-                       )
-               );
-               $wp_customize->start_previewing_theme();
-
-               $widget = new WP_Widget_Text();
-               $widget->_register();
-               $this->assertSame( 10, has_action( 'wp_enqueue_scripts', array( $widget, 'enqueue_preview_scripts' ) ) );
-       }
-
-       /**
-        * Test enqueue_preview_scripts method.
-        *
-        * @global WP_Scripts $wp_scripts
-        * @global WP_Styles $wp_styles
-        * @covers WP_Widget_Text::enqueue_preview_scripts
-        */
-       function test_enqueue_preview_scripts() {
-               global $wp_scripts, $wp_styles;
-               $wp_scripts = null;
-               $wp_styles  = null;
-               $widget     = new WP_Widget_Text();
-
-               $this->assertFalse( wp_style_is( 'wp-mediaelement' ) );
-               $this->assertFalse( wp_script_is( 'wp-playlist' ) );
-
-               ob_start();
-               $widget->enqueue_preview_scripts();
-               ob_end_clean();
-
-               $this->assertTrue( wp_style_is( 'wp-mediaelement' ) );
-               $this->assertTrue( wp_script_is( 'wp-playlist' ) );
-       }
-
-       /**
-        * Test widget method.
-        *
-        * @covers WP_Widget_Text::widget
-        */
-       function test_widget() {
-               $widget = new WP_Widget_Text();
-               $text   = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n Praesent ut turpis consequat lorem volutpat bibendum vitae vitae ante.";
-
-               $args = array(
-                       'before_title'  => '<h2>',
-                       'after_title'   => "</h2>\n",
-                       'before_widget' => '<section>',
-                       'after_widget'  => "</section>\n",
-               );
-
-               add_filter( 'widget_text_content', array( $this, 'filter_widget_text_content' ), 5, 3 );
-               add_filter( 'widget_text', array( $this, 'filter_widget_text' ), 5, 3 );
-
-               // Test with filter=false, implicit legacy mode.
-               $this->widget_text_content_args = null;
-               ob_start();
-               $instance = array(
-                       'title'  => 'Foo',
-                       'text'   => $text,
-                       'filter' => false,
-               );
-               $widget->widget( $args, $instance );
-               $output = ob_get_clean();
-               $this->assertStringNotContainsString( '<p>', $output );
-               $this->assertStringNotContainsString( '<br />', $output );
-               $this->assertEmpty( $this->widget_text_content_args );
-               $this->assertNotEmpty( $this->widget_text_args );
-               $this->assertStringContainsString( '[filter:widget_text]', $output );
-               $this->assertStringNotContainsString( '[filter:widget_text_content]', $output );
-
-               // Test with filter=true, implicit legacy mode.
-               $this->widget_text_content_args = null;
-               $instance                       = array(
-                       'title'  => 'Foo',
-                       'text'   => $text,
-                       'filter' => true,
-               );
-               ob_start();
-               $widget->widget( $args, $instance );
-               $output = ob_get_clean();
-               $this->assertStringContainsString( '<p>', $output );
-               $this->assertStringContainsString( '<br />', $output );
-               $this->assertNotEmpty( $this->widget_text_args );
-               $this->assertSame( $instance['text'], $this->widget_text_args[0] );
-               $this->assertSame( $instance, $this->widget_text_args[1] );
-               $this->assertSame( $widget, $this->widget_text_args[2] );
-               $this->assertEmpty( $this->widget_text_content_args );
-               $this->assertStringContainsString( '[filter:widget_text]', $output );
-               $this->assertStringNotContainsString( '[filter:widget_text_content]', $output );
-
-               // Test with filter=content, the upgraded widget, in 4.8.0 only.
-               $this->widget_text_content_args = null;
-               $instance                       = array(
-                       'title'  => 'Foo',
-                       'text'   => $text,
-                       'filter' => 'content',
-               );
-               $expected_instance              = array_merge(
-                       $instance,
-                       array(
-                               'filter' => true,
-                               'visual' => true,
-                       )
-               );
-               ob_start();
-               $widget->widget( $args, $instance );
-               $output = ob_get_clean();
-               $this->assertStringContainsString( '<p>', $output );
-               $this->assertStringContainsString( '<br />', $output );
-               $this->assertCount( 3, $this->widget_text_args );
-               $this->assertSame( $expected_instance['text'], $this->widget_text_args[0] );
-               $this->assertSame( $expected_instance, $this->widget_text_args[1] );
-               $this->assertSame( $widget, $this->widget_text_args[2] );
-               $this->assertCount( 3, $this->widget_text_content_args );
-               $this->assertSame( $expected_instance['text'] . '[filter:widget_text]', $this->widget_text_content_args[0] );
-               $this->assertSame( $expected_instance, $this->widget_text_content_args[1] );
-               $this->assertSame( $widget, $this->widget_text_content_args[2] );
-               $this->assertStringContainsString( wpautop( $expected_instance['text'] . '[filter:widget_text][filter:widget_text_content]' ), $output );
-
-               // Test with filter=true&visual=true, the upgraded widget, in 4.8.1 and above.
-               $this->widget_text_content_args = null;
-               $instance                       = array(
-                       'title'  => 'Foo',
-                       'text'   => $text,
-                       'filter' => true,
-                       'visual' => true,
-               );
-               $expected_instance              = $instance;
-               ob_start();
-               $widget->widget( $args, $instance );
-               $output = ob_get_clean();
-               $this->assertStringContainsString( '<p>', $output );
-               $this->assertStringContainsString( '<br />', $output );
-               $this->assertCount( 3, $this->widget_text_args );
-               $this->assertSame( $expected_instance['text'], $this->widget_text_args[0] );
-               $this->assertSame( $expected_instance, $this->widget_text_args[1] );
-               $this->assertSame( $widget, $this->widget_text_args[2] );
-               $this->assertCount( 3, $this->widget_text_content_args );
-               $this->assertSame( $expected_instance['text'] . '[filter:widget_text]', $this->widget_text_content_args[0] );
-               $this->assertSame( $expected_instance, $this->widget_text_content_args[1] );
-               $this->assertSame( $widget, $this->widget_text_content_args[2] );
-               $this->assertStringContainsString( wpautop( $expected_instance['text'] . '[filter:widget_text][filter:widget_text_content]' ), $output );
-
-               // Test with filter=true&visual=true, the upgraded widget, in 4.8.1 and above.
-               $this->widget_text_content_args = null;
-               $instance                       = array(
-                       'title'  => 'Foo',
-                       'text'   => $text,
-                       'filter' => true,
-                       'visual' => false,
-               );
-               $expected_instance              = $instance;
-               ob_start();
-               $widget->widget( $args, $instance );
-               $output = ob_get_clean();
-               $this->assertStringContainsString( '<p>', $output );
-               $this->assertStringContainsString( '<br />', $output );
-               $this->assertCount( 3, $this->widget_text_args );
-               $this->assertSame( $expected_instance['text'], $this->widget_text_args[0] );
-               $this->assertSame( $expected_instance, $this->widget_text_args[1] );
-               $this->assertSame( $widget, $this->widget_text_args[2] );
-               $this->assertNull( $this->widget_text_content_args );
-               $this->assertStringContainsString( wpautop( $expected_instance['text'] . '[filter:widget_text]' ), $output );
-
-               // Test with filter=false&visual=false, the upgraded widget, in 4.8.1 and above.
-               $this->widget_text_content_args = null;
-               $instance                       = array(
-                       'title'  => 'Foo',
-                       'text'   => $text,
-                       'filter' => false,
-                       'visual' => false,
-               );
-               $expected_instance              = $instance;
-               ob_start();
-               $widget->widget( $args, $instance );
-               $output = ob_get_clean();
-               $this->assertStringNotContainsString( '<p>', $output );
-               $this->assertStringNotContainsString( '<br />', $output );
-               $this->assertCount( 3, $this->widget_text_args );
-               $this->assertSame( $expected_instance['text'], $this->widget_text_args[0] );
-               $this->assertSame( $expected_instance, $this->widget_text_args[1] );
-               $this->assertSame( $widget, $this->widget_text_args[2] );
-               $this->assertNull( $this->widget_text_content_args );
-               $this->assertStringContainsString( $expected_instance['text'] . '[filter:widget_text]', $output );
-       }
-
-       /**
-        * Example shortcode content to test for wpautop corruption.
-        *
-        * @var string
-        */
-       protected $example_shortcode_content = "<p class='sortcodep'>One\nTwo\n\nThree\n\nThis is testing the <code>[example note='This will not get processed since it is part of shortcode output itself.']</code> shortcode.</p>\n<script>\ndocument.write('Test1');\n\ndocument.write('Test2');\n</script>";
-
-       /**
-        * The captured global post during shortcode rendering.
-        *
-        * @var WP_Post|null
-        */
-       protected $post_during_shortcode = null;
-
-       /**
-        * Number of times the shortcode was rendered.
-        *
-        * @var int
-        */
-       protected $shortcode_render_count = 0;
-
-       /**
-        * Do example shortcode.
-        *
-        * @return string Shortcode content.
-        */
-       function do_example_shortcode() {
-               $this->post_during_shortcode = get_post();
-               $this->shortcode_render_count++;
-               return $this->example_shortcode_content;
-       }
-
-       /**
-        * Test widget method with shortcodes.
-        *
-        * @covers WP_Widget_Text::widget
-        */
-       function test_widget_shortcodes() {
-               global $post;
-               $post_id = $this->factory()->post->create();
-               $post    = get_post( $post_id );
-
-               $args   = array(
-                       'before_title'  => '<h2>',
-                       'after_title'   => "</h2>\n",
-                       'before_widget' => '<section>',
-                       'after_widget'  => "</section>\n",
-               );
-               $widget = new WP_Widget_Text();
-               add_shortcode( 'example', array( $this, 'do_example_shortcode' ) );
-
-               $base_instance = array(
-                       'title'  => 'Example',
-                       'text'   => "This is an example:\n\n[example]\n\nHello.",
-                       'filter' => false,
-               );
-
-               // Legacy Text Widget without wpautop().
-               $instance                     = array_merge(
-                       $base_instance,
-                       array(
-                               'filter' => false,
-                       )
-               );
-               $this->shortcode_render_count = 0;
-               ob_start();
-               $widget->widget( $args, $instance );
-               $output = ob_get_clean();
-               $this->assertSame( 1, $this->shortcode_render_count );
-               $this->assertStringNotContainsString( '[example]', $output, 'Expected shortcode to be processed in legacy widget with plugin adding filter' );
-               $this->assertStringContainsString( $this->example_shortcode_content, $output, 'Shortcode was applied without wpautop corrupting it.' );
-               $this->assertStringNotContainsString( '<p>' . $this->example_shortcode_content . '</p>', $output, 'Expected shortcode_unautop() to have run.' );
-               $this->assertNull( $this->post_during_shortcode );
-
-               // Legacy Text Widget with wpautop().
-               $instance                     = array_merge(
-                       $base_instance,
-                       array(
-                               'filter' => true,
-                               'visual' => false,
-                       )
-               );
-               $this->shortcode_render_count = 0;
-               ob_start();
-               $widget->widget( $args, $instance );
-               $output = ob_get_clean();
-               $this->assertSame( 1, $this->shortcode_render_count );
-               $this->assertStringNotContainsString( '[example]', $output, 'Expected shortcode to be processed in legacy widget with plugin adding filter' );
-               $this->assertStringContainsString( $this->example_shortcode_content, $output, 'Shortcode was applied without wpautop corrupting it.' );
-               $this->assertStringNotContainsString( '<p>' . $this->example_shortcode_content . '</p>', $output, 'Expected shortcode_unautop() to have run.' );
-               $this->assertNull( $this->post_during_shortcode );
-
-               // Legacy text widget with plugin adding shortcode support as well.
-               add_filter( 'widget_text', 'do_shortcode' );
-               $this->shortcode_render_count = 0;
-               ob_start();
-               $widget->widget( $args, $instance );
-               $output = ob_get_clean();
-               $this->assertSame( 1, $this->shortcode_render_count );
-               $this->assertStringNotContainsString( '[example]', $output, 'Expected shortcode to be processed in legacy widget with plugin adding filter' );
-               $this->assertStringContainsString( wpautop( $this->example_shortcode_content ), $output, 'Shortcode was applied *with* wpautop() applying to shortcode output since plugin used legacy filter.' );
-               $this->assertNull( $this->post_during_shortcode );
-               remove_filter( 'widget_text', 'do_shortcode' );
-
-               $instance = array_merge(
-                       $base_instance,
-                       array(
-                               'filter' => true,
-                               'visual' => true,
-                       )
-               );
-
-               // Visual Text Widget with only core-added widget_text_content filter for do_shortcode().
-               $this->assertFalse( has_filter( 'widget_text', 'do_shortcode' ) );
-               $this->assertSame( 11, has_filter( 'widget_text_content', 'do_shortcode' ), 'Expected core to have set do_shortcode as widget_text_content filter.' );
-               $this->shortcode_render_count = 0;
-               ob_start();
-               $widget->widget( $args, $instance );
-               $output = ob_get_clean();
-               $this->assertSame( 1, $this->shortcode_render_count );
-               $this->assertStringContainsString( $this->example_shortcode_content, $output, 'Shortcode was applied without wpautop corrupting it.' );
-               $this->assertStringNotContainsString( '<p>' . $this->example_shortcode_content . '</p>', $output, 'Expected shortcode_unautop() to have run.' );
-               $this->assertFalse( has_filter( 'widget_text', 'do_shortcode' ), 'The widget_text filter still lacks do_shortcode handler.' );
-               $this->assertSame( 11, has_filter( 'widget_text_content', 'do_shortcode' ), 'The widget_text_content filter still has do_shortcode handler.' );
-               $this->assertNull( $this->post_during_shortcode );
-
-               // Visual Text Widget with both filters applied added, one from core and another via plugin.
-               add_filter( 'widget_text', 'do_shortcode' );
-               $this->shortcode_render_count = 0;
-               ob_start();
-               $widget->widget( $args, $instance );
-               $output = ob_get_clean();
-               $this->assertSame( 1, $this->shortcode_render_count );
-               $this->assertStringContainsString( $this->example_shortcode_content, $output, 'Shortcode was applied without wpautop corrupting it.' );
-               $this->assertStringNotContainsString( '<p>' . $this->example_shortcode_content . '</p>', $output, 'Expected shortcode_unautop() to have run.' );
-               $this->assertSame( 10, has_filter( 'widget_text', 'do_shortcode' ), 'Expected do_shortcode to be restored to widget_text.' );
-               $this->assertNull( $this->post_during_shortcode );
-               $this->assertNull( $this->post_during_shortcode );
-               remove_filter( 'widget_text', 'do_shortcode' );
-
-               // Visual Text Widget with shortcode handling disabled via plugin removing filter.
-               remove_filter( 'widget_text_content', 'do_shortcode', 11 );
-               remove_filter( 'widget_text', 'do_shortcode' );
-               $this->shortcode_render_count = 0;
-               ob_start();
-               $widget->widget( $args, $instance );
-               $output = ob_get_clean();
-               $this->assertSame( 0, $this->shortcode_render_count );
-               $this->assertStringContainsString( '[example]', $output );
-               $this->assertStringNotContainsString( $this->example_shortcode_content, $output );
-               $this->assertFalse( has_filter( 'widget_text', 'do_shortcode' ) );
-               $this->assertFalse( has_filter( 'widget_text_content', 'do_shortcode' ) );
-       }
-
-       /**
-        * Filters the content of the Text widget.
-        *
-        * @param string         $widget_text The widget content.
-        * @param array          $instance    Array of settings for the current widget.
-        * @param WP_Widget_Text $widget      Current Text widget instance.
-        * @return string Widget text.
-        */
-       function filter_widget_text( $widget_text, $instance, $widget ) {
-               $this->widget_text_args = func_get_args();
-
-               $widget_text .= '[filter:widget_text]';
-               return $widget_text;
-       }
-
-       /**
-        * Filters the content of the Text widget to apply changes expected from the visual (TinyMCE) editor.
-        *
-        * @param string         $widget_text The widget content.
-        * @param array          $instance    Array of settings for the current widget.
-        * @param WP_Widget_Text $widget      Current Text widget instance.
-        * @return string Widget content.
-        */
-       function filter_widget_text_content( $widget_text, $instance, $widget ) {
-               $this->widget_text_content_args = func_get_args();
-
-               $widget_text .= '[filter:widget_text_content]';
-               return $widget_text;
-       }
-
-       /**
-        * Test is_legacy_instance method.
-        *
-        * @covers WP_Widget_Text::is_legacy_instance
-        */
-       function test_is_legacy_instance() {
-               $widget        = new WP_Widget_Text();
-               $base_instance = array(
-                       'title' => 'Title',
-                       'text'  => "Hello\n\nWorld",
-               );
-
-               $instance = array_merge(
-                       $base_instance,
-                       array(
-                               'visual' => false,
-                       )
-               );
-               $this->assertTrue( $widget->is_legacy_instance( $instance ), 'Legacy when visual=false prop is present.' );
-
-               $instance = array_merge(
-                       $base_instance,
-                       array(
-                               'visual' => true,
-                       )
-               );
-               $this->assertFalse( $widget->is_legacy_instance( $instance ), 'Not legacy when visual=true prop is present.' );
-
-               $instance = array_merge(
-                       $base_instance,
-                       array(
-                               'filter' => 'content',
-                       )
-               );
-               $this->assertFalse( $widget->is_legacy_instance( $instance ), 'Not legacy when filter is explicitly content (in WP 4.8.0 only).' );
-
-               $instance = array_merge(
-                       $base_instance,
-                       array(
-                               'text'   => '',
-                               'filter' => true,
-                       )
-               );
-               $this->assertFalse( $widget->is_legacy_instance( $instance ), 'Not legacy when text is empty.' );
-
-               $instance = array_merge(
-                       $base_instance,
-                       array(
-                               'text'   => "\nOne line",
-                               'filter' => false,
-                       )
-               );
-               $this->assertFalse( $widget->is_legacy_instance( $instance ), 'Not legacy when there is leading whitespace.' );
-
-               $instance = array_merge(
-                       $base_instance,
-                       array(
-                               'text'   => "\nOne line\n\n",
-                               'filter' => false,
-                       )
-               );
-               $this->assertFalse( $widget->is_legacy_instance( $instance ), 'Not legacy when there is trailing whitespace.' );
-
-               $instance = array_merge(
-                       $base_instance,
-                       array(
-                               'text'   => "One\nTwo",
-                               'filter' => false,
-                       )
-               );
-               $this->assertTrue( $widget->is_legacy_instance( $instance ), 'Legacy when not-wpautop and there are line breaks.' );
-
-               $instance = array_merge(
-                       $base_instance,
-                       array(
-                               'text'   => "One\n\nTwo",
-                               'filter' => false,
-                       )
-               );
-               $this->assertTrue( $widget->is_legacy_instance( $instance ), 'Legacy when not-wpautop and there are paragraph breaks.' );
-
-               $instance = array_merge(
-                       $base_instance,
-                       array(
-                               'text'   => "One\nTwo",
-                               'filter' => true,
-                       )
-               );
-               $this->assertFalse( $widget->is_legacy_instance( $instance ), 'Not automatically legacy when wpautop and there are line breaks.' );
-
-               $instance = array_merge(
-                       $base_instance,
-                       array(
-                               'text'   => "One\n\nTwo",
-                               'filter' => true,
-                       )
-               );
-               $this->assertFalse( $widget->is_legacy_instance( $instance ), 'Not automatically legacy when wpautop and there are paragraph breaks.' );
-
-               $instance = array_merge(
-                       $base_instance,
-                       array(
-                               'text'   => 'Test<!-- comment -->',
-                               'filter' => true,
-                       )
-               );
-               $this->assertTrue( $widget->is_legacy_instance( $instance ), 'Legacy when HTML comment is present.' );
-
-               // Check text examples that will not migrate to TinyMCE.
-               $legacy_text_examples = array(
-                       '<span class="hello"></span>',
-                       '<blockquote>Quote <footer>Citation</footer></blockquote>',
-                       '<img src=\"http://example.com/img.jpg\" border=\"0\" title=\"Example\" /></a>',
-                       '<span></span>',
-                       "<ul>\n<li><a href=\"#\" class=\"location\"></a>List Item 1</li>\n<li><a href=\"#\" class=\"location\"></a>List Item 2</li>\n</ul>",
-                       '<a href="#" class="map"></a>',
-                       "<script>\n\\Line one\n\n\\Line two</script>",
-                       "<style>body {\ncolor:red;\n}</style>",
-                       '<span class="fa fa-cc-discover fa-2x" aria-hidden="true"></span>',
-                       "<p>\nStay updated with our latest news and specials. We never sell your information and you can unsubscribe at any time.\n</p>\n\n<div class=\"custom-form-class\">\n\t<form action=\"#\" method=\"post\" name=\"mc-embedded-subscribe-form\">\n\n\t\t<label class=\"screen-reader-text\" for=\"mce-EMAIL-b\">Email </label>\n\t\t<input id=\"mce-EMAIL-b\" class=\"required email\" name=\"EMAIL\" required=\"\" type=\"email\" value=\"\" placeholder=\"Email Address*\" />\n\n\t\t<input class=\"button\" name=\"subscribe\" type=\"submit\" value=\"Go!\" />\n\n\t</form>\n</div>",
-                       '<span class="sectiondown"><a href="#front-page-3"><i class="fa fa-chevron-circle-down"></i></a></span>',
-               );
-               foreach ( $legacy_text_examples as $legacy_text_example ) {
-                       $instance = array_merge(
-                               $base_instance,
-                               array(
-                                       'text'   => $legacy_text_example,
-                                       'filter' => true,
-                               )
-                       );
-                       $this->assertTrue( $widget->is_legacy_instance( $instance ), 'Legacy when wpautop and there is HTML that is not liable to be mutated.' );
-
-                       $instance = array_merge(
-                               $base_instance,
-                               array(
-                                       'text'   => $legacy_text_example,
-                                       'filter' => false,
-                               )
-                       );
-                       $this->assertTrue( $widget->is_legacy_instance( $instance ), 'Legacy when not-wpautop and there is HTML that is not liable to be mutated.' );
-               }
-
-               // Check text examples that will migrate to TinyMCE, where elements and attributes are not in the allowed list.
-               $migratable_text_examples = array(
-                       'Check out <a href="http://example.com">Example</a>',
-                       '<img src="http://example.com/img.jpg" alt="Img">',
-                       '<strong><em>Hello</em></strong>',
-                       '<b><i><u><s>Hello</s></u></i></b>',
-                       "<ul>\n<li>One</li>\n<li>One</li>\n<li>One</li>\n</ul>",
-                       "<ol>\n<li>One</li>\n<li>One</li>\n<li>One</li>\n</ol>",
-                       "Text\n<hr>\nAddendum",
-                       "Look at this code:\n\n<code>echo 'Hello World!';</code>",
-               );
-               foreach ( $migratable_text_examples as $migratable_text_example ) {
-                       $instance = array_merge(
-                               $base_instance,
-                               array(
-                                       'text'   => $migratable_text_example,
-                                       'filter' => true,
-                               )
-                       );
-                       $this->assertFalse( $widget->is_legacy_instance( $instance ), 'Legacy when wpautop and there is HTML that is not liable to be mutated.' );
-               }
-       }
-
-       /**
-        * Test update method.
-        *
-        * @covers WP_Widget_Text::form
-        */
-       function test_form() {
-               add_filter( 'user_can_richedit', '__return_true' );
-               $widget = new WP_Widget_Text();
-               $widget->_set( 2 );
-               $instance = array(
-                       'title'  => 'Title',
-                       'text'   => 'Text',
-                       'filter' => false,
-                       'visual' => false,
-               );
-               $this->assertTrue( $widget->is_legacy_instance( $instance ) );
-               ob_start();
-               $widget->form( $instance );
-               $form = ob_get_clean();
-               $this->assertStringContainsString( 'class="visual" type="hidden" value=""', $form );
-               $this->assertStringNotContainsString( 'class="visual sync-input" type="hidden" value="on"', $form );
-
-               $instance = array(
-                       'title'  => 'Title',
-                       'text'   => 'Text',
-                       'filter' => 'content',
-               );
-               $this->assertFalse( $widget->is_legacy_instance( $instance ) );
-               ob_start();
-               $widget->form( $instance );
-               $form = ob_get_clean();
-               $this->assertStringContainsString( 'class="visual sync-input" type="hidden" value="on"', $form );
-               $this->assertStringNotContainsString( 'class="visual sync-input" type="hidden" value=""', $form );
-
-               $instance = array(
-                       'title'  => 'Title',
-                       'text'   => 'Text',
-                       'filter' => true,
-               );
-               $this->assertFalse( $widget->is_legacy_instance( $instance ) );
-               ob_start();
-               $widget->form( $instance );
-               $form = ob_get_clean();
-               $this->assertStringContainsString( 'class="visual sync-input" type="hidden" value="on"', $form );
-               $this->assertStringNotContainsString( 'class="visual sync-input" type="hidden" value=""', $form );
-
-               $instance = array(
-                       'title'  => 'Title',
-                       'text'   => 'This is some HTML Code: <code>&lt;strong&gt;BOLD!&lt;/strong&gt;</code>',
-                       'filter' => true,
-                       'visual' => true,
-               );
-               $this->assertFalse( $widget->is_legacy_instance( $instance ) );
-               ob_start();
-               $widget->form( $instance );
-               $form = ob_get_clean();
-               $this->assertStringContainsString( 'class="visual sync-input" type="hidden" value="on"', $form );
-               $this->assertStringContainsString( '&lt;code&gt;&amp;lt;strong&amp;gt;BOLD!', $form );
-               $this->assertStringNotContainsString( 'class="visual sync-input" type="hidden" value=""', $form );
-
-               remove_filter( 'user_can_richedit', '__return_true' );
-               add_filter( 'user_can_richedit', '__return_false' );
-               $instance = array(
-                       'title'  => 'Title',
-                       'text'   => 'Evil:</textarea><script>alert("XSS")</script>',
-                       'filter' => true,
-                       'visual' => true,
-               );
-               $this->assertFalse( $widget->is_legacy_instance( $instance ) );
-               ob_start();
-               $widget->form( $instance );
-               $form = ob_get_clean();
-               $this->assertStringNotContainsString( 'Evil:</textarea>', $form );
-               $this->assertStringContainsString( 'Evil:&lt;/textarea>', $form );
-       }
-
-       /**
-        * Test update method.
-        *
-        * @covers WP_Widget_Text::update
-        */
-       function test_update() {
-               $widget   = new WP_Widget_Text();
-               $instance = array(
-                       'title'  => "The\nTitle",
-                       'text'   => "The\n\nText",
-                       'filter' => true,
-                       'visual' => true,
-               );
-
-               wp_set_current_user(
-                       $this->factory()->user->create(
-                               array(
-                                       'role' => 'administrator',
-                               )
-                       )
-               );
-
-               $expected = array(
-                       'title'  => sanitize_text_field( $instance['title'] ),
-                       'text'   => $instance['text'],
-                       'filter' => true,
-                       'visual' => true,
-               );
-               $result   = $widget->update( $instance, array() );
-               $this->assertSame( $expected, $result );
-               $this->assertNotEmpty( $expected['filter'], 'Expected filter prop to be truthy, to handle case where 4.8 is downgraded to 4.7.' );
-
-               add_filter( 'map_meta_cap', array( $this, 'grant_unfiltered_html_cap' ), 10, 2 );
-               $this->assertTrue( current_user_can( 'unfiltered_html' ) );
-               $instance['text'] = '<script>alert( "Howdy!" );</script>';
-               $expected['text'] = $instance['text'];
-               $result           = $widget->update( $instance, array() );
-               $this->assertSame( $expected, $result, 'KSES should apply as expected.' );
-               remove_filter( 'map_meta_cap', array( $this, 'grant_unfiltered_html_cap' ) );
-
-               add_filter( 'map_meta_cap', array( $this, 'revoke_unfiltered_html_cap' ), 10, 2 );
-               $this->assertFalse( current_user_can( 'unfiltered_html' ) );
-               $instance['text'] = '<script>alert( "Howdy!" );</script>';
-               $expected['text'] = wp_kses_post( $instance['text'] );
-               $result           = $widget->update( $instance, array() );
-               $this->assertSame( $expected, $result, 'KSES should not apply since user can unfiltered_html.' );
-               remove_filter( 'map_meta_cap', array( $this, 'revoke_unfiltered_html_cap' ), 10 );
-       }
-
-       /**
-        * Test update for legacy widgets.
-        *
-        * @covers WP_Widget_Text::update
-        */
-       function test_update_legacy() {
-               $widget = new WP_Widget_Text();
-
-               // --
-               $instance = array(
-                       'title'  => 'Legacy',
-                       'text'   => 'Text',
-                       'filter' => false,
-               );
-               $result   = $widget->update( $instance, array() );
-               $this->assertSameSets( $instance, $result, 'Updating a widget without visual prop and explicit filter=false leaves visual prop absent' );
-
-               // --
-               $instance = array(
-                       'title'  => 'Legacy',
-                       'text'   => 'Text',
-                       'filter' => true,
-               );
-               $result   = $widget->update( $instance, array() );
-               $this->assertSameSets( $instance, $result, 'Updating a widget without visual prop and explicit filter=true leaves legacy prop absent.' );
-
-               // --
-               $instance     = array(
-                       'title'  => 'Legacy',
-                       'text'   => 'Text',
-                       'visual' => true,
-               );
-               $old_instance = array_merge(
-                       $instance,
-                       array(
-                               'filter' => false,
-                       )
-               );
-               $expected     = array_merge(
-                       $instance,
-                       array(
-                               'filter' => true,
-                       )
-               );
-               $result       = $widget->update( $instance, $old_instance );
-               $this->assertSameSets( $expected, $result, 'Updating a pre-existing widget with visual mode forces filter to be true.' );
-
-               // --
-               $instance     = array(
-                       'title'  => 'Legacy',
-                       'text'   => 'Text',
-                       'filter' => true,
-               );
-               $old_instance = array_merge(
-                       $instance,
-                       array(
-                               'visual' => true,
-                       )
-               );
-               $result       = $widget->update( $instance, $old_instance );
-               $expected     = array_merge(
-                       $instance,
-                       array(
-                               'visual' => true,
-                       )
-               );
-               $this->assertSameSets( $expected, $result, 'Updating a pre-existing visual widget retains visual mode when updated.' );
-
-               // --
-               $instance     = array(
-                       'title' => 'Legacy',
-                       'text'  => 'Text',
-               );
-               $old_instance = array_merge(
-                       $instance,
-                       array(
-                               'visual' => true,
-                       )
-               );
-               $result       = $widget->update( $instance, $old_instance );
-               $expected     = array_merge(
-                       $instance,
-                       array(
-                               'visual' => true,
-                               'filter' => true,
-                       )
-               );
-               $this->assertSameSets( $expected, $result, 'Updating a pre-existing visual widget retains visual=true and supplies missing filter=true.' );
-
-               // --
-               $instance = array(
-                       'title'  => 'Legacy',
-                       'text'   => 'Text',
-                       'visual' => true,
-               );
-               $expected = array_merge(
-                       $instance,
-                       array(
-                               'filter' => true,
-                       )
-               );
-               $result   = $widget->update( $instance, array() );
-               $this->assertSameSets( $expected, $result, 'Updating a widget with explicit visual=true and absent filter prop causes filter to be set to true.' );
-
-               // --
-               $instance = array(
-                       'title'  => 'Legacy',
-                       'text'   => 'Text',
-                       'visual' => false,
-               );
-               $result   = $widget->update( $instance, array() );
-               $expected = array_merge(
-                       $instance,
-                       array(
-                               'filter' => false,
-                       )
-               );
-               $this->assertSameSets( $expected, $result, 'Updating a widget in legacy mode results in filter=false as if checkbox not checked.' );
-
-               // --
-               $instance     = array(
-                       'title'  => 'Title',
-                       'text'   => 'Text',
-                       'filter' => false,
-               );
-               $old_instance = array_merge(
-                       $instance,
-                       array(
-                               'visual' => false,
-                               'filter' => true,
-                       )
-               );
-               $result       = $widget->update( $instance, $old_instance );
-               $expected     = array_merge(
-                       $instance,
-                       array(
-                               'visual' => false,
-                               'filter' => false,
-                       )
-               );
-               $this->assertSameSets( $expected, $result, 'Updating a widget that previously had legacy form results in filter allowed to be false.' );
-
-               // --
-               $instance = array(
-                       'title'  => 'Title',
-                       'text'   => 'Text',
-                       'filter' => 'content',
-               );
-               $result   = $widget->update( $instance, array() );
-               $expected = array_merge(
-                       $instance,
-                       array(
-                               'filter' => true,
-                               'visual' => true,
-                       )
-               );
-               $this->assertSameSets( $expected, $result, 'Updating a widget that had \'content\' as its filter value persists non-legacy mode. This only existed in WP 4.8.0.' );
-
-               // --
-               $instance     = array(
-                       'title' => 'Title',
-                       'text'  => 'Text',
-               );
-               $old_instance = array_merge(
-                       $instance,
-                       array(
-                               'filter' => 'content',
-                       )
-               );
-               $result       = $widget->update( $instance, $old_instance );
-               $expected     = array_merge(
-                       $instance,
-                       array(
-                               'visual' => true,
-                               'filter' => true,
-                       )
-               );
-               $this->assertSameSets( $expected, $result, 'Updating a pre-existing widget with the filter=content prop in WP 4.8.0 upgrades to filter=true&visual=true.' );
-
-               // --
-               $instance = array(
-                       'title'  => 'Title',
-                       'text'   => 'Text',
-                       'filter' => 'content',
-               );
-               $result   = $widget->update( $instance, array() );
-               $expected = array_merge(
-                       $instance,
-                       array(
-                               'filter' => true,
-                               'visual' => true,
-                       )
-               );
-               $this->assertSameSets( $expected, $result, 'Updating a widget with filter=content (from WP 4.8.0) upgrades to filter=true&visual=true.' );
-       }
-
-       /**
-        * Grant unfiltered_html cap via map_meta_cap.
-        *
-        * @param array  $caps    Returns the user's actual capabilities.
-        * @param string $cap     Capability name.
-        * @return array Caps.
-        */
-       function grant_unfiltered_html_cap( $caps, $cap ) {
-               if ( 'unfiltered_html' === $cap ) {
-                       $caps   = array_diff( $caps, array( 'do_not_allow' ) );
-                       $caps[] = 'unfiltered_html';
-               }
-               return $caps;
-       }
-
-       /**
-        * Revoke unfiltered_html cap via map_meta_cap.
-        *
-        * @param array  $caps    Returns the user's actual capabilities.
-        * @param string $cap     Capability name.
-        * @return array Caps.
-        */
-       function revoke_unfiltered_html_cap( $caps, $cap ) {
-               if ( 'unfiltered_html' === $cap ) {
-                       $caps   = array_diff( $caps, array( 'unfiltered_html' ) );
-                       $caps[] = 'do_not_allow';
-               }
-               return $caps;
-       }
-
-       /**
-        * Test enqueue_admin_scripts method.
-        *
-        * @covers WP_Widget_Text::enqueue_admin_scripts
-        */
-       function test_enqueue_admin_scripts() {
-               set_current_screen( 'widgets.php' );
-               $widget = new WP_Widget_Text();
-               $widget->enqueue_admin_scripts();
-
-               $this->assertTrue( wp_script_is( 'text-widgets' ) );
-       }
-
-       /**
-        * Test render_control_template_scripts method.
-        *
-        * @covers WP_Widget_Text::render_control_template_scripts
-        */
-       function test_render_control_template_scripts() {
-               ob_start();
-               WP_Widget_Text::render_control_template_scripts();
-               $output = ob_get_clean();
-
-               $this->assertStringContainsString( '<script type="text/html" id="tmpl-widget-text-control-fields">', $output );
-       }
-
-       /**
-        * Ensure that rel="noopener" is added to links with a target.
-        *
-        * @ticket 46421
-        */
-       function test_render_links_with_target() {
-               $widget = new WP_Widget_Text();
-
-               $text = 'Test content with an external <a href="https://example.org" target="_blank">link</a>.';
-
-               $args = array(
-                       'before_title'  => '<h2>',
-                       'after_title'   => '</h2>',
-                       'before_widget' => '',
-                       'after_widget'  => '',
-               );
-
-               $instance = array(
-                       'title' => 'Foo',
-                       'text'  => $text,
-               );
-
-               $output = get_echo( array( $widget, 'widget' ), array( $args, $instance ) );
-
-               $this->assertStringContainsString( 'rel="noopener"', $output );
-       }
-
-       /**
-        * Ensure that rel="noopener" is not added to links without a target.
-        *
-        * @ticket 46421
-        */
-       function test_render_links_without_target() {
-               $widget = new WP_Widget_Text();
-
-               $text = 'Test content with an internal <a href="/">link</a>.';
-
-               $args = array(
-                       'before_title'  => '<h2>',
-                       'after_title'   => '</h2>',
-                       'before_widget' => '',
-                       'after_widget'  => '',
-               );
-
-               $instance = array(
-                       'title' => 'Foo',
-                       'text'  => $text,
-               );
-
-               $output = get_echo( array( $widget, 'widget' ), array( $args, $instance ) );
-
-               $this->assertStringNotContainsString( 'rel="noopener"', $output );
-       }
-}
</del></span></pre></div>
<a id="trunktestsphpunittestswidgetswpWidgetCustomHtmlphpfromrev51492trunktestsphpunittestswidgetscustomhtmlwidgetphp"></a>
<div class="copfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Copied: trunk/tests/phpunit/tests/widgets/wpWidgetCustomHtml.php (from rev 51492, trunk/tests/phpunit/tests/widgets/custom-html-widget.php)</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/widgets/wpWidgetCustomHtml.php                          (rev 0)
+++ trunk/tests/phpunit/tests/widgets/wpWidgetCustomHtml.php    2021-07-26 19:25:09 UTC (rev 51493)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,358 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * Unit tests covering WP_Widget_Custom_HTML functionality.
+ *
+ * @package    WordPress
+ * @subpackage widgets
+ */
+
+/**
+ * Test wp-includes/widgets/class-wp-widget-custom-html.php
+ *
+ * @group widgets
+ */
+class Tests_Widgets_wpWidgetCustomHtml extends WP_UnitTestCase {
+
+       /**
+        * Args passed to the widget_custom_html_content filter.
+        *
+        * @var array
+        */
+       protected $widget_custom_html_content_args;
+
+       /**
+        * Args passed to the widget_text filter.
+        *
+        * @var array
+        */
+       protected $widget_text_args;
+
+       /**
+        * Clean up global scope.
+        *
+        * @global WP_Scripts $wp_scripts
+        * @global WP_Styles  $wp_style
+        */
+       public function clean_up_global_scope() {
+               global $wp_scripts, $wp_styles;
+               parent::clean_up_global_scope();
+               $wp_scripts = null;
+               $wp_styles  = null;
+       }
+
+       /**
+        * Test construct.
+        *
+        * @covers WP_Widget_Custom_HTML::__construct
+        */
+       public function test_construct() {
+               $widget = new WP_Widget_Custom_HTML();
+               $this->assertSame( 'custom_html', $widget->id_base );
+               $this->assertSame( 'widget_custom_html', $widget->widget_options['classname'] );
+               $this->assertSame( 400, $widget->control_options['width'] );
+               $this->assertSame( 350, $widget->control_options['height'] );
+               $this->assertTrue( $widget->widget_options['customize_selective_refresh'] );
+       }
+
+       /**
+        * Test enqueue_admin_scripts method.
+        *
+        * @covers WP_Widget_Custom_HTML::_register
+        */
+       public function test__register() {
+               set_current_screen( 'widgets.php' );
+               $widget = new WP_Widget_Custom_HTML();
+               $widget->_register();
+
+               $this->assertSame( 10, has_action( 'admin_print_scripts-widgets.php', array( $widget, 'enqueue_admin_scripts' ) ) );
+               $this->assertSame( 10, has_action( 'admin_footer-widgets.php', array( 'WP_Widget_Custom_HTML', 'render_control_template_scripts' ) ) );
+               $this->assertSame( 10, has_action( 'admin_head-widgets.php', array( 'WP_Widget_Custom_HTML', 'add_help_text' ) ) );
+               $this->assertContains( 'wp.customHtmlWidgets.idBases.push( "custom_html" );', wp_scripts()->registered['custom-html-widgets']->extra['after'] );
+       }
+
+       /**
+        * Test widget method.
+        *
+        * @covers WP_Widget_Custom_HTML::widget
+        */
+       public function test_widget() {
+               $widget  = new WP_Widget_Custom_HTML();
+               $content = "<i>Custom HTML</i>\n\n<b>CODE</b>\nLast line.<u>unclosed";
+
+               $args     = array(
+                       'before_title'  => '<h2>',
+                       'after_title'   => "</h2>\n",
+                       'before_widget' => '<section id="custom_html-5" class="widget widget_custom_html">',
+                       'after_widget'  => "</section>\n",
+               );
+               $instance = array(
+                       'title'   => 'Foo',
+                       'content' => $content,
+               );
+
+               // Convert Custom HTML widget instance into Text widget instance data.
+               $text_widget_instance = array_merge(
+                       $instance,
+                       array(
+                               'text'   => $instance['content'],
+                               'filter' => false,
+                               'visual' => false,
+                       )
+               );
+               unset( $text_widget_instance['content'] );
+
+               update_option( 'use_balanceTags', 0 );
+               add_filter( 'widget_custom_html_content', array( $this, 'filter_widget_custom_html_content' ), 5, 3 );
+               add_filter( 'widget_text', array( $this, 'filter_widget_text' ), 10, 3 );
+               ob_start();
+               $this->widget_custom_html_content_args = null;
+               $this->widget_text_args                = null;
+               $widget->widget( $args, $instance );
+               $output = ob_get_clean();
+               $this->assertNotEmpty( $this->widget_custom_html_content_args );
+               $this->assertNotEmpty( $this->widget_text_args );
+               $this->assertStringContainsString( '[filter:widget_text][filter:widget_custom_html_content]', $output );
+               $this->assertStringContainsString( '<section id="custom_html-5" class="widget_text widget widget_custom_html">', $output );
+               $this->assertStringContainsString( '<div class="textwidget custom-html-widget">', $output );
+               $this->assertStringNotContainsString( '<p>', $output );
+               $this->assertStringNotContainsString( '<br>', $output );
+               $this->assertStringNotContainsString( '</u>', $output );
+               $this->assertSame( $text_widget_instance, $this->widget_text_args[1] );
+               $this->assertSame( $instance, $this->widget_custom_html_content_args[1] );
+               $this->assertSame( $widget, $this->widget_text_args[2] );
+               $this->assertSame( $widget, $this->widget_custom_html_content_args[2] );
+               remove_filter( 'widget_custom_html_content', array( $this, 'filter_widget_custom_html_content' ), 5 );
+               remove_filter( 'widget_text', array( $this, 'filter_widget_text' ), 10 );
+
+               update_option( 'use_balanceTags', 1 );
+               ob_start();
+               $widget->widget( $args, $instance );
+               $output = ob_get_clean();
+               $this->assertStringContainsString( '</u>', $output );
+       }
+
+       /**
+        * Filters the content of the Custom HTML widget using the legacy widget_text filter.
+        *
+        * @param string                $text     The widget content.
+        * @param array                 $instance Array of settings for the current widget.
+        * @param WP_Widget_Custom_HTML $widget   Current widget instance.
+        * @return string Widget content.
+        */
+       public function filter_widget_text( $text, $instance, $widget ) {
+               $this->widget_text_args = array( $text, $instance, $widget );
+               $text                  .= '[filter:widget_text]';
+               return $text;
+       }
+
+       /**
+        * Filters the content of the Custom HTML widget using the dedicated widget_custom_html_content filter.
+        *
+        * @param string                $widget_content The widget content.
+        * @param array                 $instance       Array of settings for the current widget.
+        * @param WP_Widget_Custom_HTML $widget         Current Custom HTML widget instance.
+        * @return string Widget content.
+        */
+       public function filter_widget_custom_html_content( $widget_content, $instance, $widget ) {
+               $this->widget_custom_html_content_args = array( $widget_content, $instance, $widget );
+               $widget_content                       .= '[filter:widget_custom_html_content]';
+               return $widget_content;
+       }
+
+       /**
+        * Test update method.
+        *
+        * @covers WP_Widget_Custom_HTML::update
+        */
+       public function test_update() {
+               $widget   = new WP_Widget_Custom_HTML();
+               $instance = array(
+                       'title'   => "The\n<b>Title</b>",
+                       'content' => "The\n\n<b>Code</b>",
+               );
+
+               wp_set_current_user(
+                       $this->factory()->user->create(
+                               array(
+                                       'role' => 'administrator',
+                               )
+                       )
+               );
+
+               // Should return valid instance.
+               $expected = array(
+                       'title'   => sanitize_text_field( $instance['title'] ),
+                       'content' => $instance['content'],
+               );
+               $result   = $widget->update( $instance, array() );
+               $this->assertSame( $result, $expected );
+
+               // Make sure KSES is applying as expected.
+               add_filter( 'map_meta_cap', array( $this, 'grant_unfiltered_html_cap' ), 10, 2 );
+               $this->assertTrue( current_user_can( 'unfiltered_html' ) );
+               $instance['content'] = '<script>alert( "Howdy!" );</script>';
+               $expected['content'] = $instance['content'];
+               $result              = $widget->update( $instance, array() );
+               $this->assertSame( $result, $expected );
+               remove_filter( 'map_meta_cap', array( $this, 'grant_unfiltered_html_cap' ) );
+
+               add_filter( 'map_meta_cap', array( $this, 'revoke_unfiltered_html_cap' ), 10, 2 );
+               $this->assertFalse( current_user_can( 'unfiltered_html' ) );
+               $instance['content'] = '<script>alert( "Howdy!" );</script>';
+               $expected['content'] = wp_kses_post( $instance['content'] );
+               $result              = $widget->update( $instance, array() );
+               $this->assertSame( $result, $expected );
+               remove_filter( 'map_meta_cap', array( $this, 'revoke_unfiltered_html_cap' ), 10 );
+       }
+
+       /**
+        * Grant unfiltered_html cap via map_meta_cap.
+        *
+        * @param array  $caps    Returns the user's actual capabilities.
+        * @param string $cap     Capability name.
+        * @return array Caps.
+        */
+       public function grant_unfiltered_html_cap( $caps, $cap ) {
+               if ( 'unfiltered_html' === $cap ) {
+                       $caps   = array_diff( $caps, array( 'do_not_allow' ) );
+                       $caps[] = 'unfiltered_html';
+               }
+               return $caps;
+       }
+
+       /**
+        * Revoke unfiltered_html cap via map_meta_cap.
+        *
+        * @param array  $caps    Returns the user's actual capabilities.
+        * @param string $cap     Capability name.
+        * @return array Caps.
+        */
+       public function revoke_unfiltered_html_cap( $caps, $cap ) {
+               if ( 'unfiltered_html' === $cap ) {
+                       $caps   = array_diff( $caps, array( 'unfiltered_html' ) );
+                       $caps[] = 'do_not_allow';
+               }
+               return $caps;
+       }
+
+       /**
+        * Test enqueue_admin_scripts method. Condition: logged_in, syntax_highlighting is on.
+        *
+        * @covers WP_Widget_Custom_HTML::enqueue_admin_scripts
+        */
+       public function test_enqueue_admin_scripts_when_logged_in_and_syntax_highlighting_on() {
+               $user = $this->factory()->user->create();
+               wp_set_current_user( $user );
+               wp_get_current_user()->syntax_highlighting = 'true';
+               set_current_screen( 'widgets.php' );
+               $widget = new WP_Widget_Custom_HTML();
+               $widget->enqueue_admin_scripts();
+
+               $this->assertTrue( wp_script_is( 'custom-html-widgets', 'enqueued' ) );
+               $this->assertTrue( wp_script_is( 'code-editor', 'enqueued' ) );
+               $this->assertTrue( wp_script_is( 'wp-codemirror', 'enqueued' ) );
+               $this->assertTrue( wp_script_is( 'csslint', 'enqueued' ) );
+               $this->assertTrue( wp_script_is( 'jshint', 'enqueued' ) );
+               $this->assertTrue( wp_script_is( 'htmlhint', 'enqueued' ) );
+       }
+
+       /**
+        * Test enqueue_admin_scripts method. Condition: logged_in, syntax_highlighting is off.
+        *
+        * @covers WP_Widget_Custom_HTML::enqueue_admin_scripts
+        */
+       public function test_enqueue_admin_scripts_when_logged_in_and_syntax_highlighting_off() {
+               $user = $this->factory()->user->create();
+               wp_set_current_user( $user );
+               update_user_meta( $user, 'syntax_highlighting', 'false' );
+               set_current_screen( 'widgets.php' );
+               $widget = new WP_Widget_Custom_HTML();
+               $widget->enqueue_admin_scripts();
+
+               $this->assertTrue( wp_script_is( 'custom-html-widgets', 'enqueued' ) );
+               $this->assertFalse( wp_script_is( 'code-editor', 'enqueued' ) );
+               $this->assertFalse( wp_script_is( 'wp-codemirror', 'enqueued' ) );
+               $this->assertFalse( wp_script_is( 'csslint', 'enqueued' ) );
+               $this->assertFalse( wp_script_is( 'jshint', 'enqueued' ) );
+               $this->assertFalse( wp_script_is( 'htmlhint', 'enqueued' ) );
+       }
+
+       /**
+        * Test render_control_template_scripts method.
+        *
+        * @covers WP_Widget_Custom_HTML::render_control_template_scripts
+        */
+       public function test_render_control_template_scripts() {
+               ob_start();
+               WP_Widget_Custom_HTML::render_control_template_scripts();
+               $output = ob_get_clean();
+
+               $this->assertStringContainsString( '<script type="text/html" id="tmpl-widget-custom-html-control-fields">', $output );
+       }
+
+       /**
+        * Test add_help_text method.
+        *
+        * @covers WP_Widget_Custom_HTML::add_help_text
+        */
+       public function test_add_help_text() {
+               set_current_screen( 'widgets.php' );
+               WP_Widget_Custom_HTML::add_help_text();
+               $help_tab = get_current_screen()->get_help_tab( 'custom_html_widget' );
+
+               $this->assertStringContainsString( 'Use the Custom HTML widget to add arbitrary HTML code to your widget areas.', $help_tab['content'] );
+       }
+
+       /**
+        * Ensure that rel="noopener" is added to links with a target.
+        *
+        * @ticket 46421
+        */
+       function test_render_links_with_target() {
+               $widget = new WP_Widget_Custom_HTML();
+
+               $content = 'Test content with an external <a href="https://example.org" target="_blank">link</a>.';
+
+               $args = array(
+                       'before_title'  => '<h2>',
+                       'after_title'   => '</h2>',
+                       'before_widget' => '',
+                       'after_widget'  => '',
+               );
+
+               $instance = array(
+                       'title'   => 'Foo',
+                       'content' => $content,
+               );
+
+               $output = get_echo( array( $widget, 'widget' ), array( $args, $instance ) );
+               $this->assertStringContainsString( 'rel="noopener"', $output );
+       }
+
+       /**
+        * Ensure that rel="noopener" is not added to links without a target.
+        *
+        * @ticket 46421
+        */
+       function test_render_links_without_target() {
+               $widget = new WP_Widget_Custom_HTML();
+
+               $content = 'Test content with an internal <a href="/">link</a>.';
+
+               $args = array(
+                       'before_title'  => '<h2>',
+                       'after_title'   => '</h2>',
+                       'before_widget' => '',
+                       'after_widget'  => '',
+               );
+
+               $instance = array(
+                       'title'   => 'Foo',
+                       'content' => $content,
+               );
+
+               $output = get_echo( array( $widget, 'widget' ), array( $args, $instance ) );
+               $this->assertStringNotContainsString( 'rel="noopener"', $output );
+       }
+
+}
</ins></span></pre></div>
<a id="trunktestsphpunittestswidgetswpWidgetMediaphpfromrev51492trunktestsphpunittestswidgetsmediawidgetphp"></a>
<div class="copfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Copied: trunk/tests/phpunit/tests/widgets/wpWidgetMedia.php (from rev 51492, trunk/tests/phpunit/tests/widgets/media-widget.php)</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/widgets/wpWidgetMedia.php                               (rev 0)
+++ trunk/tests/phpunit/tests/widgets/wpWidgetMedia.php 2021-07-26 19:25:09 UTC (rev 51493)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,525 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * Unit tests covering WP_Widget_Media functionality.
+ *
+ * @package    WordPress
+ * @subpackage widgets
+ */
+
+/**
+ * Test wp-includes/widgets/class-wp-widget-media.php
+ *
+ * @group widgets
+ */
+class Tests_Widgets_wpWidgetMedia extends WP_UnitTestCase {
+
+       /**
+        * Clean up global scope.
+        *
+        * @global WP_Scripts $wp_scripts
+        * @global WP_Styles $wp_styles
+        */
+       function clean_up_global_scope() {
+               global $wp_scripts, $wp_styles;
+               parent::clean_up_global_scope();
+               $wp_scripts = null;
+               $wp_styles  = null;
+       }
+
+       /**
+        * Get instance for mocked media widget class.
+        *
+        * @param string $id_base         Base ID for the widget, lowercase and unique.
+        * @param string $name            Name for the widget displayed on the configuration page.
+        * @param array  $widget_options  Optional. Widget options.
+        * @param array  $control_options Optional. Widget control options.
+        * @return PHPUnit_Framework_MockObject_MockObject|WP_Widget_Media Mocked instance.
+        */
+       function get_mocked_class_instance( $id_base = 'mocked', $name = 'Mocked', $widget_options = array(), $control_options = array() ) {
+               $original_class_name       = 'WP_Widget_Media';
+               $arguments                 = array( $id_base, $name, $widget_options, $control_options );
+               $mock_class_name           = '';
+               $call_original_constructor = true;
+               $call_original_clone       = true;
+               $call_autoload             = true;
+               $mocked_methods            = array( 'render_media' );
+
+               return $this->getMockForAbstractClass( $original_class_name, $arguments, $mock_class_name, $call_original_constructor, $call_original_clone, $call_autoload, $mocked_methods );
+       }
+
+       /**
+        * Test constructor.
+        *
+        * @covers WP_Widget_Media::__construct
+        * @covers WP_Widget_Media::_register
+        */
+       function test_constructor() {
+               $widget = $this->get_mocked_class_instance();
+               $widget->_register();
+
+               $this->assertArrayHasKey( 'mime_type', $widget->widget_options );
+               $this->assertArrayHasKey( 'customize_selective_refresh', $widget->widget_options );
+               $this->assertArrayHasKey( 'description', $widget->widget_options );
+               $this->assertTrue( $widget->widget_options['customize_selective_refresh'] );
+               $this->assertEmpty( $widget->widget_options['mime_type'] );
+               $this->assertSameSets(
+                       array(
+                               'add_to_widget',
+                               'replace_media',
+                               'edit_media',
+                               'media_library_state_multi',
+                               'media_library_state_single',
+                               'missing_attachment',
+                               'no_media_selected',
+                               'add_media',
+                               'unsupported_file_type',
+                       ),
+                       array_keys( $widget->l10n )
+               );
+               $this->assertSame( count( $widget->l10n ), count( array_filter( $widget->l10n ) ), 'Expected all translation strings to be defined.' );
+               $this->assertSame( 10, has_action( 'admin_print_scripts-widgets.php', array( $widget, 'enqueue_admin_scripts' ) ) );
+               $this->assertFalse( has_action( 'wp_enqueue_scripts', array( $widget, 'enqueue_preview_scripts' ) ), 'Did not expect preview scripts to be enqueued when not in customize preview context.' );
+               $this->assertSame( 10, has_action( 'admin_footer-widgets.php', array( $widget, 'render_control_template_scripts' ) ) );
+
+               // With non-default args.
+               $id_base         = 'media_pdf';
+               $name            = 'PDF';
+               $widget_options  = array(
+                       'mime_type' => 'application/pdf',
+               );
+               $control_options = array(
+                       'width'  => 850,
+                       'height' => 1100,
+               );
+               $widget          = $this->get_mocked_class_instance( $id_base, $name, $widget_options, $control_options );
+               $this->assertSame( $id_base, $widget->id_base );
+               $this->assertSame( $name, $widget->name );
+
+               $this->assertArraySubset( $widget_options, $widget->widget_options );
+               $this->assertArraySubset( $control_options, $widget->control_options );
+       }
+
+       /**
+        * Test constructor in customize preview.
+        *
+        * @global WP_Customize_Manager $wp_customize
+        * @covers WP_Widget_Media::__construct
+        * @covers WP_Widget_Media::_register
+        */
+       function test_constructor_in_customize_preview() {
+               global $wp_customize;
+               wp_set_current_user(
+                       $this->factory()->user->create(
+                               array(
+                                       'role' => 'administrator',
+                               )
+                       )
+               );
+               require_once ABSPATH . WPINC . '/class-wp-customize-manager.php';
+               $wp_customize = new WP_Customize_Manager(
+                       array(
+                               'changeset_uuid' => wp_generate_uuid4(),
+                       )
+               );
+               $wp_customize->start_previewing_theme();
+
+               $widget = $this->get_mocked_class_instance();
+               $widget->_register();
+               $this->assertSame( 10, has_action( 'wp_enqueue_scripts', array( $widget, 'enqueue_preview_scripts' ) ) );
+       }
+
+       /**
+        * Test is_attachment_with_mime_type method.
+        *
+        * @covers WP_Widget_Media::is_attachment_with_mime_type
+        * @requires function imagejpeg
+        */
+       function test_is_attachment_with_mime_type() {
+
+               $test_image = get_temp_dir() . 'canola.jpg';
+               copy( DIR_TESTDATA . '/images/canola.jpg', $test_image );
+               $attachment_id = self::factory()->attachment->create_object(
+                       array(
+                               'file'           => $test_image,
+                               'post_parent'    => 0,
+                               'post_mime_type' => 'image/jpeg',
+                               'post_title'     => 'Canola',
+                       )
+               );
+               wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $test_image ) );
+               $widget = $this->get_mocked_class_instance();
+
+               $this->assertFalse( $widget->is_attachment_with_mime_type( 0, 'image' ) );
+               $this->assertFalse( $widget->is_attachment_with_mime_type( -123, 'image' ) );
+
+               $post_id = $this->factory()->post->create();
+               $this->assertFalse( $widget->is_attachment_with_mime_type( $post_id, 'image' ) );
+               $this->assertFalse( $widget->is_attachment_with_mime_type( $attachment_id, 'video' ) );
+               $this->assertTrue( $widget->is_attachment_with_mime_type( $attachment_id, 'image' ) );
+       }
+
+       /**
+        * Test sanitize_token_list method.
+        *
+        * @covers WP_Widget_Media::sanitize_token_list
+        */
+       function test_sanitize_token_list_string() {
+               $widget = $this->get_mocked_class_instance();
+
+               $result = $widget->sanitize_token_list( 'What A false class with-token <a href="#">and link</a>' );
+               $this->assertSame( 'What A false class with-token a hrefand linka', $result );
+
+               $result = $widget->sanitize_token_list( array( 'foo', '<i>bar', '">NO' ) );
+               $this->assertSame( $result, 'foo ibar NO' );
+       }
+
+       /**
+        * Instance schema args.
+        *
+        * @var array
+        */
+       protected $filter_instance_schema_args;
+
+       /**
+        * Filter instance schema.
+        *
+        * @param array           $schema Schema.
+        * @param WP_Widget_Media $widget Widget.
+        * @return array
+        */
+       public function filter_instance_schema( $schema, $widget ) {
+               $this->filter_instance_schema_args = compact( 'schema', 'widget' );
+               $schema['injected']                = array(
+                       'type' => 'boolean',
+               );
+               return $schema;
+       }
+
+       /**
+        * Test get_instance_schema method.
+        *
+        * @covers WP_Widget_Media::get_instance_schema
+        */
+       function test_get_instance_schema() {
+               $widget = $this->get_mocked_class_instance();
+               $schema = $widget->get_instance_schema();
+
+               $this->assertSameSets(
+                       array(
+                               'attachment_id',
+                               'title',
+                               'url',
+                       ),
+                       array_keys( $schema )
+               );
+
+               // Check filter usage.
+               $this->filter_instance_schema_args = null;
+               add_filter( 'widget_mocked_instance_schema', array( $this, 'filter_instance_schema' ), 10, 2 );
+               $schema = $widget->get_instance_schema();
+               $this->assertIsArray( $this->filter_instance_schema_args );
+               $this->assertSame( $widget, $this->filter_instance_schema_args['widget'] );
+               $this->assertSameSets( array( 'attachment_id', 'title', 'url' ), array_keys( $this->filter_instance_schema_args['schema'] ) );
+               $this->assertArrayHasKey( 'injected', $schema );
+       }
+
+       /**
+        * Test update method.
+        *
+        * @covers WP_Widget_Media::update
+        */
+       function test_update() {
+               $widget   = $this->get_mocked_class_instance();
+               $instance = array();
+
+               // Should return valid attachment ID.
+               $expected = array(
+                       'attachment_id' => 1,
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid attachment ID.
+               $result = $widget->update(
+                       array(
+                               'attachment_id' => 'media',
+                       ),
+                       $instance
+               );
+               $this->assertSame( $result, $instance );
+
+               // Should return valid attachment url.
+               $expected = array(
+                       'url' => 'https://example.org',
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid attachment url.
+               $result = $widget->update(
+                       array(
+                               'url' => 'not_a_url',
+                       ),
+                       $instance
+               );
+               $this->assertNotSame( $result, $instance );
+
+               // Should return valid attachment title.
+               $expected = array(
+                       'title' => 'What a title',
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid attachment title.
+               $result = $widget->update(
+                       array(
+                               'title' => '<h1>W00t!</h1>',
+                       ),
+                       $instance
+               );
+               $this->assertNotSame( $result, $instance );
+
+               // Should filter invalid key.
+               $result = $widget->update(
+                       array(
+                               'imaginary_key' => 'value',
+                       ),
+                       $instance
+               );
+               $this->assertSame( $result, $instance );
+
+               add_filter( 'sanitize_text_field', array( $this, '_return_wp_error' ) );
+               $result = $widget->update(
+                       array(
+                               'title' => 'Title',
+                       ),
+                       $instance
+               );
+               remove_filter( 'sanitize_text_field', array( $this, '_return_wp_error' ) );
+               $this->assertSame( $result, $instance );
+       }
+
+       /**
+        * Helper function for Test_WP_Widget_Media::test_update().
+        *
+        * @return \WP_Error
+        */
+       function _return_wp_error() {
+               return new WP_Error( 'some-error', 'This is not valid!' );
+       }
+
+       /**
+        * Test widget method.
+        *
+        * @covers WP_Widget_Media::widget
+        * @covers WP_Widget_Media::render_media
+        */
+       function test_widget() {
+               $args     = array(
+                       'before_title'  => '<h2>',
+                       'after_title'   => "</h2>\n",
+                       'before_widget' => '<section>',
+                       'after_widget'  => "</section>\n",
+               );
+               $instance = array(
+                       'title'         => 'Foo',
+                       'url'           => 'http://example.com/image.jpg',
+                       'attachment_id' => 0,
+               );
+
+               add_filter( 'widget_mocked_instance', array( $this, 'filter_widget_mocked_instance' ), 10, 3 );
+
+               ob_start();
+               $widget = $this->get_mocked_class_instance();
+               $widget->expects( $this->atLeastOnce() )->method( 'render_media' )->with( $instance );
+               $this->widget_instance_filter_args = array();
+               $widget->widget( $args, $instance );
+               $this->assertCount( 3, $this->widget_instance_filter_args );
+               $this->assertEquals( $instance, $this->widget_instance_filter_args[0] );
+               $this->assertSame( $args, $this->widget_instance_filter_args[1] );
+               $this->assertSame( $widget, $this->widget_instance_filter_args[2] );
+               $output = ob_get_clean();
+
+               $this->assertStringContainsString( '<h2>Foo</h2>', $output );
+               $this->assertStringContainsString( '<section>', $output );
+               $this->assertStringContainsString( '</section>', $output );
+
+               // No title.
+               ob_start();
+               $widget            = $this->get_mocked_class_instance();
+               $instance['title'] = '';
+               $widget->expects( $this->atLeastOnce() )->method( 'render_media' )->with( $instance );
+               $widget->widget( $args, $instance );
+               $output = ob_get_clean();
+               $this->assertStringNotContainsString( '<h2>Foo</h2>', $output );
+
+               // No attachment_id nor url.
+               $instance['url']           = '';
+               $instance['attachment_id'] = 0;
+               ob_start();
+               $widget = $this->get_mocked_class_instance();
+               $widget->widget( $args, $instance );
+               $output = ob_get_clean();
+               $this->assertEmpty( $output );
+       }
+
+       /**
+        * Args passed to the widget_{$id_base}_instance filter.
+        *
+        * @var array
+        */
+       protected $widget_instance_filter_args = array();
+
+       /**
+        * Filters the media widget instance prior to rendering the media.
+        *
+        * @param array           $instance Instance data.
+        * @param array           $args     Widget args.
+        * @param WP_Widget_Media $object   Widget object.
+        * @return array Instance.
+        */
+       function filter_widget_mocked_instance( $instance, $args, $object ) {
+               $this->widget_instance_filter_args = func_get_args();
+               return $instance;
+       }
+
+       /**
+        * Test form method.
+        *
+        * @covers WP_Widget_Media::form
+        */
+       function test_form() {
+               $widget = $this->get_mocked_class_instance();
+
+               ob_start();
+               $widget->form( array() );
+               $output = ob_get_clean();
+
+               $this->assertStringContainsString( 'name="widget-mocked[][attachment_id]"', $output );
+               $this->assertStringContainsString( 'name="widget-mocked[][title]"', $output );
+               $this->assertStringContainsString( 'name="widget-mocked[][url]"', $output );
+       }
+
+       /**
+        * Test display_media_state method.
+        *
+        * @covers WP_Widget_Media::display_media_state
+        */
+       function test_display_media_state() {
+               $widget        = $this->get_mocked_class_instance();
+               $attachment_id = self::factory()->attachment->create_object(
+                       array(
+                               'file'           => DIR_TESTDATA . '/images/canola.jpg',
+                               'post_parent'    => 0,
+                               'post_mime_type' => 'image/jpeg',
+                       )
+               );
+
+               $result = $widget->display_media_state( array(), get_post( $attachment_id ) );
+               $this->assertSameSets( array(), $result );
+
+               $widget->save_settings(
+                       array(
+                               array(
+                                       'attachment_id' => $attachment_id,
+                               ),
+                       )
+               );
+               $result = $widget->display_media_state( array(), get_post( $attachment_id ) );
+               $this->assertSameSets( array( $widget->l10n['media_library_state_single'] ), $result );
+
+               $widget->save_settings(
+                       array(
+                               array(
+                                       'attachment_id' => $attachment_id,
+                               ),
+                               array(
+                                       'attachment_id' => $attachment_id,
+                               ),
+                       )
+               );
+               $result = $widget->display_media_state( array(), get_post( $attachment_id ) );
+               $this->assertSameSets( array( sprintf( $widget->l10n['media_library_state_multi']['singular'], 2 ) ), $result );
+       }
+
+       /**
+        * Test enqueue_admin_scripts method.
+        *
+        * @covers WP_Widget_Media::enqueue_admin_scripts
+        */
+       function test_enqueue_admin_scripts() {
+               set_current_screen( 'widgets.php' );
+               $widget = $this->get_mocked_class_instance();
+               $widget->enqueue_admin_scripts();
+
+               $this->assertTrue( wp_script_is( 'media-widgets' ) );
+       }
+
+       /**
+        * Test render_control_template_scripts method.
+        *
+        * @covers WP_Widget_Media::render_control_template_scripts
+        */
+       function test_render_control_template_scripts() {
+               $widget = $this->get_mocked_class_instance();
+
+               ob_start();
+               $widget->render_control_template_scripts();
+               $output = ob_get_clean();
+
+               $this->assertStringContainsString( '<script type="text/html" id="tmpl-widget-media-mocked-control">', $output );
+       }
+
+       /**
+        * Test has_content method.
+        *
+        * @covers WP_Widget_Media::has_content
+        */
+       function test_has_content() {
+               $attachment_id = self::factory()->attachment->create_object(
+                       array(
+                               'file'           => DIR_TESTDATA . '/images/canola.jpg',
+                               'post_parent'    => 0,
+                               'post_mime_type' => 'image/jpeg',
+                       )
+               );
+
+               $wp_widget_media = new ReflectionClass( 'WP_Widget_Media' );
+               $has_content     = $wp_widget_media->getMethod( 'has_content' );
+               $has_content->setAccessible( true );
+
+               $result = $has_content->invokeArgs(
+                       $this->get_mocked_class_instance(),
+                       array(
+                               array(
+                                       'attachment_id' => 0,
+                                       'url'           => '',
+                               ),
+                       )
+               );
+               $this->assertFalse( $result );
+
+               $result = $has_content->invokeArgs(
+                       $this->get_mocked_class_instance(),
+                       array(
+                               array(
+                                       'attachment_id' => $attachment_id,
+                                       'url'           => '',
+                               ),
+                       )
+               );
+               $this->assertTrue( $result );
+
+               $result = $has_content->invokeArgs(
+                       $this->get_mocked_class_instance(),
+                       array(
+                               array(
+                                       'attachment_id' => 0,
+                                       'url'           => 'http://example.com/image.jpg',
+                               ),
+                       )
+               );
+               $this->assertTrue( $result );
+       }
+}
</ins></span></pre></div>
<a id="trunktestsphpunittestswidgetswpWidgetMediaAudiophpfromrev51492trunktestsphpunittestswidgetsmediaaudiowidgetphp"></a>
<div class="copfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Copied: trunk/tests/phpunit/tests/widgets/wpWidgetMediaAudio.php (from rev 51492, trunk/tests/phpunit/tests/widgets/media-audio-widget.php)</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/widgets/wpWidgetMediaAudio.php                          (rev 0)
+++ trunk/tests/phpunit/tests/widgets/wpWidgetMediaAudio.php    2021-07-26 19:25:09 UTC (rev 51493)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,327 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * Unit tests covering WP_Widget_Media_Audio functionality.
+ *
+ * @package    WordPress
+ * @subpackage widgets
+ */
+
+/**
+ * Test wp-includes/widgets/class-wp-widget-media-audio.php
+ *
+ * @group widgets
+ */
+class Tests_Widgets_wpWidgetMediaAudio extends WP_UnitTestCase {
+
+       /**
+        * Clean up global scope.
+        *
+        * @global WP_Scripts $wp_scripts
+        * @global WP_Styles $wp_styles
+        */
+       function clean_up_global_scope() {
+               global $wp_scripts, $wp_styles;
+               parent::clean_up_global_scope();
+               $wp_scripts = null;
+               $wp_styles  = null;
+       }
+
+       /**
+        * Test get_instance_schema method.
+        *
+        * @covers WP_Widget_Media_Audio::get_instance_schema
+        */
+       function test_get_instance_schema() {
+               $wp_widget_audio = new WP_Widget_Media_Audio();
+               $schema          = $wp_widget_audio->get_instance_schema();
+
+               $this->assertSameSets(
+                       array_merge(
+                               array(
+                                       'attachment_id',
+                                       'preload',
+                                       'loop',
+                                       'title',
+                                       'url',
+                               ),
+                               wp_get_audio_extensions()
+                       ),
+                       array_keys( $schema )
+               );
+       }
+
+       /**
+        * Test get_instance_schema filtering.
+        *
+        * @covers WP_Widget_Media_Audio::get_instance_schema
+        *
+        * @ticket 45029
+        */
+       function test_get_instance_schema_filtering() {
+               $wp_widget_audio = new WP_Widget_Media_Audio();
+               $schema          = $wp_widget_audio->get_instance_schema();
+
+               add_filter( 'widget_media_audio_instance_schema', array( $this, 'filter_instance_schema' ), 10, 2 );
+               $schema = $wp_widget_audio->get_instance_schema();
+
+               $this->assertTrue( $schema['loop']['default'] );
+       }
+
+       /**
+        * Filters instance schema.
+        *
+        * @since 5.2.0
+        *
+        * @param array                 $schema Schema.
+        * @param WP_Widget_Media_Audio $widget Widget.
+        * @return array
+        */
+       public function filter_instance_schema( $schema, $widget ) {
+               // Override the default loop value (false).
+               $schema['loop']['default'] = true;
+               return $schema;
+       }
+
+       /**
+        * Test constructor.
+        *
+        * @covers WP_Widget_Media_Audio::__construct
+        */
+       function test_constructor() {
+               $widget = new WP_Widget_Media_Audio();
+
+               $this->assertArrayHasKey( 'mime_type', $widget->widget_options );
+               $this->assertArrayHasKey( 'customize_selective_refresh', $widget->widget_options );
+               $this->assertArrayHasKey( 'description', $widget->widget_options );
+               $this->assertTrue( $widget->widget_options['customize_selective_refresh'] );
+               $this->assertSame( 'audio', $widget->widget_options['mime_type'] );
+               $this->assertSameSets(
+                       array(
+                               'add_to_widget',
+                               'replace_media',
+                               'edit_media',
+                               'media_library_state_multi',
+                               'media_library_state_single',
+                               'missing_attachment',
+                               'no_media_selected',
+                               'add_media',
+                               'unsupported_file_type',
+                       ),
+                       array_keys( $widget->l10n )
+               );
+       }
+
+       /**
+        * Test get_instance_schema method.
+        *
+        * @covers WP_Widget_Media_Audio::update
+        */
+       function test_update() {
+               $widget   = new WP_Widget_Media_Audio();
+               $instance = array();
+
+               // Should return valid attachment ID.
+               $expected = array(
+                       'attachment_id' => 1,
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid attachment ID.
+               $result = $widget->update(
+                       array(
+                               'attachment_id' => 'media',
+                       ),
+                       $instance
+               );
+               $this->assertSame( $result, $instance );
+
+               // Should return valid attachment url.
+               $expected = array(
+                       'url' => 'https://chickenandribs.org',
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid attachment url.
+               $result = $widget->update(
+                       array(
+                               'url' => 'not_a_url',
+                       ),
+                       $instance
+               );
+               $this->assertNotSame( $result, $instance );
+               $this->assertStringStartsWith( 'http://', $result['url'] );
+
+               // Should return loop setting.
+               $expected = array(
+                       'loop' => true,
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid loop setting.
+               $result = $widget->update(
+                       array(
+                               'loop' => 'not-boolean',
+                       ),
+                       $instance
+               );
+               $this->assertSame( $result, $instance );
+
+               // Should return valid attachment title.
+               $expected = array(
+                       'title' => 'An audio sample of parrots',
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid attachment title.
+               $result = $widget->update(
+                       array(
+                               'title' => '<h1>Cute Baby Goats</h1>',
+                       ),
+                       $instance
+               );
+               $this->assertNotSame( $result, $instance );
+
+               // Should return valid preload setting.
+               $expected = array(
+                       'preload' => 'none',
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid preload setting.
+               $result = $widget->update(
+                       array(
+                               'preload' => 'nope',
+                       ),
+                       $instance
+               );
+               $this->assertSame( $result, $instance );
+
+               // Should filter invalid key.
+               $result = $widget->update(
+                       array(
+                               'h4x' => 'value',
+                       ),
+                       $instance
+               );
+               $this->assertSame( $result, $instance );
+       }
+
+       /**
+        * Test render_media method.
+        *
+        * @covers WP_Widget_Media_Audio::render_media
+        */
+       function test_render_media() {
+               $test_audio_file = __FILE__ . '../../data/uploads/small-audio.mp3';
+               $widget          = new WP_Widget_Media_Audio();
+               $attachment_id   = self::factory()->attachment->create_object(
+                       array(
+                               'file'           => $test_audio_file,
+                               'post_parent'    => 0,
+                               'post_mime_type' => 'audio/mp3',
+                               'post_title'     => 'Test Audio',
+                       )
+               );
+               wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $test_audio_file ) );
+
+               // Should be empty when there is no attachment_id.
+               ob_start();
+               $widget->render_media( array() );
+               $output = ob_get_clean();
+               $this->assertEmpty( $output );
+
+               // Should be empty when there is an invalid attachment_id.
+               ob_start();
+               $widget->render_media(
+                       array(
+                               'attachment_id' => 777,
+                       )
+               );
+               $output = ob_get_clean();
+               $this->assertEmpty( $output );
+
+               // Tests with audio from library.
+               ob_start();
+               $widget->render_media(
+                       array(
+                               'attachment_id' => $attachment_id,
+                       )
+               );
+               $output = ob_get_clean();
+
+               // Check default outputs.
+               $this->assertStringContainsString( 'preload="none"', $output );
+               $this->assertStringContainsString( 'class="wp-audio-shortcode"', $output );
+               $this->assertStringContainsString( 'small-audio.mp3', $output );
+
+               ob_start();
+               $widget->render_media(
+                       array(
+                               'attachment_id' => $attachment_id,
+                               'title'         => 'Funny',
+                               'preload'       => 'auto',
+                               'loop'          => true,
+                       )
+               );
+               $output = ob_get_clean();
+
+               // Custom attributes.
+               $this->assertStringContainsString( 'preload="auto"', $output );
+               $this->assertStringContainsString( 'loop="1"', $output );
+       }
+
+       /**
+        * Test enqueue_preview_scripts method.
+        *
+        * @global WP_Scripts $wp_scripts
+        * @global WP_Styles $wp_styles
+        * @covers WP_Widget_Media_Audio::enqueue_preview_scripts
+        */
+       function test_enqueue_preview_scripts() {
+               global $wp_scripts, $wp_styles;
+               $wp_scripts = null;
+               $wp_styles  = null;
+               $widget     = new WP_Widget_Media_Audio();
+
+               $this->assertFalse( wp_script_is( 'wp-mediaelement' ) );
+               $this->assertFalse( wp_style_is( 'wp-mediaelement' ) );
+
+               $widget->enqueue_preview_scripts();
+
+               $this->assertTrue( wp_script_is( 'wp-mediaelement' ) );
+               $this->assertTrue( wp_style_is( 'wp-mediaelement' ) );
+       }
+
+       /**
+        * Test enqueue_admin_scripts method.
+        *
+        * @covers WP_Widget_Media_Audio::enqueue_admin_scripts
+        */
+       function test_enqueue_admin_scripts() {
+               set_current_screen( 'widgets.php' );
+               $widget = new WP_Widget_Media_Audio();
+               $widget->enqueue_admin_scripts();
+
+               $this->assertTrue( wp_script_is( 'media-audio-widget' ) );
+       }
+
+       /**
+        * Test render_control_template_scripts method.
+        *
+        * @covers WP_Widget_Media_Audio::render_control_template_scripts
+        */
+       function test_render_control_template_scripts() {
+               $widget = new WP_Widget_Media_Audio();
+
+               ob_start();
+               $widget->render_control_template_scripts();
+               $output = ob_get_clean();
+
+               $this->assertStringContainsString( '<script type="text/html" id="tmpl-wp-media-widget-audio-preview">', $output );
+       }
+}
</ins></span></pre></div>
<a id="trunktestsphpunittestswidgetswpWidgetMediaGalleryphpfromrev51492trunktestsphpunittestswidgetsmediagallerywidgetphp"></a>
<div class="copfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Copied: trunk/tests/phpunit/tests/widgets/wpWidgetMediaGallery.php (from rev 51492, trunk/tests/phpunit/tests/widgets/media-gallery-widget.php)</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/widgets/wpWidgetMediaGallery.php                                (rev 0)
+++ trunk/tests/phpunit/tests/widgets/wpWidgetMediaGallery.php  2021-07-26 19:25:09 UTC (rev 51493)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,204 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * Unit tests covering WP_Widget_Media_Gallery functionality.
+ *
+ * @package    WordPress
+ * @subpackage widgets
+ */
+
+/**
+ * Test wp-includes/widgets/class-wp-widget-media-gallery.php
+ *
+ * @group widgets
+ */
+class Tests_Widgets_wpWidgetMediaGallery extends WP_UnitTestCase {
+
+       /**
+        * Clean up global scope.
+        *
+        * @global WP_Scripts $wp_scripts
+        * @global WP_Styles $wp_styles
+        */
+       public function clean_up_global_scope() {
+               global $wp_scripts, $wp_styles;
+               parent::clean_up_global_scope();
+               $wp_scripts = null;
+               $wp_styles  = null;
+       }
+
+       /**
+        * Test get_instance_schema method.
+        *
+        * @covers WP_Widget_Media_Gallery::get_instance_schema
+        */
+       public function test_get_instance_schema() {
+               $widget = new WP_Widget_Media_Gallery();
+               $schema = $widget->get_instance_schema();
+
+               $this->assertSameSets(
+                       array(
+                               'title',
+                               'ids',
+                               'columns',
+                               'size',
+                               'link_type',
+                               'orderby_random',
+                       ),
+                       array_keys( $schema )
+               );
+       }
+
+       /**
+        * Test update() method.
+        *
+        * @covers WP_Widget_Media_Gallery::render_media
+        * @requires function imagejpeg
+        */
+       public function test_render_media() {
+               $widget = new WP_Widget_Media_Gallery();
+
+               $attachments = array();
+               foreach ( array( 'canola.jpg', 'waffles.jpg' ) as $filename ) {
+                       $test_image = get_temp_dir() . $filename;
+                       copy( DIR_TESTDATA . '/images/canola.jpg', $test_image );
+                       $attachment_id = self::factory()->attachment->create_object(
+                               array(
+                                       'file'           => $test_image,
+                                       'post_parent'    => 0,
+                                       'post_mime_type' => 'image/jpeg',
+                                       'post_title'     => 'Canola',
+                               )
+                       );
+                       wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $test_image ) );
+                       $attachments[ $filename ] = $attachment_id;
+               }
+
+               $instance            = wp_list_pluck( $widget->get_instance_schema(), 'default' );
+               $instance['size']    = 'thumbnail';
+               $instance['columns'] = 3;
+               $instance['ids']     = array_values( $attachments );
+               ob_start();
+               $widget->render_media( $instance );
+               $output = ob_get_clean();
+
+               $this->assertStringContainsString( 'gallery-columns-3', $output );
+               $this->assertStringContainsString( 'gallery-size-thumbnail', $output );
+               $this->assertStringContainsString( 'canola', $output );
+               $this->assertStringContainsString( 'waffles', $output );
+       }
+
+       /**
+        * Test enqueue_admin_scripts() method.
+        *
+        * @covers WP_Widget_Media_Gallery::enqueue_admin_scripts
+        */
+       public function test_enqueue_admin_scripts() {
+               set_current_screen( 'widgets.php' );
+               $widget = new WP_Widget_Media_Gallery();
+
+               $this->assertFalse( wp_script_is( 'media-gallery-widget' ) );
+
+               $widget->enqueue_admin_scripts();
+
+               $this->assertTrue( wp_script_is( 'media-gallery-widget' ) );
+
+               $after = implode( '', wp_scripts()->registered['media-gallery-widget']->extra['after'] );
+               $this->assertStringContainsString( 'wp.mediaWidgets.modelConstructors[ "media_gallery" ].prototype', $after );
+       }
+
+       /**
+        * Test update() method.
+        *
+        * @covers WP_Widget_Media_Gallery::update
+        */
+       public function test_update() {
+               $widget   = new WP_Widget_Media_Gallery();
+               $schema   = $widget->get_instance_schema();
+               $instance = wp_list_pluck( $schema, 'default' );
+
+               // Field: title.
+               $instance['title'] = 'Hello <b>World</b> ';
+               $instance          = $widget->update( $instance, array() );
+               $this->assertSame( 'Hello World', $instance['title'] );
+
+               // Field: ids.
+               $instance['ids'] = '1,2,3';
+               $instance        = $widget->update( $instance, array() );
+               $this->assertSame( array( 1, 2, 3 ), $instance['ids'] );
+
+               $instance['ids'] = array( 1, 2, '3' );
+               $instance        = $widget->update( $instance, array() );
+               $this->assertSame( array( 1, 2, 3 ), $instance['ids'] );
+
+               $instance['ids'] = array( 'too', 'bad' );
+               $instance        = $widget->update( $instance, array( 'ids' => array( 2, 3 ) ) );
+               $this->assertSame( array( 2, 3 ), $instance['ids'] );
+
+               // Field: columns.
+               $instance['columns'] = 4;
+               $instance            = $widget->update( $instance, array() );
+               $this->assertSame( 4, $instance['columns'] );
+
+               $instance['columns'] = '2';
+               $instance            = $widget->update( $instance, array() );
+               $this->assertSame( 2, $instance['columns'] );
+
+               $instance['columns'] = -1; // Under min of 1.
+               $instance            = $widget->update( $instance, array( 'columns' => 3 ) );
+               $this->assertSame( 3, $instance['columns'] );
+
+               $instance['columns'] = 10; // Over max of 9.
+               $instance            = $widget->update( $instance, array( 'columns' => 3 ) );
+               $this->assertSame( 3, $instance['columns'] );
+
+               // Field: size.
+               $instance['size'] = 'large';
+               $instance         = $widget->update( $instance, array() );
+               $this->assertSame( 'large', $instance['size'] );
+
+               $instance['size'] = 'bad';
+               $instance         = $widget->update( $instance, array( 'size' => 'thumbnail' ) );
+               $this->assertSame( 'thumbnail', $instance['size'] );
+
+               // Field: link_type.
+               $instance['link_type'] = 'none';
+               $instance              = $widget->update( $instance, array() );
+               $this->assertSame( 'none', $instance['link_type'] );
+
+               $instance['link_type'] = 'unknown';
+               $instance              = $widget->update( $instance, array( 'link_type' => 'file' ) );
+               $this->assertSame( 'file', $instance['link_type'] );
+
+               // Field: orderby_random.
+               $instance['orderby_random'] = '1';
+               $instance                   = $widget->update( $instance, array() );
+               $this->assertTrue( $instance['orderby_random'] );
+
+               $instance['orderby_random'] = true;
+               $instance                   = $widget->update( $instance, array() );
+               $this->assertTrue( $instance['orderby_random'] );
+
+               $instance['orderby_random'] = '';
+               $instance                   = $widget->update( $instance, array() );
+               $this->assertFalse( $instance['orderby_random'] );
+
+               $instance['orderby_random'] = false;
+               $instance                   = $widget->update( $instance, array() );
+               $this->assertFalse( $instance['orderby_random'] );
+       }
+
+       /**
+        * Test render_control_template_scripts() method.
+        *
+        * @covers WP_Widget_Media_Gallery::render_control_template_scripts
+        */
+       public function test_render_control_template_scripts() {
+               $widget = new WP_Widget_Media_Gallery();
+
+               ob_start();
+               $widget->render_control_template_scripts();
+               $output = ob_get_clean();
+
+               $this->assertStringContainsString( '<script type="text/html" id="tmpl-wp-media-widget-gallery-preview">', $output );
+       }
+}
</ins></span></pre></div>
<a id="trunktestsphpunittestswidgetswpWidgetMediaImagephpfromrev51492trunktestsphpunittestswidgetsmediaimagewidgetphp"></a>
<div class="copfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Copied: trunk/tests/phpunit/tests/widgets/wpWidgetMediaImage.php (from rev 51492, trunk/tests/phpunit/tests/widgets/media-image-widget.php)</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/widgets/wpWidgetMediaImage.php                          (rev 0)
+++ trunk/tests/phpunit/tests/widgets/wpWidgetMediaImage.php    2021-07-26 19:25:09 UTC (rev 51493)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,633 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * Unit tests covering WP_Widget_Media_Image functionality.
+ *
+ * @package    WordPress
+ * @subpackage widgets
+ */
+
+/**
+ * Test wp-includes/widgets/class-wp-widget-media-image.php
+ *
+ * @group widgets
+ */
+class Tests_Widgets_wpWidgetMediaImage extends WP_UnitTestCase {
+
+       /**
+        * Clean up global scope.
+        *
+        * @global WP_Scripts $wp_scripts
+        * @global WP_Styles $wp_styles
+        */
+       function clean_up_global_scope() {
+               global $wp_scripts, $wp_styles;
+               parent::clean_up_global_scope();
+               $wp_scripts = null;
+               $wp_styles  = null;
+       }
+
+       /**
+        * Test get_instance_schema method.
+        *
+        * @covers WP_Widget_Media_Image::get_instance_schema
+        */
+       function test_get_instance_schema() {
+               $widget = new WP_Widget_Media_Image();
+               $schema = $widget->get_instance_schema();
+
+               $this->assertSameSets(
+                       array(
+                               'alt',
+                               'attachment_id',
+                               'caption',
+                               'height',
+                               'image_classes',
+                               'image_title',
+                               'link_classes',
+                               'link_rel',
+                               'link_target_blank',
+                               'link_type',
+                               'link_url',
+                               'size',
+                               'title',
+                               'url',
+                               'width',
+                       ),
+                       array_keys( $schema )
+               );
+       }
+
+       /**
+        * Test schema filtering.
+        *
+        * @covers WP_Widget_Media_Image::get_instance_schema
+        *
+        * @ticket 45029
+        */
+       function test_get_instance_schema_filtering() {
+               $widget = new WP_Widget_Media_Image();
+               $schema = $widget->get_instance_schema();
+
+               add_filter( 'widget_media_image_instance_schema', array( $this, 'filter_instance_schema' ), 10, 2 );
+               $schema = $widget->get_instance_schema();
+
+               $this->assertSame( 'large', $schema['size']['default'] );
+       }
+
+       /**
+        * Filters instance schema.
+        *
+        * @since 5.2.0
+        *
+        * @param array                 $schema Schema.
+        * @param WP_Widget_Media_Image $widget Widget.
+        * @return array
+        */
+       public function filter_instance_schema( $schema, $widget ) {
+               // Override the default size value ('medium').
+               $schema['size']['default'] = 'large';
+               return $schema;
+       }
+
+       /**
+        * Test constructor.
+        *
+        * @covers WP_Widget_Media_Image::__construct
+        */
+       function test_constructor() {
+               $widget = new WP_Widget_Media_Image();
+
+               $this->assertArrayHasKey( 'mime_type', $widget->widget_options );
+               $this->assertArrayHasKey( 'customize_selective_refresh', $widget->widget_options );
+               $this->assertArrayHasKey( 'description', $widget->widget_options );
+               $this->assertTrue( $widget->widget_options['customize_selective_refresh'] );
+               $this->assertSame( 'image', $widget->widget_options['mime_type'] );
+               $this->assertSameSets(
+                       array(
+                               'add_to_widget',
+                               'replace_media',
+                               'edit_media',
+                               'media_library_state_multi',
+                               'media_library_state_single',
+                               'missing_attachment',
+                               'no_media_selected',
+                               'add_media',
+                               'unsupported_file_type',
+                       ),
+                       array_keys( $widget->l10n )
+               );
+       }
+
+       /**
+        * Test get_instance_schema method.
+        *
+        * @covers WP_Widget_Media_Image::update
+        */
+       function test_update() {
+               $widget   = new WP_Widget_Media_Image();
+               $instance = array();
+
+               // Should return valid attachment ID.
+               $expected = array(
+                       'attachment_id' => 1,
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid attachment ID.
+               $result = $widget->update(
+                       array(
+                               'attachment_id' => 'media',
+                       ),
+                       $instance
+               );
+               $this->assertSame( $result, $instance );
+
+               // Should return valid attachment url.
+               $expected = array(
+                       'url' => 'https://example.org',
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid attachment url.
+               $result = $widget->update(
+                       array(
+                               'url' => 'not_a_url',
+                       ),
+                       $instance
+               );
+               $this->assertNotSame( $result, $instance );
+               $this->assertStringStartsWith( 'http://', $result['url'] );
+
+               // Should return valid attachment title.
+               $expected = array(
+                       'title' => 'What a title',
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid attachment title.
+               $result = $widget->update(
+                       array(
+                               'title' => '<h1>W00t!</h1>',
+                       ),
+                       $instance
+               );
+               $this->assertNotSame( $result, $instance );
+
+               // Should return valid image size.
+               $expected = array(
+                       'size' => 'thumbnail',
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid image size.
+               $result = $widget->update(
+                       array(
+                               'size' => 'big league',
+                       ),
+                       $instance
+               );
+               $this->assertSame( $result, $instance );
+
+               // Should return valid image width.
+               $expected = array(
+                       'width' => 300,
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid image width.
+               $result = $widget->update(
+                       array(
+                               'width' => 'wide',
+                       ),
+                       $instance
+               );
+               $this->assertSame( $result, $instance );
+
+               // Should return valid image height.
+               $expected = array(
+                       'height' => 200,
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid image height.
+               $result = $widget->update(
+                       array(
+                               'height' => 'high',
+                       ),
+                       $instance
+               );
+               $this->assertSame( $result, $instance );
+
+               // Should return valid image caption.
+               $expected = array(
+                       'caption' => 'A caption with <a href="#">link</a>',
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid image caption.
+               $result = $widget->update(
+                       array(
+                               'caption' => '"><i onload="alert(\'hello\')" />',
+                       ),
+                       $instance
+               );
+               $this->assertSame(
+                       $result,
+                       array(
+                               'caption' => '"&gt;<i />',
+                       )
+               );
+
+               // Should return valid alt text.
+               $expected = array(
+                       'alt' => 'A water tower',
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid alt text.
+               $result = $widget->update(
+                       array(
+                               'alt' => '"><i onload="alert(\'hello\')" />',
+                       ),
+                       $instance
+               );
+               $this->assertSame(
+                       $result,
+                       array(
+                               'alt' => '">',
+                       )
+               );
+
+               // Should return valid link type.
+               $expected = array(
+                       'link_type' => 'file',
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid link type.
+               $result = $widget->update(
+                       array(
+                               'link_type' => 'interesting',
+                       ),
+                       $instance
+               );
+               $this->assertSame( $result, $instance );
+
+               // Should return valid link url.
+               $expected = array(
+                       'link_url' => 'https://example.org',
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid link url.
+               $result = $widget->update(
+                       array(
+                               'link_url' => 'not_a_url',
+                       ),
+                       $instance
+               );
+               $this->assertNotSame( $result, $instance );
+               $this->assertStringStartsWith( 'http://', $result['link_url'] );
+
+               // Should return valid image classes.
+               $expected = array(
+                       'image_classes' => 'A water tower',
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid image classes.
+               $result = $widget->update(
+                       array(
+                               'image_classes' => '"><i onload="alert(\'hello\')" />',
+                       ),
+                       $instance
+               );
+               $this->assertSame(
+                       $result,
+                       array(
+                               'image_classes' => 'i onloadalerthello',
+                       )
+               );
+
+               // Should return valid link classes.
+               $expected = array(
+                       'link_classes' => 'A water tower',
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid link classes.
+               $result = $widget->update(
+                       array(
+                               'link_classes' => '"><i onload="alert(\'hello\')" />',
+                       ),
+                       $instance
+               );
+               $this->assertSame(
+                       $result,
+                       array(
+                               'link_classes' => 'i onloadalerthello',
+                       )
+               );
+
+               // Should return valid rel text.
+               $expected = array(
+                       'link_rel' => 'previous',
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid rel text.
+               $result = $widget->update(
+                       array(
+                               'link_rel' => '"><i onload="alert(\'hello\')" />',
+                       ),
+                       $instance
+               );
+               $this->assertSame(
+                       $result,
+                       array(
+                               'link_rel' => 'i onloadalerthello',
+                       )
+               );
+
+               // Should return valid link target.
+               $expected = array(
+                       'link_target_blank' => false,
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid  link target.
+               $result = $widget->update(
+                       array(
+                               'link_target_blank' => 'top',
+                       ),
+                       $instance
+               );
+               $this->assertSame( $result, $instance );
+
+               // Should return valid image title.
+               $expected = array(
+                       'image_title' => 'What a title',
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid image title.
+               $result = $widget->update(
+                       array(
+                               'image_title' => '<h1>W00t!</h1>',
+                       ),
+                       $instance
+               );
+               $this->assertNotSame( $result, $instance );
+
+               // Should filter invalid key.
+               $result = $widget->update(
+                       array(
+                               'imaginary_key' => 'value',
+                       ),
+                       $instance
+               );
+               $this->assertSame( $result, $instance );
+       }
+
+       /**
+        * Test render_media method.
+        *
+        * @covers WP_Widget_Media_Image::render_media
+        * @requires function imagejpeg
+        */
+       function test_render_media() {
+               $widget = new WP_Widget_Media_Image();
+
+               $test_image = get_temp_dir() . 'canola.jpg';
+               copy( DIR_TESTDATA . '/images/canola.jpg', $test_image );
+               $attachment_id = self::factory()->attachment->create_object(
+                       array(
+                               'file'           => $test_image,
+                               'post_parent'    => 0,
+                               'post_mime_type' => 'image/jpeg',
+                               'post_title'     => 'Canola',
+                       )
+               );
+               wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $test_image ) );
+
+               // Should be empty when there is no attachment_id.
+               ob_start();
+               $widget->render_media( array() );
+               $output = ob_get_clean();
+               $this->assertEmpty( $output );
+
+               // Should be empty when there is an invalid attachment_id.
+               ob_start();
+               $widget->render_media(
+                       array(
+                               'attachment_id' => 666,
+                       )
+               );
+               $output = ob_get_clean();
+               $this->assertEmpty( $output );
+
+               ob_start();
+               $widget->render_media(
+                       array(
+                               'attachment_id' => $attachment_id,
+                       )
+               );
+               $output = ob_get_clean();
+
+               // No default title.
+               $this->assertStringNotContainsString( 'title="', $output );
+               // Default image classes.
+               $this->assertStringContainsString( 'class="image wp-image-' . $attachment_id, $output );
+               $this->assertStringContainsString( 'style="max-width: 100%; height: auto;"', $output );
+               $this->assertStringContainsString( 'alt=""', $output );
+
+               ob_start();
+               $widget->render_media(
+                       array(
+                               'attachment_id' => $attachment_id,
+                               'image_title'   => 'Custom Title',
+                               'image_classes' => 'custom-class',
+                               'alt'           => 'A flower',
+                               'size'          => 'custom',
+                               'width'         => 100,
+                               'height'        => 100,
+                       )
+               );
+               $output = ob_get_clean();
+
+               // Custom image title.
+               $this->assertStringContainsString( 'title="Custom Title"', $output );
+               // Custom image class.
+               $this->assertStringContainsString( 'class="image wp-image-' . $attachment_id . ' custom-class', $output );
+               $this->assertStringContainsString( 'alt="A flower"', $output );
+               $this->assertStringContainsString( 'width="100"', $output );
+               $this->assertStringContainsString( 'height="100"', $output );
+
+               // Embeded images.
+               ob_start();
+               $widget->render_media(
+                       array(
+                               'attachment_id' => null,
+                               'caption'       => 'With caption',
+                               'height'        => 100,
+                               'link_type'     => 'file',
+                               'url'           => 'http://example.org/url/to/image.jpg',
+                               'width'         => 100,
+                       )
+               );
+               $output = ob_get_clean();
+
+               // Custom image class.
+               $this->assertStringContainsString( 'src="http://example.org/url/to/image.jpg"', $output );
+
+               // Link settings.
+               ob_start();
+               $widget->render_media(
+                       array(
+                               'attachment_id' => $attachment_id,
+                               'link_type'     => 'file',
+                       )
+               );
+               $output = ob_get_clean();
+
+               $link = '<a href="' . wp_get_attachment_url( $attachment_id ) . '"';
+               $this->assertStringContainsString( $link, $output );
+               $this->assertTrue( (bool) preg_match( '#<a href.*?>#', $output, $matches ) );
+               $this->assertStringNotContainsString( ' class="', $matches[0] );
+               $this->assertStringNotContainsString( ' rel="', $matches[0] );
+               $this->assertStringNotContainsString( ' target="', $matches[0] );
+
+               ob_start();
+               $widget->render_media(
+                       array(
+                               'attachment_id'     => $attachment_id,
+                               'link_type'         => 'post',
+                               'link_classes'      => 'custom-link-class',
+                               'link_rel'          => 'attachment',
+                               'link_target_blank' => false,
+                       )
+               );
+               $output = ob_get_clean();
+
+               $this->assertStringContainsString( '<a href="' . get_attachment_link( $attachment_id ) . '"', $output );
+               $this->assertStringContainsString( 'class="custom-link-class"', $output );
+               $this->assertStringContainsString( 'rel="attachment"', $output );
+               $this->assertStringNotContainsString( 'target=""', $output );
+
+               ob_start();
+               $widget->render_media(
+                       array(
+                               'attachment_id'     => $attachment_id,
+                               'link_type'         => 'custom',
+                               'link_url'          => 'https://example.org',
+                               'link_target_blank' => true,
+                       )
+               );
+               $output = ob_get_clean();
+
+               $this->assertStringContainsString( '<a href="https://example.org"', $output );
+               $this->assertStringContainsString( 'target="_blank"', $output );
+               $this->assertStringContainsString( 'rel="noopener"', $output );
+
+               // Populate caption in attachment.
+               wp_update_post(
+                       array(
+                               'ID'           => $attachment_id,
+                               'post_excerpt' => 'Default caption',
+                       )
+               );
+
+               // If no caption is supplied, then the default is '', and so the caption will not be displayed.
+               ob_start();
+               $widget->render_media(
+                       array(
+                               'attachment_id' => $attachment_id,
+                       )
+               );
+               $output = ob_get_clean();
+               $this->assertStringNotContainsString( 'wp-caption', $output );
+               $this->assertStringNotContainsString( '<p class="wp-caption-text">', $output );
+
+               // If the caption is explicitly null, then the caption of the underlying attachment will be displayed.
+               ob_start();
+               $widget->render_media(
+                       array(
+                               'attachment_id' => $attachment_id,
+                               'caption'       => null,
+                       )
+               );
+               $output = ob_get_clean();
+               $this->assertStringContainsString( 'class="wp-caption alignnone"', $output );
+               $this->assertStringContainsString( '<p class="wp-caption-text">Default caption</p>', $output );
+
+               // If caption is provided, then it will be displayed.
+               ob_start();
+               $widget->render_media(
+                       array(
+                               'attachment_id' => $attachment_id,
+                               'caption'       => 'Custom caption',
+                       )
+               );
+               $output = ob_get_clean();
+               $this->assertStringContainsString( 'class="wp-caption alignnone"', $output );
+               $this->assertStringContainsString( '<p class="wp-caption-text">Custom caption</p>', $output );
+
+               // Attachments with custom sizes can render captions.
+               ob_start();
+               $widget->render_media(
+                       array(
+                               'attachment_id' => $attachment_id,
+                               'size'          => 'custom',
+                               'width'         => '300',
+                               'height'        => '200',
+                               'caption'       => 'Caption for an image with custom size',
+                       )
+               );
+               $output = ob_get_clean();
+               $this->assertStringContainsString( 'style="width: 310px"', $output );
+               $this->assertStringContainsString( '<p class="wp-caption-text">Caption for an image with custom size</p>', $output );
+       }
+
+       /**
+        * Test enqueue_admin_scripts method.
+        *
+        * @covers WP_Widget_Media_Image::enqueue_admin_scripts
+        */
+       function test_enqueue_admin_scripts() {
+               set_current_screen( 'widgets.php' );
+               $widget = new WP_Widget_Media_Image();
+               $widget->enqueue_admin_scripts();
+
+               $this->assertTrue( wp_script_is( 'media-image-widget' ) );
+       }
+
+       /**
+        * Test render_control_template_scripts method.
+        *
+        * @covers WP_Widget_Media_Image::render_control_template_scripts
+        */
+       function test_render_control_template_scripts() {
+               $widget = new WP_Widget_Media_Image();
+
+               ob_start();
+               $widget->render_control_template_scripts();
+               $output = ob_get_clean();
+
+               $this->assertStringContainsString( '<script type="text/html" id="tmpl-wp-media-widget-image-preview">', $output );
+       }
+}
</ins></span></pre></div>
<a id="trunktestsphpunittestswidgetswpWidgetMediaVideophpfromrev51492trunktestsphpunittestswidgetsmediavideowidgetphp"></a>
<div class="copfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Copied: trunk/tests/phpunit/tests/widgets/wpWidgetMediaVideo.php (from rev 51492, trunk/tests/phpunit/tests/widgets/media-video-widget.php)</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/widgets/wpWidgetMediaVideo.php                          (rev 0)
+++ trunk/tests/phpunit/tests/widgets/wpWidgetMediaVideo.php    2021-07-26 19:25:09 UTC (rev 51493)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,355 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * Unit tests covering WP_Widget_Media_Video functionality.
+ *
+ * @package    WordPress
+ * @subpackage widgets
+ */
+
+/**
+ * Test wp-includes/widgets/class-wp-widget-media-video.php
+ *
+ * @group widgets
+ */
+class Tests_Widgets_wpWidgetMediaVideo extends WP_UnitTestCase {
+
+       /**
+        * Clean up global scope.
+        *
+        * @global WP_Scripts $wp_scripts
+        * @global WP_Styles $wp_styles
+        */
+       function clean_up_global_scope() {
+               global $wp_scripts, $wp_styles;
+               parent::clean_up_global_scope();
+               $wp_scripts = null;
+               $wp_styles  = null;
+       }
+
+       /**
+        * Test get_instance_schema method.
+        *
+        * @covers WP_Widget_Media_Video::get_instance_schema
+        */
+       function test_get_instance_schema() {
+               $widget = new WP_Widget_Media_Video();
+               $schema = $widget->get_instance_schema();
+
+               $this->assertSameSets(
+                       array_merge(
+                               array(
+                                       'attachment_id',
+                                       'preload',
+                                       'loop',
+                                       'title',
+                                       'url',
+                                       'content',
+                               ),
+                               wp_get_video_extensions()
+                       ),
+                       array_keys( $schema )
+               );
+       }
+
+       /**
+        * Test schema filtering.
+        *
+        * @covers WP_Widget_Media_Video::get_instance_schema
+        *
+        * @ticket 45029
+        */
+       function test_get_instance_schema_filtering() {
+               $widget = new WP_Widget_Media_Video();
+               $schema = $widget->get_instance_schema();
+
+               add_filter( 'widget_media_video_instance_schema', array( $this, 'filter_instance_schema' ), 10, 2 );
+               $schema = $widget->get_instance_schema();
+
+               $this->assertTrue( $schema['loop']['default'] );
+       }
+
+       /**
+        * Filters instance schema.
+        *
+        * @since 5.2.0
+        *
+        * @param array                 $schema Schema.
+        * @param WP_Widget_Media_Video $widget Widget.
+        * @return array
+        */
+       public function filter_instance_schema( $schema, $widget ) {
+               // Override the default loop value (false).
+               $schema['loop']['default'] = true;
+               return $schema;
+       }
+
+       /**
+        * Test constructor.
+        *
+        * @covers WP_Widget_Media_Video::__construct
+        */
+       function test_constructor() {
+               $widget = new WP_Widget_Media_Video();
+
+               $this->assertArrayHasKey( 'mime_type', $widget->widget_options );
+               $this->assertArrayHasKey( 'customize_selective_refresh', $widget->widget_options );
+               $this->assertArrayHasKey( 'description', $widget->widget_options );
+               $this->assertTrue( $widget->widget_options['customize_selective_refresh'] );
+               $this->assertSame( 'video', $widget->widget_options['mime_type'] );
+               $this->assertSameSets(
+                       array(
+                               'add_to_widget',
+                               'replace_media',
+                               'unsupported_file_type',
+                               'edit_media',
+                               'media_library_state_multi',
+                               'media_library_state_single',
+                               'missing_attachment',
+                               'no_media_selected',
+                               'add_media',
+                       ),
+                       array_keys( $widget->l10n )
+               );
+       }
+
+       /**
+        * Test get_instance_schema method.
+        *
+        * @covers WP_Widget_Media_Video::update
+        */
+       function test_update() {
+               $widget   = new WP_Widget_Media_Video();
+               $instance = array();
+
+               // Should return valid attachment ID.
+               $expected = array(
+                       'attachment_id' => 1,
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid attachment ID.
+               $result = $widget->update(
+                       array(
+                               'attachment_id' => 'media',
+                       ),
+                       $instance
+               );
+               $this->assertSame( $result, $instance );
+
+               // Should return valid attachment url.
+               $expected = array(
+                       'url' => 'https://chickenandribs.org',
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid attachment url.
+               $result = $widget->update(
+                       array(
+                               'url' => 'not_a_url',
+                       ),
+                       $instance
+               );
+               $this->assertNotSame( $result, $instance );
+               $this->assertStringStartsWith( 'http://', $result['url'] );
+
+               // Should return loop setting.
+               $expected = array(
+                       'loop' => true,
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid loop setting.
+               $result = $widget->update(
+                       array(
+                               'loop' => 'not-boolean',
+                       ),
+                       $instance
+               );
+               $this->assertSame( $result, $instance );
+
+               // Should return valid attachment title.
+               $expected = array(
+                       'title' => 'A video of goats',
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid attachment title.
+               $result = $widget->update(
+                       array(
+                               'title' => '<h1>Cute Baby Goats</h1>',
+                       ),
+                       $instance
+               );
+               $this->assertNotSame( $result, $instance );
+
+               // Should return valid preload setting.
+               $expected = array(
+                       'preload' => 'none',
+               );
+               $result   = $widget->update( $expected, $instance );
+               $this->assertSame( $result, $expected );
+
+               // Should filter invalid preload setting.
+               $result = $widget->update(
+                       array(
+                               'preload' => 'nope',
+                       ),
+                       $instance
+               );
+               $this->assertSame( $result, $instance );
+
+               // Should filter invalid key.
+               $result = $widget->update(
+                       array(
+                               'h4x' => 'value',
+                       ),
+                       $instance
+               );
+               $this->assertSame( $result, $instance );
+       }
+
+       /**
+        * Test render_media method.
+        *
+        * @covers WP_Widget_Media_Video::render_media
+        * @covers WP_Widget_Media_Video::inject_video_max_width_style
+        */
+       function test_render_media() {
+               $test_movie_file = __FILE__ . '../../data/uploads/small-video.m4v';
+               $widget          = new WP_Widget_Media_Video();
+               $attachment_id   = self::factory()->attachment->create_object(
+                       array(
+                               'file'           => $test_movie_file,
+                               'post_parent'    => 0,
+                               'post_mime_type' => 'video/mp4',
+                               'post_title'     => 'Test Video',
+                       )
+               );
+               wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $test_movie_file ) );
+
+               // Should be empty when there is no attachment_id.
+               ob_start();
+               $widget->render_media( array() );
+               $output = ob_get_clean();
+               $this->assertEmpty( $output );
+
+               // Should be empty when there is an invalid attachment_id.
+               ob_start();
+               $widget->render_media(
+                       array(
+                               'attachment_id' => 777,
+                       )
+               );
+               $output = ob_get_clean();
+               $this->assertEmpty( $output );
+
+               // Tests with video from library.
+               ob_start();
+               $widget->render_media(
+                       array(
+                               'attachment_id' => $attachment_id,
+                       )
+               );
+               $output = ob_get_clean();
+
+               // Check default outputs.
+               $this->assertStringContainsString( 'preload="metadata"', $output );
+               $this->assertStringContainsString( 'class="wp-video"', $output );
+               $this->assertStringContainsString( 'width:100%', $output );
+               $this->assertStringNotContainsString( 'height=', $output );
+               $this->assertStringNotContainsString( 'width="', $output );
+               $this->assertStringContainsString( 'small-video.m4v', $output );// Auto parses dimensions.
+
+               ob_start();
+               $widget->render_media(
+                       array(
+                               'attachment_id' => $attachment_id,
+                               'title'         => 'Open Source Cartoon',
+                               'preload'       => 'metadata',
+                               'loop'          => true,
+                       )
+               );
+               $output = ob_get_clean();
+
+               // Custom attributes.
+               $this->assertStringContainsString( 'preload="metadata"', $output );
+               $this->assertStringContainsString( 'loop="1"', $output );
+
+               // Externally hosted video.
+               ob_start();
+               $content = '<track srclang="en" label="English" kind="subtitles" src="http://example.com/wp-content/uploads/2017/04/subtitles-en.vtt">';
+               $widget->render_media(
+                       array(
+                               'attachment_id' => null,
+                               'loop'          => false,
+                               'url'           => 'https://www.youtube.com/watch?v=72xdCU__XCk',
+                               'content'       => $content,
+                       )
+               );
+               $output = ob_get_clean();
+
+               // Custom attributes.
+               $this->assertStringContainsString( 'preload="metadata"', $output );
+               $this->assertStringContainsString( 'src="https://www.youtube.com/watch?v=72xdCU__XCk', $output );
+               $this->assertStringContainsString( $content, $output );
+       }
+
+       /**
+        * Test enqueue_preview_scripts method.
+        *
+        * @global WP_Scripts $wp_scripts
+        * @global WP_Styles $wp_styles
+        * @covers WP_Widget_Media_Video::enqueue_preview_scripts
+        */
+       function test_enqueue_preview_scripts() {
+               global $wp_scripts, $wp_styles;
+               $widget = new WP_Widget_Media_Video();
+
+               $wp_scripts = null;
+               $wp_styles  = null;
+               $widget->enqueue_preview_scripts();
+               $this->assertTrue( wp_script_is( 'wp-mediaelement' ) );
+               $this->assertTrue( wp_style_is( 'wp-mediaelement' ) );
+               $this->assertTrue( wp_script_is( 'mediaelement-vimeo' ) );
+
+               $wp_scripts = null;
+               $wp_styles  = null;
+               add_filter( 'wp_video_shortcode_library', '__return_empty_string' );
+               $widget->enqueue_preview_scripts();
+               $this->assertFalse( wp_script_is( 'wp-mediaelement' ) );
+               $this->assertFalse( wp_style_is( 'wp-mediaelement' ) );
+               $this->assertFalse( wp_script_is( 'mediaelement-vimeo' ) );
+       }
+
+       /**
+        * Test enqueue_admin_scripts method.
+        *
+        * @covers WP_Widget_Media_Video::enqueue_admin_scripts
+        */
+       function test_enqueue_admin_scripts() {
+               set_current_screen( 'widgets.php' );
+               $widget = new WP_Widget_Media_Video();
+               $widget->enqueue_admin_scripts();
+
+               $this->assertTrue( wp_script_is( 'media-video-widget' ) );
+       }
+
+       /**
+        * Test render_control_template_scripts method.
+        *
+        * @covers WP_Widget_Media_Video::render_control_template_scripts
+        */
+       function test_render_control_template_scripts() {
+               $widget = new WP_Widget_Media_Video();
+
+               ob_start();
+               $widget->render_control_template_scripts();
+               $output = ob_get_clean();
+
+               $this->assertStringContainsString( '<script type="text/html" id="tmpl-wp-media-widget-video-preview">', $output );
+       }
+}
</ins></span></pre></div>
<a id="trunktestsphpunittestswidgetswpWidgetRssphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/widgets/wpWidgetRss.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/widgets/wpWidgetRss.php 2021-07-26 19:09:41 UTC (rev 51492)
+++ trunk/tests/phpunit/tests/widgets/wpWidgetRss.php   2021-07-26 19:25:09 UTC (rev 51493)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -11,7 +11,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">  *
</span><span class="cx" style="display: block; padding: 0 10px">  * @group widgets
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-class Test_Widgets_wpWidgetRss extends WP_UnitTestCase {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+class Tests_Widgets_wpWidgetRss extends WP_UnitTestCase {
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><span class="cx" style="display: block; padding: 0 10px">         * @ticket 53278
</span></span></pre></div>
<a id="trunktestsphpunittestswidgetswpWidgetTextphpfromrev51492trunktestsphpunittestswidgetstextwidgetphp"></a>
<div class="copfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Copied: trunk/tests/phpunit/tests/widgets/wpWidgetText.php (from rev 51492, trunk/tests/phpunit/tests/widgets/text-widget.php)</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/widgets/wpWidgetText.php                                (rev 0)
+++ trunk/tests/phpunit/tests/widgets/wpWidgetText.php  2021-07-26 19:25:09 UTC (rev 51493)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,1058 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+<?php
+/**
+ * Unit tests covering WP_Widget_Text functionality.
+ *
+ * @package    WordPress
+ * @subpackage widgets
+ */
+
+/**
+ * Test wp-includes/widgets/class-wp-widget-text.php
+ *
+ * @group widgets
+ */
+class Tests_Widgets_wpWidgetText extends WP_UnitTestCase {
+       /**
+        * Args passed to the widget_text filter.
+        *
+        * @var array
+        */
+       protected $widget_text_args;
+
+       /**
+        * Args passed to the widget_text_content filter.
+        *
+        * @var array
+        */
+       protected $widget_text_content_args;
+
+       /**
+        * Clean up global scope.
+        *
+        * @global WP_Scripts           $wp_scripts
+        * @global WP_Styles            $wp_style
+        * @global WP_Customize_Manager $wp_customize
+        */
+       function clean_up_global_scope() {
+               global $wp_scripts, $wp_styles, $wp_customize;
+               parent::clean_up_global_scope();
+               $wp_scripts   = null;
+               $wp_styles    = null;
+               $wp_customize = null;
+       }
+
+       /**
+        * Test constructor method.
+        *
+        * @covers WP_Widget_Text::__construct
+        */
+       function test_construct() {
+               $widget = new WP_Widget_Text();
+               $this->assertSame( 'text', $widget->id_base );
+               $this->assertSame( 'widget_text', $widget->widget_options['classname'] );
+               $this->assertTrue( $widget->widget_options['customize_selective_refresh'] );
+               $this->assertSame( 400, $widget->control_options['width'] );
+               $this->assertSame( 350, $widget->control_options['height'] );
+       }
+
+       /**
+        * Test enqueue_admin_scripts method.
+        *
+        * @covers WP_Widget_Text::_register
+        */
+       function test__register() {
+               set_current_screen( 'widgets.php' );
+               $widget = new WP_Widget_Text();
+               $widget->_register();
+
+               $this->assertSame( 10, has_action( 'admin_print_scripts-widgets.php', array( $widget, 'enqueue_admin_scripts' ) ) );
+               $this->assertSame( 10, has_action( 'admin_footer-widgets.php', array( 'WP_Widget_Text', 'render_control_template_scripts' ) ) );
+               $this->assertContains( 'wp.textWidgets.idBases.push( "text" );', wp_scripts()->registered['text-widgets']->extra['after'] );
+               $this->assertFalse( has_action( 'wp_enqueue_scripts', array( $widget, 'enqueue_preview_scripts' ) ) );
+       }
+
+       /**
+        * Test register in customize preview.
+        *
+        * @global WP_Customize_Manager $wp_customize
+        * @covers WP_Widget_Text::__construct
+        * @covers WP_Widget_Text::_register
+        */
+       function test__register_in_customize_preview() {
+               global $wp_customize;
+               wp_set_current_user(
+                       $this->factory()->user->create(
+                               array(
+                                       'role' => 'administrator',
+                               )
+                       )
+               );
+               require_once ABSPATH . WPINC . '/class-wp-customize-manager.php';
+               $wp_customize = new WP_Customize_Manager(
+                       array(
+                               'changeset_uuid' => wp_generate_uuid4(),
+                       )
+               );
+               $wp_customize->start_previewing_theme();
+
+               $widget = new WP_Widget_Text();
+               $widget->_register();
+               $this->assertSame( 10, has_action( 'wp_enqueue_scripts', array( $widget, 'enqueue_preview_scripts' ) ) );
+       }
+
+       /**
+        * Test enqueue_preview_scripts method.
+        *
+        * @global WP_Scripts $wp_scripts
+        * @global WP_Styles $wp_styles
+        * @covers WP_Widget_Text::enqueue_preview_scripts
+        */
+       function test_enqueue_preview_scripts() {
+               global $wp_scripts, $wp_styles;
+               $wp_scripts = null;
+               $wp_styles  = null;
+               $widget     = new WP_Widget_Text();
+
+               $this->assertFalse( wp_style_is( 'wp-mediaelement' ) );
+               $this->assertFalse( wp_script_is( 'wp-playlist' ) );
+
+               ob_start();
+               $widget->enqueue_preview_scripts();
+               ob_end_clean();
+
+               $this->assertTrue( wp_style_is( 'wp-mediaelement' ) );
+               $this->assertTrue( wp_script_is( 'wp-playlist' ) );
+       }
+
+       /**
+        * Test widget method.
+        *
+        * @covers WP_Widget_Text::widget
+        */
+       function test_widget() {
+               $widget = new WP_Widget_Text();
+               $text   = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n Praesent ut turpis consequat lorem volutpat bibendum vitae vitae ante.";
+
+               $args = array(
+                       'before_title'  => '<h2>',
+                       'after_title'   => "</h2>\n",
+                       'before_widget' => '<section>',
+                       'after_widget'  => "</section>\n",
+               );
+
+               add_filter( 'widget_text_content', array( $this, 'filter_widget_text_content' ), 5, 3 );
+               add_filter( 'widget_text', array( $this, 'filter_widget_text' ), 5, 3 );
+
+               // Test with filter=false, implicit legacy mode.
+               $this->widget_text_content_args = null;
+               ob_start();
+               $instance = array(
+                       'title'  => 'Foo',
+                       'text'   => $text,
+                       'filter' => false,
+               );
+               $widget->widget( $args, $instance );
+               $output = ob_get_clean();
+               $this->assertStringNotContainsString( '<p>', $output );
+               $this->assertStringNotContainsString( '<br />', $output );
+               $this->assertEmpty( $this->widget_text_content_args );
+               $this->assertNotEmpty( $this->widget_text_args );
+               $this->assertStringContainsString( '[filter:widget_text]', $output );
+               $this->assertStringNotContainsString( '[filter:widget_text_content]', $output );
+
+               // Test with filter=true, implicit legacy mode.
+               $this->widget_text_content_args = null;
+               $instance                       = array(
+                       'title'  => 'Foo',
+                       'text'   => $text,
+                       'filter' => true,
+               );
+               ob_start();
+               $widget->widget( $args, $instance );
+               $output = ob_get_clean();
+               $this->assertStringContainsString( '<p>', $output );
+               $this->assertStringContainsString( '<br />', $output );
+               $this->assertNotEmpty( $this->widget_text_args );
+               $this->assertSame( $instance['text'], $this->widget_text_args[0] );
+               $this->assertSame( $instance, $this->widget_text_args[1] );
+               $this->assertSame( $widget, $this->widget_text_args[2] );
+               $this->assertEmpty( $this->widget_text_content_args );
+               $this->assertStringContainsString( '[filter:widget_text]', $output );
+               $this->assertStringNotContainsString( '[filter:widget_text_content]', $output );
+
+               // Test with filter=content, the upgraded widget, in 4.8.0 only.
+               $this->widget_text_content_args = null;
+               $instance                       = array(
+                       'title'  => 'Foo',
+                       'text'   => $text,
+                       'filter' => 'content',
+               );
+               $expected_instance              = array_merge(
+                       $instance,
+                       array(
+                               'filter' => true,
+                               'visual' => true,
+                       )
+               );
+               ob_start();
+               $widget->widget( $args, $instance );
+               $output = ob_get_clean();
+               $this->assertStringContainsString( '<p>', $output );
+               $this->assertStringContainsString( '<br />', $output );
+               $this->assertCount( 3, $this->widget_text_args );
+               $this->assertSame( $expected_instance['text'], $this->widget_text_args[0] );
+               $this->assertSame( $expected_instance, $this->widget_text_args[1] );
+               $this->assertSame( $widget, $this->widget_text_args[2] );
+               $this->assertCount( 3, $this->widget_text_content_args );
+               $this->assertSame( $expected_instance['text'] . '[filter:widget_text]', $this->widget_text_content_args[0] );
+               $this->assertSame( $expected_instance, $this->widget_text_content_args[1] );
+               $this->assertSame( $widget, $this->widget_text_content_args[2] );
+               $this->assertStringContainsString( wpautop( $expected_instance['text'] . '[filter:widget_text][filter:widget_text_content]' ), $output );
+
+               // Test with filter=true&visual=true, the upgraded widget, in 4.8.1 and above.
+               $this->widget_text_content_args = null;
+               $instance                       = array(
+                       'title'  => 'Foo',
+                       'text'   => $text,
+                       'filter' => true,
+                       'visual' => true,
+               );
+               $expected_instance              = $instance;
+               ob_start();
+               $widget->widget( $args, $instance );
+               $output = ob_get_clean();
+               $this->assertStringContainsString( '<p>', $output );
+               $this->assertStringContainsString( '<br />', $output );
+               $this->assertCount( 3, $this->widget_text_args );
+               $this->assertSame( $expected_instance['text'], $this->widget_text_args[0] );
+               $this->assertSame( $expected_instance, $this->widget_text_args[1] );
+               $this->assertSame( $widget, $this->widget_text_args[2] );
+               $this->assertCount( 3, $this->widget_text_content_args );
+               $this->assertSame( $expected_instance['text'] . '[filter:widget_text]', $this->widget_text_content_args[0] );
+               $this->assertSame( $expected_instance, $this->widget_text_content_args[1] );
+               $this->assertSame( $widget, $this->widget_text_content_args[2] );
+               $this->assertStringContainsString( wpautop( $expected_instance['text'] . '[filter:widget_text][filter:widget_text_content]' ), $output );
+
+               // Test with filter=true&visual=true, the upgraded widget, in 4.8.1 and above.
+               $this->widget_text_content_args = null;
+               $instance                       = array(
+                       'title'  => 'Foo',
+                       'text'   => $text,
+                       'filter' => true,
+                       'visual' => false,
+               );
+               $expected_instance              = $instance;
+               ob_start();
+               $widget->widget( $args, $instance );
+               $output = ob_get_clean();
+               $this->assertStringContainsString( '<p>', $output );
+               $this->assertStringContainsString( '<br />', $output );
+               $this->assertCount( 3, $this->widget_text_args );
+               $this->assertSame( $expected_instance['text'], $this->widget_text_args[0] );
+               $this->assertSame( $expected_instance, $this->widget_text_args[1] );
+               $this->assertSame( $widget, $this->widget_text_args[2] );
+               $this->assertNull( $this->widget_text_content_args );
+               $this->assertStringContainsString( wpautop( $expected_instance['text'] . '[filter:widget_text]' ), $output );
+
+               // Test with filter=false&visual=false, the upgraded widget, in 4.8.1 and above.
+               $this->widget_text_content_args = null;
+               $instance                       = array(
+                       'title'  => 'Foo',
+                       'text'   => $text,
+                       'filter' => false,
+                       'visual' => false,
+               );
+               $expected_instance              = $instance;
+               ob_start();
+               $widget->widget( $args, $instance );
+               $output = ob_get_clean();
+               $this->assertStringNotContainsString( '<p>', $output );
+               $this->assertStringNotContainsString( '<br />', $output );
+               $this->assertCount( 3, $this->widget_text_args );
+               $this->assertSame( $expected_instance['text'], $this->widget_text_args[0] );
+               $this->assertSame( $expected_instance, $this->widget_text_args[1] );
+               $this->assertSame( $widget, $this->widget_text_args[2] );
+               $this->assertNull( $this->widget_text_content_args );
+               $this->assertStringContainsString( $expected_instance['text'] . '[filter:widget_text]', $output );
+       }
+
+       /**
+        * Example shortcode content to test for wpautop corruption.
+        *
+        * @var string
+        */
+       protected $example_shortcode_content = "<p class='sortcodep'>One\nTwo\n\nThree\n\nThis is testing the <code>[example note='This will not get processed since it is part of shortcode output itself.']</code> shortcode.</p>\n<script>\ndocument.write('Test1');\n\ndocument.write('Test2');\n</script>";
+
+       /**
+        * The captured global post during shortcode rendering.
+        *
+        * @var WP_Post|null
+        */
+       protected $post_during_shortcode = null;
+
+       /**
+        * Number of times the shortcode was rendered.
+        *
+        * @var int
+        */
+       protected $shortcode_render_count = 0;
+
+       /**
+        * Do example shortcode.
+        *
+        * @return string Shortcode content.
+        */
+       function do_example_shortcode() {
+               $this->post_during_shortcode = get_post();
+               $this->shortcode_render_count++;
+               return $this->example_shortcode_content;
+       }
+
+       /**
+        * Test widget method with shortcodes.
+        *
+        * @covers WP_Widget_Text::widget
+        */
+       function test_widget_shortcodes() {
+               global $post;
+               $post_id = $this->factory()->post->create();
+               $post    = get_post( $post_id );
+
+               $args   = array(
+                       'before_title'  => '<h2>',
+                       'after_title'   => "</h2>\n",
+                       'before_widget' => '<section>',
+                       'after_widget'  => "</section>\n",
+               );
+               $widget = new WP_Widget_Text();
+               add_shortcode( 'example', array( $this, 'do_example_shortcode' ) );
+
+               $base_instance = array(
+                       'title'  => 'Example',
+                       'text'   => "This is an example:\n\n[example]\n\nHello.",
+                       'filter' => false,
+               );
+
+               // Legacy Text Widget without wpautop().
+               $instance                     = array_merge(
+                       $base_instance,
+                       array(
+                               'filter' => false,
+                       )
+               );
+               $this->shortcode_render_count = 0;
+               ob_start();
+               $widget->widget( $args, $instance );
+               $output = ob_get_clean();
+               $this->assertSame( 1, $this->shortcode_render_count );
+               $this->assertStringNotContainsString( '[example]', $output, 'Expected shortcode to be processed in legacy widget with plugin adding filter' );
+               $this->assertStringContainsString( $this->example_shortcode_content, $output, 'Shortcode was applied without wpautop corrupting it.' );
+               $this->assertStringNotContainsString( '<p>' . $this->example_shortcode_content . '</p>', $output, 'Expected shortcode_unautop() to have run.' );
+               $this->assertNull( $this->post_during_shortcode );
+
+               // Legacy Text Widget with wpautop().
+               $instance                     = array_merge(
+                       $base_instance,
+                       array(
+                               'filter' => true,
+                               'visual' => false,
+                       )
+               );
+               $this->shortcode_render_count = 0;
+               ob_start();
+               $widget->widget( $args, $instance );
+               $output = ob_get_clean();
+               $this->assertSame( 1, $this->shortcode_render_count );
+               $this->assertStringNotContainsString( '[example]', $output, 'Expected shortcode to be processed in legacy widget with plugin adding filter' );
+               $this->assertStringContainsString( $this->example_shortcode_content, $output, 'Shortcode was applied without wpautop corrupting it.' );
+               $this->assertStringNotContainsString( '<p>' . $this->example_shortcode_content . '</p>', $output, 'Expected shortcode_unautop() to have run.' );
+               $this->assertNull( $this->post_during_shortcode );
+
+               // Legacy text widget with plugin adding shortcode support as well.
+               add_filter( 'widget_text', 'do_shortcode' );
+               $this->shortcode_render_count = 0;
+               ob_start();
+               $widget->widget( $args, $instance );
+               $output = ob_get_clean();
+               $this->assertSame( 1, $this->shortcode_render_count );
+               $this->assertStringNotContainsString( '[example]', $output, 'Expected shortcode to be processed in legacy widget with plugin adding filter' );
+               $this->assertStringContainsString( wpautop( $this->example_shortcode_content ), $output, 'Shortcode was applied *with* wpautop() applying to shortcode output since plugin used legacy filter.' );
+               $this->assertNull( $this->post_during_shortcode );
+               remove_filter( 'widget_text', 'do_shortcode' );
+
+               $instance = array_merge(
+                       $base_instance,
+                       array(
+                               'filter' => true,
+                               'visual' => true,
+                       )
+               );
+
+               // Visual Text Widget with only core-added widget_text_content filter for do_shortcode().
+               $this->assertFalse( has_filter( 'widget_text', 'do_shortcode' ) );
+               $this->assertSame( 11, has_filter( 'widget_text_content', 'do_shortcode' ), 'Expected core to have set do_shortcode as widget_text_content filter.' );
+               $this->shortcode_render_count = 0;
+               ob_start();
+               $widget->widget( $args, $instance );
+               $output = ob_get_clean();
+               $this->assertSame( 1, $this->shortcode_render_count );
+               $this->assertStringContainsString( $this->example_shortcode_content, $output, 'Shortcode was applied without wpautop corrupting it.' );
+               $this->assertStringNotContainsString( '<p>' . $this->example_shortcode_content . '</p>', $output, 'Expected shortcode_unautop() to have run.' );
+               $this->assertFalse( has_filter( 'widget_text', 'do_shortcode' ), 'The widget_text filter still lacks do_shortcode handler.' );
+               $this->assertSame( 11, has_filter( 'widget_text_content', 'do_shortcode' ), 'The widget_text_content filter still has do_shortcode handler.' );
+               $this->assertNull( $this->post_during_shortcode );
+
+               // Visual Text Widget with both filters applied added, one from core and another via plugin.
+               add_filter( 'widget_text', 'do_shortcode' );
+               $this->shortcode_render_count = 0;
+               ob_start();
+               $widget->widget( $args, $instance );
+               $output = ob_get_clean();
+               $this->assertSame( 1, $this->shortcode_render_count );
+               $this->assertStringContainsString( $this->example_shortcode_content, $output, 'Shortcode was applied without wpautop corrupting it.' );
+               $this->assertStringNotContainsString( '<p>' . $this->example_shortcode_content . '</p>', $output, 'Expected shortcode_unautop() to have run.' );
+               $this->assertSame( 10, has_filter( 'widget_text', 'do_shortcode' ), 'Expected do_shortcode to be restored to widget_text.' );
+               $this->assertNull( $this->post_during_shortcode );
+               $this->assertNull( $this->post_during_shortcode );
+               remove_filter( 'widget_text', 'do_shortcode' );
+
+               // Visual Text Widget with shortcode handling disabled via plugin removing filter.
+               remove_filter( 'widget_text_content', 'do_shortcode', 11 );
+               remove_filter( 'widget_text', 'do_shortcode' );
+               $this->shortcode_render_count = 0;
+               ob_start();
+               $widget->widget( $args, $instance );
+               $output = ob_get_clean();
+               $this->assertSame( 0, $this->shortcode_render_count );
+               $this->assertStringContainsString( '[example]', $output );
+               $this->assertStringNotContainsString( $this->example_shortcode_content, $output );
+               $this->assertFalse( has_filter( 'widget_text', 'do_shortcode' ) );
+               $this->assertFalse( has_filter( 'widget_text_content', 'do_shortcode' ) );
+       }
+
+       /**
+        * Filters the content of the Text widget.
+        *
+        * @param string         $widget_text The widget content.
+        * @param array          $instance    Array of settings for the current widget.
+        * @param WP_Widget_Text $widget      Current Text widget instance.
+        * @return string Widget text.
+        */
+       function filter_widget_text( $widget_text, $instance, $widget ) {
+               $this->widget_text_args = func_get_args();
+
+               $widget_text .= '[filter:widget_text]';
+               return $widget_text;
+       }
+
+       /**
+        * Filters the content of the Text widget to apply changes expected from the visual (TinyMCE) editor.
+        *
+        * @param string         $widget_text The widget content.
+        * @param array          $instance    Array of settings for the current widget.
+        * @param WP_Widget_Text $widget      Current Text widget instance.
+        * @return string Widget content.
+        */
+       function filter_widget_text_content( $widget_text, $instance, $widget ) {
+               $this->widget_text_content_args = func_get_args();
+
+               $widget_text .= '[filter:widget_text_content]';
+               return $widget_text;
+       }
+
+       /**
+        * Test is_legacy_instance method.
+        *
+        * @covers WP_Widget_Text::is_legacy_instance
+        */
+       function test_is_legacy_instance() {
+               $widget        = new WP_Widget_Text();
+               $base_instance = array(
+                       'title' => 'Title',
+                       'text'  => "Hello\n\nWorld",
+               );
+
+               $instance = array_merge(
+                       $base_instance,
+                       array(
+                               'visual' => false,
+                       )
+               );
+               $this->assertTrue( $widget->is_legacy_instance( $instance ), 'Legacy when visual=false prop is present.' );
+
+               $instance = array_merge(
+                       $base_instance,
+                       array(
+                               'visual' => true,
+                       )
+               );
+               $this->assertFalse( $widget->is_legacy_instance( $instance ), 'Not legacy when visual=true prop is present.' );
+
+               $instance = array_merge(
+                       $base_instance,
+                       array(
+                               'filter' => 'content',
+                       )
+               );
+               $this->assertFalse( $widget->is_legacy_instance( $instance ), 'Not legacy when filter is explicitly content (in WP 4.8.0 only).' );
+
+               $instance = array_merge(
+                       $base_instance,
+                       array(
+                               'text'   => '',
+                               'filter' => true,
+                       )
+               );
+               $this->assertFalse( $widget->is_legacy_instance( $instance ), 'Not legacy when text is empty.' );
+
+               $instance = array_merge(
+                       $base_instance,
+                       array(
+                               'text'   => "\nOne line",
+                               'filter' => false,
+                       )
+               );
+               $this->assertFalse( $widget->is_legacy_instance( $instance ), 'Not legacy when there is leading whitespace.' );
+
+               $instance = array_merge(
+                       $base_instance,
+                       array(
+                               'text'   => "\nOne line\n\n",
+                               'filter' => false,
+                       )
+               );
+               $this->assertFalse( $widget->is_legacy_instance( $instance ), 'Not legacy when there is trailing whitespace.' );
+
+               $instance = array_merge(
+                       $base_instance,
+                       array(
+                               'text'   => "One\nTwo",
+                               'filter' => false,
+                       )
+               );
+               $this->assertTrue( $widget->is_legacy_instance( $instance ), 'Legacy when not-wpautop and there are line breaks.' );
+
+               $instance = array_merge(
+                       $base_instance,
+                       array(
+                               'text'   => "One\n\nTwo",
+                               'filter' => false,
+                       )
+               );
+               $this->assertTrue( $widget->is_legacy_instance( $instance ), 'Legacy when not-wpautop and there are paragraph breaks.' );
+
+               $instance = array_merge(
+                       $base_instance,
+                       array(
+                               'text'   => "One\nTwo",
+                               'filter' => true,
+                       )
+               );
+               $this->assertFalse( $widget->is_legacy_instance( $instance ), 'Not automatically legacy when wpautop and there are line breaks.' );
+
+               $instance = array_merge(
+                       $base_instance,
+                       array(
+                               'text'   => "One\n\nTwo",
+                               'filter' => true,
+                       )
+               );
+               $this->assertFalse( $widget->is_legacy_instance( $instance ), 'Not automatically legacy when wpautop and there are paragraph breaks.' );
+
+               $instance = array_merge(
+                       $base_instance,
+                       array(
+                               'text'   => 'Test<!-- comment -->',
+                               'filter' => true,
+                       )
+               );
+               $this->assertTrue( $widget->is_legacy_instance( $instance ), 'Legacy when HTML comment is present.' );
+
+               // Check text examples that will not migrate to TinyMCE.
+               $legacy_text_examples = array(
+                       '<span class="hello"></span>',
+                       '<blockquote>Quote <footer>Citation</footer></blockquote>',
+                       '<img src=\"http://example.com/img.jpg\" border=\"0\" title=\"Example\" /></a>',
+                       '<span></span>',
+                       "<ul>\n<li><a href=\"#\" class=\"location\"></a>List Item 1</li>\n<li><a href=\"#\" class=\"location\"></a>List Item 2</li>\n</ul>",
+                       '<a href="#" class="map"></a>',
+                       "<script>\n\\Line one\n\n\\Line two</script>",
+                       "<style>body {\ncolor:red;\n}</style>",
+                       '<span class="fa fa-cc-discover fa-2x" aria-hidden="true"></span>',
+                       "<p>\nStay updated with our latest news and specials. We never sell your information and you can unsubscribe at any time.\n</p>\n\n<div class=\"custom-form-class\">\n\t<form action=\"#\" method=\"post\" name=\"mc-embedded-subscribe-form\">\n\n\t\t<label class=\"screen-reader-text\" for=\"mce-EMAIL-b\">Email </label>\n\t\t<input id=\"mce-EMAIL-b\" class=\"required email\" name=\"EMAIL\" required=\"\" type=\"email\" value=\"\" placeholder=\"Email Address*\" />\n\n\t\t<input class=\"button\" name=\"subscribe\" type=\"submit\" value=\"Go!\" />\n\n\t</form>\n</div>",
+                       '<span class="sectiondown"><a href="#front-page-3"><i class="fa fa-chevron-circle-down"></i></a></span>',
+               );
+               foreach ( $legacy_text_examples as $legacy_text_example ) {
+                       $instance = array_merge(
+                               $base_instance,
+                               array(
+                                       'text'   => $legacy_text_example,
+                                       'filter' => true,
+                               )
+                       );
+                       $this->assertTrue( $widget->is_legacy_instance( $instance ), 'Legacy when wpautop and there is HTML that is not liable to be mutated.' );
+
+                       $instance = array_merge(
+                               $base_instance,
+                               array(
+                                       'text'   => $legacy_text_example,
+                                       'filter' => false,
+                               )
+                       );
+                       $this->assertTrue( $widget->is_legacy_instance( $instance ), 'Legacy when not-wpautop and there is HTML that is not liable to be mutated.' );
+               }
+
+               // Check text examples that will migrate to TinyMCE, where elements and attributes are not in the allowed list.
+               $migratable_text_examples = array(
+                       'Check out <a href="http://example.com">Example</a>',
+                       '<img src="http://example.com/img.jpg" alt="Img">',
+                       '<strong><em>Hello</em></strong>',
+                       '<b><i><u><s>Hello</s></u></i></b>',
+                       "<ul>\n<li>One</li>\n<li>One</li>\n<li>One</li>\n</ul>",
+                       "<ol>\n<li>One</li>\n<li>One</li>\n<li>One</li>\n</ol>",
+                       "Text\n<hr>\nAddendum",
+                       "Look at this code:\n\n<code>echo 'Hello World!';</code>",
+               );
+               foreach ( $migratable_text_examples as $migratable_text_example ) {
+                       $instance = array_merge(
+                               $base_instance,
+                               array(
+                                       'text'   => $migratable_text_example,
+                                       'filter' => true,
+                               )
+                       );
+                       $this->assertFalse( $widget->is_legacy_instance( $instance ), 'Legacy when wpautop and there is HTML that is not liable to be mutated.' );
+               }
+       }
+
+       /**
+        * Test update method.
+        *
+        * @covers WP_Widget_Text::form
+        */
+       function test_form() {
+               add_filter( 'user_can_richedit', '__return_true' );
+               $widget = new WP_Widget_Text();
+               $widget->_set( 2 );
+               $instance = array(
+                       'title'  => 'Title',
+                       'text'   => 'Text',
+                       'filter' => false,
+                       'visual' => false,
+               );
+               $this->assertTrue( $widget->is_legacy_instance( $instance ) );
+               ob_start();
+               $widget->form( $instance );
+               $form = ob_get_clean();
+               $this->assertStringContainsString( 'class="visual" type="hidden" value=""', $form );
+               $this->assertStringNotContainsString( 'class="visual sync-input" type="hidden" value="on"', $form );
+
+               $instance = array(
+                       'title'  => 'Title',
+                       'text'   => 'Text',
+                       'filter' => 'content',
+               );
+               $this->assertFalse( $widget->is_legacy_instance( $instance ) );
+               ob_start();
+               $widget->form( $instance );
+               $form = ob_get_clean();
+               $this->assertStringContainsString( 'class="visual sync-input" type="hidden" value="on"', $form );
+               $this->assertStringNotContainsString( 'class="visual sync-input" type="hidden" value=""', $form );
+
+               $instance = array(
+                       'title'  => 'Title',
+                       'text'   => 'Text',
+                       'filter' => true,
+               );
+               $this->assertFalse( $widget->is_legacy_instance( $instance ) );
+               ob_start();
+               $widget->form( $instance );
+               $form = ob_get_clean();
+               $this->assertStringContainsString( 'class="visual sync-input" type="hidden" value="on"', $form );
+               $this->assertStringNotContainsString( 'class="visual sync-input" type="hidden" value=""', $form );
+
+               $instance = array(
+                       'title'  => 'Title',
+                       'text'   => 'This is some HTML Code: <code>&lt;strong&gt;BOLD!&lt;/strong&gt;</code>',
+                       'filter' => true,
+                       'visual' => true,
+               );
+               $this->assertFalse( $widget->is_legacy_instance( $instance ) );
+               ob_start();
+               $widget->form( $instance );
+               $form = ob_get_clean();
+               $this->assertStringContainsString( 'class="visual sync-input" type="hidden" value="on"', $form );
+               $this->assertStringContainsString( '&lt;code&gt;&amp;lt;strong&amp;gt;BOLD!', $form );
+               $this->assertStringNotContainsString( 'class="visual sync-input" type="hidden" value=""', $form );
+
+               remove_filter( 'user_can_richedit', '__return_true' );
+               add_filter( 'user_can_richedit', '__return_false' );
+               $instance = array(
+                       'title'  => 'Title',
+                       'text'   => 'Evil:</textarea><script>alert("XSS")</script>',
+                       'filter' => true,
+                       'visual' => true,
+               );
+               $this->assertFalse( $widget->is_legacy_instance( $instance ) );
+               ob_start();
+               $widget->form( $instance );
+               $form = ob_get_clean();
+               $this->assertStringNotContainsString( 'Evil:</textarea>', $form );
+               $this->assertStringContainsString( 'Evil:&lt;/textarea>', $form );
+       }
+
+       /**
+        * Test update method.
+        *
+        * @covers WP_Widget_Text::update
+        */
+       function test_update() {
+               $widget   = new WP_Widget_Text();
+               $instance = array(
+                       'title'  => "The\nTitle",
+                       'text'   => "The\n\nText",
+                       'filter' => true,
+                       'visual' => true,
+               );
+
+               wp_set_current_user(
+                       $this->factory()->user->create(
+                               array(
+                                       'role' => 'administrator',
+                               )
+                       )
+               );
+
+               $expected = array(
+                       'title'  => sanitize_text_field( $instance['title'] ),
+                       'text'   => $instance['text'],
+                       'filter' => true,
+                       'visual' => true,
+               );
+               $result   = $widget->update( $instance, array() );
+               $this->assertSame( $expected, $result );
+               $this->assertNotEmpty( $expected['filter'], 'Expected filter prop to be truthy, to handle case where 4.8 is downgraded to 4.7.' );
+
+               add_filter( 'map_meta_cap', array( $this, 'grant_unfiltered_html_cap' ), 10, 2 );
+               $this->assertTrue( current_user_can( 'unfiltered_html' ) );
+               $instance['text'] = '<script>alert( "Howdy!" );</script>';
+               $expected['text'] = $instance['text'];
+               $result           = $widget->update( $instance, array() );
+               $this->assertSame( $expected, $result, 'KSES should apply as expected.' );
+               remove_filter( 'map_meta_cap', array( $this, 'grant_unfiltered_html_cap' ) );
+
+               add_filter( 'map_meta_cap', array( $this, 'revoke_unfiltered_html_cap' ), 10, 2 );
+               $this->assertFalse( current_user_can( 'unfiltered_html' ) );
+               $instance['text'] = '<script>alert( "Howdy!" );</script>';
+               $expected['text'] = wp_kses_post( $instance['text'] );
+               $result           = $widget->update( $instance, array() );
+               $this->assertSame( $expected, $result, 'KSES should not apply since user can unfiltered_html.' );
+               remove_filter( 'map_meta_cap', array( $this, 'revoke_unfiltered_html_cap' ), 10 );
+       }
+
+       /**
+        * Test update for legacy widgets.
+        *
+        * @covers WP_Widget_Text::update
+        */
+       function test_update_legacy() {
+               $widget = new WP_Widget_Text();
+
+               // --
+               $instance = array(
+                       'title'  => 'Legacy',
+                       'text'   => 'Text',
+                       'filter' => false,
+               );
+               $result   = $widget->update( $instance, array() );
+               $this->assertSameSets( $instance, $result, 'Updating a widget without visual prop and explicit filter=false leaves visual prop absent' );
+
+               // --
+               $instance = array(
+                       'title'  => 'Legacy',
+                       'text'   => 'Text',
+                       'filter' => true,
+               );
+               $result   = $widget->update( $instance, array() );
+               $this->assertSameSets( $instance, $result, 'Updating a widget without visual prop and explicit filter=true leaves legacy prop absent.' );
+
+               // --
+               $instance     = array(
+                       'title'  => 'Legacy',
+                       'text'   => 'Text',
+                       'visual' => true,
+               );
+               $old_instance = array_merge(
+                       $instance,
+                       array(
+                               'filter' => false,
+                       )
+               );
+               $expected     = array_merge(
+                       $instance,
+                       array(
+                               'filter' => true,
+                       )
+               );
+               $result       = $widget->update( $instance, $old_instance );
+               $this->assertSameSets( $expected, $result, 'Updating a pre-existing widget with visual mode forces filter to be true.' );
+
+               // --
+               $instance     = array(
+                       'title'  => 'Legacy',
+                       'text'   => 'Text',
+                       'filter' => true,
+               );
+               $old_instance = array_merge(
+                       $instance,
+                       array(
+                               'visual' => true,
+                       )
+               );
+               $result       = $widget->update( $instance, $old_instance );
+               $expected     = array_merge(
+                       $instance,
+                       array(
+                               'visual' => true,
+                       )
+               );
+               $this->assertSameSets( $expected, $result, 'Updating a pre-existing visual widget retains visual mode when updated.' );
+
+               // --
+               $instance     = array(
+                       'title' => 'Legacy',
+                       'text'  => 'Text',
+               );
+               $old_instance = array_merge(
+                       $instance,
+                       array(
+                               'visual' => true,
+                       )
+               );
+               $result       = $widget->update( $instance, $old_instance );
+               $expected     = array_merge(
+                       $instance,
+                       array(
+                               'visual' => true,
+                               'filter' => true,
+                       )
+               );
+               $this->assertSameSets( $expected, $result, 'Updating a pre-existing visual widget retains visual=true and supplies missing filter=true.' );
+
+               // --
+               $instance = array(
+                       'title'  => 'Legacy',
+                       'text'   => 'Text',
+                       'visual' => true,
+               );
+               $expected = array_merge(
+                       $instance,
+                       array(
+                               'filter' => true,
+                       )
+               );
+               $result   = $widget->update( $instance, array() );
+               $this->assertSameSets( $expected, $result, 'Updating a widget with explicit visual=true and absent filter prop causes filter to be set to true.' );
+
+               // --
+               $instance = array(
+                       'title'  => 'Legacy',
+                       'text'   => 'Text',
+                       'visual' => false,
+               );
+               $result   = $widget->update( $instance, array() );
+               $expected = array_merge(
+                       $instance,
+                       array(
+                               'filter' => false,
+                       )
+               );
+               $this->assertSameSets( $expected, $result, 'Updating a widget in legacy mode results in filter=false as if checkbox not checked.' );
+
+               // --
+               $instance     = array(
+                       'title'  => 'Title',
+                       'text'   => 'Text',
+                       'filter' => false,
+               );
+               $old_instance = array_merge(
+                       $instance,
+                       array(
+                               'visual' => false,
+                               'filter' => true,
+                       )
+               );
+               $result       = $widget->update( $instance, $old_instance );
+               $expected     = array_merge(
+                       $instance,
+                       array(
+                               'visual' => false,
+                               'filter' => false,
+                       )
+               );
+               $this->assertSameSets( $expected, $result, 'Updating a widget that previously had legacy form results in filter allowed to be false.' );
+
+               // --
+               $instance = array(
+                       'title'  => 'Title',
+                       'text'   => 'Text',
+                       'filter' => 'content',
+               );
+               $result   = $widget->update( $instance, array() );
+               $expected = array_merge(
+                       $instance,
+                       array(
+                               'filter' => true,
+                               'visual' => true,
+                       )
+               );
+               $this->assertSameSets( $expected, $result, 'Updating a widget that had \'content\' as its filter value persists non-legacy mode. This only existed in WP 4.8.0.' );
+
+               // --
+               $instance     = array(
+                       'title' => 'Title',
+                       'text'  => 'Text',
+               );
+               $old_instance = array_merge(
+                       $instance,
+                       array(
+                               'filter' => 'content',
+                       )
+               );
+               $result       = $widget->update( $instance, $old_instance );
+               $expected     = array_merge(
+                       $instance,
+                       array(
+                               'visual' => true,
+                               'filter' => true,
+                       )
+               );
+               $this->assertSameSets( $expected, $result, 'Updating a pre-existing widget with the filter=content prop in WP 4.8.0 upgrades to filter=true&visual=true.' );
+
+               // --
+               $instance = array(
+                       'title'  => 'Title',
+                       'text'   => 'Text',
+                       'filter' => 'content',
+               );
+               $result   = $widget->update( $instance, array() );
+               $expected = array_merge(
+                       $instance,
+                       array(
+                               'filter' => true,
+                               'visual' => true,
+                       )
+               );
+               $this->assertSameSets( $expected, $result, 'Updating a widget with filter=content (from WP 4.8.0) upgrades to filter=true&visual=true.' );
+       }
+
+       /**
+        * Grant unfiltered_html cap via map_meta_cap.
+        *
+        * @param array  $caps    Returns the user's actual capabilities.
+        * @param string $cap     Capability name.
+        * @return array Caps.
+        */
+       function grant_unfiltered_html_cap( $caps, $cap ) {
+               if ( 'unfiltered_html' === $cap ) {
+                       $caps   = array_diff( $caps, array( 'do_not_allow' ) );
+                       $caps[] = 'unfiltered_html';
+               }
+               return $caps;
+       }
+
+       /**
+        * Revoke unfiltered_html cap via map_meta_cap.
+        *
+        * @param array  $caps    Returns the user's actual capabilities.
+        * @param string $cap     Capability name.
+        * @return array Caps.
+        */
+       function revoke_unfiltered_html_cap( $caps, $cap ) {
+               if ( 'unfiltered_html' === $cap ) {
+                       $caps   = array_diff( $caps, array( 'unfiltered_html' ) );
+                       $caps[] = 'do_not_allow';
+               }
+               return $caps;
+       }
+
+       /**
+        * Test enqueue_admin_scripts method.
+        *
+        * @covers WP_Widget_Text::enqueue_admin_scripts
+        */
+       function test_enqueue_admin_scripts() {
+               set_current_screen( 'widgets.php' );
+               $widget = new WP_Widget_Text();
+               $widget->enqueue_admin_scripts();
+
+               $this->assertTrue( wp_script_is( 'text-widgets' ) );
+       }
+
+       /**
+        * Test render_control_template_scripts method.
+        *
+        * @covers WP_Widget_Text::render_control_template_scripts
+        */
+       function test_render_control_template_scripts() {
+               ob_start();
+               WP_Widget_Text::render_control_template_scripts();
+               $output = ob_get_clean();
+
+               $this->assertStringContainsString( '<script type="text/html" id="tmpl-widget-text-control-fields">', $output );
+       }
+
+       /**
+        * Ensure that rel="noopener" is added to links with a target.
+        *
+        * @ticket 46421
+        */
+       function test_render_links_with_target() {
+               $widget = new WP_Widget_Text();
+
+               $text = 'Test content with an external <a href="https://example.org" target="_blank">link</a>.';
+
+               $args = array(
+                       'before_title'  => '<h2>',
+                       'after_title'   => '</h2>',
+                       'before_widget' => '',
+                       'after_widget'  => '',
+               );
+
+               $instance = array(
+                       'title' => 'Foo',
+                       'text'  => $text,
+               );
+
+               $output = get_echo( array( $widget, 'widget' ), array( $args, $instance ) );
+
+               $this->assertStringContainsString( 'rel="noopener"', $output );
+       }
+
+       /**
+        * Ensure that rel="noopener" is not added to links without a target.
+        *
+        * @ticket 46421
+        */
+       function test_render_links_without_target() {
+               $widget = new WP_Widget_Text();
+
+               $text = 'Test content with an internal <a href="/">link</a>.';
+
+               $args = array(
+                       'before_title'  => '<h2>',
+                       'after_title'   => '</h2>',
+                       'before_widget' => '',
+                       'after_widget'  => '',
+               );
+
+               $instance = array(
+                       'title' => 'Foo',
+                       'text'  => $text,
+               );
+
+               $output = get_echo( array( $widget, 'widget' ), array( $args, $instance ) );
+
+               $this->assertStringNotContainsString( 'rel="noopener"', $output );
+       }
+}
</ins></span></pre>
</div>
</div>

</body>
</html>