Skip to content

Commit

Permalink
Don't prepare the response body for HEAD requests in WP_Test_REST_Pos…
Browse files Browse the repository at this point in the history
…t_Types_Controller.
  • Loading branch information
anton-vlasenko committed Dec 14, 2024
1 parent 3bd2742 commit b80fd51
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ public function get_items_permissions_check( $request ) {
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
*/
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();
}

$data = array();
$types = get_post_types( array( 'show_in_rest' => true ), 'objects' );

Expand Down Expand Up @@ -159,6 +164,10 @@ public function get_item( $request ) {
);
}

if ( $request->is_method( 'HEAD' ) ) {
return new WP_REST_Response();
}

$data = $this->prepare_item_for_response( $obj, $request );

return rest_ensure_response( $data );
Expand Down
76 changes: 70 additions & 6 deletions tests/phpunit/tests/rest-api/rest-post-types-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,32 @@ public function test_get_items() {
$this->assertArrayNotHasKey( 'revision', $data );
}

public function test_get_items_invalid_permission_for_context() {
/**
* @dataProvider data_readable_http_methods
* @ticket 56481
*
* @param string $method HTTP method to use.
*/
public function test_get_items_invalid_permission_for_context( $method ) {
wp_set_current_user( 0 );
$request = new WP_REST_Request( 'GET', '/wp/v2/types' );
$request = new WP_REST_Request( $method, '/wp/v2/types' );
$request->set_param( 'context', 'edit' );
$response = rest_get_server()->dispatch( $request );
$this->assertErrorResponse( 'rest_cannot_view', $response, 401 );
}

/**
* Data provider intended to provide HTTP method names for testing GET and HEAD requests.
*
* @return array
*/
public static function data_readable_http_methods() {
return array(
'GET request' => array( 'GET' ),
'HEAD request' => array( 'HEAD' ),
);
}

public function test_get_item() {
$request = new WP_REST_Request( 'GET', '/wp/v2/types/post' );
$response = rest_get_server()->dispatch( $request );
Expand All @@ -60,6 +78,24 @@ public function test_get_item() {
$this->assertSame( array( 'category', 'post_tag' ), $data['taxonomies'] );
}

/**
* @ticket 56481
*/
public function test_get_item_with_head_request_should_not_prepare_post_type_data() {
$request = new WP_REST_Request( 'HEAD', '/wp/v2/types/post' );
$hook_name = 'rest_prepare_post_type';
$filter = new MockAction();
$callback = array( $filter, 'filter' );
add_filter( $hook_name, $callback );
$response = rest_get_server()->dispatch( $request );
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.' );
}

/**
* @ticket 53656
*/
Expand Down Expand Up @@ -106,8 +142,14 @@ public function test_get_item_page() {
$this->assertSame( array(), $data['taxonomies'] );
}

public function test_get_item_invalid_type() {
$request = new WP_REST_Request( 'GET', '/wp/v2/types/invalid' );
/**
* @dataProvider data_readable_http_methods
* @ticket 56481
*
* @param string $method HTTP method to use.
*/
public function test_get_item_invalid_type( $method ) {
$request = new WP_REST_Request( $method, '/wp/v2/types/invalid' );
$response = rest_get_server()->dispatch( $request );
$this->assertErrorResponse( 'rest_type_invalid', $response, 404 );
}
Expand All @@ -121,9 +163,15 @@ public function test_get_item_edit_context() {
$this->check_post_type_object_response( 'edit', $response );
}

public function test_get_item_invalid_permission_for_context() {
/**
* @dataProvider data_readable_http_methods
* @ticket 56481
*
* @param string $method HTTP method to use.
*/
public function test_get_item_invalid_permission_for_context( $method ) {
wp_set_current_user( 0 );
$request = new WP_REST_Request( 'GET', '/wp/v2/types/post' );
$request = new WP_REST_Request( $method, '/wp/v2/types/post' );
$request->set_param( 'context', 'edit' );
$response = rest_get_server()->dispatch( $request );
$this->assertErrorResponse( 'rest_forbidden_context', $response, 401 );
Expand Down Expand Up @@ -245,6 +293,22 @@ public function additional_field_get_callback( $response_data ) {
return 123;
}

/**
* @ticket 56481
*/
public function test_get_items_with_head_request_should_not_prepare_post_types_data() {
$request = new WP_REST_Request( 'HEAD', '/wp/v2/types' );
$hook_name = 'rest_prepare_post_type';
$filter = new MockAction();
$callback = array( $filter, 'filter' );
add_filter( $hook_name, $callback );
$response = rest_get_server()->dispatch( $request );
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.' );
}

protected function check_post_type_obj( $context, $post_type_obj, $data, $links ) {
$this->assertSame( $post_type_obj->label, $data['name'] );
$this->assertSame( $post_type_obj->name, $data['slug'] );
Expand Down

0 comments on commit b80fd51

Please sign in to comment.