Make WordPress Core

Changeset 54043


Ignore:
Timestamp:
08/31/2022 10:44:04 PM (18 months ago)
Author:
flixos90
Message:

Site Health: Introduce page cache check.

This changeset adds a new page_cache check which determines whether the site uses a full page cache, and in addition assesses the server response time. If no page cache is present and the server response time is slow, the check will suggest use of a page cache.

A few filters are included for customization of the check:

  • site_status_good_response_time_threshold filters the number of milliseconds below which the server response time is considered good. The default value is based on the server-response-time Lighthouse audit and can be altered using this filter.
  • site_status_page_cache_supported_cache_headers filters the map of supported cache headers and their callback to determine whether it was a cache hit. The default list includes commonly used cache headers, and it is filterable to support e.g. additional cache headers used by specific vendors.

Note that due to the nature of this check it is only run in production environments.

Props furi3r, westonruter, spacedmonkey, swissspidy, Clorith.
Fixes #56041.

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/class-wp-site-health.php

    r54042 r54043  
    16681668
    16691669    /**
     1670     * Tests if a full page cache is available.
     1671     *
     1672     * @since 6.1.0
     1673     *
     1674     * @return array The test result.
     1675     */
     1676    public function get_test_page_cache() {
     1677        $description  = '<p>' . __( 'Page cache enhances the speed and performance of your site by saving and serving static pages instead of calling for a page every time a user visits.' ) . '</p>';
     1678        $description .= '<p>' . __( 'Page cache is detected by looking for an active page cache plugin as well as making three requests to the homepage and looking for one or more of the following HTTP client caching response headers:' ) . '</p>';
     1679        $description .= '<code>' . implode( '</code>, <code>', array_keys( $this->get_page_cache_headers() ) ) . '.</code>';
     1680
     1681        $result = array(
     1682            'badge'       => array(
     1683                'label' => __( 'Performance' ),
     1684                'color' => 'blue',
     1685            ),
     1686            'description' => wp_kses_post( $description ),
     1687            'test'        => 'page_cache',
     1688            'status'      => 'good',
     1689            'label'       => '',
     1690            'actions'     => sprintf(
     1691                '<p><a href="%1$s" target="_blank" rel="noopener noreferrer">%2$s <span class="screen-reader-text">%3$s</span><span aria-hidden="true" class="dashicons dashicons-external"></span></a></p>',
     1692                __( 'https://wordpress.org/support/article/optimization/#Caching' ),
     1693                __( 'Learn more about page cache' ),
     1694                /* translators: Accessibility text. */
     1695                __( '(opens in a new tab)' )
     1696            ),
     1697        );
     1698
     1699        $page_cache_detail = $this->get_page_cache_detail();
     1700
     1701        if ( is_wp_error( $page_cache_detail ) ) {
     1702            $result['label']  = __( 'Unable to detect the presence of page cache' );
     1703            $result['status'] = 'recommended';
     1704            $error_info       = sprintf(
     1705            /* translators: 1 is error message, 2 is error code */
     1706                __( 'Unable to detect page cache due to possible loopback request problem. Please verify that the loopback request test is passing. Error: %1$s (Code: %2$s)' ),
     1707                $page_cache_detail->get_error_message(),
     1708                $page_cache_detail->get_error_code()
     1709            );
     1710            $result['description'] = wp_kses_post( "<p>$error_info</p>" ) . $result['description'];
     1711            return $result;
     1712        }
     1713
     1714        $result['status'] = $page_cache_detail['status'];
     1715
     1716        switch ( $page_cache_detail['status'] ) {
     1717            case 'recommended':
     1718                $result['label'] = __( 'Page cache is not detected but the server response time is OK' );
     1719                break;
     1720            case 'good':
     1721                $result['label'] = __( 'Page cache is detected and the server response time is good' );
     1722                break;
     1723            default:
     1724                if ( empty( $page_cache_detail['headers'] ) && ! $page_cache_detail['advanced_cache_present'] ) {
     1725                    $result['label'] = __( 'Page cache is not detected and the server response time is slow' );
     1726                } else {
     1727                    $result['label'] = __( 'Page cache is detected but the server response time is still slow' );
     1728                }
     1729        }
     1730
     1731        $page_cache_test_summary = array();
     1732
     1733        if ( empty( $page_cache_detail['response_time'] ) ) {
     1734            $page_cache_test_summary[] = '<span class="dashicons dashicons-dismiss"></span> ' . __( 'Server response time could not be determined. Verify that loopback requests are working.' );
     1735        } else {
     1736
     1737            $threshold = $this->get_good_response_time_threshold();
     1738            if ( $page_cache_detail['response_time'] < $threshold ) {
     1739                $page_cache_test_summary[] = '<span class="dashicons dashicons-yes-alt"></span> ' . sprintf(
     1740                    /* translators: 1: The response time in milliseconds. 2: The recommended threshold milliseconds. */
     1741                    __( 'Median server response time was %1$s milliseconds. This is less than the recommended %2$s milliseconds threshold.' ),
     1742                    number_format_i18n( $page_cache_detail['response_time'] ),
     1743                    number_format_i18n( $threshold )
     1744                );
     1745            } else {
     1746                $page_cache_test_summary[] = '<span class="dashicons dashicons-warning"></span> ' . sprintf(
     1747                    /* translators: 1: The response time in milliseconds. 2: The recommended threshold milliseconds. */
     1748                    __( 'Median server response time was %1$s milliseconds. It should be less than the recommended %2$s milliseconds threshold.' ),
     1749                    number_format_i18n( $page_cache_detail['response_time'] ),
     1750                    number_format_i18n( $threshold )
     1751                );
     1752            }
     1753
     1754            if ( empty( $page_cache_detail['headers'] ) ) {
     1755                $page_cache_test_summary[] = '<span class="dashicons dashicons-warning"></span> ' . __( 'No client caching response headers were detected.' );
     1756            } else {
     1757                $headers_summary  = '<span class="dashicons dashicons-yes-alt"></span>';
     1758                $headers_summary .= sprintf(
     1759                /* translators: Placeholder is number of caching headers */
     1760                    _n(
     1761                        ' There was %d client caching response header detected: ',
     1762                        ' There were %d client caching response headers detected: ',
     1763                        count( $page_cache_detail['headers'] )
     1764                    ),
     1765                    count( $page_cache_detail['headers'] )
     1766                );
     1767                $headers_summary          .= '<code>' . implode( '</code>, <code>', $page_cache_detail['headers'] ) . '</code>.';
     1768                $page_cache_test_summary[] = $headers_summary;
     1769            }
     1770        }
     1771
     1772        if ( $page_cache_detail['advanced_cache_present'] ) {
     1773            $page_cache_test_summary[] = '<span class="dashicons dashicons-yes-alt"></span> ' . __( 'A page cache plugin was detected.' );
     1774        } elseif ( ! ( is_array( $page_cache_detail ) && ! empty( $page_cache_detail['headers'] ) ) ) {
     1775            // Note: This message is not shown if client caching response headers were present since an external caching layer may be employed.
     1776            $page_cache_test_summary[] = '<span class="dashicons dashicons-warning"></span> ' . __( 'A page cache plugin was not detected.' );
     1777        }
     1778
     1779        $result['description'] .= '<ul><li>' . implode( '</li><li>', $page_cache_test_summary ) . '</li></ul>';
     1780        return $result;
     1781    }
     1782
     1783    /**
    16701784     * Check if the HTTP API can handle SSL/TLS requests.
    16711785     *
    16721786     * @since 5.2.0
    16731787     *
    1674      * @return array The test results.
     1788     * @return array The test result.
    16751789     */
    16761790    public function get_test_ssl_support() {
     
    24832597        }
    24842598
    2485         // Only check for a persistent object cache in production environments to not unnecessarily promote complicated setups.
     2599        // Only check for caches in production environments.
    24862600        if ( 'production' === wp_get_environment_type() ) {
     2601            $tests['async']['page_cache'] = array(
     2602                'label'             => __( 'Page cache' ),
     2603                'test'              => rest_url( 'wp-site-health/v1/tests/page-cache' ),
     2604                'has_rest'          => true,
     2605                'async_direct_test' => array( WP_Site_Health::get_instance(), 'get_test_page_cache' ),
     2606            );
     2607
    24872608            $tests['direct']['persistent_object_cache'] = array(
    24882609                'label' => __( 'Persistent object cache' ),
     
    29673088
    29683089    /**
     3090     * Returns a list of headers and its verification callback to verify if page cache is enabled or not.
     3091     *
     3092     * Note: key is header name and value could be callable function to verify header value.
     3093     * Empty value mean existence of header detect page cache is enabled.
     3094     *
     3095     * @since 6.1.0
     3096     *
     3097     * @return array List of client caching headers and their (optional) verification callbacks.
     3098     */
     3099    public function get_page_cache_headers() {
     3100
     3101        $cache_hit_callback = static function ( $header_value ) {
     3102            return false !== strpos( strtolower( $header_value ), 'hit' );
     3103        };
     3104
     3105        $cache_headers = array(
     3106            'cache-control'          => static function ( $header_value ) {
     3107                return (bool) preg_match( '/max-age=[1-9]/', $header_value );
     3108            },
     3109            'expires'                => static function ( $header_value ) {
     3110                return strtotime( $header_value ) > time();
     3111            },
     3112            'age'                    => static function ( $header_value ) {
     3113                return is_numeric( $header_value ) && $header_value > 0;
     3114            },
     3115            'last-modified'          => '',
     3116            'etag'                   => '',
     3117            'x-cache-enabled'        => static function ( $header_value ) {
     3118                return 'true' === strtolower( $header_value );
     3119            },
     3120            'x-cache-disabled'       => static function ( $header_value ) {
     3121                return ( 'on' !== strtolower( $header_value ) );
     3122            },
     3123            'x-srcache-store-status' => $cache_hit_callback,
     3124            'x-srcache-fetch-status' => $cache_hit_callback,
     3125        );
     3126
     3127        /**
     3128         * Filters the list of cache headers supported by core.
     3129         *
     3130         * @since 6.1.0
     3131         *
     3132         * @param int $cache_headers Array of supported cache headers.
     3133         */
     3134        return apply_filters( 'site_status_page_cache_supported_cache_headers', $cache_headers );
     3135    }
     3136
     3137    /**
     3138     * Checks if site has page cache enabled or not.
     3139     *
     3140     * @since 6.1.0
     3141     *
     3142     * @return WP_Error|array {
     3143     *     Page cache detection details or else error information.
     3144     *
     3145     *     @type bool    $advanced_cache_present        Whether a page cache plugin is present.
     3146     *     @type array[] $page_caching_response_headers Sets of client caching headers for the responses.
     3147     *     @type float[] $response_timing               Response timings.
     3148     * }
     3149     */
     3150    private function check_for_page_caching() {
     3151
     3152        /** This filter is documented in wp-includes/class-wp-http-streams.php */
     3153        $sslverify = apply_filters( 'https_local_ssl_verify', false );
     3154
     3155        $headers = array();
     3156
     3157        // Include basic auth in loopback requests. Note that this will only pass along basic auth when user is
     3158        // initiating the test. If a site requires basic auth, the test will fail when it runs in WP Cron as part of
     3159        // wp_site_health_scheduled_check. This logic is copied from WP_Site_Health::can_perform_loopback().
     3160        if ( isset( $_SERVER['PHP_AUTH_USER'] ) && isset( $_SERVER['PHP_AUTH_PW'] ) ) {
     3161            $headers['Authorization'] = 'Basic ' . base64_encode( wp_unslash( $_SERVER['PHP_AUTH_USER'] ) . ':' . wp_unslash( $_SERVER['PHP_AUTH_PW'] ) );
     3162        }
     3163
     3164        $caching_headers               = $this->get_page_cache_headers();
     3165        $page_caching_response_headers = array();
     3166        $response_timing               = array();
     3167
     3168        for ( $i = 1; $i <= 3; $i++ ) {
     3169            $start_time    = microtime( true );
     3170            $http_response = wp_remote_get( home_url( '/' ), compact( 'sslverify', 'headers' ) );
     3171            $end_time      = microtime( true );
     3172
     3173            if ( is_wp_error( $http_response ) ) {
     3174                return $http_response;
     3175            }
     3176            if ( wp_remote_retrieve_response_code( $http_response ) !== 200 ) {
     3177                return new WP_Error(
     3178                    'http_' . wp_remote_retrieve_response_code( $http_response ),
     3179                    wp_remote_retrieve_response_message( $http_response )
     3180                );
     3181            }
     3182
     3183            $response_headers = array();
     3184
     3185            foreach ( $caching_headers as $header => $callback ) {
     3186                $header_values = wp_remote_retrieve_header( $http_response, $header );
     3187                if ( empty( $header_values ) ) {
     3188                    continue;
     3189                }
     3190                $header_values = (array) $header_values;
     3191                if ( empty( $callback ) || ( is_callable( $callback ) && count( array_filter( $header_values, $callback ) ) > 0 ) ) {
     3192                    $response_headers[ $header ] = $header_values;
     3193                }
     3194            }
     3195
     3196            $page_caching_response_headers[] = $response_headers;
     3197            $response_timing[]               = ( $end_time - $start_time ) * 1000;
     3198        }
     3199
     3200        return array(
     3201            'advanced_cache_present'        => (
     3202                file_exists( WP_CONTENT_DIR . '/advanced-cache.php' )
     3203                &&
     3204                ( defined( 'WP_CACHE' ) && WP_CACHE )
     3205                &&
     3206                /** This filter is documented in wp-settings.php */
     3207                apply_filters( 'enable_loading_advanced_cache_dropin', true )
     3208            ),
     3209            'page_caching_response_headers' => $page_caching_response_headers,
     3210            'response_timing'               => $response_timing,
     3211        );
     3212    }
     3213
     3214    /**
     3215     * Get page cache details.
     3216     *
     3217     * @since 6.1.0
     3218     *
     3219     * @return WP_Error|array {
     3220     *    Page cache detail or else a WP_Error if unable to determine.
     3221     *
     3222     *    @type string   $status                 Page cache status. Good, Recommended or Critical.
     3223     *    @type bool     $advanced_cache_present Whether page cache plugin is available or not.
     3224     *    @type string[] $headers                Client caching response headers detected.
     3225     *    @type float    $response_time          Response time of site.
     3226     * }
     3227     */
     3228    private function get_page_cache_detail() {
     3229        $page_cache_detail = $this->check_for_page_caching();
     3230        if ( is_wp_error( $page_cache_detail ) ) {
     3231            return $page_cache_detail;
     3232        }
     3233
     3234        // Use the median server response time.
     3235        $response_timings = $page_cache_detail['response_timing'];
     3236        rsort( $response_timings );
     3237        $page_speed = $response_timings[ floor( count( $response_timings ) / 2 ) ];
     3238
     3239        // Obtain unique set of all client caching response headers.
     3240        $headers = array();
     3241        foreach ( $page_cache_detail['page_caching_response_headers'] as $page_caching_response_headers ) {
     3242            $headers = array_merge( $headers, array_keys( $page_caching_response_headers ) );
     3243        }
     3244        $headers = array_unique( $headers );
     3245
     3246        // Page cache is detected if there are response headers or a page cache plugin is present.
     3247        $has_page_caching = ( count( $headers ) > 0 || $page_cache_detail['advanced_cache_present'] );
     3248
     3249        if ( $page_speed && $page_speed < $this->get_good_response_time_threshold() ) {
     3250            $result = $has_page_caching ? 'good' : 'recommended';
     3251        } else {
     3252            $result = 'critical';
     3253        }
     3254
     3255        return array(
     3256            'status'                 => $result,
     3257            'advanced_cache_present' => $page_cache_detail['advanced_cache_present'],
     3258            'headers'                => $headers,
     3259            'response_time'          => $page_speed,
     3260        );
     3261    }
     3262
     3263    /**
     3264     * Get the threshold below which a response time is considered good.
     3265     *
     3266     * @since 6.1.0
     3267     *
     3268     * @return int Threshold in milliseconds.
     3269     */
     3270    private function get_good_response_time_threshold() {
     3271        /**
     3272         * Filters the threshold below which a response time is considered good.
     3273         *
     3274         * The default is based on https://web.dev/time-to-first-byte/.
     3275         *
     3276         * @param int $threshold Threshold in milliseconds. Default 600.
     3277         *
     3278         * @since 6.1.0
     3279         */
     3280        return (int) apply_filters( 'site_status_good_response_time_threshold', 600 );
     3281    }
     3282
     3283    /**
    29693284     * Determines whether to suggest using a persistent object cache.
    29703285     *
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-site-health-controller.php

    r50072 r54043  
    4444     *
    4545     * @since 5.6.0
     46     * @since 6.1.0 Adds page-cache async test.
    4647     *
    4748     * @see register_rest_route()
     
    155156                    return $this->validate_request_permission( 'debug_enabled' ) && ! is_multisite();
    156157                },
     158            )
     159        );
     160
     161        register_rest_route(
     162            $this->namespace,
     163            sprintf(
     164                '/%s/%s',
     165                $this->rest_base,
     166                'page-cache'
     167            ),
     168            array(
     169                array(
     170                    'methods'             => 'GET',
     171                    'callback'            => array( $this, 'test_page_cache' ),
     172                    'permission_callback' => function () {
     173                        return $this->validate_request_permission( 'view_site_health_checks' );
     174                    },
     175                ),
    157176            )
    158177        );
     
    241260        $this->load_admin_textdomain();
    242261        return $this->site_health->get_test_authorization_header();
     262    }
     263
     264    /**
     265     * Checks that full page cache is active.
     266     *
     267     * @since 6.1.0
     268     *
     269     * @return array The test result.
     270     */
     271    public function test_page_cache() {
     272        $this->load_admin_textdomain();
     273        return $this->site_health->get_test_page_cache();
    243274    }
    244275
  • trunk/tests/phpunit/tests/rest-api/rest-schema-setup.php

    r53464 r54043  
    184184            '/wp-site-health/v1/tests/dotorg-communication',
    185185            '/wp-site-health/v1/tests/authorization-header',
     186            '/wp-site-health/v1/tests/page-cache',
    186187            '/wp-site-health/v1/directory-sizes',
    187188        );
  • trunk/tests/phpunit/tests/rest-api/rest-site-health-controller.php

    r49603 r54043  
    100100        $this->assertSame( 'dotorg_communication', $response->get_data()['test'] );
    101101    }
     102
     103    /**
     104     * Tests Page Cache Rest endpoint registration.
     105     *
     106     * @ticket 56041
     107     */
     108    public function test_page_cache_endpoint() {
     109        $server = rest_get_server();
     110        $routes = $server->get_routes();
     111
     112        $endpoint = '/wp-site-health/v1/tests/page-cache';
     113        $this->assertArrayHasKey( $endpoint, $routes );
     114
     115        $route = $routes[ $endpoint ];
     116        $this->assertCount( 1, $route );
     117
     118        $route = current( $route );
     119        $this->assertEquals(
     120            array( WP_REST_Server::READABLE => true ),
     121            $route['methods']
     122        );
     123
     124        $this->assertEquals(
     125            'test_page_cache',
     126            $route['callback'][1]
     127        );
     128
     129        $this->assertIsCallable( $route['permission_callback'] );
     130
     131        if ( current_user_can( 'view_site_health_checks' ) ) {
     132            $this->assertTrue( call_user_func( $route['permission_callback'] ) );
     133        } else {
     134            $this->assertFalse( call_user_func( $route['permission_callback'] ) );
     135        }
     136
     137        wp_set_current_user( self::factory()->user->create( array( 'role' => 'author' ) ) );
     138        $this->assertFalse( call_user_func( $route['permission_callback'] ) );
     139
     140        $user = wp_set_current_user( self::factory()->user->create( array( 'role' => 'administrator' ) ) );
     141        if ( is_multisite() ) {
     142            // Site health cap is only available for super admins in Multi sites.
     143            grant_super_admin( $user->ID );
     144        }
     145        $this->assertTrue( call_user_func( $route['permission_callback'] ) );
     146    }
    102147}
  • trunk/tests/phpunit/tests/site-health.php

    r53955 r54043  
    110110
    111111    /**
     112     * @ticket 56041
     113     * @dataProvider data_page_cache_test
     114     * @covers ::get_test_page_cache()
     115     * @covers ::get_page_cache_detail()
     116     * @covers ::get_page_cache_headers()
     117     * @covers ::check_for_page_caching()
     118     */
     119    public function test_get_page_cache( $responses, $expected_status, $expected_label, $good_basic_auth = null, $delay_the_response = false ) {
     120        $wp_site_health = new WP_Site_Health();
     121
     122        $expected_props = array(
     123            'badge'  => array(
     124                'label' => __( 'Performance' ),
     125                'color' => 'blue',
     126            ),
     127            'test'   => 'page_cache',
     128            'status' => $expected_status,
     129            'label'  => $expected_label,
     130        );
     131
     132        if ( null !== $good_basic_auth ) {
     133            $_SERVER['PHP_AUTH_USER'] = 'admin';
     134            $_SERVER['PHP_AUTH_PW']   = 'password';
     135        }
     136
     137        $threshold = 10;
     138        if ( $delay_the_response ) {
     139            add_filter(
     140                'site_status_good_response_time_threshold',
     141                static function () use ( $threshold ) {
     142                    return $threshold;
     143                }
     144            );
     145        }
     146
     147        add_filter(
     148            'pre_http_request',
     149            function ( $r, $parsed_args ) use ( &$responses, &$is_unauthorized, $good_basic_auth, $delay_the_response, $threshold ) {
     150
     151                $expected_response = array_shift( $responses );
     152
     153                if ( $delay_the_response ) {
     154                    usleep( $threshold * 1000 + 1 );
     155                }
     156
     157                if ( 'unauthorized' === $expected_response ) {
     158                    $is_unauthorized = true;
     159
     160                    return array(
     161                        'response' => array(
     162                            'code'    => 401,
     163                            'message' => 'Unauthorized',
     164                        ),
     165                    );
     166                }
     167
     168                if ( null !== $good_basic_auth ) {
     169                    $this->assertArrayHasKey(
     170                        'Authorization',
     171                        $parsed_args['headers']
     172                    );
     173                }
     174
     175                $this->assertIsArray( $expected_response );
     176
     177                return array(
     178                    'headers'  => $expected_response,
     179                    'response' => array(
     180                        'code'    => 200,
     181                        'message' => 'OK',
     182                    ),
     183                );
     184            },
     185            20,
     186            2
     187        );
     188
     189        $actual = $wp_site_health->get_test_page_cache();
     190        $this->assertArrayHasKey( 'description', $actual );
     191        $this->assertArrayHasKey( 'actions', $actual );
     192        if ( $is_unauthorized ) {
     193            $this->assertStringContainsString( 'Unauthorized', $actual['description'] );
     194        } else {
     195            $this->assertStringNotContainsString( 'Unauthorized', $actual['description'] );
     196        }
     197
     198        $this->assertEquals(
     199            $expected_props,
     200            wp_array_slice_assoc( $actual, array_keys( $expected_props ) )
     201        );
     202    }
     203
     204    /**
    112205     * @group ms-excluded
    113206     * @ticket 56040
     
    160253        $this->assertTrue(
    161254            $wp_site_health->should_suggest_persistent_object_cache()
     255        );
     256    }
     257
     258    /**
     259     * Gets response data for get_test_page_cache().
     260     * @ticket 56041
     261     *
     262     * @return array[]
     263     */
     264    public function data_page_cache_test() {
     265        $recommended_label = 'Page cache is not detected but the server response time is OK';
     266        $good_label        = 'Page cache is detected and the server response time is good';
     267        $critical_label    = 'Page cache is not detected and the server response time is slow';
     268        $error_label       = 'Unable to detect the presence of page cache';
     269
     270        return array(
     271            'basic-auth-fail'                        => array(
     272                'responses'       => array(
     273                    'unauthorized',
     274                ),
     275                'expected_status' => 'recommended',
     276                'expected_label'  => $error_label,
     277                'good_basic_auth' => false,
     278            ),
     279            'no-cache-control'                       => array(
     280                'responses'          => array_fill( 0, 3, array() ),
     281                'expected_status'    => 'critical',
     282                'expected_label'     => $critical_label,
     283                'good_basic_auth'    => null,
     284                'delay_the_response' => true,
     285            ),
     286            'no-cache'                               => array(
     287                'responses'       => array_fill( 0, 3, array( 'cache-control' => 'no-cache' ) ),
     288                'expected_status' => 'recommended',
     289                'expected_label'  => $recommended_label,
     290            ),
     291            'no-cache-arrays'                        => array(
     292                'responses'       => array_fill(
     293                    0,
     294                    3,
     295                    array(
     296                        'cache-control' => array(
     297                            'no-cache',
     298                            'no-store',
     299                        ),
     300                    )
     301                ),
     302                'expected_status' => 'recommended',
     303                'expected_label'  => $recommended_label,
     304            ),
     305            'no-cache-with-delayed-response'         => array(
     306                'responses'          => array_fill( 0, 3, array( 'cache-control' => 'no-cache' ) ),
     307                'expected_status'    => 'critical',
     308                'expected_label'     => $critical_label,
     309                'good_basic_auth'    => null,
     310                'delay_the_response' => true,
     311            ),
     312            'age'                                    => array(
     313                'responses'       => array_fill(
     314                    0,
     315                    3,
     316                    array( 'age' => '1345' )
     317                ),
     318                'expected_status' => 'good',
     319                'expected_label'  => $good_label,
     320            ),
     321            'cache-control-max-age'                  => array(
     322                'responses'       => array_fill(
     323                    0,
     324                    3,
     325                    array( 'cache-control' => 'public; max-age=600' )
     326                ),
     327                'expected_status' => 'good',
     328                'expected_label'  => $good_label,
     329            ),
     330            'etag'                                   => array(
     331                'responses'       => array_fill(
     332                    0,
     333                    3,
     334                    array( 'etag' => '"1234567890"' )
     335                ),
     336                'expected_status' => 'good',
     337                'expected_label'  => $good_label,
     338            ),
     339            'cache-control-max-age-after-2-requests' => array(
     340                'responses'       => array(
     341                    array(),
     342                    array(),
     343                    array( 'cache-control' => 'public; max-age=600' ),
     344                ),
     345                'expected_status' => 'good',
     346                'expected_label'  => $good_label,
     347            ),
     348            'cache-control-with-future-expires'      => array(
     349                'responses'       => array_fill(
     350                    0,
     351                    3,
     352                    array( 'expires' => gmdate( 'r', time() + MINUTE_IN_SECONDS * 10 ) )
     353                ),
     354                'expected_status' => 'good',
     355                'expected_label'  => $good_label,
     356            ),
     357            'cache-control-with-past-expires'        => array(
     358                'responses'          => array_fill(
     359                    0,
     360                    3,
     361                    array( 'expires' => gmdate( 'r', time() - MINUTE_IN_SECONDS * 10 ) )
     362                ),
     363                'expected_status'    => 'critical',
     364                'expected_label'     => $critical_label,
     365                'good_basic_auth'    => null,
     366                'delay_the_response' => true,
     367            ),
     368            'cache-control-with-basic-auth'          => array(
     369                'responses'       => array_fill(
     370                    0,
     371                    3,
     372                    array( 'cache-control' => 'public; max-age=600' )
     373                ),
     374                'expected_status' => 'good',
     375                'expected_label'  => $good_label,
     376                'good_basic_auth' => true,
     377            ),
     378            'x-cache-enabled'                        => array(
     379                'responses'       => array_fill(
     380                    0,
     381                    3,
     382                    array( 'x-cache-enabled' => 'true' )
     383                ),
     384                'expected_status' => 'good',
     385                'expected_label'  => $good_label,
     386            ),
     387            'x-cache-enabled-with-delay'             => array(
     388                'responses'          => array_fill(
     389                    0,
     390                    3,
     391                    array( 'x-cache-enabled' => 'false' )
     392                ),
     393                'expected_status'    => 'critical',
     394                'expected_label'     => $critical_label,
     395                'good_basic_auth'    => null,
     396                'delay_the_response' => true,
     397            ),
     398            'x-cache-disabled'                       => array(
     399                'responses'       => array_fill(
     400                    0,
     401                    3,
     402                    array( 'x-cache-disabled' => 'off' )
     403                ),
     404                'expected_status' => 'good',
     405                'expected_label'  => $good_label,
     406            ),
    162407        );
    163408    }
  • trunk/tests/qunit/fixtures/wp-api-generated.js

    r53815 r54043  
    1061610616            }
    1061710617        },
     10618        "/wp-site-health/v1/tests/page-cache": {
     10619            "namespace": "wp-site-health/v1",
     10620            "methods": [
     10621                "GET"
     10622            ],
     10623            "endpoints": [
     10624                {
     10625                    "methods": [
     10626                        "GET"
     10627                    ],
     10628                    "args": []
     10629                }
     10630            ],
     10631            "_links": {
     10632                "self": [
     10633                    {
     10634                        "href": "http://example.org/index.php?rest_route=/wp-site-health/v1/tests/page-cache"
     10635                    }
     10636                ]
     10637            }
     10638        },
    1061810639        "/wp-block-editor/v1": {
    1061910640            "namespace": "wp-block-editor/v1",
Note: See TracChangeset for help on using the changeset viewer.