From 8ae3a2642bc967b2291401053dfb28b2978fca2c Mon Sep 17 00:00:00 2001 From: Timothy Jacobs Date: Tue, 11 Mar 2025 14:17:41 +0000 Subject: [PATCH] REST API: Fix fatal error when making HEAD requests with _fields filter. In [59889] the REST API controllers were adjusted to perform less work when responding to HEAD requests. The WP_REST_Response body would now be `null`, which caused issues with filters that expected the response body to be an array. This commit sets the response body to be an empty array when preparing the response instead. The body will still be discarded, but this provides better backward comppatibility with code that assumes an array will be used. See #56481. Props antonvlasenko, timothyblynjacobs, mamaduka, wildworks. git-svn-id: https://develop.svn.wordpress.org/trunk@59970 602fd350-edb4-49c9-b593-d223f7449a82 --- .../class-wp-rest-autosaves-controller.php | 4 +- ...st-block-pattern-categories-controller.php | 2 +- .../class-wp-rest-block-types-controller.php | 4 +- .../class-wp-rest-comments-controller.php | 4 +- ...ss-wp-rest-font-collections-controller.php | 6 +- ...est-global-styles-revisions-controller.php | 4 +- ...s-wp-rest-pattern-directory-controller.php | 2 +- .../class-wp-rest-post-types-controller.php | 4 +- .../class-wp-rest-posts-controller.php | 4 +- .../class-wp-rest-revisions-controller.php | 4 +- .../class-wp-rest-search-controller.php | 2 +- .../class-wp-rest-sidebars-controller.php | 4 +- .../class-wp-rest-taxonomies-controller.php | 4 +- .../class-wp-rest-templates-controller.php | 4 +- .../class-wp-rest-terms-controller.php | 4 +- .../class-wp-rest-users-controller.php | 4 +- .../class-wp-rest-widget-types-controller.php | 4 +- .../class-wp-rest-widgets-controller.php | 4 +- .../wpRestFontCollectionsController.php | 4 +- .../rest-api/rest-autosaves-controller.php | 35 ++++++++- .../rest-api/rest-block-type-controller.php | 35 ++++++++- .../rest-api/rest-categories-controller.php | 32 +++++++- .../rest-api/rest-comments-controller.php | 32 +++++++- ...est-global-styles-revisions-controller.php | 35 ++++++++- .../rest-pattern-directory-controller.php | 19 ++++- .../rest-api/rest-post-types-controller.php | 34 +++++++- .../tests/rest-api/rest-posts-controller.php | 52 ++++++++++--- .../rest-api/rest-revisions-controller.php | 36 ++++++++- .../rest-api/rest-sidebars-controller.php | 43 ++++++++++- .../tests/rest-api/rest-tags-controller.php | 33 +++++++- .../rest-api/rest-taxonomies-controller.php | 34 +++++++- .../tests/rest-api/rest-users-controller.php | 39 +++++++++- .../rest-api/rest-widget-types-controller.php | 35 ++++++++- .../rest-api/rest-widgets-controller.php | 65 +++++++++++++++- ...wpRestBlockPatternCategoriesController.php | 20 ++++- .../wpRestTemplateAutosavesController.php | 77 ++++++++++++++++++- .../wpRestTemplateRevisionsController.php | 63 ++++++++++++++- .../rest-api/wpRestTemplatesController.php | 35 ++++++++- 38 files changed, 747 insertions(+), 79 deletions(-) diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php index 43fd8d3b29..2e093f6656 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php @@ -307,7 +307,7 @@ class WP_REST_Autosaves_Controller extends WP_REST_Revisions_Controller { if ( $request->is_method( 'HEAD' ) ) { // Return early as this handler doesn't add any response headers. - return new WP_REST_Response(); + return new WP_REST_Response( array() ); } $response = array(); $parent_id = $parent->ID; @@ -455,7 +455,7 @@ class WP_REST_Autosaves_Controller extends WP_REST_Revisions_Controller { // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php */ - return apply_filters( 'rest_prepare_autosave', new WP_REST_Response(), $post, $request ); + return apply_filters( 'rest_prepare_autosave', new WP_REST_Response( array() ), $post, $request ); } $response = $this->revisions_controller->prepare_item_for_response( $post, $request ); $fields = $this->get_fields_for_response( $request ); diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-block-pattern-categories-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-block-pattern-categories-controller.php index 86ee4cdc52..17efc869f8 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-block-pattern-categories-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-block-pattern-categories-controller.php @@ -83,7 +83,7 @@ class WP_REST_Block_Pattern_Categories_Controller extends WP_REST_Controller { public function get_items( $request ) { if ( $request->is_method( 'HEAD' ) ) { // Return early as this handler doesn't add any response headers. - return new WP_REST_Response(); + return new WP_REST_Response( array() ); } $response = array(); diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-block-types-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-block-types-controller.php index f167d72255..9b099a44a2 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-block-types-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-block-types-controller.php @@ -133,7 +133,7 @@ class WP_REST_Block_Types_Controller extends WP_REST_Controller { public function get_items( $request ) { if ( $request->is_method( 'HEAD' ) ) { // Return early as this handler doesn't add any response headers. - return new WP_REST_Response(); + return new WP_REST_Response( array() ); } $data = array(); @@ -258,7 +258,7 @@ class WP_REST_Block_Types_Controller extends WP_REST_Controller { // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-block-types-controller.php */ - return apply_filters( 'rest_prepare_block_type', new WP_REST_Response(), $block_type, $request ); + return apply_filters( 'rest_prepare_block_type', new WP_REST_Response( array() ), $block_type, $request ); } $fields = $this->get_fields_for_response( $request ); diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php index 57214ef62e..a0b68759f9 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php @@ -313,7 +313,7 @@ class WP_REST_Comments_Controller extends WP_REST_Controller { $max_pages = (int) ceil( $total_comments / $request['per_page'] ); } - $response = $is_head_request ? new WP_REST_Response() : rest_ensure_response( $comments ); + $response = $is_head_request ? new WP_REST_Response( array() ) : rest_ensure_response( $comments ); $response->header( 'X-WP-Total', $total_comments ); $response->header( 'X-WP-TotalPages', $max_pages ); @@ -1054,7 +1054,7 @@ class WP_REST_Comments_Controller extends WP_REST_Controller { // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php */ - return apply_filters( 'rest_prepare_comment', new WP_REST_Response(), $comment, $request ); + return apply_filters( 'rest_prepare_comment', new WP_REST_Response( array() ), $comment, $request ); } $fields = $this->get_fields_for_response( $request ); diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-font-collections-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-font-collections-controller.php index 476f1b750f..3a726681f0 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-font-collections-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-font-collections-controller.php @@ -113,7 +113,7 @@ class WP_REST_Font_Collections_Controller extends WP_REST_Controller { $items[] = $item; } - $response = $is_head_request ? new WP_REST_Response() : rest_ensure_response( $items ); + $response = $is_head_request ? new WP_REST_Response( array() ) : rest_ensure_response( $items ); $response->header( 'X-WP-Total', (int) $total_items ); $response->header( 'X-WP-TotalPages', $max_pages ); @@ -193,7 +193,7 @@ class WP_REST_Font_Collections_Controller extends WP_REST_Controller { */ if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-font-collections-controller.php */ - return apply_filters( 'rest_prepare_font_collection', new WP_REST_Response(), $item, $request ); + return apply_filters( 'rest_prepare_font_collection', new WP_REST_Response( array() ), $item, $request ); } foreach ( $data_fields as $field ) { @@ -209,7 +209,7 @@ class WP_REST_Font_Collections_Controller extends WP_REST_Controller { */ if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-font-collections-controller.php */ - return apply_filters( 'rest_prepare_font_collection', new WP_REST_Response(), $item, $request ); + return apply_filters( 'rest_prepare_font_collection', new WP_REST_Response( array() ), $item, $request ); } $response = rest_ensure_response( $data ); diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php index e214ab6d39..b80b8d8812 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php @@ -248,7 +248,7 @@ class WP_REST_Global_Styles_Revisions_Controller extends WP_REST_Revisions_Contr $response = rest_ensure_response( $response ); } else { - $response = new WP_REST_Response(); + $response = new WP_REST_Response( array() ); } $response->header( 'X-WP-Total', (int) $total_revisions ); @@ -291,7 +291,7 @@ class WP_REST_Global_Styles_Revisions_Controller extends WP_REST_Revisions_Contr public function prepare_item_for_response( $post, $request ) { // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { - return new WP_REST_Response(); + return new WP_REST_Response( array() ); } $parent = $this->get_parent( $request['parent'] ); diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-pattern-directory-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-pattern-directory-controller.php index 4dda8b3455..bec92f1c7e 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-pattern-directory-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-pattern-directory-controller.php @@ -163,7 +163,7 @@ class WP_REST_Pattern_Directory_Controller extends WP_REST_Controller { if ( $request->is_method( 'HEAD' ) ) { // Return early as this handler doesn't add any response headers. - return new WP_REST_Response(); + return new WP_REST_Response( array() ); } $response = array(); diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-post-types-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-post-types-controller.php index 6ead90af59..0a66389346 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-post-types-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-post-types-controller.php @@ -111,7 +111,7 @@ class WP_REST_Post_Types_Controller extends WP_REST_Controller { public function get_items( $request ) { if ( $request->is_method( 'HEAD' ) ) { // Return early as this handler doesn't add any response headers. - return new WP_REST_Response(); + return new WP_REST_Response( array() ); } $data = array(); @@ -186,7 +186,7 @@ class WP_REST_Post_Types_Controller extends WP_REST_Controller { // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-post-types-controller.php */ - return apply_filters( 'rest_prepare_post_type', new WP_REST_Response(), $post_type, $request ); + return apply_filters( 'rest_prepare_post_type', new WP_REST_Response( array() ), $post_type, $request ); } $taxonomies = wp_list_filter( get_object_taxonomies( $post_type->name, 'objects' ), array( 'show_in_rest' => true ) ); diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php index 37b7c6305a..c51915a974 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php @@ -499,7 +499,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { ); } - $response = $is_head_request ? new WP_REST_Response() : rest_ensure_response( $posts ); + $response = $is_head_request ? new WP_REST_Response( array() ) : rest_ensure_response( $posts ); $response->header( 'X-WP-Total', (int) $total_posts ); $response->header( 'X-WP-TotalPages', (int) $max_pages ); @@ -1847,7 +1847,7 @@ class WP_REST_Posts_Controller extends WP_REST_Controller { // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php */ - return apply_filters( "rest_prepare_{$this->post_type}", new WP_REST_Response(), $post, $request ); + return apply_filters( "rest_prepare_{$this->post_type}", new WP_REST_Response( array() ), $post, $request ); } $fields = $this->get_fields_for_response( $request ); diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php index 2756e3d751..3b943044d2 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php @@ -355,7 +355,7 @@ class WP_REST_Revisions_Controller extends WP_REST_Controller { $response = rest_ensure_response( $response ); } else { - $response = new WP_REST_Response(); + $response = new WP_REST_Response( array() ); } $response->header( 'X-WP-Total', (int) $total_revisions ); @@ -591,7 +591,7 @@ class WP_REST_Revisions_Controller extends WP_REST_Controller { // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php */ - return apply_filters( 'rest_prepare_revision', new WP_REST_Response(), $post, $request ); + return apply_filters( 'rest_prepare_revision', new WP_REST_Response( array() ), $post, $request ); } $fields = $this->get_fields_for_response( $request ); diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-search-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-search-controller.php index 345a200c67..1168580d41 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-search-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-search-controller.php @@ -165,7 +165,7 @@ class WP_REST_Search_Controller extends WP_REST_Controller { ); } - $response = $is_head_request ? new WP_REST_Response() : rest_ensure_response( $results ); + $response = $is_head_request ? new WP_REST_Response( array() ) : rest_ensure_response( $results ); $response->header( 'X-WP-Total', $total ); $response->header( 'X-WP-TotalPages', $max_pages ); diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-sidebars-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-sidebars-controller.php index 95a24cf53e..aba1773884 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-sidebars-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-sidebars-controller.php @@ -121,7 +121,7 @@ class WP_REST_Sidebars_Controller extends WP_REST_Controller { public function get_items( $request ) { if ( $request->is_method( 'HEAD' ) ) { // Return early as this handler doesn't add any response headers. - return new WP_REST_Response(); + return new WP_REST_Response( array() ); } $this->retrieve_widgets(); @@ -329,7 +329,7 @@ class WP_REST_Sidebars_Controller extends WP_REST_Controller { // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-sidebars-controller.php */ - return apply_filters( 'rest_prepare_sidebar', new WP_REST_Response(), $raw_sidebar, $request ); + return apply_filters( 'rest_prepare_sidebar', new WP_REST_Response( array() ), $raw_sidebar, $request ); } $id = $raw_sidebar['id']; diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-taxonomies-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-taxonomies-controller.php index b7492c8150..082067b23e 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-taxonomies-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-taxonomies-controller.php @@ -115,7 +115,7 @@ class WP_REST_Taxonomies_Controller extends WP_REST_Controller { public function get_items( $request ) { if ( $request->is_method( 'HEAD' ) ) { // Return early as this handler doesn't add any response headers. - return new WP_REST_Response(); + return new WP_REST_Response( array() ); } // Retrieve the list of registered collection query parameters. @@ -217,7 +217,7 @@ class WP_REST_Taxonomies_Controller extends WP_REST_Controller { // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-taxonomies-controller.php */ - return apply_filters( 'rest_prepare_taxonomy', new WP_REST_Response(), $taxonomy, $request ); + return apply_filters( 'rest_prepare_taxonomy', new WP_REST_Response( array() ), $taxonomy, $request ); } $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-templates-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-templates-controller.php index 45e0d59d5b..3f13968ae2 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-templates-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-templates-controller.php @@ -271,7 +271,7 @@ class WP_REST_Templates_Controller extends WP_REST_Controller { public function get_items( $request ) { if ( $request->is_method( 'HEAD' ) ) { // Return early as this handler doesn't add any response headers. - return new WP_REST_Response(); + return new WP_REST_Response( array() ); } $query = array(); @@ -675,7 +675,7 @@ class WP_REST_Templates_Controller extends WP_REST_Controller { public function prepare_item_for_response( $item, $request ) { // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { - return new WP_REST_Response(); + return new WP_REST_Response( array() ); } /* diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php index d927ba5e04..72632fa96a 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php @@ -370,7 +370,7 @@ class WP_REST_Terms_Controller extends WP_REST_Controller { } } - $response = $is_head_request ? new WP_REST_Response() : rest_ensure_response( $response ); + $response = $is_head_request ? new WP_REST_Response( array() ) : rest_ensure_response( $response ); // Store pagination values for headers. $per_page = (int) $prepared_args['number']; @@ -899,7 +899,7 @@ class WP_REST_Terms_Controller extends WP_REST_Controller { // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php */ - return apply_filters( "rest_prepare_{$this->taxonomy}", new WP_REST_Response(), $item, $request ); + return apply_filters( "rest_prepare_{$this->taxonomy}", new WP_REST_Response( array() ), $item, $request ); } $fields = $this->get_fields_for_response( $request ); diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php index 3995bd1816..78e1b38b1b 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php @@ -384,7 +384,7 @@ class WP_REST_Users_Controller extends WP_REST_Controller { } } - $response = $is_head_request ? new WP_REST_Response() : rest_ensure_response( $users ); + $response = $is_head_request ? new WP_REST_Response( array() ) : rest_ensure_response( $users ); // Store pagination values for headers then unset for count query. $per_page = (int) $prepared_args['number']; @@ -1032,7 +1032,7 @@ class WP_REST_Users_Controller extends WP_REST_Controller { // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php */ - return apply_filters( 'rest_prepare_user', new WP_REST_Response(), $user, $request ); + return apply_filters( 'rest_prepare_user', new WP_REST_Response( array() ), $user, $request ); } $fields = $this->get_fields_for_response( $request ); diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-widget-types-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-widget-types-controller.php index cd0aef0c87..1eb1ef27eb 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-widget-types-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-widget-types-controller.php @@ -147,7 +147,7 @@ class WP_REST_Widget_Types_Controller extends WP_REST_Controller { public function get_items( $request ) { if ( $request->is_method( 'HEAD' ) ) { // Return early as this handler doesn't add any response headers. - return new WP_REST_Response(); + return new WP_REST_Response( array() ); } $data = array(); @@ -306,7 +306,7 @@ class WP_REST_Widget_Types_Controller extends WP_REST_Controller { // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-widget-types-controller.php */ - return apply_filters( 'rest_prepare_widget_type', new WP_REST_Response(), $widget_type, $request ); + return apply_filters( 'rest_prepare_widget_type', new WP_REST_Response( array() ), $widget_type, $request ); } $fields = $this->get_fields_for_response( $request ); diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-widgets-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-widgets-controller.php index 2a154693a1..52a42258ed 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-widgets-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-widgets-controller.php @@ -138,7 +138,7 @@ class WP_REST_Widgets_Controller extends WP_REST_Controller { public function get_items( $request ) { if ( $request->is_method( 'HEAD' ) ) { // Return early as this handler doesn't add any response headers. - return new WP_REST_Response(); + return new WP_REST_Response( array() ); } $this->retrieve_widgets(); @@ -686,7 +686,7 @@ class WP_REST_Widgets_Controller extends WP_REST_Controller { // Don't prepare the response body for HEAD requests. if ( $request->is_method( 'HEAD' ) ) { /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-widgets-controller.php */ - return apply_filters( 'rest_prepare_widget', new WP_REST_Response(), $widget, $request ); + return apply_filters( 'rest_prepare_widget', new WP_REST_Response( array() ), $widget, $request ); } $parsed_id = wp_parse_widget_id( $widget_id ); diff --git a/tests/phpunit/tests/fonts/font-library/wpRestFontCollectionsController.php b/tests/phpunit/tests/fonts/font-library/wpRestFontCollectionsController.php index 6f95def922..5bad543547 100644 --- a/tests/phpunit/tests/fonts/font-library/wpRestFontCollectionsController.php +++ b/tests/phpunit/tests/fonts/font-library/wpRestFontCollectionsController.php @@ -108,7 +108,7 @@ class Tests_REST_WpRestFontCollectionsController extends WP_Test_REST_Controller return null; } - $this->assertNull( $content, 'The response should be empty.' ); + $this->assertSame( array(), $content, 'The response should be empty.' ); $headers = $response->get_headers(); $this->assertArrayHasKey( 'X-WP-Total', $headers, 'The "X-WP-Total" header should be present in the response.' ); // Includes non-valid collections. @@ -172,7 +172,7 @@ class Tests_REST_WpRestFontCollectionsController extends WP_Test_REST_Controller if ( 'HEAD' !== $method ) { return null; } - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); } /** diff --git a/tests/phpunit/tests/rest-api/rest-autosaves-controller.php b/tests/phpunit/tests/rest-api/rest-autosaves-controller.php index d452d6d126..7815f8ced2 100644 --- a/tests/phpunit/tests/rest-api/rest-autosaves-controller.php +++ b/tests/phpunit/tests/rest-api/rest-autosaves-controller.php @@ -196,7 +196,7 @@ class WP_Test_REST_Autosaves_Controller extends WP_Test_REST_Post_Type_Controlle $this->assertNotWPError( $response ); $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); $this->assertSame( 0, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' ); - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); } /** @@ -314,7 +314,7 @@ class WP_Test_REST_Autosaves_Controller extends WP_Test_REST_Post_Type_Controlle if ( 'HEAD' !== $method ) { return null; } - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); } public function test_get_item_embed_context() { @@ -889,4 +889,35 @@ class WP_Test_REST_Autosaves_Controller extends WP_Test_REST_Post_Type_Controlle $this->assertSame( 200, $response->get_status() ); $this->assertSame( $autosave['id'], $data['id'], 'Original autosave was not returned' ); } + + /** + * @dataProvider data_head_request_with_specified_fields_returns_success_response + * @ticket 56481 + * + * @param string $path The path to test. + */ + public function test_head_request_with_specified_fields_returns_success_response( $path ) { + wp_set_current_user( self::$editor_id ); + $request = new WP_REST_Request( 'HEAD', sprintf( $path, self::$post_id, self::$autosave_post_id ) ); + $request->set_param( '_fields', 'id' ); + $server = rest_get_server(); + $response = $server->dispatch( $request ); + add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 ); + $response = apply_filters( 'rest_post_dispatch', $response, $server, $request ); + remove_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10 ); + + $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); + } + + /** + * Data provider intended to provide paths for testing HEAD requests. + * + * @return array + */ + public static function data_head_request_with_specified_fields_returns_success_response() { + return array( + 'get_item request' => array( '/wp/v2/posts/%d/autosaves/%d' ), + 'get_items request' => array( '/wp/v2/posts/%d' ), + ); + } } diff --git a/tests/phpunit/tests/rest-api/rest-block-type-controller.php b/tests/phpunit/tests/rest-api/rest-block-type-controller.php index e0b0de91d0..7ba693286c 100644 --- a/tests/phpunit/tests/rest-api/rest-block-type-controller.php +++ b/tests/phpunit/tests/rest-api/rest-block-type-controller.php @@ -636,7 +636,7 @@ class REST_Block_Type_Controller_Test extends WP_Test_REST_Controller_Testcase { if ( 'HEAD' !== $method ) { return null; } - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); } /** @@ -659,7 +659,38 @@ class REST_Block_Type_Controller_Test extends WP_Test_REST_Controller_Testcase { $request = new WP_REST_Request( 'HEAD', '/wp/v2/block-types' ); $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + } + + /** + * @dataProvider data_head_request_with_specified_fields_returns_success_response + * @ticket 56481 + * + * @param string $path The path to test. + */ + public function test_head_request_with_specified_fields_returns_success_response( $path ) { + wp_set_current_user( self::$admin_id ); + $request = new WP_REST_Request( 'HEAD', $path ); + $request->set_param( '_fields', 'title' ); + $server = rest_get_server(); + $response = $server->dispatch( $request ); + add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 ); + $response = apply_filters( 'rest_post_dispatch', $response, $server, $request ); + remove_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10 ); + + $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); + } + + /** + * Data provider intended to provide paths for testing HEAD requests. + * + * @return array + */ + public static function data_head_request_with_specified_fields_returns_success_response() { + return array( + 'get_item request' => array( '/wp/v2/block-types/fake/test' ), + 'get_items request' => array( '/wp/v2/block-types' ), + ); } /** diff --git a/tests/phpunit/tests/rest-api/rest-categories-controller.php b/tests/phpunit/tests/rest-api/rest-categories-controller.php index ba921b999b..5d1f893d87 100644 --- a/tests/phpunit/tests/rest-api/rest-categories-controller.php +++ b/tests/phpunit/tests/rest-api/rest-categories-controller.php @@ -1360,6 +1360,36 @@ class WP_Test_REST_Categories_Controller extends WP_Test_REST_Controller_Testcas if ( 'HEAD' !== $method ) { return null; } - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + } + + /** + * @dataProvider data_head_request_with_specified_fields_returns_success_response + * @ticket 56481 + * + * @param string $path The path to test. + */ + public function test_head_request_with_specified_fields_returns_success_response( $path ) { + $request = new WP_REST_Request( 'HEAD', $path ); + $request->set_param( '_fields', 'id' ); + $server = rest_get_server(); + $response = $server->dispatch( $request ); + add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 ); + $response = apply_filters( 'rest_post_dispatch', $response, $server, $request ); + remove_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10 ); + + $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); + } + + /** + * Data provider intended to provide paths for testing HEAD requests. + * + * @return array + */ + public static function data_head_request_with_specified_fields_returns_success_response() { + return array( + 'get_item request' => array( '/wp/v2/categories/1' ), + 'get_items request' => array( '/wp/v2/categories' ), + ); } } diff --git a/tests/phpunit/tests/rest-api/rest-comments-controller.php b/tests/phpunit/tests/rest-api/rest-comments-controller.php index 3de15cfa76..647d5df03d 100644 --- a/tests/phpunit/tests/rest-api/rest-comments-controller.php +++ b/tests/phpunit/tests/rest-api/rest-comments-controller.php @@ -3567,6 +3567,36 @@ class WP_Test_REST_Comments_Controller extends WP_Test_REST_Controller_Testcase if ( 'HEAD' !== $method ) { return null; } - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + } + + /** + * @dataProvider data_head_request_with_specified_fields_returns_success_response + * @ticket 56481 + * + * @param string $path The path to test. + */ + public function test_head_request_with_specified_fields_returns_success_response( $path ) { + $request = new WP_REST_Request( 'HEAD', sprintf( $path, self::$approved_id ) ); + $request->set_param( '_fields', 'id' ); + $server = rest_get_server(); + $response = $server->dispatch( $request ); + add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 ); + $response = apply_filters( 'rest_post_dispatch', $response, $server, $request ); + remove_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10 ); + + $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); + } + + /** + * Data provider intended to provide paths for testing HEAD requests. + * + * @return array + */ + public static function data_head_request_with_specified_fields_returns_success_response() { + return array( + 'get_item request' => array( '/wp/v2/comments/%d' ), + 'get_items request' => array( '/wp/v2/comments' ), + ); } } diff --git a/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php b/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php index c57d16da5e..8f730d4c88 100644 --- a/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php +++ b/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php @@ -336,7 +336,38 @@ class WP_REST_Global_Styles_Revisions_Controller_Test extends WP_Test_REST_Contr $request = new WP_REST_Request( 'HEAD', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status(), 'Response status is 200.' ); - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + } + + /** + * @dataProvider data_head_request_with_specified_fields_returns_success_response + * @ticket 56481 + * + * @param string $path The path to test. + */ + public function test_head_request_with_specified_fields_returns_success_response( $path ) { + wp_set_current_user( self::$admin_id ); + $request = new WP_REST_Request( 'GET', sprintf( $path, self::$global_styles_id, $this->revision_1_id ) ); + $request->set_param( '_fields', 'id' ); + $server = rest_get_server(); + $response = $server->dispatch( $request ); + add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 ); + $response = apply_filters( 'rest_post_dispatch', $response, $server, $request ); + remove_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10 ); + + $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); + } + + /** + * Data provider intended to provide paths for testing HEAD requests. + * + * @return array + */ + public static function data_head_request_with_specified_fields_returns_success_response() { + return array( + 'get_item request' => array( '/wp/v2/global-styles/%d/revisions/%d' ), + 'get_items request' => array( '/wp/v2/global-styles/%d/revisions' ), + ); } /** @@ -366,7 +397,7 @@ class WP_REST_Global_Styles_Revisions_Controller_Test extends WP_Test_REST_Contr $request = new WP_REST_Request( 'HEAD', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions/' . $this->revision_1_id ); $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status(), 'Response status is 200.' ); - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); } /** diff --git a/tests/phpunit/tests/rest-api/rest-pattern-directory-controller.php b/tests/phpunit/tests/rest-api/rest-pattern-directory-controller.php index 23a7931511..1eb3d4f587 100644 --- a/tests/phpunit/tests/rest-api/rest-pattern-directory-controller.php +++ b/tests/phpunit/tests/rest-api/rest-pattern-directory-controller.php @@ -167,7 +167,24 @@ class WP_REST_Pattern_Directory_Controller_Test extends WP_Test_REST_Controller_ $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); $this->assertSame( 0, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' ); - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + } + + /** + * @ticket 56481 + */ + public function test_get_items_head_request_with_specified_fields_returns_success_response() { + wp_set_current_user( self::$contributor_id ); + self::mock_successful_response( 'browse-all', true ); + $request = new WP_REST_Request( 'HEAD', '/wp/v2/pattern-directory/patterns' ); + $request->set_param( '_fields', 'id' ); + $server = rest_get_server(); + $response = $server->dispatch( $request ); + add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 ); + $response = apply_filters( 'rest_post_dispatch', $response, $server, $request ); + remove_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10 ); + + $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); } /** diff --git a/tests/phpunit/tests/rest-api/rest-post-types-controller.php b/tests/phpunit/tests/rest-api/rest-post-types-controller.php index 3b61e0d6a9..f230373ce2 100644 --- a/tests/phpunit/tests/rest-api/rest-post-types-controller.php +++ b/tests/phpunit/tests/rest-api/rest-post-types-controller.php @@ -111,7 +111,37 @@ class WP_Test_REST_Post_Types_Controller extends WP_Test_REST_Controller_Testcas if ( 'HEAD' !== $method ) { return null; } - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + } + + /** + * @dataProvider data_head_request_with_specified_fields_returns_success_response + * @ticket 56481 + * + * @param string $path The path to test. + */ + public function test_head_request_with_specified_fields_returns_success_response( $path ) { + $request = new WP_REST_Request( 'HEAD', $path ); + $request->set_param( '_fields', 'slug' ); + $server = rest_get_server(); + $response = $server->dispatch( $request ); + add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 ); + $response = apply_filters( 'rest_post_dispatch', $response, $server, $request ); + remove_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10 ); + + $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); + } + + /** + * Data provider intended to provide paths for testing HEAD requests. + * + * @return array + */ + public static function data_head_request_with_specified_fields_returns_success_response() { + return array( + 'get_item request' => array( '/wp/v2/types/post' ), + 'get_items request' => array( '/wp/v2/types' ), + ); } /** @@ -324,7 +354,7 @@ class WP_Test_REST_Post_Types_Controller extends WP_Test_REST_Controller_Testcas remove_filter( $hook_name, $callback ); $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); $this->assertSame( 0, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' ); - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); } protected function check_post_type_obj( $context, $post_type_obj, $data, $links ) { diff --git a/tests/phpunit/tests/rest-api/rest-posts-controller.php b/tests/phpunit/tests/rest-api/rest-posts-controller.php index e26eb3350c..2af803a09c 100644 --- a/tests/phpunit/tests/rest-api/rest-posts-controller.php +++ b/tests/phpunit/tests/rest-api/rest-posts-controller.php @@ -295,7 +295,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te $headers = $response->get_headers(); $this->assertSame( 0, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' ); $this->assertArrayHasKey( 'Link', $headers, 'The "Link" header should be present in the response.' ); - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); } /** @@ -320,7 +320,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te $response = rest_get_server()->dispatch( $request ); if ( $request->is_method( 'HEAD' ) ) { - $this->assertNull( $response->get_data(), 'Failed asserting that response data is null for HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'Failed asserting that response data is null for HEAD request.' ); } else { $this->assertSame( array(), $response->get_data(), 'Failed asserting that response data is an empty array for GET request.' ); } @@ -351,7 +351,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te $this->assertCount( $total_posts, $response->get_data() ); } else { - $this->assertNull( $response->get_data(), 'Failed asserting that response data is null for HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'Failed asserting that response data is null for HEAD request.' ); $headers = $response->get_headers(); $this->assertSame( $total_posts, $headers['X-WP-Total'] ); } @@ -366,7 +366,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te $this->assertCount( 2, $data ); $this->assertSameSets( array( self::$editor_id, self::$author_id ), wp_list_pluck( $data, 'author' ) ); } else { - $this->assertNull( $data, 'Failed asserting that response data is null for HEAD request.' ); + $this->assertSame( array(), $data, 'Failed asserting that response data is null for HEAD request.' ); $headers = $response->get_headers(); $this->assertSame( 2, $headers['X-WP-Total'], 'Failed asserting that X-WP-Total header is 2.' ); } @@ -381,7 +381,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te $this->assertCount( 1, $data ); $this->assertSame( self::$editor_id, $data[0]['author'] ); } else { - $this->assertNull( $data, 'Failed asserting that response data is null for HEAD request.' ); + $this->assertSame( array(), $data, 'Failed asserting that response data is null for HEAD request.' ); $headers = $response->get_headers(); $this->assertSame( 1, $headers['X-WP-Total'], 'Failed asserting that X-WP-Total header is 1.' ); } @@ -407,7 +407,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te if ( $request->is_method( 'get' ) ) { $this->assertCount( $total_posts, $response->get_data() ); } else { - $this->assertNull( $response->get_data(), 'Failed asserting that response data is null for HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'Failed asserting that response data is null for HEAD request.' ); $headers = $response->get_headers(); $this->assertSame( $total_posts, $headers['X-WP-Total'], 'Failed asserting that the number of posts is correct.' ); } @@ -424,7 +424,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te $this->assertNotEquals( self::$editor_id, $data[0]['author'] ); $this->assertNotEquals( self::$author_id, $data[0]['author'] ); } else { - $this->assertNull( $response->get_data(), 'Failed asserting that response data is null for HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'Failed asserting that response data is null for HEAD request.' ); $headers = $response->get_headers(); $this->assertSame( $total_posts - 2, $headers['X-WP-Total'], 'Failed asserting that the number of posts is correct.' ); } @@ -441,7 +441,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te $this->assertNotEquals( self::$editor_id, $data[0]['author'] ); $this->assertNotEquals( self::$editor_id, $data[1]['author'] ); } else { - $this->assertNull( $response->get_data(), 'Failed asserting that response data is null for HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'Failed asserting that response data is null for HEAD request.' ); $headers = $response->get_headers(); $this->assertSame( $total_posts - 1, $headers['X-WP-Total'], 'Failed asserting that the number of posts is correct.' ); } @@ -483,7 +483,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te $this->assertCount( 2, $data ); $this->assertSame( $id2, $data[0]['id'] ); } else { - $this->assertNull( $data, 'Failed asserting that response data is null for HEAD request.' ); + $this->assertSame( array(), $data, 'Failed asserting that response data is null for HEAD request.' ); $headers = $response->get_headers(); $this->assertSame( 2, $headers['X-WP-Total'], 'Failed asserting that the number of posts is correct.' ); } @@ -498,7 +498,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te $this->assertCount( 2, $data ); $this->assertSame( $id1, $data[0]['id'] ); } else { - $this->assertNull( $data, 'Failed asserting that response data is null for HEAD request.' ); + $this->assertSame( array(), $data, 'Failed asserting that response data is null for HEAD request.' ); $headers = $response->get_headers(); $this->assertSame( 2, $headers['X-WP-Total'], 'Failed asserting that the number of posts is correct.' ); } @@ -2193,7 +2193,37 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te if ( 'HEAD' !== $method ) { return null; } - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + } + + /** + * @dataProvider data_head_request_with_specified_fields_returns_success_response + * @ticket 56481 + * + * @param string $path The path to test. + */ + public function test_head_request_with_specified_fields_returns_success_response( $path ) { + $request = new WP_REST_Request( 'HEAD', sprintf( $path, self::$post_id ) ); + $request->set_param( '_fields', 'id' ); + $server = rest_get_server(); + $response = $server->dispatch( $request ); + add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 ); + $response = apply_filters( 'rest_post_dispatch', $response, $server, $request ); + remove_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10 ); + + $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); + } + + /** + * Data provider intended to provide paths for testing HEAD requests. + * + * @return array + */ + public static function data_head_request_with_specified_fields_returns_success_response() { + return array( + 'get_item request' => array( '/wp/v2/posts/%d' ), + 'get_items request' => array( '/wp/v2/posts' ), + ); } public function test_get_item_links() { diff --git a/tests/phpunit/tests/rest-api/rest-revisions-controller.php b/tests/phpunit/tests/rest-api/rest-revisions-controller.php index 8d1c7c540c..c0b7a94726 100644 --- a/tests/phpunit/tests/rest-api/rest-revisions-controller.php +++ b/tests/phpunit/tests/rest-api/rest-revisions-controller.php @@ -182,7 +182,7 @@ class WP_Test_REST_Revisions_Controller extends WP_Test_REST_Controller_Testcase $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); $this->assertSame( 0, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' ); - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); } /** @@ -300,7 +300,39 @@ class WP_Test_REST_Revisions_Controller extends WP_Test_REST_Controller_Testcase if ( 'GET' === $method ) { return null; } - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + } + + /** + * @dataProvider data_head_request_with_specified_fields_returns_success_response + * @ticket 56481 + * + * @param string $path The path to test. + */ + public function test_head_request_with_specified_fields_returns_success_response( $path ) { + wp_set_current_user( self::$editor_id ); + $request = new WP_REST_Request( 'HEAD', sprintf( $path, self::$post_id, $this->revision_id1 ) ); + $request->set_param( '_fields', 'id' ); + $server = rest_get_server(); + $response = $server->dispatch( $request ); + add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 ); + $response = apply_filters( 'rest_post_dispatch', $response, $server, $request ); + remove_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10 ); + + $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); + } + + /** + * Data provider intended to provide paths for testing HEAD requests. + * + * @return array + */ + public static function data_head_request_with_specified_fields_returns_success_response() { + return array( + + 'get_item request' => array( '/wp/v2/posts/%d/revisions/%d' ), + 'get_items request' => array( '/wp/v2/posts/%d/revisions' ), + ); } public function test_get_item_embed_context() { diff --git a/tests/phpunit/tests/rest-api/rest-sidebars-controller.php b/tests/phpunit/tests/rest-api/rest-sidebars-controller.php index 1c6249da9e..dd01d4f2de 100644 --- a/tests/phpunit/tests/rest-api/rest-sidebars-controller.php +++ b/tests/phpunit/tests/rest-api/rest-sidebars-controller.php @@ -171,7 +171,7 @@ class WP_Test_REST_Sidebars_Controller extends WP_Test_REST_Controller_Testcase $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); $this->assertSame( 0, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' ); - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); } /** @@ -567,7 +567,46 @@ class WP_Test_REST_Sidebars_Controller extends WP_Test_REST_Controller_Testcase if ( 'HEAD' !== $method ) { return null; } - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + } + + /** + * @dataProvider data_head_request_with_specified_fields_returns_success_response + * @ticket 56481 + * + * @param string $path The path to test. + */ + public function test_head_request_with_specified_fields_returns_success_response( $path ) { + $this->setup_sidebar( + 'sidebar-1', + array( + 'name' => 'Test sidebar', + ) + ); + + $request = new WP_REST_Request( 'HEAD', $path ); + // This endpoint doesn't seem to support _fields param, but we need to set it to reproduce the fatal error. + $request->set_param( '_fields', 'name' ); + $server = rest_get_server(); + $response = $server->dispatch( $request ); + add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 ); + $response = apply_filters( 'rest_post_dispatch', $response, $server, $request ); + remove_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10 ); + + $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); + } + + /** + * Data provider intended to provide paths for testing HEAD requests. + * + * @return array + */ + public static function data_head_request_with_specified_fields_returns_success_response() { + return array( + + 'get_item request' => array( '/wp/v2/sidebars/sidebar-1' ), + 'get_items request' => array( '/wp/v2/sidebars' ), + ); } /** diff --git a/tests/phpunit/tests/rest-api/rest-tags-controller.php b/tests/phpunit/tests/rest-api/rest-tags-controller.php index bf09be0615..3b23135c93 100644 --- a/tests/phpunit/tests/rest-api/rest-tags-controller.php +++ b/tests/phpunit/tests/rest-api/rest-tags-controller.php @@ -1614,6 +1614,37 @@ class WP_Test_REST_Tags_Controller extends WP_Test_REST_Controller_Testcase { if ( 'HEAD' !== $method ) { return null; } - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + } + + /** + * @dataProvider data_head_request_with_specified_fields_returns_success_response + * @ticket 56481 + * + * @param string $path The path to test. + */ + public function test_head_request_with_specified_fields_returns_success_response( $path ) { + $tag_id = self::factory()->tag->create(); + $request = new WP_REST_Request( 'HEAD', sprintf( $path, $tag_id ) ); + $request->set_param( '_fields', 'id' ); + $server = rest_get_server(); + $response = $server->dispatch( $request ); + add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 ); + $response = apply_filters( 'rest_post_dispatch', $response, $server, $request ); + remove_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10 ); + + $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); + } + + /** + * Data provider intended to provide paths for testing HEAD requests. + * + * @return array + */ + public static function data_head_request_with_specified_fields_returns_success_response() { + return array( + 'get_item request' => array( '/wp/v2/tags/%d' ), + 'get_items request' => array( '/wp/v2/tags' ), + ); } } diff --git a/tests/phpunit/tests/rest-api/rest-taxonomies-controller.php b/tests/phpunit/tests/rest-api/rest-taxonomies-controller.php index 9ff0450af9..4d8a57d560 100644 --- a/tests/phpunit/tests/rest-api/rest-taxonomies-controller.php +++ b/tests/phpunit/tests/rest-api/rest-taxonomies-controller.php @@ -73,7 +73,7 @@ class WP_Test_REST_Taxonomies_Controller extends WP_Test_REST_Controller_Testcas remove_filter( $hook_name, $callback ); $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); $this->assertSame( 0, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' ); - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); } public function test_get_items_context_edit() { @@ -185,7 +185,37 @@ class WP_Test_REST_Taxonomies_Controller extends WP_Test_REST_Controller_Testcas if ( 'HEAD' !== $method ) { return null; } - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + } + + /** + * @dataProvider data_head_request_with_specified_fields_returns_success_response + * @ticket 56481 + * + * @param string $path The path to test. + */ + public function test_head_request_with_specified_fields_returns_success_response( $path ) { + $request = new WP_REST_Request( 'HEAD', $path ); + $request->set_param( '_fields', 'name' ); + $server = rest_get_server(); + $response = $server->dispatch( $request ); + add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 ); + $response = apply_filters( 'rest_post_dispatch', $response, $server, $request ); + remove_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10 ); + + $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); + } + + /** + * Data provider intended to provide paths for testing HEAD requests. + * + * @return array + */ + public static function data_head_request_with_specified_fields_returns_success_response() { + return array( + 'get_item request' => array( '/wp/v2/taxonomies/category' ), + 'get_items request' => array( '/wp/v2/taxonomies' ), + ); } public function test_get_item_edit_context() { diff --git a/tests/phpunit/tests/rest-api/rest-users-controller.php b/tests/phpunit/tests/rest-api/rest-users-controller.php index 1219a0c8a2..5542c12d7d 100644 --- a/tests/phpunit/tests/rest-api/rest-users-controller.php +++ b/tests/phpunit/tests/rest-api/rest-users-controller.php @@ -254,7 +254,7 @@ class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { ); if ( 'HEAD' === $method ) { - $this->assertNull( $response->get_data(), 'Expected null response data for HEAD request, but received non-null data.' ); + $this->assertSame( array(), $response->get_data(), 'Expected null response data for HEAD request, but received non-null data.' ); return null; } @@ -3251,7 +3251,7 @@ class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { if ( 'HEAD' !== $method ) { return null; } - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); } /** @@ -3272,7 +3272,7 @@ class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { $this->assertSame( 200, $response->get_status() ); if ( $is_head_request ) { - $this->assertNull( $response->get_data() ); + $this->assertSame( array(), $response->get_data() ); } else { $this->assertNotEmpty( $response->get_data() ); } @@ -3306,6 +3306,39 @@ class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { $this->assertMatchesRegularExpression( $pattern, $query->request, 'The SQL query does not match the expected string.' ); } + /** + * @dataProvider data_head_request_with_specified_fields_returns_success_response + * @ticket 56481 + * + * @param string $path The path to test. + */ + public function test_head_request_with_specified_fields_returns_success_response( $path ) { + $user_id = self::factory()->user->create(); + wp_set_current_user( self::$user ); + + $request = new WP_REST_Request( 'HEAD', sprintf( $path, $user_id ) ); + $request->set_param( '_fields', 'id' ); + $server = rest_get_server(); + $response = $server->dispatch( $request ); + add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 ); + $response = apply_filters( 'rest_post_dispatch', $response, $server, $request ); + remove_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10 ); + + $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); + } + + /** + * Data provider intended to provide paths for testing HEAD requests. + * + * @return array + */ + public static function data_head_request_with_specified_fields_returns_success_response() { + return array( + 'get_item request' => array( '/wp/v2/users/%d' ), + 'get_items request' => array( '/wp/v2/users' ), + ); + } + protected function check_user_data( $user, $data, $context, $links ) { $this->assertSame( $user->ID, $data['id'] ); $this->assertSame( $user->display_name, $data['name'] ); diff --git a/tests/phpunit/tests/rest-api/rest-widget-types-controller.php b/tests/phpunit/tests/rest-api/rest-widget-types-controller.php index bf7c1a3d7a..3003c2e974 100644 --- a/tests/phpunit/tests/rest-api/rest-widget-types-controller.php +++ b/tests/phpunit/tests/rest-api/rest-widget-types-controller.php @@ -129,7 +129,7 @@ class WP_Test_REST_Widget_Types_Controller extends WP_Test_REST_Controller_Testc $request = new WP_REST_Request( 'HEAD', '/wp/v2/widget-types' ); $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); } /** @@ -227,7 +227,7 @@ class WP_Test_REST_Widget_Types_Controller extends WP_Test_REST_Controller_Testc if ( 'HEAD' !== $method ) { return null; } - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); } /** @@ -242,6 +242,37 @@ class WP_Test_REST_Widget_Types_Controller extends WP_Test_REST_Controller_Testc ); } + /** + * @dataProvider data_head_request_with_specified_fields_returns_success_response + * @ticket 56481 + * + * @param string $path The path to test. + */ + public function test_head_request_with_specified_fields_returns_success_response( $path ) { + wp_set_current_user( self::$admin_id ); + $request = new WP_REST_Request( 'HEAD', $path ); + $request->set_param( '_fields', 'id' ); + $server = rest_get_server(); + $response = $server->dispatch( $request ); + add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 ); + $response = apply_filters( 'rest_post_dispatch', $response, $server, $request ); + remove_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10 ); + + $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); + } + + /** + * Data provider intended to provide paths for testing HEAD requests. + * + * @return array + */ + public static function data_head_request_with_specified_fields_returns_success_response() { + return array( + 'get_item request' => array( '/wp/v2/widget-types/calendar' ), + 'get_items request' => array( '/wp/v2/widget-types' ), + ); + } + /** * @ticket 41683 */ diff --git a/tests/phpunit/tests/rest-api/rest-widgets-controller.php b/tests/phpunit/tests/rest-api/rest-widgets-controller.php index 02b63da6d8..246ad3b61e 100644 --- a/tests/phpunit/tests/rest-api/rest-widgets-controller.php +++ b/tests/phpunit/tests/rest-api/rest-widgets-controller.php @@ -472,7 +472,7 @@ class WP_Test_REST_Widgets_Controller extends WP_Test_REST_Controller_Testcase { $this->assertNotWPError( $response ); $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); $this->assertSame( 0, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' ); - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); } public function mocked_rss_response() { @@ -644,7 +644,68 @@ class WP_Test_REST_Widgets_Controller extends WP_Test_REST_Controller_Testcase { if ( 'HEAD' !== $method ) { return null; } - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + } + + /** + * @dataProvider data_head_request_with_specified_fields_returns_success_response + * @ticket 56481 + * + * @param string $path The path to test. + */ + public function test_head_request_with_specified_fields_returns_success_response( $path ) { + add_filter( 'pre_http_request', array( $this, 'mocked_rss_response' ) ); + global $wp_widget_factory; + + $wp_widget_factory->widgets['WP_Widget_RSS']->widget_options['show_instance_in_rest'] = false; + + $block_content = '

Block test

'; + + $this->setup_widget( + 'rss', + 1, + array( + 'title' => 'RSS test', + 'url' => 'https://wordpress.org/news/feed', + ) + ); + $this->setup_widget( + 'block', + 1, + array( + 'content' => $block_content, + ) + ); + $this->setup_sidebar( + 'sidebar-1', + array( + 'name' => 'Test sidebar', + ), + array( 'block-1', 'rss-1', 'testwidget' ) + ); + + $request = new WP_REST_Request( 'HEAD', $path ); + $request->set_param( '_fields', 'id' ); + $server = rest_get_server(); + $response = $server->dispatch( $request ); + add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 ); + $response = apply_filters( 'rest_post_dispatch', $response, $server, $request ); + remove_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10 ); + remove_filter( 'pre_http_request', array( $this, 'mocked_rss_response' ) ); + + $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); + } + + /** + * Data provider intended to provide paths for testing HEAD requests. + * + * @return array + */ + public static function data_head_request_with_specified_fields_returns_success_response() { + return array( + 'get_item request' => array( '/wp/v2/widgets/block-1' ), + 'get_items request' => array( '/wp/v2/widgets' ), + ); } /** diff --git a/tests/phpunit/tests/rest-api/wpRestBlockPatternCategoriesController.php b/tests/phpunit/tests/rest-api/wpRestBlockPatternCategoriesController.php index 58352a0a62..bae0bbb88a 100644 --- a/tests/phpunit/tests/rest-api/wpRestBlockPatternCategoriesController.php +++ b/tests/phpunit/tests/rest-api/wpRestBlockPatternCategoriesController.php @@ -131,7 +131,25 @@ class Tests_REST_WpRestBlockPatternCategoriesController extends WP_Test_REST_Con $request = new WP_REST_Request( 'HEAD', static::REQUEST_ROUTE ); $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + } + + /** + * @ticket 56481 + * + * @param string $path The path to test. + */ + public function test_head_request_with_specified_fields_returns_success_response() { + wp_set_current_user( self::$admin_id ); + $request = new WP_REST_Request( 'HEAD', static::REQUEST_ROUTE ); + $request->set_param( '_fields', 'name' ); + $server = rest_get_server(); + $response = $server->dispatch( $request ); + add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 ); + $response = apply_filters( 'rest_post_dispatch', $response, $server, $request ); + remove_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10 ); + + $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); } /** diff --git a/tests/phpunit/tests/rest-api/wpRestTemplateAutosavesController.php b/tests/phpunit/tests/rest-api/wpRestTemplateAutosavesController.php index d5e9213517..d3cbf91260 100644 --- a/tests/phpunit/tests/rest-api/wpRestTemplateAutosavesController.php +++ b/tests/phpunit/tests/rest-api/wpRestTemplateAutosavesController.php @@ -316,7 +316,7 @@ class Tests_REST_wpRestTemplateAutosavesController extends WP_Test_REST_Controll ); $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status(), 'Response status is 200.' ); - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); } /** @@ -470,7 +470,7 @@ class Tests_REST_wpRestTemplateAutosavesController extends WP_Test_REST_Controll $request = new WP_REST_Request( 'HEAD', '/wp/v2/templates/' . self::TEST_THEME . '/' . self::TEMPLATE_NAME . '/autosaves/' . $autosave_post_id ); $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status(), 'Response status is 200.' ); - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); } /** @@ -485,6 +485,79 @@ class Tests_REST_wpRestTemplateAutosavesController extends WP_Test_REST_Controll ); } + /** + * @dataProvider data_get_item_with_data_provider + * @covers WP_REST_Template_Autosaves_Controller::get_item + * @ticket 56922 + * + * @param string $parent_post_property_name A class property name that contains the parent post object. + * @param string $rest_base Base part of the REST API endpoint to test. + * @param string $template_id Template ID to use in the test. + */ + public function test_get_item_head_request_with_specified_fields_returns_success_response( $parent_post_property_name, $rest_base, $template_id ) { + wp_set_current_user( self::$admin_id ); + + $parent_post = self::$$parent_post_property_name; + + $autosave_post_id = wp_create_post_autosave( + array( + 'post_content' => 'Autosave content.', + 'post_ID' => $parent_post->ID, + 'post_type' => $parent_post->post_type, + ) + ); + + $request = new WP_REST_Request( + 'HEAD', + '/wp/v2/' . $rest_base . '/' . $template_id . '/autosaves/' . $autosave_post_id + ); + $request->set_param( '_fields', 'id' ); + $server = rest_get_server(); + $response = $server->dispatch( $request ); + + add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 ); + $response = apply_filters( 'rest_post_dispatch', $response, $server, $request ); + remove_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10 ); + + $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); + } + + /** + * @dataProvider data_get_items_with_data_provider + * @covers WP_REST_Template_Autosaves_Controller::get_items + * @ticket 56922 + * + * @param string $parent_post_property_name A class property name that contains the parent post object. + * @param string $rest_base Base part of the REST API endpoint to test. + * @param string $template_id Template ID to use in the test. + */ + public function test_get_items_head_request_with_specified_fields_returns_success_response( $parent_post_property_name, $rest_base, $template_id ) { + wp_set_current_user( self::$admin_id ); + // Cannot access this property in the data provider because it is not initialized at the time of execution. + $parent_post = self::$$parent_post_property_name; + wp_create_post_autosave( + array( + 'post_content' => 'Autosave content.', + 'post_ID' => $parent_post->ID, + 'post_type' => $parent_post->post_type, + ) + ); + + $request = new WP_REST_Request( + 'HEAD', + '/wp/v2/' . $rest_base . '/' . $template_id . '/autosaves' + ); + $request->set_param( '_fields', 'id' ); + $server = rest_get_server(); + $response = $server->dispatch( $request ); + + add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 ); + $response = apply_filters( 'rest_post_dispatch', $response, $server, $request ); + remove_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10 ); + + $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); + } + /** * @coversNothing * @ticket 56922 diff --git a/tests/phpunit/tests/rest-api/wpRestTemplateRevisionsController.php b/tests/phpunit/tests/rest-api/wpRestTemplateRevisionsController.php index 700d31360c..86b29c12bf 100644 --- a/tests/phpunit/tests/rest-api/wpRestTemplateRevisionsController.php +++ b/tests/phpunit/tests/rest-api/wpRestTemplateRevisionsController.php @@ -437,7 +437,7 @@ class Tests_REST_wpRestTemplateRevisionsController extends WP_Test_REST_Controll ); $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status(), 'Response status is 200.' ); - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); } /** @@ -627,7 +627,7 @@ class Tests_REST_wpRestTemplateRevisionsController extends WP_Test_REST_Controll $request = new WP_REST_Request( 'HEAD', '/wp/v2/templates/' . self::TEST_THEME . '/' . self::TEMPLATE_NAME . '/revisions/' . $revision_id ); $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status(), 'Response status is 200.' ); - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); } /** @@ -642,6 +642,65 @@ class Tests_REST_wpRestTemplateRevisionsController extends WP_Test_REST_Controll ); } + /** + * @dataProvider data_get_item_with_data_provider + * @covers WP_REST_Template_Revisions_Controller::get_item + * @ticket 56922 + * + * @param string $parent_post_property_name A class property name that contains the parent post object. + * @param string $rest_base Base part of the REST API endpoint to test. + * @param string $template_id Template ID to use in the test. + */ + public function test_get_item_head_request_with_specified_fields_returns_success_response( $parent_post_property_name, $rest_base, $template_id ) { + wp_set_current_user( self::$admin_id ); + + $parent_post = self::$$parent_post_property_name; + + $revisions = wp_get_post_revisions( $parent_post, array( 'fields' => 'ids' ) ); + $revision_id = array_shift( $revisions ); + + $request = new WP_REST_Request( + 'HEAD', + '/wp/v2/' . $rest_base . '/' . $template_id . '/revisions/' . $revision_id + ); + $request->set_param( '_fields', 'id' ); + $server = rest_get_server(); + $response = $server->dispatch( $request ); + add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 ); + $response = apply_filters( 'rest_post_dispatch', $response, $server, $request ); + remove_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10 ); + + $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); + } + + /** + * @dataProvider data_get_items_with_data_provider + * @covers WP_REST_Template_Revisions_Controller::get_items + * @ticket 56922 + * + * @param string $parent_post_property_name A class property name that contains the parent post object. + * @param string $rest_base Base part of the REST API endpoint to test. + * @param string $template_id Template ID to use in the test. + */ + public function test_get_items_head_request_with_specified_fields_returns_success_response( $parent_post_property_name, $rest_base, $template_id ) { + wp_set_current_user( self::$admin_id ); + $parent_post = self::$$parent_post_property_name; + + $request = new WP_REST_Request( + 'HEAD', + '/wp/v2/' . $rest_base . '/' . $template_id . '/revisions' + ); + + $request->set_param( '_fields', 'id' ); + $server = rest_get_server(); + $response = $server->dispatch( $request ); + add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 ); + $response = apply_filters( 'rest_post_dispatch', $response, $server, $request ); + remove_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10 ); + + $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); + } + /** * @dataProvider data_get_item_not_found * @covers WP_REST_Template_Revisions_Controller::get_item diff --git a/tests/phpunit/tests/rest-api/wpRestTemplatesController.php b/tests/phpunit/tests/rest-api/wpRestTemplatesController.php index 8ffa8b4e79..b10b8b68ab 100644 --- a/tests/phpunit/tests/rest-api/wpRestTemplatesController.php +++ b/tests/phpunit/tests/rest-api/wpRestTemplatesController.php @@ -185,7 +185,38 @@ class Tests_REST_WpRestTemplatesController extends WP_Test_REST_Controller_Testc $request = new WP_REST_Request( 'HEAD', '/wp/v2/templates' ); $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status(), 'Response status is 200.' ); - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + } + + /** + * @dataProvider data_head_request_with_specified_fields_returns_success_response + * @ticket 56481 + * + * @param string $path The path to test. + */ + public function test_head_request_with_specified_fields_returns_success_response( $path ) { + wp_set_current_user( self::$admin_id ); + $request = new WP_REST_Request( 'HEAD', $path ); + $request->set_param( '_fields', 'id' ); + $server = rest_get_server(); + $response = $server->dispatch( $request ); + add_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10, 3 ); + $response = apply_filters( 'rest_post_dispatch', $response, $server, $request ); + remove_filter( 'rest_post_dispatch', 'rest_filter_response_fields', 10 ); + + $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); + } + + /** + * Data provider intended to provide paths for testing HEAD requests. + * + * @return array + */ + public static function data_head_request_with_specified_fields_returns_success_response() { + return array( + 'get_item request' => array( '/wp/v2/templates/default//my_template' ), + 'get_items request' => array( '/wp/v2/templates' ), + ); } /** @@ -291,7 +322,7 @@ class Tests_REST_WpRestTemplatesController extends WP_Test_REST_Controller_Testc $request = new WP_REST_Request( 'HEAD', '/wp/v2/templates/default//my_template' ); $response = rest_get_server()->dispatch( $request ); $this->assertSame( 200, $response->get_status(), 'Response status is 200.' ); - $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); + $this->assertSame( array(), $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); } /**