WordPress.org

Make WordPress Core

Ticket #49037: 49037.7.diff

File 49037.7.diff, 30.6 KB (added by TimothyBlynJacobs, 6 months ago)
  • src/wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php

    diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php
    index 1d86d9938a..87051db58e 100644
    a b class WP_REST_Themes_Controller extends WP_REST_Controller { 
    110110                $fields = $this->get_fields_for_response( $request );
    111111
    112112                if ( in_array( 'theme_supports', $fields, true ) ) {
    113                         $formats                           = get_theme_support( 'post-formats' );
    114                         $formats                           = is_array( $formats ) ? array_values( $formats[0] ) : array();
    115                         $formats                           = array_merge( array( 'standard' ), $formats );
    116                         $data['theme_supports']['formats'] = $formats;
     113                        $item_schemas   = $this->get_item_schema();
     114                        $theme_supports = $item_schemas['properties']['theme_supports']['properties'];
     115                        foreach ( $theme_supports as $name => $schema ) {
     116                                if ( 'formats' === $name ) {
     117                                        continue;
     118                                }
     119
     120                                if ( ! current_theme_supports( $name ) ) {
     121                                        $data['theme_supports'][ $name ] = false;
     122                                        continue;
     123                                }
     124
     125                                if ( 'boolean' === $schema['type'] ) {
     126                                        $data['theme_supports'][ $name ] = true;
     127                                        continue;
     128                                }
     129
     130                                $support = get_theme_support( $name );
    117131
    118                         $data['theme_supports']['post-thumbnails']   = false;
    119                         $data['theme_supports']['responsive-embeds'] = (bool) get_theme_support( 'responsive-embeds' );
    120                         $post_thumbnails                             = get_theme_support( 'post-thumbnails' );
     132                                if ( is_array( $support ) ) {
     133                                        // None of the Core theme supports have variadic args.
     134                                        $support = $support[0];
    121135
    122                         if ( $post_thumbnails ) {
    123                                 // $post_thumbnails can contain a nested array of post types.
    124                                 // e.g. array( array( 'post', 'page' ) ).
    125                                 $data['theme_supports']['post-thumbnails'] = is_array( $post_thumbnails ) ? $post_thumbnails[0] : true;
     136                                        // Core multi-type theme-support schema definitions always list boolean first.
     137                                        if ( is_array( $schema['type'] ) && 'boolean' === $schema['type'][0] ) {
     138                                                // Pass the non-boolean type through to the sanitizer, which cannot itself
     139                                                // determine the intended type if the value is invalid (for example if an
     140                                                // object includes non-safelisted properties).
     141                                                $schema['type'] = $schema['type'][1];
     142                                        }
     143                                }
     144
     145                                $data['theme_supports'][ $name ] = rest_sanitize_value_from_schema( $support, $schema );
    126146                        }
     147
     148                        $formats = get_theme_support( 'post-formats' );
     149                        $formats = is_array( $formats ) ? array_values( $formats[0] ) : array();
     150                        $formats = array_merge( array( 'standard' ), $formats );
     151
     152                        $data['theme_supports']['formats'] = $formats;
    127153                }
    128154
    129155                $data = $this->add_additional_fields_to_object( $data, $request );
    class WP_REST_Themes_Controller extends WP_REST_Controller { 
    162188                        'properties' => array(
    163189                                'theme_supports' => array(
    164190                                        'description' => __( 'Features supported by this theme.' ),
    165                                         'type'        => 'array',
     191                                        'type'        => 'object',
    166192                                        'readonly'    => true,
    167193                                        'properties'  => array(
    168                                                 'formats'           => array(
     194                                                'align-wide'                => array(
     195                                                        'description' => __( 'Whether theme opts in to wide alignment CSS class.' ),
     196                                                        'type'        => 'boolean',
     197                                                ),
     198                                                'automatic-feed-links'      => array(
     199                                                        'description' => __( 'Whether posts and comments RSS feed links are added to head.' ),
     200                                                        'type'        => 'boolean',
     201                                                ),
     202                                                'custom-header'             => array(
     203                                                        'description'          => __( 'Custom header if defined by the theme.' ),
     204                                                        'type'                 => array( 'boolean', 'object' ),
     205                                                        'properties'           => array(
     206                                                                'default-image'      => array(
     207                                                                        'type'   => 'string',
     208                                                                        'format' => 'uri',
     209                                                                ),
     210                                                                'random-default'     => array(
     211                                                                        'type' => 'boolean',
     212                                                                ),
     213                                                                'width'              => array(
     214                                                                        'type' => 'integer',
     215                                                                ),
     216                                                                'height'             => array(
     217                                                                        'type' => 'integer',
     218                                                                ),
     219                                                                'flex-height'        => array(
     220                                                                        'type' => 'boolean',
     221                                                                ),
     222                                                                'flex-width'         => array(
     223                                                                        'type' => 'boolean',
     224                                                                ),
     225                                                                'default-text-color' => array(
     226                                                                        'type' => 'string',
     227                                                                ),
     228                                                                'header-text'        => array(
     229                                                                        'type' => 'boolean',
     230                                                                ),
     231                                                                'uploads'            => array(
     232                                                                        'type' => 'boolean',
     233                                                                ),
     234                                                                'video'              => array(
     235                                                                        'type' => 'boolean',
     236                                                                ),
     237                                                        ),
     238                                                        'additionalProperties' => false,
     239                                                ),
     240                                                'custom-background'         => array(
     241                                                        'description'          => __( 'Custom background if defined by the theme.' ),
     242                                                        'type'                 => array( 'boolean', 'object' ),
     243                                                        'properties'           => array(
     244                                                                'default-image'      => array(
     245                                                                        'type'   => 'string',
     246                                                                        'format' => 'uri',
     247                                                                ),
     248                                                                'default-preset'     => array(
     249                                                                        'type' => 'string',
     250                                                                        'enum' => array(
     251                                                                                'default',
     252                                                                                'fill',
     253                                                                                'fit',
     254                                                                                'repeat',
     255                                                                                'custom',
     256                                                                        ),
     257                                                                ),
     258                                                                'default-position-x' => array(
     259                                                                        'type' => 'string',
     260                                                                        'enum' => array(
     261                                                                                'left',
     262                                                                                'center',
     263                                                                                'right',
     264                                                                        ),
     265                                                                ),
     266                                                                'default-position-y' => array(
     267                                                                        'type' => 'string',
     268                                                                        'enum' => array(
     269                                                                                'left',
     270                                                                                'center',
     271                                                                                'right',
     272                                                                        ),
     273                                                                ),
     274                                                                'default-size'       => array(
     275                                                                        'type' => 'string',
     276                                                                        'enum' => array(
     277                                                                                'auto',
     278                                                                                'contain',
     279                                                                                'cover',
     280                                                                        ),
     281                                                                ),
     282                                                                'default-repeat'     => array(
     283                                                                        'type' => 'string',
     284                                                                        'enum' => array(
     285                                                                                'repeat-x',
     286                                                                                'repeat-y',
     287                                                                                'repeat',
     288                                                                                'no-repeat',
     289                                                                        ),
     290                                                                ),
     291                                                                'default-attachment' => array(
     292                                                                        'type' => 'string',
     293                                                                        'enum' => array(
     294                                                                                'scroll',
     295                                                                                'fixed',
     296                                                                        ),
     297                                                                ),
     298                                                                'default-color'      => array(
     299                                                                        'type' => 'string',
     300                                                                ),
     301                                                        ),
     302                                                        'additionalProperties' => false,
     303                                                ),
     304                                                'custom-logo'               => array(
     305                                                        'description'          => __( 'Custom logo if defined by the theme.' ),
     306                                                        'type'                 => array( 'boolean', 'object' ),
     307                                                        'properties'           => array(
     308                                                                'width'       => array(
     309                                                                        'type' => 'integer',
     310                                                                ),
     311                                                                'height'      => array(
     312                                                                        'type' => 'integer',
     313                                                                ),
     314                                                                'flex-width'  => array(
     315                                                                        'type' => 'boolean',
     316                                                                ),
     317                                                                'flex-height' => array(
     318                                                                        'type' => 'boolean',
     319                                                                ),
     320                                                                'header-text' => array(
     321                                                                        'type'  => 'array',
     322                                                                        'items' => array(
     323                                                                                'type' => 'string',
     324                                                                        ),
     325                                                                ),
     326                                                        ),
     327                                                        'additionalProperties' => false,
     328                                                ),
     329                                                'customize-selective-refresh-widgets' => array(
     330                                                        'description' => __( 'Whether the theme enables Selective Refresh for Widgets being managed with the Customizer.' ),
     331                                                        'type'        => 'boolean',
     332                                                ),
     333                                                'dark-editor-style'         => array(
     334                                                        'description' => __( 'Whether theme opts in to the dark editor style UI.' ),
     335                                                        'type'        => 'boolean',
     336                                                ),
     337                                                'disable-custom-colors'     => array(
     338                                                        'description' => __( 'Whether the theme disables custom colors.' ),
     339                                                        'type'        => 'boolean',
     340                                                ),
     341                                                'disable-custom-font-sizes' => array(
     342                                                        'description' => __( 'Whether the theme disables custom font sizes.' ),
     343                                                        'type'        => 'boolean',
     344                                                ),
     345                                                'disable-custom-gradients'  => array(
     346                                                        'description' => __( 'Whether the theme disables custom graidients.' ),
     347                                                        'type'        => 'boolean',
     348                                                ),
     349                                                'editor-color-palette'      => array(
     350                                                        'description' => __( 'Custom color palette if defined by the theme.' ),
     351                                                        'type'        => array( 'boolean', 'array' ),
     352                                                        'items'       => array(
     353                                                                'type'                 => 'object',
     354                                                                'properties'           => array(
     355                                                                        'name'  => array(
     356                                                                                'type' => 'string',
     357                                                                        ),
     358                                                                        'slug'  => array(
     359                                                                                'type' => 'string',
     360                                                                        ),
     361                                                                        'color' => array(
     362                                                                                'type' => 'string',
     363                                                                        ),
     364                                                                ),
     365                                                                'additionalProperties' => false,
     366                                                        ),
     367                                                ),
     368                                                'editor-font-sizes'         => array(
     369                                                        'description' => __( 'Custom font sizes if defined by the theme.' ),
     370                                                        'type'        => array( 'boolean', 'array' ),
     371                                                        'items'       => array(
     372                                                                'type'                 => 'object',
     373                                                                'properties'           => array(
     374                                                                        'name' => array(
     375                                                                                'type' => 'string',
     376                                                                        ),
     377                                                                        'size' => array(
     378                                                                                'type' => 'number',
     379                                                                        ),
     380                                                                        'slug' => array(
     381                                                                                'type' => 'string',
     382                                                                        ),
     383                                                                ),
     384                                                                'additionalProperties' => false,
     385                                                        ),
     386                                                ),
     387                                                'editor-gradient-presets'   => array(
     388                                                        'description' => __( 'Custom gradient presets if defined by the theme.' ),
     389                                                        'type'        => array( 'boolean', 'array' ),
     390                                                        'items'       => array(
     391                                                                'type'                 => 'object',
     392                                                                'properties'           => array(
     393                                                                        'name'     => array(
     394                                                                                'type' => 'string',
     395                                                                        ),
     396                                                                        'gradient' => array(
     397                                                                                'type' => 'string',
     398                                                                        ),
     399                                                                        'slug'     => array(
     400                                                                                'type' => 'string',
     401                                                                        ),
     402                                                                ),
     403                                                                'additionalProperties' => false,
     404                                                        ),
     405                                                ),
     406                                                'editor-styles'             => array(
     407                                                        'description' => __( 'Whether theme opts in to the editor styles CSS wrapper.' ),
     408                                                        'type'        => 'boolean',
     409                                                ),
     410                                                'formats'                   => array(
    169411                                                        'description' => __( 'Post formats supported.' ),
    170412                                                        'type'        => 'array',
    171                                                         'readonly'    => true,
     413                                                        'items'       => array(
     414                                                                'type' => 'string',
     415                                                                'enum' => get_post_format_slugs(),
     416                                                        ),
    172417                                                ),
    173                                                 'post-thumbnails'   => array(
     418                                                'html5'                     => array(
     419                                                        'description' => __( 'Allows use of html5 markup for search forms, comment forms, comment lists, gallery, and caption.' ),
     420                                                        'type'        => array( 'boolean', 'array' ),
     421                                                        'items'       => array(
     422                                                                'type' => 'string',
     423                                                                'enum' => array(
     424                                                                        'search-form',
     425                                                                        'comment-form',
     426                                                                        'comment-list',
     427                                                                        'gallery',
     428                                                                        'caption',
     429                                                                        'script',
     430                                                                        'style',
     431                                                                ),
     432                                                        ),
     433                                                ),
     434                                                'post-thumbnails'           => array(
    174435                                                        'description' => __( 'Whether the theme supports post thumbnails.' ),
    175                                                         'type'        => array( 'array', 'bool' ),
    176                                                         'readonly'    => true,
     436                                                        'type'        => array( 'boolean', 'array' ),
     437                                                        'items'       => array(
     438                                                                'type' => 'string',
     439                                                        ),
    177440                                                ),
    178                                                 'responsive-embeds' => array(
     441                                                'responsive-embeds'         => array(
    179442                                                        'description' => __( 'Whether the theme supports responsive embedded content.' ),
    180                                                         'type'        => 'bool',
    181                                                         'readonly'    => true,
     443                                                        'type'        => 'boolean',
     444                                                ),
     445                                                'title-tag'                 => array(
     446                                                        'description' => __( 'Whether the theme can manage the document title tag.' ),
     447                                                        'type'        => 'boolean',
     448                                                ),
     449                                                'wp-block-styles'           => array(
     450                                                        'description' => __( 'Whether theme opts in to default WordPress block styles for viewing.' ),
     451                                                        'type'        => 'boolean',
    182452                                                ),
    183453                                        ),
    184454                                ),
  • tests/phpunit/tests/rest-api/rest-themes-controller.php

    diff --git a/tests/phpunit/tests/rest-api/rest-themes-controller.php b/tests/phpunit/tests/rest-api/rest-themes-controller.php
    index 520dbed9d0..931b479572 100644
    a b class WP_Test_REST_Themes_Controller extends WP_Test_REST_Controller_Testcase { 
    188188                $properties = $data['schema']['properties'];
    189189                $this->assertEquals( 1, count( $properties ) );
    190190                $this->assertArrayHasKey( 'theme_supports', $properties );
     191                $theme_supports = $properties['theme_supports']['properties'];
     192                $this->assertEquals( 20, count( $theme_supports ) );
     193                $this->assertArrayHasKey( 'align-wide', $theme_supports );
     194                $this->assertArrayHasKey( 'automatic-feed-links', $theme_supports );
     195                $this->assertArrayHasKey( 'custom-header', $theme_supports );
     196                $this->assertArrayHasKey( 'custom-background', $theme_supports );
     197                $this->assertArrayHasKey( 'custom-logo', $theme_supports );
     198                $this->assertArrayHasKey( 'customize-selective-refresh-widgets', $theme_supports );
     199                $this->assertArrayHasKey( 'title-tag', $theme_supports );
     200                $this->assertArrayHasKey( 'dark-editor-style', $theme_supports );
     201                $this->assertArrayHasKey( 'disable-custom-font-sizes', $theme_supports );
     202                $this->assertArrayHasKey( 'disable-custom-gradients', $theme_supports );
     203                $this->assertArrayHasKey( 'editor-color-palette', $theme_supports );
     204                $this->assertArrayHasKey( 'editor-font-sizes', $theme_supports );
     205                $this->assertArrayHasKey( 'editor-gradient-presets', $theme_supports );
     206                $this->assertArrayHasKey( 'editor-styles', $theme_supports );
     207                $this->assertArrayHasKey( 'formats', $theme_supports );
     208                $this->assertArrayHasKey( 'html5', $theme_supports );
     209                $this->assertArrayHasKey( 'post-thumbnails', $theme_supports );
     210                $this->assertArrayHasKey( 'responsive-embeds', $theme_supports );
     211                $this->assertArrayHasKey( 'title-tag', $theme_supports );
     212                $this->assertArrayHasKey( 'wp-block-styles', $theme_supports );
     213        }
     214
     215        /**
     216         * @ticket 49037
     217         */
     218        public function test_theme_supports_disable_custom_colors_false() {
     219                remove_theme_support( 'disable-custom-colors' );
     220                $response = self::perform_active_theme_request();
     221                $result   = $response->get_data();
     222                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     223                $this->assertArrayHasKey( 'disable-custom-colors', $result[0]['theme_supports'] );
     224                $this->assertFalse( $result[0]['theme_supports']['disable-custom-colors'] );
     225        }
     226
     227        /**
     228         * @ticket 49037
     229         */
     230        public function test_theme_supports_disable_custom_colors_true() {
     231                remove_theme_support( 'disable-custom-colors' );
     232                add_theme_support( 'disable-custom-colors' );
     233                $response = self::perform_active_theme_request();
     234                $result   = $response->get_data();
     235                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     236                $this->assertTrue( $result[0]['theme_supports']['disable-custom-colors'] );
     237        }
     238
     239        /**
     240         * @ticket 49037
     241         */
     242        public function test_theme_supports_disable_custom_font_sizes_false() {
     243                remove_theme_support( 'disable-custom-font-sizes' );
     244                $response = self::perform_active_theme_request();
     245                $result   = $response->get_data();
     246                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     247                $this->assertArrayHasKey( 'disable-custom-font-sizes', $result[0]['theme_supports'] );
     248                $this->assertFalse( $result[0]['theme_supports']['disable-custom-font-sizes'] );
     249        }
     250
     251        /**
     252         * @ticket 49037
     253         */
     254        public function test_theme_supports_disable_custom_font_sizes_true() {
     255                remove_theme_support( 'disable-custom-font-sizes' );
     256                add_theme_support( 'disable-custom-font-sizes' );
     257                $response = self::perform_active_theme_request();
     258                $result   = $response->get_data();
     259                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     260                $this->assertTrue( $result[0]['theme_supports']['disable-custom-font-sizes'] );
     261        }
     262
     263        /**
     264         * @ticket 49037
     265         */
     266        public function test_theme_supports_editor_font_sizes_false() {
     267                remove_theme_support( 'editor-font-sizes' );
     268                $response = self::perform_active_theme_request();
     269                $result   = $response->get_data();
     270                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     271                $this->assertArrayHasKey( 'editor-font-sizes', $result[0]['theme_supports'] );
     272                $this->assertFalse( $result[0]['theme_supports']['editor-font-sizes'] );
     273        }
     274
     275        /**
     276         * @ticket 49037
     277         */
     278        public function test_theme_supports_editor_font_sizes_array() {
     279                remove_theme_support( 'editor-font-sizes' );
     280                $tiny = array(
     281                        'name' => 'Tiny',
     282                        'size' => 8,
     283                        'slug' => 'tiny',
     284                );
     285                add_theme_support( 'editor-font-sizes', array( $tiny ) );
     286                $response = self::perform_active_theme_request();
     287                $result   = $response->get_data();
     288                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     289                $this->assertArrayHasKey( 'editor-font-sizes', $result[0]['theme_supports'] );
     290                $this->assertEquals( array( $tiny ), $result[0]['theme_supports']['editor-font-sizes'] );
     291        }
     292
     293        /**
     294         * @ticket 49037
     295         */
     296        public function test_theme_supports_editor_color_palette_false() {
     297                remove_theme_support( 'editor-color-palette' );
     298                $response = self::perform_active_theme_request();
     299                $result   = $response->get_data();
     300                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     301                $this->assertArrayHasKey( 'editor-color-palette', $result[0]['theme_supports'] );
     302                $this->assertFalse( $result[0]['theme_supports']['editor-color-palette'] );
     303        }
     304
     305        /**
     306         * @ticket 49037
     307         */
     308        public function test_theme_supports_editor_color_palette_array() {
     309                remove_theme_support( 'editor-color-palette' );
     310                $wordpress_blue = array(
     311                        'name'  => 'WordPress Blue',
     312                        'slug'  => 'wordpress-blue',
     313                        'color' => '#0073AA',
     314                );
     315                add_theme_support( 'editor-color-palette', array( $wordpress_blue ) );
     316                $response = self::perform_active_theme_request();
     317                $result   = $response->get_data();
     318                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     319                $this->assertEquals( array( $wordpress_blue ), $result[0]['theme_supports']['editor-color-palette'] );
     320        }
     321
     322        /**
     323         * @ticket 49037
     324         */
     325        public function test_theme_supports_enable_automatic_feed_links() {
     326                remove_theme_support( 'automatic-feed-links' );
     327                add_theme_support( 'automatic-feed-links' );
     328                $response = self::perform_active_theme_request();
     329                $result   = $response->get_data();
     330                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     331                $this->assertTrue( $result[0]['theme_supports']['automatic-feed-links'] );
     332        }
     333
     334        /**
     335         * @ticket 49037
     336         */
     337        public function test_theme_supports_does_not_enable_automatic_feed_links() {
     338                remove_theme_support( 'automatic-feed-links' );
     339                $response = self::perform_active_theme_request();
     340                $result   = $response->get_data();
     341                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     342                $this->assertArrayHasKey( 'automatic-feed-links', $result[0]['theme_supports'] );
     343                $this->assertFalse( $result[0]['theme_supports']['automatic-feed-links'] );
     344        }
     345
     346        /**
     347         * @ticket 49037
     348         */
     349        public function test_theme_does_not_support_custom_logo() {
     350                remove_theme_support( 'custom-logo' );
     351                $response = self::perform_active_theme_request();
     352                $result   = $response->get_data();
     353                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     354                $this->assertArrayHasKey( 'custom-logo', $result[0]['theme_supports'] );
     355                $this->assertFalse( $result[0]['theme_supports']['custom-logo'] );
     356        }
     357
     358        /**
     359         * @ticket 49037
     360         */
     361        public function test_theme_supports_custom_logo() {
     362                remove_theme_support( 'custom-logo' );
     363                $wordpress_logo = array(
     364                        'height'      => 100,
     365                        'width'       => 400,
     366                        'flex-height' => true,
     367                        'flex-width'  => true,
     368                        'header-text' => array( 'site-title', 'site-description' ),
     369                );
     370                add_theme_support( 'custom-logo', $wordpress_logo );
     371                $response = self::perform_active_theme_request();
     372                $result   = $response->get_data();
     373                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     374                $this->assertEquals( $wordpress_logo, $result[0]['theme_supports']['custom-logo'] );
     375        }
     376
     377        /**
     378         * @ticket 49037
     379         */
     380        public function test_theme_does_not_support_custom_header() {
     381                remove_theme_support( 'custom-header' );
     382                $response = self::perform_active_theme_request();
     383                $result   = $response->get_data();
     384                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     385                $this->assertArrayHasKey( 'custom-header', $result[0]['theme_supports'] );
     386                $this->assertFalse( $result[0]['theme_supports']['custom-header'] );
     387        }
     388
     389        /**
     390         * @ticket 49037
     391         */
     392        public function test_theme_supports_custom_header() {
     393                remove_theme_support( 'custom-header' );
     394                $wordpress_header = array(
     395                        'default-image'          => '',
     396                        'random-default'         => false,
     397                        'width'                  => 0,
     398                        'height'                 => 0,
     399                        'flex-height'            => false,
     400                        'flex-width'             => false,
     401                        'default-text-color'     => '',
     402                        'header-text'            => true,
     403                        'uploads'                => true,
     404                        'wp-head-callback'       => '',
     405                        'admin-head-callback'    => '',
     406                        'admin-preview-callback' => '',
     407                        'video'                  => false,
     408                        'video-active-callback'  => 'is_front_page',
     409                );
     410                $excluded         = array(
     411                        'wp-head-callback',
     412                        'admin-head-callback',
     413                        'admin-preview-callback',
     414                        'video-active-callback',
     415                );
     416                add_theme_support( 'custom-header', $wordpress_header );
     417                $response = self::perform_active_theme_request();
     418                $result   = $response->get_data();
     419                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     420
     421                $expected = array_diff_key( $wordpress_header, array_flip( $excluded ) );
     422                $this->assertEquals( $expected, $result[0]['theme_supports']['custom-header'] );
     423        }
     424
     425        /**
     426         * @ticket 49037
     427         */
     428        public function test_theme_does_not_support_custom_background() {
     429                remove_theme_support( 'custom-background' );
     430                $response = self::perform_active_theme_request();
     431                $result   = $response->get_data();
     432                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     433                $this->assertArrayHasKey( 'custom-background', $result[0]['theme_supports'] );
     434                $this->assertFalse( $result[0]['theme_supports']['custom-background'] );
     435        }
     436
     437        /**
     438         * @ticket 49037
     439         */
     440        public function test_theme_supports_custom_background() {
     441                remove_theme_support( 'custom-background' );
     442                $background = array(
     443                        'default-image'          => '',
     444                        'default-preset'         => 'default',
     445                        'default-position-x'     => 'left',
     446                        'default-position-y'     => 'top',
     447                        'default-size'           => 'auto',
     448                        'default-repeat'         => 'repeat',
     449                        'default-attachment'     => 'scroll',
     450                        'default-color'          => '',
     451                        'wp-head-callback'       => '_custom_background_cb',
     452                        'admin-head-callback'    => '',
     453                        'admin-preview-callback' => '',
     454                );
     455                $excluded   = array(
     456                        'wp-head-callback',
     457                        'admin-head-callback',
     458                        'admin-preview-callback',
     459                );
     460                add_theme_support( 'custom-background', $background );
     461                $response = self::perform_active_theme_request();
     462                $result   = $response->get_data();
     463                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     464
     465                $expected = array_diff_key( $background, array_flip( $excluded ) );
     466                $this->assertEquals( $expected, $result[0]['theme_supports']['custom-background'] );
     467        }
     468
     469        /**
     470         * @ticket 49037
     471         */
     472        public function test_theme_does_not_support_html5() {
     473                remove_theme_support( 'html5' );
     474                $response = self::perform_active_theme_request();
     475                $result   = $response->get_data();
     476                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     477                $this->assertArrayHasKey( 'html5', $result[0]['theme_supports'] );
     478                $this->assertFalse( $result[0]['theme_supports']['html5'] );
     479        }
     480
     481        /**
     482         * @ticket 49037
     483         */
     484        public function test_theme_supports_html5() {
     485                remove_theme_support( 'html5' );
     486                $html5 = array(
     487                        'search-form',
     488                        'comment-form',
     489                        'comment-list',
     490                        'gallery',
     491                        'caption',
     492                        'script',
     493                        'style',
     494                );
     495                add_theme_support( 'html5', $html5 );
     496                $response = self::perform_active_theme_request();
     497                $result   = $response->get_data();
     498                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     499                $this->assertEquals( $html5, $result[0]['theme_supports']['html5'] );
     500        }
     501
     502        /**
     503         * @ticket 49037
     504         */
     505        public function test_theme_cannot_manage_title_tag() {
     506                remove_theme_support( 'title-tag' );
     507                $response = self::perform_active_theme_request();
     508                $result   = $response->get_data();
     509                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     510                $this->assertArrayHasKey( 'title-tag', $result[0]['theme_supports'] );
     511                $this->assertFalse( $result[0]['theme_supports']['title-tag'] );
     512        }
     513
     514        /**
     515         * @ticket 49037
     516         */
     517        public function test_theme_can_manage_title_tag() {
     518                global $_wp_theme_features;
     519                $_wp_theme_features['title-tag'] = true;
     520                $response                        = self::perform_active_theme_request();
     521                $result                          = $response->get_data();
     522                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     523                $this->assertTrue( $result[0]['theme_supports']['title-tag'] );
     524        }
    191525
    192                 $this->assertEquals( 3, count( $properties['theme_supports']['properties'] ) );
    193                 $this->assertArrayHasKey( 'formats', $properties['theme_supports']['properties'] );
    194                 $this->assertArrayHasKey( 'post-thumbnails', $properties['theme_supports']['properties'] );
    195                 $this->assertArrayHasKey( 'responsive-embeds', $properties['theme_supports']['properties'] );
     526        /**
     527         * @ticket 49037
     528         */
     529        public function test_theme_cannot_manage_selective_refresh_for_widgets() {
     530                remove_theme_support( 'customize-selective-refresh-widgets' );
     531                $response = self::perform_active_theme_request();
     532                $result   = $response->get_data();
     533                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     534                $this->assertArrayHasKey( 'customize-selective-refresh-widgets', $result[0]['theme_supports'] );
     535                $this->assertFalse( $result[0]['theme_supports']['customize-selective-refresh-widgets'] );
     536        }
     537
     538        /**
     539         * @ticket 49037
     540         */
     541        public function test_theme_can_manage_selective_refresh_for_widgets() {
     542                remove_theme_support( 'customize-selective-refresh-widgets' );
     543                add_theme_support( 'customize-selective-refresh-widgets' );
     544                $response = self::perform_active_theme_request();
     545                $result   = $response->get_data();
     546                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     547                $this->assertTrue( $result[0]['theme_supports']['customize-selective-refresh-widgets'] );
     548        }
     549
     550        /**
     551         * @ticket 49037
     552         */
     553        public function test_theme_no_wp_block_styles() {
     554                remove_theme_support( 'wp-block-styles' );
     555                $response = self::perform_active_theme_request();
     556                $result   = $response->get_data();
     557                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     558                $this->assertArrayHasKey( 'wp-block-styles', $result[0]['theme_supports'] );
     559                $this->assertFalse( $result[0]['theme_supports']['wp-block-styles'] );
     560        }
     561
     562        /**
     563         * @ticket 49037
     564         */
     565        public function test_theme_wp_block_styles_optin() {
     566                remove_theme_support( 'wp-block-styles' );
     567                add_theme_support( 'wp-block-styles' );
     568                $response = self::perform_active_theme_request();
     569                $result   = $response->get_data();
     570                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     571                $this->assertTrue( $result[0]['theme_supports']['wp-block-styles'] );
     572        }
     573
     574        /**
     575         * @ticket 49037
     576         */
     577        public function test_theme_no_align_wide() {
     578                remove_theme_support( 'align-wide' );
     579                $response = self::perform_active_theme_request();
     580                $result   = $response->get_data();
     581                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     582                $this->assertArrayHasKey( 'align-wide', $result[0]['theme_supports'] );
     583                $this->assertFalse( $result[0]['theme_supports']['align-wide'] );
     584        }
     585
     586        /**
     587         * @ticket 49037
     588         */
     589        public function test_theme_align_wide_optin() {
     590                remove_theme_support( 'align-wide' );
     591                add_theme_support( 'align-wide' );
     592                $response = self::perform_active_theme_request();
     593                $result   = $response->get_data();
     594                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     595                $this->assertTrue( $result[0]['theme_supports']['align-wide'] );
     596        }
     597
     598        /**
     599         * @ticket 49037
     600         */
     601        public function test_theme_no_editor_styles() {
     602                remove_theme_support( 'editor-styles' );
     603                $response = self::perform_active_theme_request();
     604                $result   = $response->get_data();
     605                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     606                $this->assertArrayHasKey( 'editor-styles', $result[0]['theme_supports'] );
     607                $this->assertFalse( $result[0]['theme_supports']['editor-styles'] );
     608        }
     609
     610        /**
     611         * @ticket 49037
     612         */
     613        public function test_theme_editor_styles_optin() {
     614                remove_theme_support( 'editor-styles' );
     615                add_theme_support( 'editor-styles' );
     616                $response = self::perform_active_theme_request();
     617                $result   = $response->get_data();
     618                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     619                $this->assertTrue( $result[0]['theme_supports']['editor-styles'] );
     620        }
     621
     622        /**
     623         * @ticket 49037
     624         */
     625        public function test_theme_no_dark_editor_style() {
     626                remove_theme_support( 'dark-editor-style' );
     627                $response = self::perform_active_theme_request();
     628                $result   = $response->get_data();
     629                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     630                $this->assertArrayHasKey( 'dark-editor-style', $result[0]['theme_supports'] );
     631                $this->assertFalse( $result[0]['theme_supports']['dark-editor-style'] );
     632        }
     633
     634        /**
     635         * @ticket 49037
     636         */
     637        public function test_theme_dark_editor_style_optin() {
     638                remove_theme_support( 'dark-editor-style' );
     639                add_theme_support( 'dark-editor-style' );
     640                $response = self::perform_active_theme_request();
     641                $result   = $response->get_data();
     642                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     643                $this->assertTrue( $result[0]['theme_supports']['dark-editor-style'] );
     644        }
     645
     646        /**
     647         * @ticket 49037
     648         */
     649        public function test_theme_no_disable_custom_gradients() {
     650                remove_theme_support( 'disable-custom-gradients' );
     651                $response = self::perform_active_theme_request();
     652                $result   = $response->get_data();
     653                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     654                $this->assertArrayHasKey( 'disable-custom-gradients', $result[0]['theme_supports'] );
     655                $this->assertFalse( $result[0]['theme_supports']['disable-custom-gradients'] );
     656        }
     657
     658        /**
     659         * @ticket 49037
     660         */
     661        public function test_theme_disable_custom_gradients() {
     662                remove_theme_support( 'disable-custom-gradients' );
     663                add_theme_support( 'disable-custom-gradients' );
     664                $response = self::perform_active_theme_request();
     665                $result   = $response->get_data();
     666                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     667                $this->assertTrue( $result[0]['theme_supports']['disable-custom-gradients'] );
     668        }
     669
     670        /**
     671         * @ticket 49037
     672         */
     673        public function test_theme_supports_editor_gradient_presets_array() {
     674                remove_theme_support( 'editor-gradient-presets' );
     675                $gradient = array(
     676                        'name'     => __( 'Vivid cyan blue to vivid purple', 'themeLangDomain' ),
     677                        'gradient' => 'linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)',
     678                        'slug'     => 'vivid-cyan-blue-to-vivid-purple',
     679                );
     680                add_theme_support( 'editor-gradient-presets', array( $gradient ) );
     681                $response = self::perform_active_theme_request();
     682                $result   = $response->get_data();
     683                $this->assertArrayHasKey( 'theme_supports', $result[0] );
     684                $this->assertEquals( array( $gradient ), $result[0]['theme_supports']['editor-gradient-presets'] );
    196685        }
    197686
    198687        /**