Changeset 59899
- Timestamp:
- 03/02/2025 10:05:08 PM (7 weeks ago)
- Location:
- trunk
- Files:
-
- 43 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/rest-api/class-wp-rest-request.php
r58706 r59899 163 163 164 164 /** 165 * Determines if the request is the given method. 166 * 167 * @since 6.8.0 168 * 169 * @param string $method HTTP method. 170 * @return bool Whether the request is of the given method. 171 */ 172 public function is_method( $method ) { 173 return $this->get_method() === strtoupper( $method ); 174 } 175 176 /** 165 177 * Canonicalizes the header name. 166 178 * -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php
r56819 r59899 306 306 } 307 307 308 if ( $request->is_method( 'HEAD' ) ) { 309 // Return early as this handler doesn't add any response headers. 310 return new WP_REST_Response(); 311 } 308 312 $response = array(); 309 313 $parent_id = $parent->ID; … … 449 453 $post = $item; 450 454 455 // Don't prepare the response body for HEAD requests. 456 if ( $request->is_method( 'HEAD' ) ) { 457 /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php */ 458 return apply_filters( 'rest_prepare_autosave', new WP_REST_Response(), $post, $request ); 459 } 451 460 $response = $this->revisions_controller->prepare_item_for_response( $post, $request ); 452 461 $fields = $this->get_fields_for_response( $request ); -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-block-pattern-categories-controller.php
r58704 r59899 82 82 */ 83 83 public function get_items( $request ) { 84 if ( $request->is_method( 'HEAD' ) ) { 85 // Return early as this handler doesn't add any response headers. 86 return new WP_REST_Response(); 87 } 88 84 89 $response = array(); 85 90 $categories = WP_Block_Pattern_Categories_Registry::get_instance()->get_all_registered(); -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-block-types-controller.php
r58694 r59899 132 132 */ 133 133 public function get_items( $request ) { 134 if ( $request->is_method( 'HEAD' ) ) { 135 // Return early as this handler doesn't add any response headers. 136 return new WP_REST_Response(); 137 } 138 134 139 $data = array(); 135 140 $block_types = $this->block_registry->get_all_registered(); … … 250 255 // Restores the more descriptive, specific name for use within this method. 251 256 $block_type = $item; 257 258 // Don't prepare the response body for HEAD requests. 259 if ( $request->is_method( 'HEAD' ) ) { 260 /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-block-types-controller.php */ 261 return apply_filters( 'rest_prepare_block_type', new WP_REST_Response(), $block_type, $request ); 262 } 252 263 253 264 $fields = $this->get_fields_for_response( $request ); -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php
r59882 r59899 263 263 } 264 264 265 $is_head_request = $request->is_method( 'HEAD' ); 266 if ( $is_head_request ) { 267 // Force the 'fields' argument. For HEAD requests, only post IDs are required to calculate pagination. 268 $prepared_args['fields'] = 'ids'; 269 // Disable priming comment meta for HEAD requests to improve performance. 270 $prepared_args['update_comment_meta_cache'] = false; 271 } 272 265 273 /** 266 274 * Filters WP_Comment_Query arguments when querying comments via the REST API. … … 278 286 $query_result = $query->query( $prepared_args ); 279 287 280 $comments = array(); 281 282 foreach ( $query_result as $comment ) { 283 if ( ! $this->check_read_permission( $comment, $request ) ) { 284 continue; 285 } 286 287 $data = $this->prepare_item_for_response( $comment, $request ); 288 $comments[] = $this->prepare_response_for_collection( $data ); 288 if ( ! $is_head_request ) { 289 $comments = array(); 290 291 foreach ( $query_result as $comment ) { 292 if ( ! $this->check_read_permission( $comment, $request ) ) { 293 continue; 294 } 295 296 $data = $this->prepare_item_for_response( $comment, $request ); 297 $comments[] = $this->prepare_response_for_collection( $data ); 298 } 289 299 } 290 300 … … 304 314 } 305 315 306 $response = rest_ensure_response( $comments );316 $response = $is_head_request ? new WP_REST_Response() : rest_ensure_response( $comments ); 307 317 $response->header( 'X-WP-Total', $total_comments ); 308 318 $response->header( 'X-WP-TotalPages', $max_pages ); … … 1041 1051 // Restores the more descriptive, specific name for use within this method. 1042 1052 $comment = $item; 1053 1054 // Don't prepare the response body for HEAD requests. 1055 if ( $request->is_method( 'HEAD' ) ) { 1056 /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-comments-controller.php */ 1057 return apply_filters( 'rest_prepare_comment', new WP_REST_Response(), $comment, $request ); 1058 } 1043 1059 1044 1060 $fields = $this->get_fields_for_response( $request ); -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-font-collections-controller.php
r57686 r59899 90 90 $collections_page = array_slice( $collections_all, ( $page - 1 ) * $per_page, $per_page ); 91 91 92 $is_head_request = $request->is_method( 'HEAD' ); 93 92 94 $items = array(); 93 95 foreach ( $collections_page as $collection ) { … … 98 100 continue; 99 101 } 102 103 /* 104 * Skip preparing the response body for HEAD requests. 105 * Cannot exit earlier due to backward compatibility reasons, 106 * as validation occurs in the prepare_item_for_response method. 107 */ 108 if ( $is_head_request ) { 109 continue; 110 } 111 100 112 $item = $this->prepare_response_for_collection( $item ); 101 113 $items[] = $item; 102 114 } 103 115 104 $response = rest_ensure_response( $items );116 $response = $is_head_request ? new WP_REST_Response() : rest_ensure_response( $items ); 105 117 106 118 $response->header( 'X-WP-Total', (int) $total_items ); … … 176 188 } 177 189 190 /** 191 * Don't prepare the response body for HEAD requests. 192 * Can't exit at the beginning of the method due to the potential need to return a WP_Error object. 193 */ 194 if ( $request->is_method( 'HEAD' ) ) { 195 /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-font-collections-controller.php */ 196 return apply_filters( 'rest_prepare_font_collection', new WP_REST_Response(), $item, $request ); 197 } 198 178 199 foreach ( $data_fields as $field ) { 179 200 if ( rest_is_field_included( $field, $fields ) ) { … … 181 202 } 182 203 } 204 } 205 206 /** 207 * Don't prepare the response body for HEAD requests. 208 * Can't exit at the beginning of the method due to the potential need to return a WP_Error object. 209 */ 210 if ( $request->is_method( 'HEAD' ) ) { 211 /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-font-collections-controller.php */ 212 return apply_filters( 'rest_prepare_font_collection', new WP_REST_Response(), $item, $request ); 183 213 } 184 214 -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-global-styles-revisions-controller.php
r59630 r59899 164 164 } 165 165 166 $is_head_request = $request->is_method( 'HEAD' ); 167 166 168 if ( wp_revisions_enabled( $parent ) ) { 167 169 $registered = $this->get_collection_params(); … … 185 187 $query_args[ $wp_param ] = $request[ $api_param ]; 186 188 } 189 } 190 191 if ( $is_head_request ) { 192 // Force the 'fields' argument. For HEAD requests, only post IDs are required to calculate pagination. 193 $query_args['fields'] = 'ids'; 194 // Disable priming post meta for HEAD requests to improve performance. 195 $query_args['update_post_term_cache'] = false; 196 $query_args['update_post_meta_cache'] = false; 187 197 } 188 198 … … 229 239 } 230 240 231 $response = array(); 232 233 foreach ( $revisions as $revision ) { 234 $data = $this->prepare_item_for_response( $revision, $request ); 235 $response[] = $this->prepare_response_for_collection( $data ); 236 } 237 238 $response = rest_ensure_response( $response ); 241 if ( ! $is_head_request ) { 242 $response = array(); 243 244 foreach ( $revisions as $revision ) { 245 $data = $this->prepare_item_for_response( $revision, $request ); 246 $response[] = $this->prepare_response_for_collection( $data ); 247 } 248 249 $response = rest_ensure_response( $response ); 250 } else { 251 $response = new WP_REST_Response(); 252 } 239 253 240 254 $response->header( 'X-WP-Total', (int) $total_revisions ); … … 276 290 */ 277 291 public function prepare_item_for_response( $post, $request ) { 292 // Don't prepare the response body for HEAD requests. 293 if ( $request->is_method( 'HEAD' ) ) { 294 return new WP_REST_Response(); 295 } 296 278 297 $parent = $this->get_parent( $request['parent'] ); 279 298 $global_styles_config = $this->get_decoded_global_styles_json( $post->post_content ); -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-pattern-directory-controller.php
r59203 r59899 160 160 161 161 return $raw_patterns; 162 } 163 164 if ( $request->is_method( 'HEAD' ) ) { 165 // Return early as this handler doesn't add any response headers. 166 return new WP_REST_Response(); 162 167 } 163 168 -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-post-types-controller.php
r58452 r59899 110 110 */ 111 111 public function get_items( $request ) { 112 if ( $request->is_method( 'HEAD' ) ) { 113 // Return early as this handler doesn't add any response headers. 114 return new WP_REST_Response(); 115 } 116 112 117 $data = array(); 113 118 $types = get_post_types( array( 'show_in_rest' => true ), 'objects' ); … … 178 183 // Restores the more descriptive, specific name for use within this method. 179 184 $post_type = $item; 185 186 // Don't prepare the response body for HEAD requests. 187 if ( $request->is_method( 'HEAD' ) ) { 188 /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-post-types-controller.php */ 189 return apply_filters( 'rest_prepare_post_type', new WP_REST_Response(), $post_type, $request ); 190 } 180 191 181 192 $taxonomies = wp_list_filter( get_object_taxonomies( $post_type->name, 'objects' ), array( 'show_in_rest' => true ) ); -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php
r59801 r59899 412 412 $args['post_type'] = $this->post_type; 413 413 414 $is_head_request = $request->is_method( 'HEAD' ); 415 if ( $is_head_request ) { 416 // Force the 'fields' argument. For HEAD requests, only post IDs are required to calculate pagination. 417 $args['fields'] = 'ids'; 418 // Disable priming post meta for HEAD requests to improve performance. 419 $args['update_post_term_cache'] = false; 420 $args['update_post_meta_cache'] = false; 421 } 422 414 423 /** 415 424 * Filters WP_Query arguments when querying posts via the REST API. … … 444 453 } 445 454 446 $posts = array(); 447 448 update_post_author_caches( $query_result ); 449 update_post_parent_caches( $query_result ); 450 451 if ( post_type_supports( $this->post_type, 'thumbnail' ) ) { 452 update_post_thumbnail_cache( $posts_query ); 453 } 454 455 foreach ( $query_result as $post ) { 456 if ( ! $this->check_read_permission( $post ) ) { 457 continue; 458 } 459 460 $data = $this->prepare_item_for_response( $post, $request ); 461 $posts[] = $this->prepare_response_for_collection( $data ); 455 if ( ! $is_head_request ) { 456 $posts = array(); 457 458 update_post_author_caches( $query_result ); 459 update_post_parent_caches( $query_result ); 460 461 if ( post_type_supports( $this->post_type, 'thumbnail' ) ) { 462 update_post_thumbnail_cache( $posts_query ); 463 } 464 465 foreach ( $query_result as $post ) { 466 if ( ! $this->check_read_permission( $post ) ) { 467 continue; 468 } 469 470 $data = $this->prepare_item_for_response( $post, $request ); 471 $posts[] = $this->prepare_response_for_collection( $data ); 472 } 462 473 } 463 474 … … 489 500 } 490 501 491 $response = rest_ensure_response( $posts );502 $response = $is_head_request ? new WP_REST_Response() : rest_ensure_response( $posts ); 492 503 493 504 $response->header( 'X-WP-Total', (int) $total_posts ); … … 1833 1844 1834 1845 setup_postdata( $post ); 1846 1847 // Don't prepare the response body for HEAD requests. 1848 if ( $request->is_method( 'HEAD' ) ) { 1849 /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php */ 1850 return apply_filters( "rest_prepare_{$this->post_type}", new WP_REST_Response(), $post, $request ); 1851 } 1835 1852 1836 1853 $fields = $this->get_fields_for_response( $request ); -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php
r59630 r59899 254 254 } 255 255 256 $is_head_request = $request->is_method( 'HEAD' ); 257 256 258 if ( wp_revisions_enabled( $parent ) ) { 257 259 $registered = $this->get_collection_params(); … … 286 288 if ( isset( $args['orderby'] ) && 'date' === $args['orderby'] ) { 287 289 $args['orderby'] = 'date ID'; 290 } 291 292 if ( $is_head_request ) { 293 // Force the 'fields' argument. For HEAD requests, only post IDs are required to calculate pagination. 294 $args['fields'] = 'ids'; 295 // Disable priming post meta for HEAD requests to improve performance. 296 $args['update_post_term_cache'] = false; 297 $args['update_post_meta_cache'] = false; 288 298 } 289 299 … … 336 346 } 337 347 338 $response = array(); 339 340 foreach ( $revisions as $revision ) { 341 $data = $this->prepare_item_for_response( $revision, $request ); 342 $response[] = $this->prepare_response_for_collection( $data ); 343 } 344 345 $response = rest_ensure_response( $response ); 348 if ( ! $is_head_request ) { 349 $response = array(); 350 351 foreach ( $revisions as $revision ) { 352 $data = $this->prepare_item_for_response( $revision, $request ); 353 $response[] = $this->prepare_response_for_collection( $data ); 354 } 355 356 $response = rest_ensure_response( $response ); 357 } else { 358 $response = new WP_REST_Response(); 359 } 346 360 347 361 $response->header( 'X-WP-Total', (int) $total_revisions ); … … 574 588 575 589 setup_postdata( $post ); 590 591 // Don't prepare the response body for HEAD requests. 592 if ( $request->is_method( 'HEAD' ) ) { 593 /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php */ 594 return apply_filters( 'rest_prepare_revision', new WP_REST_Response(), $post, $request ); 595 } 576 596 577 597 $fields = $this->get_fields_for_response( $request ); -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-search-controller.php
r57839 r59899 143 143 $ids = $result[ WP_REST_Search_Handler::RESULT_IDS ]; 144 144 145 $results = array(); 146 147 foreach ( $ids as $id ) { 148 $data = $this->prepare_item_for_response( $id, $request ); 149 $results[] = $this->prepare_response_for_collection( $data ); 145 $is_head_request = $request->is_method( 'HEAD' ); 146 if ( ! $is_head_request ) { 147 $results = array(); 148 149 foreach ( $ids as $id ) { 150 $data = $this->prepare_item_for_response( $id, $request ); 151 $results[] = $this->prepare_response_for_collection( $data ); 152 } 150 153 } 151 154 … … 163 166 } 164 167 165 $response = rest_ensure_response( $results );168 $response = $is_head_request ? new WP_REST_Response() : rest_ensure_response( $results ); 166 169 $response->header( 'X-WP-Total', $total ); 167 170 $response->header( 'X-WP-TotalPages', $max_pages ); -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-sidebars-controller.php
r56586 r59899 120 120 */ 121 121 public function get_items( $request ) { 122 if ( $request->is_method( 'HEAD' ) ) { 123 // Return early as this handler doesn't add any response headers. 124 return new WP_REST_Response(); 125 } 126 122 127 $this->retrieve_widgets(); 123 128 … … 321 326 // Restores the more descriptive, specific name for use within this method. 322 327 $raw_sidebar = $item; 328 329 // Don't prepare the response body for HEAD requests. 330 if ( $request->is_method( 'HEAD' ) ) { 331 /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-sidebars-controller.php */ 332 return apply_filters( 'rest_prepare_sidebar', new WP_REST_Response(), $raw_sidebar, $request ); 333 } 323 334 324 335 $id = $raw_sidebar['id']; -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-taxonomies-controller.php
r58704 r59899 114 114 */ 115 115 public function get_items( $request ) { 116 if ( $request->is_method( 'HEAD' ) ) { 117 // Return early as this handler doesn't add any response headers. 118 return new WP_REST_Response(); 119 } 116 120 117 121 // Retrieve the list of registered collection query parameters. … … 210 214 // Restores the more descriptive, specific name for use within this method. 211 215 $taxonomy = $item; 216 217 // Don't prepare the response body for HEAD requests. 218 if ( $request->is_method( 'HEAD' ) ) { 219 /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-taxonomies-controller.php */ 220 return apply_filters( 'rest_prepare_taxonomy', new WP_REST_Response(), $taxonomy, $request ); 221 } 212 222 213 223 $base = ! empty( $taxonomy->rest_base ) ? $taxonomy->rest_base : $taxonomy->name; -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-template-autosaves-controller.php
r56819 r59899 176 176 $response = $this->parent_controller->prepare_item_for_response( $template, $request ); 177 177 178 // Don't prepare the response body for HEAD requests. 179 if ( $request->is_method( 'HEAD' ) ) { 180 return $response; 181 } 182 178 183 $fields = $this->get_fields_for_response( $request ); 179 184 $data = $response->get_data(); -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-template-revisions-controller.php
r59605 r59899 201 201 $response = $this->parent_controller->prepare_item_for_response( $template, $request ); 202 202 203 // Don't prepare the response body for HEAD requests. 204 if ( $request->is_method( 'HEAD' ) ) { 205 return $response; 206 } 207 203 208 $fields = $this->get_fields_for_response( $request ); 204 209 $data = $response->get_data(); -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-templates-controller.php
r59461 r59899 270 270 */ 271 271 public function get_items( $request ) { 272 if ( $request->is_method( 'HEAD' ) ) { 273 // Return early as this handler doesn't add any response headers. 274 return new WP_REST_Response(); 275 } 276 272 277 $query = array(); 273 278 if ( isset( $request['wp_id'] ) ) { … … 669 674 */ 670 675 public function prepare_item_for_response( $item, $request ) { 676 // Don't prepare the response body for HEAD requests. 677 if ( $request->is_method( 'HEAD' ) ) { 678 return new WP_REST_Response(); 679 } 680 671 681 /* 672 682 * Resolve pattern blocks so they don't need to be resolved client-side -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php
r59458 r59899 313 313 } 314 314 315 $is_head_request = $request->is_method( 'HEAD' ); 316 if ( $is_head_request ) { 317 // Force the 'fields' argument. For HEAD requests, only term IDs are required. 318 $prepared_args['fields'] = 'ids'; 319 // Disable priming term meta for HEAD requests to improve performance. 320 $prepared_args['update_term_meta_cache'] = false; 321 } 322 315 323 /** 316 324 * Filters get_terms() arguments when querying terms via the REST API. … … 355 363 } 356 364 357 $response = array(); 358 359 foreach ( $query_result as $term ) { 360 $data = $this->prepare_item_for_response( $term, $request ); 361 $response[] = $this->prepare_response_for_collection( $data ); 362 } 363 364 $response = rest_ensure_response( $response ); 365 if ( ! $is_head_request ) { 366 $response = array(); 367 foreach ( $query_result as $term ) { 368 $data = $this->prepare_item_for_response( $term, $request ); 369 $response[] = $this->prepare_response_for_collection( $data ); 370 } 371 } 372 373 $response = $is_head_request ? new WP_REST_Response() : rest_ensure_response( $response ); 365 374 366 375 // Store pagination values for headers. … … 887 896 */ 888 897 public function prepare_item_for_response( $item, $request ) { 898 899 // Don't prepare the response body for HEAD requests. 900 if ( $request->is_method( 'HEAD' ) ) { 901 /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-terms-controller.php */ 902 return apply_filters( "rest_prepare_{$this->taxonomy}", new WP_REST_Response(), $item, $request ); 903 } 889 904 890 905 $fields = $this->get_fields_for_response( $request ); -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php
r59892 r59899 356 356 $prepared_args['search'] = '*' . $prepared_args['search'] . '*'; 357 357 } 358 359 $is_head_request = $request->is_method( 'HEAD' ); 360 if ( $is_head_request ) { 361 // Force the 'fields' argument. For HEAD requests, only user IDs are required. 362 $prepared_args['fields'] = 'id'; 363 } 358 364 /** 359 365 * Filters WP_User_Query arguments when querying users via the REST API. … … 370 376 $query = new WP_User_Query( $prepared_args ); 371 377 372 $users = array(); 373 374 foreach ( $query->get_results() as $user ) { 375 $data = $this->prepare_item_for_response( $user, $request ); 376 $users[] = $this->prepare_response_for_collection( $data ); 377 } 378 379 $response = rest_ensure_response( $users ); 378 if ( ! $is_head_request ) { 379 $users = array(); 380 381 foreach ( $query->get_results() as $user ) { 382 $data = $this->prepare_item_for_response( $user, $request ); 383 $users[] = $this->prepare_response_for_collection( $data ); 384 } 385 } 386 387 $response = $is_head_request ? new WP_REST_Response() : rest_ensure_response( $users ); 380 388 381 389 // Store pagination values for headers then unset for count query. … … 1021 1029 // Restores the more descriptive, specific name for use within this method. 1022 1030 $user = $item; 1031 1032 // Don't prepare the response body for HEAD requests. 1033 if ( $request->is_method( 'HEAD' ) ) { 1034 /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php */ 1035 return apply_filters( 'rest_prepare_user', new WP_REST_Response(), $user, $request ); 1036 } 1023 1037 1024 1038 $fields = $this->get_fields_for_response( $request ); -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-widget-types-controller.php
r56586 r59899 146 146 */ 147 147 public function get_items( $request ) { 148 if ( $request->is_method( 'HEAD' ) ) { 149 // Return early as this handler doesn't add any response headers. 150 return new WP_REST_Response(); 151 } 152 148 153 $data = array(); 149 154 foreach ( $this->get_widgets() as $widget ) { … … 298 303 // Restores the more descriptive, specific name for use within this method. 299 304 $widget_type = $item; 305 306 // Don't prepare the response body for HEAD requests. 307 if ( $request->is_method( 'HEAD' ) ) { 308 /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-widget-types-controller.php */ 309 return apply_filters( 'rest_prepare_widget_type', new WP_REST_Response(), $widget_type, $request ); 310 } 300 311 301 312 $fields = $this->get_fields_for_response( $request ); -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-widgets-controller.php
r58704 r59899 137 137 */ 138 138 public function get_items( $request ) { 139 if ( $request->is_method( 'HEAD' ) ) { 140 // Return early as this handler doesn't add any response headers. 141 return new WP_REST_Response(); 142 } 143 139 144 $this->retrieve_widgets(); 140 145 … … 679 684 680 685 $widget = $wp_registered_widgets[ $widget_id ]; 686 // Don't prepare the response body for HEAD requests. 687 if ( $request->is_method( 'HEAD' ) ) { 688 /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-widgets-controller.php */ 689 return apply_filters( 'rest_prepare_widget', new WP_REST_Response(), $widget, $request ); 690 } 691 681 692 $parsed_id = wp_parse_widget_id( $widget_id ); 682 693 $fields = $this->get_fields_for_response( $request ); -
trunk/tests/phpunit/tests/fonts/font-library/wpRestFontCollectionsController.php
r57686 r59899 79 79 80 80 /** 81 * @dataProvider data_readable_http_methods 81 82 * @covers WP_REST_Font_Collections_Controller::get_items 82 */ 83 public function test_get_items_should_only_return_valid_collections() { 83 * @ticket 56481 84 * 85 * @param string $method The HTTP method to use. 86 */ 87 public function test_get_items_should_only_return_valid_collections( $method ) { 84 88 $this->setExpectedIncorrectUsage( 'WP_Font_Collection::load_from_json' ); 85 89 … … 93 97 ); 94 98 95 $request = new WP_REST_Request( 'GET', '/wp/v2/font-collections' );99 $request = new WP_REST_Request( $method, '/wp/v2/font-collections' ); 96 100 $response = rest_get_server()->dispatch( $request ); 97 101 $content = $response->get_data(); … … 100 104 101 105 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 102 $this->assertCount( 1, $content, 'The response should only contain valid collections.' ); 106 if ( 'HEAD' !== $method ) { 107 $this->assertCount( 1, $content, 'The response should only contain valid collections.' ); 108 return null; 109 } 110 111 $this->assertNull( $content, 'The response should be empty.' ); 112 $headers = $response->get_headers(); 113 $this->assertArrayHasKey( 'X-WP-Total', $headers, 'The "X-WP-Total" header should be present in the response.' ); 114 // Includes non-valid collections. 115 $this->assertSame( 2, $headers['X-WP-Total'], 'The "X-WP-Total" header value should be equal to 1.' ); 103 116 } 104 117 … … 128 141 129 142 /** 143 * @dataProvider data_readable_http_methods 144 * @ticket 56481 145 * 146 * @param string $method The HTTP method to use. 147 */ 148 public function test_get_item_should_allow_adding_headers_via_filter( $method ) { 149 $hook_name = 'rest_prepare_font_collection'; 150 $filter = new MockAction(); 151 $callback = array( $filter, 'filter' ); 152 add_filter( $hook_name, $callback ); 153 $header_filter = new class() { 154 public static function add_custom_header( $response ) { 155 $response->header( 'X-Test-Header', 'Test' ); 156 157 return $response; 158 } 159 }; 160 add_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 161 wp_set_current_user( self::$admin_id ); 162 $request = new WP_REST_Request( $method, '/wp/v2/font-collections/mock-col-slug' ); 163 $response = rest_get_server()->dispatch( $request ); 164 remove_filter( $hook_name, $callback ); 165 remove_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 166 167 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 168 $this->assertSame( 1, $filter->get_call_count(), 'The "' . $hook_name . '" filter was not called when it should be for GET/HEAD requests.' ); 169 $headers = $response->get_headers(); 170 $this->assertArrayHasKey( 'X-Test-Header', $headers, 'The "X-Test-Header" header should be present in the response.' ); 171 $this->assertSame( 'Test', $headers['X-Test-Header'], 'The "X-Test-Header" header value should be equal to "Test".' ); 172 if ( 'HEAD' !== $method ) { 173 return null; 174 } 175 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 176 } 177 178 /** 179 * Data provider intended to provide HTTP method names for testing GET and HEAD requests. 180 * 181 * @return array 182 */ 183 public static function data_readable_http_methods() { 184 return array( 185 'GET request' => array( 'GET' ), 186 'HEAD request' => array( 'HEAD' ), 187 ); 188 } 189 190 /** 191 * @dataProvider data_readable_http_methods 130 192 * @covers WP_REST_Font_Collections_Controller::get_item 131 */ 132 public function test_get_item_invalid_slug() { 133 wp_set_current_user( self::$admin_id ); 134 $request = new WP_REST_Request( 'GET', '/wp/v2/font-collections/non-existing-collection' ); 193 * @ticket 56481 194 * 195 * @param string $method The HTTP method to use. 196 */ 197 public function test_get_item_invalid_slug( $method ) { 198 wp_set_current_user( self::$admin_id ); 199 $request = new WP_REST_Request( $method, '/wp/v2/font-collections/non-existing-collection' ); 135 200 $response = rest_get_server()->dispatch( $request ); 136 201 $this->assertErrorResponse( 'rest_font_collection_not_found', $response, 404 ); … … 138 203 139 204 /** 205 * @dataProvider data_readable_http_methods 140 206 * @covers WP_REST_Font_Collections_Controller::get_item 141 */ 142 public function test_get_item_invalid_collection() { 207 * @ticket 56481 208 * 209 * @param string $method The HTTP method to use. 210 */ 211 public function test_get_item_invalid_collection( $method ) { 143 212 $this->setExpectedIncorrectUsage( 'WP_Font_Collection::load_from_json' ); 144 213 … … 153 222 ); 154 223 155 $request = new WP_REST_Request( 'GET', '/wp/v2/font-collections/' . $slug );224 $request = new WP_REST_Request( $method, '/wp/v2/font-collections/' . $slug ); 156 225 $response = rest_get_server()->dispatch( $request ); 157 226 … … 162 231 163 232 /** 233 * @dataProvider data_readable_http_methods 164 234 * @covers WP_REST_Font_Collections_Controller::get_item 165 */ 166 public function test_get_item_invalid_id_permission() { 167 $request = new WP_REST_Request( 'GET', '/wp/v2/font-collections/mock-col-slug' ); 235 * @ticket 56481 236 * 237 * @param string $method The HTTP method to use. 238 */ 239 public function test_get_item_invalid_id_permission( $method ) { 240 $request = new WP_REST_Request( $method, '/wp/v2/font-collections/mock-col-slug' ); 168 241 169 242 wp_set_current_user( 0 ); -
trunk/tests/phpunit/tests/rest-api/rest-autosaves-controller.php
r56745 r59899 180 180 } 181 181 182 public function test_get_items_no_permission() { 182 /** 183 * @ticket 56481 184 */ 185 public function test_get_items_with_head_request_should_not_prepare_autosaves_data() { 186 $request = new WP_REST_Request( 'HEAD', '/wp/v2/posts/' . self::$post_id . '/autosaves' ); 187 188 $hook_name = 'rest_prepare_autosave'; 189 $filter = new MockAction(); 190 $callback = array( $filter, 'filter' ); 191 192 add_filter( $hook_name, $callback ); 193 $response = rest_get_server()->dispatch( $request ); 194 remove_filter( $hook_name, $callback ); 195 196 $this->assertNotWPError( $response ); 197 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 198 $this->assertSame( 0, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' ); 199 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 200 } 201 202 /** 203 * @dataProvider data_readable_http_methods 204 * @ticket 56481 205 * 206 * @param string $method The HTTP method to use. 207 */ 208 public function test_get_items_no_permission( $method ) { 183 209 wp_set_current_user( 0 ); 184 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves' );210 $request = new WP_REST_Request( $method, '/wp/v2/posts/' . self::$post_id . '/autosaves' ); 185 211 $response = rest_get_server()->dispatch( $request ); 186 212 $this->assertErrorResponse( 'rest_cannot_read', $response, 401 ); … … 190 216 } 191 217 192 public function test_get_items_missing_parent() { 193 wp_set_current_user( self::$editor_id ); 194 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER . '/autosaves' ); 218 /** 219 * Data provider intended to provide HTTP method names for testing GET and HEAD requests. 220 * 221 * @return array 222 */ 223 public static function data_readable_http_methods() { 224 return array( 225 'GET request' => array( 'GET' ), 226 'HEAD request' => array( 'HEAD' ), 227 ); 228 } 229 230 /** 231 * @dataProvider data_readable_http_methods 232 * @ticket 56481 233 * 234 * @param string $method The HTTP method to use. 235 */ 236 public function test_get_items_missing_parent( $method ) { 237 wp_set_current_user( self::$editor_id ); 238 $request = new WP_REST_Request( $method, '/wp/v2/posts/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER . '/autosaves' ); 195 239 $response = rest_get_server()->dispatch( $request ); 196 240 $this->assertErrorResponse( 'rest_post_invalid_parent', $response, 404 ); 197 241 } 198 242 199 public function test_get_items_invalid_parent_post_type() { 200 wp_set_current_user( self::$editor_id ); 201 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$page_id . '/autosaves' ); 243 /** 244 * @dataProvider data_readable_http_methods 245 * @ticket 56481 246 * 247 * @param string $method The HTTP method to use. 248 */ 249 public function test_get_items_invalid_parent_post_type( $method ) { 250 wp_set_current_user( self::$editor_id ); 251 $request = new WP_REST_Request( $method, '/wp/v2/posts/' . self::$page_id . '/autosaves' ); 202 252 $response = rest_get_server()->dispatch( $request ); 203 253 $this->assertErrorResponse( 'rest_post_invalid_parent', $response, 404 ); … … 231 281 } 232 282 283 /** 284 * @dataProvider data_readable_http_methods 285 * @ticket 56481 286 * 287 * @param string $method The HTTP method to use. 288 */ 289 public function test_get_item_should_allow_adding_headers_via_filter( $method ) { 290 wp_set_current_user( self::$editor_id ); 291 $request = new WP_REST_Request( $method, '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id ); 292 293 $hook_name = 'rest_prepare_autosave'; 294 $filter = new MockAction(); 295 $callback = array( $filter, 'filter' ); 296 add_filter( $hook_name, $callback ); 297 $header_filter = new class() { 298 public static function add_custom_header( $response ) { 299 $response->header( 'X-Test-Header', 'Test' ); 300 301 return $response; 302 } 303 }; 304 add_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 305 $response = rest_get_server()->dispatch( $request ); 306 remove_filter( $hook_name, $callback ); 307 remove_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 308 309 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 310 $this->assertSame( 1, $filter->get_call_count(), 'The "' . $hook_name . '" filter was not called when it should be for GET/HEAD requests.' ); 311 $headers = $response->get_headers(); 312 $this->assertArrayHasKey( 'X-Test-Header', $headers, 'The "X-Test-Header" header should be present in the response.' ); 313 $this->assertSame( 'Test', $headers['X-Test-Header'], 'The "X-Test-Header" header value should be equal to "Test".' ); 314 if ( 'HEAD' !== $method ) { 315 return null; 316 } 317 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 318 } 319 233 320 public function test_get_item_embed_context() { 234 321 wp_set_current_user( self::$editor_id ); … … 249 336 } 250 337 251 public function test_get_item_no_permission() { 252 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id ); 338 /** 339 * @dataProvider data_readable_http_methods 340 * @ticket 56481 341 * 342 * @param string $method The HTTP method to use. 343 */ 344 public function test_get_item_no_permission( $method ) { 345 $request = new WP_REST_Request( $method, '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id ); 253 346 wp_set_current_user( self::$contributor_id ); 254 347 $response = rest_get_server()->dispatch( $request ); … … 256 349 } 257 350 258 public function test_get_item_missing_parent() { 259 wp_set_current_user( self::$editor_id ); 260 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER . '/autosaves/' . self::$autosave_post_id ); 351 /** 352 * @dataProvider data_readable_http_methods 353 * @ticket 56481 354 * 355 * @param string $method The HTTP method to use. 356 */ 357 public function test_get_item_missing_parent( $method ) { 358 wp_set_current_user( self::$editor_id ); 359 $request = new WP_REST_Request( $method, '/wp/v2/posts/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER . '/autosaves/' . self::$autosave_post_id ); 261 360 $response = rest_get_server()->dispatch( $request ); 262 361 $this->assertErrorResponse( 'rest_post_invalid_parent', $response, 404 ); 263 362 } 264 363 265 public function test_get_item_invalid_parent_post_type() { 266 wp_set_current_user( self::$editor_id ); 267 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$page_id . '/autosaves' ); 364 /** 365 * @dataProvider data_readable_http_methods 366 * @ticket 56481 367 * 368 * @param string $method The HTTP method to use. 369 */ 370 public function test_get_item_invalid_parent_post_type( $method ) { 371 wp_set_current_user( self::$editor_id ); 372 $request = new WP_REST_Request( $method, '/wp/v2/posts/' . self::$page_id . '/autosaves' ); 268 373 $response = rest_get_server()->dispatch( $request ); 269 374 $this->assertErrorResponse( 'rest_post_invalid_parent', $response, 404 ); -
trunk/tests/phpunit/tests/rest-api/rest-block-type-controller.php
r57565 r59899 603 603 604 604 /** 605 * @ticket 47620 606 */ 607 public function test_get_items_wrong_permission() { 605 * @dataProvider data_readable_http_methods 606 * @ticket 56481 607 * 608 * @param string $method The HTTP method to use. 609 */ 610 public function test_get_item_should_allow_adding_headers_via_filter( $method ) { 611 $block_name = 'fake/test'; 612 wp_set_current_user( self::$admin_id ); 613 614 $hook_name = 'rest_prepare_block_type'; 615 $filter = new MockAction(); 616 $callback = array( $filter, 'filter' ); 617 add_filter( $hook_name, $callback ); 618 $header_filter = new class() { 619 public static function add_custom_header( $response ) { 620 $response->header( 'X-Test-Header', 'Test' ); 621 622 return $response; 623 } 624 }; 625 add_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 626 $request = new WP_REST_Request( $method, '/wp/v2/block-types/' . $block_name ); 627 $response = rest_get_server()->dispatch( $request ); 628 remove_filter( $hook_name, $callback ); 629 remove_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 630 631 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 632 $this->assertSame( 1, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' ); 633 $headers = $response->get_headers(); 634 $this->assertArrayHasKey( 'X-Test-Header', $headers, 'The "X-Test-Header" header should be present in the response.' ); 635 $this->assertSame( 'Test', $headers['X-Test-Header'], 'The "X-Test-Header" header value should be equal to "Test".' ); 636 if ( 'HEAD' !== $method ) { 637 return null; 638 } 639 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 640 } 641 642 /** 643 * Data provider intended to provide HTTP method names for testing GET and HEAD requests. 644 * 645 * @return array 646 */ 647 public static function data_readable_http_methods() { 648 return array( 649 'GET request' => array( 'GET' ), 650 'HEAD request' => array( 'HEAD' ), 651 ); 652 } 653 654 /** 655 * @ticket 56481 656 */ 657 public function test_get_items_with_head_request_should_not_prepare_block_type_data() { 658 wp_set_current_user( self::$admin_id ); 659 $request = new WP_REST_Request( 'HEAD', '/wp/v2/block-types' ); 660 $response = rest_get_server()->dispatch( $request ); 661 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 662 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 663 } 664 665 /** 666 * @dataProvider data_readable_http_methods 667 * @ticket 47620 668 * @ticket 56481 669 * 670 * @param string $method HTTP method to use. 671 */ 672 public function test_get_items_wrong_permission( $method ) { 608 673 wp_set_current_user( self::$subscriber_id ); 609 $request = new WP_REST_Request( 'GET', '/wp/v2/block-types' );674 $request = new WP_REST_Request( $method, '/wp/v2/block-types' ); 610 675 $response = rest_get_server()->dispatch( $request ); 611 676 $this->assertErrorResponse( 'rest_block_type_cannot_view', $response, 403 ); … … 613 678 614 679 /** 615 * @ticket 47620 616 */ 617 public function test_get_item_wrong_permission() { 680 * @dataProvider data_readable_http_methods 681 * @ticket 47620 682 * @ticket 56481 683 * 684 * @param string $method HTTP method to use. 685 */ 686 public function test_get_item_wrong_permission( $method ) { 618 687 wp_set_current_user( self::$subscriber_id ); 619 $request = new WP_REST_Request( 'GET', '/wp/v2/block-types/fake/test' );688 $request = new WP_REST_Request( $method, '/wp/v2/block-types/fake/test' ); 620 689 $response = rest_get_server()->dispatch( $request ); 621 690 $this->assertErrorResponse( 'rest_block_type_cannot_view', $response, 403 ); … … 623 692 624 693 /** 625 * @ticket 47620 626 */ 627 public function test_get_items_no_permission() { 694 * @dataProvider data_readable_http_methods 695 * @ticket 47620 696 * @ticket 56481 697 * 698 * @param string $method HTTP method to use. 699 */ 700 public function test_get_items_no_permission( $method ) { 628 701 wp_set_current_user( 0 ); 629 $request = new WP_REST_Request( 'GET', '/wp/v2/block-types' );702 $request = new WP_REST_Request( $method, '/wp/v2/block-types' ); 630 703 $response = rest_get_server()->dispatch( $request ); 631 704 $this->assertErrorResponse( 'rest_block_type_cannot_view', $response, 401 ); … … 633 706 634 707 /** 635 * @ticket 47620 636 */ 637 public function test_get_item_no_permission() { 708 * @dataProvider data_readable_http_methods 709 * @ticket 47620 710 * @ticket 56481 711 * 712 * @param string $method HTTP method to use. 713 */ 714 public function test_get_item_no_permission( $method ) { 638 715 wp_set_current_user( 0 ); 639 $request = new WP_REST_Request( 'GET', '/wp/v2/block-types/fake/test' );716 $request = new WP_REST_Request( $method, '/wp/v2/block-types/fake/test' ); 640 717 $response = rest_get_server()->dispatch( $request ); 641 718 $this->assertErrorResponse( 'rest_block_type_cannot_view', $response, 401 ); … … 643 720 644 721 /** 645 * @ticket 47620 722 * @dataProvider data_readable_http_methods 723 * @ticket 47620 724 * @ticket 56481 725 * 726 * @param string $method HTTP method to use. 646 727 */ 647 728 public function test_prepare_item() { -
trunk/tests/phpunit/tests/rest-api/rest-categories-controller.php
r56746 r59899 577 577 } 578 578 579 public function test_get_terms_invalid_parent_arg() { 580 $request = new WP_REST_Request( 'GET', '/wp/v2/categories' ); 579 /** 580 * @dataProvider data_readable_http_methods 581 * @ticket 56481 582 * 583 * @param string $method HTTP method to use. 584 */ 585 public function test_get_terms_invalid_parent_arg( $method ) { 586 $request = new WP_REST_Request( $method, '/wp/v2/categories' ); 581 587 $request->set_param( 'parent', 'invalid-parent' ); 582 588 $response = rest_get_server()->dispatch( $request ); … … 610 616 } 611 617 612 public function test_get_terms_pagination_headers() { 618 /** 619 * @dataProvider data_readable_http_methods 620 * @ticket 56481 621 * 622 * @param string $method HTTP method to use. 623 */ 624 public function test_get_terms_pagination_headers( $method ) { 613 625 $total_categories = self::$total_categories; 614 626 $total_pages = (int) ceil( $total_categories / 10 ); 615 627 616 628 // Start of the index + Uncategorized default term. 617 $request = new WP_REST_Request( 'GET', '/wp/v2/categories' );629 $request = new WP_REST_Request( $method, '/wp/v2/categories' ); 618 630 $response = rest_get_server()->dispatch( $request ); 619 631 $headers = $response->get_headers(); 620 632 $this->assertSame( $total_categories, $headers['X-WP-Total'] ); 621 633 $this->assertSame( $total_pages, $headers['X-WP-TotalPages'] ); 622 $this->assertCount( 10, $response->get_data() ); 634 if ( 'HEAD' !== $method ) { 635 $this->assertCount( 10, $response->get_data() ); 636 } 623 637 $next_link = add_query_arg( 624 638 array( … … 663 677 $this->assertSame( $total_categories, $headers['X-WP-Total'] ); 664 678 $this->assertSame( $total_pages, $headers['X-WP-TotalPages'] ); 665 $this->assertCount( 1, $response->get_data() ); 679 if ( 'HEAD' !== $method ) { 680 $this->assertCount( 1, $response->get_data() ); 681 } 666 682 $prev_link = add_query_arg( 667 683 array( … … 680 696 $this->assertSame( $total_categories, $headers['X-WP-Total'] ); 681 697 $this->assertSame( $total_pages, $headers['X-WP-TotalPages'] ); 682 $this->assertCount( 0, $response->get_data() ); 698 if ( 'HEAD' !== $method ) { 699 $this->assertCount( 0, $response->get_data() ); 700 } 683 701 $prev_link = add_query_arg( 684 702 array( … … 1237 1255 $this->check_taxonomy_term( $category, $data, $response->get_links() ); 1238 1256 } 1257 1258 /** 1259 * @dataProvider data_readable_http_methods 1260 * @ticket 56481 1261 * 1262 * @param string $method HTTP method to use. 1263 */ 1264 public function test_get_items_only_fetches_ids_for_head_requests( $method ) { 1265 $is_head_request = 'HEAD' === $method; 1266 $request = new WP_REST_Request( $method, '/wp/v2/categories' ); 1267 1268 $filter = new MockAction(); 1269 1270 add_filter( 'terms_pre_query', array( $filter, 'filter' ), 10, 2 ); 1271 1272 $response = rest_get_server()->dispatch( $request ); 1273 1274 $this->assertSame( 200, $response->get_status() ); 1275 if ( $is_head_request ) { 1276 $this->assertEmpty( $response->get_data() ); 1277 } else { 1278 $this->assertNotEmpty( $response->get_data() ); 1279 } 1280 1281 $args = $filter->get_args(); 1282 $this->assertTrue( isset( $args[0][1] ), 'Query parameters were not captured.' ); 1283 $this->assertInstanceOf( WP_Term_Query::class, $args[0][1], 'Query parameters were not captured.' ); 1284 1285 /** @var WP_Term_Query $query */ 1286 $query = $args[0][1]; 1287 1288 if ( $is_head_request ) { 1289 $this->assertArrayHasKey( 'fields', $query->query_vars, 'The fields parameter is not set in the query vars.' ); 1290 $this->assertSame( 'ids', $query->query_vars['fields'], 'The query must fetch only term IDs.' ); 1291 $this->assertArrayHasKey( 'update_term_meta_cache', $query->query_vars, 'The update_term_meta_cache key is missing in the query vars.' ); 1292 $this->assertFalse( $query->query_vars['update_term_meta_cache'], 'The update_term_meta_cache value should be false for HEAD requests.' ); 1293 } else { 1294 $this->assertTrue( 1295 ! array_key_exists( 'fields', $query->query_vars ) || 'ids' !== $query->query_vars['fields'], 1296 'The fields parameter should not be forced to "ids" for non-HEAD requests.' 1297 ); 1298 $this->assertArrayHasKey( 'update_term_meta_cache', $query->query_vars, 'The update_term_meta_cache key is missing in the query vars.' ); 1299 $this->assertTrue( $query->query_vars['update_term_meta_cache'], 'The update_term_meta_cache value should be true for HEAD requests.' ); 1300 } 1301 1302 if ( ! $is_head_request ) { 1303 return; 1304 } 1305 1306 global $wpdb; 1307 $terms_table = preg_quote( $wpdb->terms, '/' ); 1308 1309 $pattern = '/SELECT\s+t\.term_id.+FROM\s+' . $terms_table . '\s+AS\s+t\s+INNER\s+JOIN/is'; 1310 1311 // Assert that the SQL query only fetches the term_id column. 1312 $this->assertMatchesRegularExpression( $pattern, $query->request, 'The SQL query does not match the expected string.' ); 1313 } 1314 1315 /** 1316 * Data provider intended to provide HTTP method names for testing GET and HEAD requests. 1317 * 1318 * @return array 1319 */ 1320 public static function data_readable_http_methods() { 1321 return array( 1322 'GET request' => array( 'GET' ), 1323 'HEAD request' => array( 'HEAD' ), 1324 ); 1325 } 1326 1327 /** 1328 * @dataProvider data_readable_http_methods 1329 * @ticket 56481 1330 * 1331 * @param string $method The HTTP method to use. 1332 */ 1333 public function test_get_item_should_allow_adding_headers_via_filter( $method ) { 1334 $category_id = self::factory()->category->create(); 1335 1336 $request = new WP_REST_Request( $method, sprintf( '/wp/v2/categories/%d', $category_id ) ); 1337 1338 $hook_name = 'rest_prepare_category'; 1339 1340 $filter = new MockAction(); 1341 $callback = array( $filter, 'filter' ); 1342 add_filter( $hook_name, $callback ); 1343 $header_filter = new class() { 1344 public static function add_custom_header( $response ) { 1345 $response->header( 'X-Test-Header', 'Test' ); 1346 1347 return $response; 1348 } 1349 }; 1350 add_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 1351 $response = rest_get_server()->dispatch( $request ); 1352 remove_filter( $hook_name, $callback ); 1353 remove_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 1354 1355 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 1356 $this->assertSame( 1, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' ); 1357 $headers = $response->get_headers(); 1358 $this->assertArrayHasKey( 'X-Test-Header', $headers, 'The "X-Test-Header" header should be present in the response.' ); 1359 $this->assertSame( 'Test', $headers['X-Test-Header'], 'The "X-Test-Header" header value should be equal to "Test".' ); 1360 if ( 'HEAD' !== $method ) { 1361 return null; 1362 } 1363 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 1364 } 1239 1365 } -
trunk/tests/phpunit/tests/rest-api/rest-comments-controller.php
r57176 r59899 433 433 } 434 434 435 public function test_get_items_no_permission_for_no_post() { 435 /** 436 * @dataProvider data_readable_http_methods 437 * @ticket 56481 438 * 439 * @param string $method HTTP method to use. 440 */ 441 public function test_get_items_no_permission_for_no_post( $method ) { 436 442 wp_set_current_user( 0 ); 437 443 438 $request = new WP_REST_Request( 'GET', '/wp/v2/comments' );444 $request = new WP_REST_Request( $method, '/wp/v2/comments' ); 439 445 $request->set_param( 'post', 0 ); 440 446 $response = rest_get_server()->dispatch( $request ); … … 442 448 } 443 449 444 public function test_get_items_edit_context() { 445 wp_set_current_user( self::$admin_id ); 446 447 $request = new WP_REST_Request( 'GET', '/wp/v2/comments' ); 450 /** 451 * Data provider intended to provide HTTP method names for testing GET and HEAD requests. 452 * 453 * @return array 454 */ 455 public static function data_readable_http_methods() { 456 return array( 457 'GET request' => array( 'GET' ), 458 'HEAD request' => array( 'HEAD' ), 459 ); 460 } 461 462 /** 463 * @dataProvider data_readable_http_methods 464 * @ticket 56481 465 * 466 * @param string $method HTTP method to use. 467 */ 468 public function test_get_items_edit_context( $method ) { 469 wp_set_current_user( self::$admin_id ); 470 471 $request = new WP_REST_Request( $method, '/wp/v2/comments' ); 448 472 $request->set_param( 'context', 'edit' ); 449 473 $response = rest_get_server()->dispatch( $request ); … … 594 618 } 595 619 596 public function test_get_items_private_post_no_permissions() { 620 /** 621 * @dataProvider data_readable_http_methods 622 * @ticket 56481 623 * 624 * @param string $method HTTP method to use. 625 */ 626 public function test_get_items_private_post_no_permissions( $method ) { 597 627 wp_set_current_user( 0 ); 598 628 599 629 $post_id = self::factory()->post->create( array( 'post_status' => 'private' ) ); 600 630 601 $request = new WP_REST_Request( 'GET', '/wp/v2/comments' );631 $request = new WP_REST_Request( $method, '/wp/v2/comments' ); 602 632 $request->set_param( 'post', $post_id ); 603 633 $response = rest_get_server()->dispatch( $request ); … … 802 832 } 803 833 804 public function test_get_comments_pagination_headers() { 834 /** 835 * @dataProvider data_readable_http_methods 836 * @ticket 56481 837 * 838 * @param string $method HTTP method to use. 839 */ 840 public function test_get_comments_pagination_headers( $method ) { 805 841 $total_comments = self::$total_comments; 806 842 $total_pages = (int) ceil( $total_comments / 10 ); … … 809 845 810 846 // Start of the index. 811 $request = new WP_REST_Request( 'GET', '/wp/v2/comments' );847 $request = new WP_REST_Request( $method, '/wp/v2/comments' ); 812 848 $response = rest_get_server()->dispatch( $request ); 813 849 $headers = $response->get_headers(); … … 885 921 } 886 922 887 public function test_get_comments_invalid_date() { 888 $request = new WP_REST_Request( 'GET', '/wp/v2/comments' ); 923 /** 924 * @dataProvider data_readable_http_methods 925 * @ticket 56481 926 * 927 * @param string $method HTTP method to use. 928 */ 929 public function test_get_comments_invalid_date( $method ) { 930 $request = new WP_REST_Request( $method, '/wp/v2/comments' ); 889 931 $request->set_param( 'after', 'foo' ); 890 932 $request->set_param( 'before', 'bar' ); … … 998 1040 } 999 1041 1000 public function test_get_comment_invalid_id() { 1001 $request = new WP_REST_Request( 'GET', '/wp/v2/comments/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ); 1042 /** 1043 * @dataProvider data_readable_http_methods 1044 * @ticket 56481 1045 * 1046 * @param string $method HTTP method to use. 1047 */ 1048 public function test_get_comment_invalid_id( $method ) { 1049 $request = new WP_REST_Request( $method, '/wp/v2/comments/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER ); 1002 1050 1003 1051 $response = rest_get_server()->dispatch( $request ); … … 1005 1053 } 1006 1054 1007 public function test_get_comment_invalid_context() { 1055 /** 1056 * @dataProvider data_readable_http_methods 1057 * @ticket 56481 1058 * 1059 * @param string $method HTTP method to use. 1060 */ 1061 public function test_get_comment_invalid_context( $method ) { 1008 1062 wp_set_current_user( 0 ); 1009 1063 1010 $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%s', self::$approved_id ) );1064 $request = new WP_REST_Request( $method, sprintf( '/wp/v2/comments/%s', self::$approved_id ) ); 1011 1065 $request->set_param( 'context', 'edit' ); 1012 1066 $response = rest_get_server()->dispatch( $request ); … … 1014 1068 } 1015 1069 1016 public function test_get_comment_invalid_post_id() { 1070 /** 1071 * @dataProvider data_readable_http_methods 1072 * @ticket 56481 1073 * 1074 * @param string $method HTTP method to use. 1075 */ 1076 public function test_get_comment_invalid_post_id( $method ) { 1017 1077 wp_set_current_user( 0 ); 1018 1078 … … 1024 1084 ); 1025 1085 1026 $request = new WP_REST_Request( 'GET', '/wp/v2/comments/' . $comment_id );1086 $request = new WP_REST_Request( $method, '/wp/v2/comments/' . $comment_id ); 1027 1087 $response = rest_get_server()->dispatch( $request ); 1028 1088 $this->assertErrorResponse( 'rest_post_invalid_id', $response, 404 ); 1029 1089 } 1030 1090 1031 public function test_get_comment_invalid_post_id_as_admin() { 1091 /** 1092 * @dataProvider data_readable_http_methods 1093 * @ticket 56481 1094 * 1095 * @param string $method HTTP method to use. 1096 */ 1097 public function test_get_comment_invalid_post_id_as_admin( $method ) { 1032 1098 wp_set_current_user( self::$admin_id ); 1033 1099 … … 1039 1105 ); 1040 1106 1041 $request = new WP_REST_Request( 'GET', '/wp/v2/comments/' . $comment_id );1107 $request = new WP_REST_Request( $method, '/wp/v2/comments/' . $comment_id ); 1042 1108 $response = rest_get_server()->dispatch( $request ); 1043 1109 $this->assertErrorResponse( 'rest_post_invalid_id', $response, 404 ); 1044 1110 } 1045 1111 1046 public function test_get_comment_not_approved() { 1112 /** 1113 * @dataProvider data_readable_http_methods 1114 * @ticket 56481 1115 * 1116 * @param string $method HTTP method to use. 1117 */ 1118 public function test_get_comment_not_approved( $method ) { 1047 1119 wp_set_current_user( 0 ); 1048 1120 1049 $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%d', self::$hold_id ) );1121 $request = new WP_REST_Request( $method, sprintf( '/wp/v2/comments/%d', self::$hold_id ) ); 1050 1122 $response = rest_get_server()->dispatch( $request ); 1051 1123 $this->assertErrorResponse( 'rest_cannot_read', $response, 401 ); 1052 1124 } 1053 1125 1054 public function test_get_comment_not_approved_same_user() { 1055 wp_set_current_user( self::$admin_id ); 1056 1057 $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%d', self::$hold_id ) ); 1126 /** 1127 * @dataProvider data_readable_http_methods 1128 * @ticket 56481 1129 * 1130 * @param string $method HTTP method to use. 1131 */ 1132 public function test_get_comment_not_approved_same_user( $method ) { 1133 wp_set_current_user( self::$admin_id ); 1134 1135 $request = new WP_REST_Request( $method, sprintf( '/wp/v2/comments/%d', self::$hold_id ) ); 1058 1136 $response = rest_get_server()->dispatch( $request ); 1059 1137 $this->assertSame( 200, $response->get_status() ); … … 1099 1177 } 1100 1178 1101 public function test_get_comment_with_password_without_edit_post_permission() { 1179 /** 1180 * @dataProvider data_readable_http_methods 1181 * @ticket 56481 1182 * 1183 * @param string $method HTTP method to use. 1184 */ 1185 public function test_get_comment_with_password_without_edit_post_permission( $method ) { 1102 1186 wp_set_current_user( self::$subscriber_id ); 1103 1187 … … 1109 1193 $password_comment = self::factory()->comment->create( $args ); 1110 1194 1111 $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%s', $password_comment ) );1195 $request = new WP_REST_Request( $method, sprintf( '/wp/v2/comments/%s', $password_comment ) ); 1112 1196 $response = rest_get_server()->dispatch( $request ); 1113 1197 $this->assertErrorResponse( 'rest_cannot_read', $response, 403 ); … … 1115 1199 1116 1200 /** 1201 * @dataProvider data_readable_http_methods 1117 1202 * @ticket 38692 1118 */ 1119 public function test_get_comment_with_password_with_valid_password() { 1203 * @ticket 56481 1204 * 1205 * @param string $method HTTP method to use. 1206 */ 1207 public function test_get_comment_with_password_with_valid_password( $method ) { 1120 1208 wp_set_current_user( self::$subscriber_id ); 1121 1209 … … 1127 1215 $password_comment = self::factory()->comment->create( $args ); 1128 1216 1129 $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/comments/%s', $password_comment ) );1217 $request = new WP_REST_Request( $method, sprintf( '/wp/v2/comments/%s', $password_comment ) ); 1130 1218 $request->set_param( 'password', 'toomanysecrets' ); 1131 1219 … … 3366 3454 3367 3455 /** 3456 * @dataProvider data_readable_http_methods 3368 3457 * @ticket 42238 3369 */ 3370 public function test_check_read_post_permission_with_invalid_post_type() { 3458 * @ticket 56481 3459 * 3460 * @param string $method HTTP method to use. 3461 */ 3462 public function test_check_read_post_permission_with_invalid_post_type( $method ) { 3371 3463 register_post_type( 3372 3464 'bug-post', … … 3387 3479 3388 3480 wp_set_current_user( self::$admin_id ); 3389 $request = new WP_REST_Request( 'GET', '/wp/v2/comments/' . $comment_id );3481 $request = new WP_REST_Request( $method, '/wp/v2/comments/' . $comment_id ); 3390 3482 $response = rest_get_server()->dispatch( $request ); 3391 3483 $this->assertSame( 403, $response->get_status() ); 3392 3484 } 3485 3486 /** 3487 * @dataProvider data_readable_http_methods 3488 * @ticket 56481 3489 * 3490 * @param string $method HTTP method to use. 3491 */ 3492 public function test_get_items_only_fetches_ids_for_head_requests( $method ) { 3493 $is_head_request = 'HEAD' === $method; 3494 $request = new WP_REST_Request( $method, '/wp/v2/comments' ); 3495 3496 $filter = new MockAction(); 3497 3498 add_filter( 'comments_pre_query', array( $filter, 'filter' ), 10, 2 ); 3499 3500 $response = rest_get_server()->dispatch( $request ); 3501 3502 $this->assertSame( 200, $response->get_status() ); 3503 if ( $is_head_request ) { 3504 $this->assertEmpty( $response->get_data() ); 3505 } else { 3506 $this->assertNotEmpty( $response->get_data() ); 3507 } 3508 3509 $args = $filter->get_args(); 3510 $this->assertTrue( isset( $args[0][1] ), 'Query parameters were not captured.' ); 3511 $this->assertInstanceOf( WP_Comment_Query::class, $args[0][1], 'Query parameters were not captured.' ); 3512 3513 /** @var WP_Comment_Query $query */ 3514 $query = $args[0][1]; 3515 3516 if ( $is_head_request ) { 3517 $this->assertArrayHasKey( 'fields', $query->query_vars, 'The fields parameter is not set in the query vars.' ); 3518 $this->assertSame( 'ids', $query->query_vars['fields'], 'The query must fetch only post IDs.' ); 3519 $this->assertArrayHasKey( 'update_comment_meta_cache', $query->query_vars, 'The update_comment_meta_cache key is missing in the query vars.' ); 3520 $this->assertFalse( $query->query_vars['update_comment_meta_cache'], 'The update_comment_meta_cache value should be false for HEAD requests.' ); 3521 } else { 3522 $this->assertTrue( ! array_key_exists( 'fields', $query->query_vars ) || 'ids' !== $query->query_vars['fields'], 'The fields parameter should not be forced to "ids" for non-HEAD requests.' ); 3523 $this->assertArrayHasKey( 'update_comment_meta_cache', $query->query_vars, 'The update_comment_meta_cache key is missing in the query vars.' ); 3524 $this->assertTrue( $query->query_vars['update_comment_meta_cache'], 'The update_comment_meta_cache value should be true for non-HEAD requests.' ); 3525 return; 3526 } 3527 3528 global $wpdb; 3529 $comments_table = preg_quote( $wpdb->comments, '/' ); 3530 $pattern = '/^SELECT\s+SQL_CALC_FOUND_ROWS\s+' . $comments_table . '\.comment_ID\s+FROM\s+' . $comments_table . '\s+WHERE/i'; 3531 3532 // Assert that the SQL query only fetches the ID column. 3533 $this->assertMatchesRegularExpression( $pattern, $query->request, 'The SQL query does not match the expected string.' ); 3534 } 3535 3536 /** 3537 * @dataProvider data_readable_http_methods 3538 * @ticket 56481 3539 * 3540 * @param string $method The HTTP method to use. 3541 */ 3542 public function test_get_item_should_allow_adding_headers_via_filter( $method ) { 3543 $request = new WP_REST_Request( $method, sprintf( '/wp/v2/comments/%d', self::$approved_id ) ); 3544 3545 $hook_name = 'rest_prepare_comment'; 3546 3547 $filter = new MockAction(); 3548 $callback = array( $filter, 'filter' ); 3549 add_filter( $hook_name, $callback ); 3550 $header_filter = new class() { 3551 public static function add_custom_header( $response ) { 3552 $response->header( 'X-Test-Header', 'Test' ); 3553 3554 return $response; 3555 } 3556 }; 3557 add_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 3558 $response = rest_get_server()->dispatch( $request ); 3559 remove_filter( $hook_name, $callback ); 3560 remove_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 3561 3562 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 3563 $headers = $response->get_headers(); 3564 $this->assertSame( 1, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' ); 3565 $this->assertArrayHasKey( 'X-Test-Header', $headers, 'The "X-Test-Header" header should be present in the response.' ); 3566 $this->assertSame( 'Test', $headers['X-Test-Header'], 'The "X-Test-Header" header value should be equal to "Test".' ); 3567 if ( 'HEAD' !== $method ) { 3568 return null; 3569 } 3570 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 3571 } 3393 3572 } -
trunk/tests/phpunit/tests/rest-api/rest-global-styles-revisions-controller.php
r59630 r59899 246 246 247 247 /** 248 * @ticket 58524 249 * 250 * @covers WP_REST_Global_Styles_Controller::get_items 251 */ 252 public function test_get_items_missing_parent() { 253 wp_set_current_user( self::$admin_id ); 254 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER . '/revisions' ); 248 * @dataProvider data_readable_http_methods 249 * @ticket 58524 250 * @ticket 56481 251 * 252 * @covers WP_REST_Global_Styles_Controller::get_items 253 * 254 * @param string $method The HTTP method to use. 255 */ 256 public function test_get_items_missing_parent( $method ) { 257 wp_set_current_user( self::$admin_id ); 258 $request = new WP_REST_Request( $method, '/wp/v2/global-styles/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER . '/revisions' ); 255 259 $response = rest_get_server()->dispatch( $request ); 256 260 $this->assertErrorResponse( 'rest_post_invalid_parent', $response, 404 ); 261 } 262 263 /** 264 * Data provider intended to provide HTTP method names for testing GET and HEAD requests. 265 * 266 * @return array 267 */ 268 public static function data_readable_http_methods() { 269 return array( 270 'GET request' => array( 'GET' ), 271 'HEAD request' => array( 'HEAD' ), 272 ); 257 273 } 258 274 … … 312 328 313 329 /** 330 * @ticket 56481 331 * 332 * @covers WP_REST_Global_Styles_Controller::prepare_item_for_response 333 */ 334 public function test_get_items_should_return_no_response_body_for_head_requests() { 335 wp_set_current_user( self::$admin_id ); 336 $request = new WP_REST_Request( 'HEAD', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); 337 $response = rest_get_server()->dispatch( $request ); 338 $this->assertSame( 200, $response->get_status(), 'Response status is 200.' ); 339 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 340 } 341 342 /** 314 343 * @ticket 59810 315 344 * … … 328 357 329 358 /** 359 * @ticket 56481 360 * 361 * @covers WP_REST_Global_Styles_Controller::get_item 362 * @covers WP_REST_Global_Styles_Controller::prepare_item_for_response 363 */ 364 public function test_get_item_should_return_no_response_body_for_head_requests() { 365 wp_set_current_user( self::$admin_id ); 366 $request = new WP_REST_Request( 'HEAD', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions/' . $this->revision_1_id ); 367 $response = rest_get_server()->dispatch( $request ); 368 $this->assertSame( 200, $response->get_status(), 'Response status is 200.' ); 369 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 370 } 371 372 /** 373 * @dataProvider data_readable_http_methods 330 374 * @ticket 59810 375 * @ticket 56481 331 376 * 332 377 * @covers WP_REST_Global_Styles_Controller::get_revision 333 */ 334 public function test_get_item_invalid_revision_id_should_error() { 378 * 379 * @param string $method The HTTP method to use. 380 */ 381 public function test_get_item_invalid_revision_id_should_error( $method ) { 335 382 wp_set_current_user( self::$admin_id ); 336 383 337 384 $expected_error = 'rest_post_invalid_id'; 338 385 $expected_status = 404; 339 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions/20000001' );386 $request = new WP_REST_Request( $method, '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions/20000001' ); 340 387 $response = rest_get_server()->dispatch( $request ); 341 388 … … 420 467 421 468 /** 469 * @dataProvider data_readable_http_methods 422 470 * @ticket 58524 423 471 * @ticket 60131 472 * @ticket 56481 424 473 * 425 474 * @covers WP_REST_Global_Styles_Controller::get_item_permissions_check 426 */ 427 public function test_get_item_permissions_check() { 475 * 476 * @param string $method The HTTP method to use. 477 */ 478 public function test_get_item_permissions_check( $method ) { 428 479 wp_set_current_user( self::$author_id ); 429 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' );480 $request = new WP_REST_Request( $method, '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); 430 481 $response = rest_get_server()->dispatch( $request ); 431 482 … … 436 487 * Tests the pagination header of the first page. 437 488 * 438 * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_pagination_header_of_the_first_page 439 * 440 * @ticket 58524 441 * 442 * @covers WP_REST_Global_Styles_Controller::get_items 443 */ 444 public function test_get_items_pagination_header_of_the_first_page() { 489 * @dataProvider data_readable_http_methods 490 * @ticket 58524 491 * @ticket 56481 492 * 493 * @covers WP_REST_Global_Styles_Controller::get_items 494 * 495 * @param string $method The HTTP method to use. 496 */ 497 public function test_get_items_pagination_header_of_the_first_page( $method ) { 445 498 wp_set_current_user( self::$admin_id ); 446 499 … … 450 503 $page = 1; // First page. 451 504 452 $request = new WP_REST_Request( 'GET', $rest_route );505 $request = new WP_REST_Request( $method, $rest_route ); 453 506 $request->set_query_params( 454 507 array( … … 477 530 * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_pagination_header_of_the_last_page 478 531 * 479 * @ticket 58524 480 * 481 * @covers WP_REST_Global_Styles_Controller::get_items 482 */ 483 public function test_get_items_pagination_header_of_the_last_page() { 532 * @dataProvider data_readable_http_methods 533 * @ticket 58524 534 * @ticket 56481 535 * 536 * @covers WP_REST_Global_Styles_Controller::get_items 537 * 538 * @param string $method The HTTP method to use. 539 */ 540 public function test_get_items_pagination_header_of_the_last_page( $method ) { 484 541 wp_set_current_user( self::$admin_id ); 485 542 … … 489 546 $page = 2; // Last page. 490 547 491 $request = new WP_REST_Request( 'GET', $rest_route );548 $request = new WP_REST_Request( $method, $rest_route ); 492 549 $request->set_query_params( 493 550 array( … … 515 572 * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_invalid_per_page_should_error 516 573 * 517 * @ticket 58524 518 * 519 * @covers WP_REST_Global_Styles_Controller::get_items 520 */ 521 public function test_get_items_invalid_per_page_should_error() { 574 * @dataProvider data_readable_http_methods 575 * @ticket 58524 576 * @ticket 56481 577 * 578 * @covers WP_REST_Global_Styles_Controller::get_items 579 * 580 * @param string $method The HTTP method to use. 581 */ 582 public function test_get_items_invalid_per_page_should_error( $method ) { 522 583 wp_set_current_user( self::$admin_id ); 523 584 … … 526 587 $expected_status = 400; 527 588 528 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' );589 $request = new WP_REST_Request( $method, '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); 529 590 $request->set_param( 'per_page', $per_page ); 530 591 $response = rest_get_server()->dispatch( $request ); … … 537 598 * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_out_of_bounds_page_should_error 538 599 * 539 * @ticket 58524 540 * 541 * @covers WP_REST_Global_Styles_Controller::get_items 542 */ 543 public function test_get_items_out_of_bounds_page_should_error() { 600 * @dataProvider data_readable_http_methods 601 * @ticket 58524 602 * @ticket 56481 603 * 604 * @covers WP_REST_Global_Styles_Controller::get_items 605 * 606 * @param string $method The HTTP method to use. 607 */ 608 public function test_get_items_out_of_bounds_page_should_error( $method ) { 544 609 wp_set_current_user( self::$admin_id ); 545 610 … … 550 615 $expected_status = 400; 551 616 552 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' );617 $request = new WP_REST_Request( $method, '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); 553 618 $request->set_query_params( 554 619 array( … … 566 631 * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_invalid_max_pages_should_error 567 632 * 568 * @ticket 58524 569 * 570 * @covers WP_REST_Global_Styles_Controller::get_items 571 */ 572 public function test_get_items_invalid_max_pages_should_error() { 633 * @dataProvider data_readable_http_methods 634 * @ticket 58524 635 * @ticket 56481 636 * 637 * @covers WP_REST_Global_Styles_Controller::get_items 638 * 639 * @param string $method The HTTP method to use. 640 */ 641 public function test_get_items_invalid_max_pages_should_error( $method ) { 573 642 wp_set_current_user( self::$admin_id ); 574 643 … … 578 647 $expected_status = 400; 579 648 580 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' );649 $request = new WP_REST_Request( $method, '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); 581 650 $request->set_query_params( 582 651 array( … … 690 759 * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_total_revisions_offset_should_return_empty_data 691 760 * 692 * @ticket 58524 693 * 694 * @covers WP_REST_Global_Styles_Controller::get_items 695 */ 696 public function test_get_items_total_revisions_offset_should_return_empty_data() { 761 * @dataProvider data_readable_http_methods 762 * @ticket 58524 763 * @ticket 56481 764 * 765 * @covers WP_REST_Global_Styles_Controller::get_items 766 * 767 * @param string $method The HTTP method to use. 768 */ 769 public function test_get_items_total_revisions_offset_should_return_empty_data( $method ) { 697 770 wp_set_current_user( self::$admin_id ); 698 771 … … 702 775 $expected_status = 400; 703 776 704 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' );777 $request = new WP_REST_Request( $method, '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); 705 778 $request->set_query_params( 706 779 array( … … 718 791 * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_out_of_bound_offset_should_error 719 792 * 720 * @ticket 58524 721 * 722 * @covers WP_REST_Global_Styles_Controller::get_items 723 */ 724 public function test_get_items_out_of_bound_offset_should_error() { 793 * @dataProvider data_readable_http_methods 794 * @ticket 58524 795 * @ticket 56481 796 * 797 * @covers WP_REST_Global_Styles_Controller::get_items 798 * 799 * @param string $method The HTTP method to use. 800 */ 801 public function test_get_items_out_of_bound_offset_should_error( $method ) { 725 802 wp_set_current_user( self::$admin_id ); 726 803 … … 730 807 $expected_status = 400; 731 808 732 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' );809 $request = new WP_REST_Request( $method, '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); 733 810 $request->set_query_params( 734 811 array( … … 746 823 * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_impossible_high_number_offset_should_error 747 824 * 748 * @ticket 58524 749 * 750 * @covers WP_REST_Global_Styles_Controller::get_items 751 */ 752 public function test_get_items_impossible_high_number_offset_should_error() { 825 * @dataProvider data_readable_http_methods 826 * @ticket 58524 827 * @ticket 56481 828 * 829 * @covers WP_REST_Global_Styles_Controller::get_items 830 * 831 * @param string $method The HTTP method to use. 832 */ 833 public function test_get_items_impossible_high_number_offset_should_error( $method ) { 753 834 wp_set_current_user( self::$admin_id ); 754 835 … … 758 839 $expected_status = 400; 759 840 760 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' );841 $request = new WP_REST_Request( $method, '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); 761 842 $request->set_query_params( 762 843 array( … … 774 855 * Duplicate of WP_Test_REST_Revisions_Controller::test_get_items_invalid_offset_should_error 775 856 * 776 * @ticket 58524 777 * 778 * @covers WP_REST_Global_Styles_Controller::get_items 779 */ 780 public function test_get_items_invalid_offset_should_error() { 857 * @dataProvider data_readable_http_methods 858 * @ticket 58524 859 * @ticket 56481 860 * 861 * @covers WP_REST_Global_Styles_Controller::get_items 862 * 863 * @param string $method The HTTP method to use. 864 */ 865 public function test_get_items_invalid_offset_should_error( $method ) { 781 866 wp_set_current_user( self::$admin_id ); 782 867 … … 786 871 $expected_status = 400; 787 872 788 $request = new WP_REST_Request( 'GET', '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' );873 $request = new WP_REST_Request( $method, '/wp/v2/global-styles/' . self::$global_styles_id . '/revisions' ); 789 874 $request->set_query_params( 790 875 array( -
trunk/tests/phpunit/tests/rest-api/rest-pattern-directory-controller.php
r56559 r59899 146 146 147 147 /** 148 * @ticket 56481 149 */ 150 public function test_get_items_with_head_request_should_not_prepare_block_patterns_data() { 151 wp_set_current_user( self::$contributor_id ); 152 self::mock_successful_response( 'browse-all', true ); 153 154 $request = new WP_REST_Request( 'HEAD', '/wp/v2/pattern-directory/patterns' ); 155 156 $hook_name = 'rest_prepare_block_pattern'; 157 $filter = new MockAction(); 158 $callback = array( $filter, 'filter' ); 159 160 add_filter( $hook_name, $callback ); 161 $response = rest_get_server()->dispatch( $request ); 162 remove_filter( $hook_name, $callback ); 163 164 $this->assertNotWPError( $response ); 165 $response = rest_ensure_response( $response ); 166 167 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 168 169 $this->assertSame( 0, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' ); 170 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 171 } 172 173 /** 148 174 * @covers WP_REST_Pattern_Directory_Controller::get_items 149 175 * … … 220 246 221 247 /** 222 * @covers WP_REST_Pattern_Directory_Controller::get_items 223 * 224 * @since 5.8.0 225 */ 226 public function test_get_items_wdotorg_unavailable() { 248 * @dataProvider data_readable_http_methods 249 * @ticket 56481 250 * 251 * @covers WP_REST_Pattern_Directory_Controller::get_items 252 * 253 * @since 5.8.0 254 * 255 * @param string $method The HTTP method to use. 256 */ 257 public function test_get_items_wdotorg_unavailable( $method ) { 227 258 wp_set_current_user( self::$contributor_id ); 228 259 self::prevent_requests_to_host( 'api.wordpress.org' ); 229 260 230 $request = new WP_REST_Request( 'GET', '/wp/v2/pattern-directory/patterns' );261 $request = new WP_REST_Request( $method, '/wp/v2/pattern-directory/patterns' ); 231 262 $response = rest_do_request( $request ); 232 263 … … 235 266 236 267 /** 237 * @covers WP_REST_Pattern_Directory_Controller::get_items 238 * 239 * @since 5.8.0 240 */ 241 public function test_get_items_logged_out() { 242 $request = new WP_REST_Request( 'GET', '/wp/v2/pattern-directory/patterns' ); 268 * Data provider intended to provide HTTP method names for testing GET and HEAD requests. 269 * 270 * @return array 271 */ 272 public static function data_readable_http_methods() { 273 return array( 274 'GET request' => array( 'GET' ), 275 'HEAD request' => array( 'HEAD' ), 276 ); 277 } 278 279 /** 280 * @dataProvider data_readable_http_methods 281 * @ticket 56481 282 * 283 * @covers WP_REST_Pattern_Directory_Controller::get_items 284 * 285 * @since 5.8.0 286 * 287 * @param string $method The HTTP method to use. 288 */ 289 public function test_get_items_logged_out( $method ) { 290 $request = new WP_REST_Request( $method, '/wp/v2/pattern-directory/patterns' ); 243 291 $request->set_query_params( array( 'search' => 'button' ) ); 244 292 $response = rest_do_request( $request ); … … 284 332 285 333 /** 286 * @covers WP_REST_Pattern_Directory_Controller::get_items 287 * 288 * @since 5.8.0 289 */ 290 public function test_get_items_invalid_response_data() { 334 * @dataProvider data_readable_http_methods 335 * @ticket 56481 336 * 337 * @covers WP_REST_Pattern_Directory_Controller::get_items 338 * 339 * @since 5.8.0 340 * 341 * @param string $method The HTTP method to use. 342 */ 343 public function test_get_items_invalid_response_data( $method ) { 291 344 wp_set_current_user( self::$contributor_id ); 292 345 self::mock_successful_response( 'invalid-data', true ); 293 346 294 $request = new WP_REST_Request( 'GET', '/wp/v2/pattern-directory/patterns' );347 $request = new WP_REST_Request( $method, '/wp/v2/pattern-directory/patterns' ); 295 348 $response = rest_do_request( $request ); 296 349 -
trunk/tests/phpunit/tests/rest-api/rest-post-types-controller.php
r58452 r59899 45 45 } 46 46 47 public function test_get_items_invalid_permission_for_context() { 47 /** 48 * @dataProvider data_readable_http_methods 49 * @ticket 56481 50 * 51 * @param string $method HTTP method to use. 52 */ 53 public function test_get_items_invalid_permission_for_context( $method ) { 48 54 wp_set_current_user( 0 ); 49 $request = new WP_REST_Request( 'GET', '/wp/v2/types' );55 $request = new WP_REST_Request( $method, '/wp/v2/types' ); 50 56 $request->set_param( 'context', 'edit' ); 51 57 $response = rest_get_server()->dispatch( $request ); 52 58 $this->assertErrorResponse( 'rest_cannot_view', $response, 401 ); 59 } 60 61 /** 62 * Data provider intended to provide HTTP method names for testing GET and HEAD requests. 63 * 64 * @return array 65 */ 66 public static function data_readable_http_methods() { 67 return array( 68 'GET request' => array( 'GET' ), 69 'HEAD request' => array( 'HEAD' ), 70 ); 53 71 } 54 72 … … 59 77 $data = $response->get_data(); 60 78 $this->assertSame( array( 'category', 'post_tag' ), $data['taxonomies'] ); 79 } 80 81 /** 82 * @dataProvider data_readable_http_methods 83 * @ticket 56481 84 * 85 * @param string $method The HTTP method to use. 86 */ 87 public function test_get_item_should_allow_adding_headers_via_filter( $method ) { 88 $request = new WP_REST_Request( $method, '/wp/v2/types/post' ); 89 90 $hook_name = 'rest_prepare_post_type'; 91 $filter = new MockAction(); 92 $callback = array( $filter, 'filter' ); 93 add_filter( $hook_name, $callback ); 94 $header_filter = new class() { 95 public static function add_custom_header( $response ) { 96 $response->header( 'X-Test-Header', 'Test' ); 97 98 return $response; 99 } 100 }; 101 add_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 102 $response = rest_get_server()->dispatch( $request ); 103 remove_filter( $hook_name, $callback ); 104 remove_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 105 106 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 107 $this->assertSame( 1, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' ); 108 $headers = $response->get_headers(); 109 $this->assertArrayHasKey( 'X-Test-Header', $headers, 'The "X-Test-Header" header should be present in the response.' ); 110 $this->assertSame( 'Test', $headers['X-Test-Header'], 'The "X-Test-Header" header value should be equal to "Test".' ); 111 if ( 'HEAD' !== $method ) { 112 return null; 113 } 114 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 61 115 } 62 116 … … 107 161 } 108 162 109 public function test_get_item_invalid_type() { 110 $request = new WP_REST_Request( 'GET', '/wp/v2/types/invalid' ); 163 /** 164 * @dataProvider data_readable_http_methods 165 * @ticket 56481 166 * 167 * @param string $method HTTP method to use. 168 */ 169 public function test_get_item_invalid_type( $method ) { 170 $request = new WP_REST_Request( $method, '/wp/v2/types/invalid' ); 111 171 $response = rest_get_server()->dispatch( $request ); 112 172 $this->assertErrorResponse( 'rest_type_invalid', $response, 404 ); … … 122 182 } 123 183 124 public function test_get_item_invalid_permission_for_context() { 184 /** 185 * @dataProvider data_readable_http_methods 186 * @ticket 56481 187 * 188 * @param string $method HTTP method to use. 189 */ 190 public function test_get_item_invalid_permission_for_context( $method ) { 125 191 wp_set_current_user( 0 ); 126 $request = new WP_REST_Request( 'GET', '/wp/v2/types/post' );192 $request = new WP_REST_Request( $method, '/wp/v2/types/post' ); 127 193 $request->set_param( 'context', 'edit' ); 128 194 $response = rest_get_server()->dispatch( $request ); … … 244 310 public function additional_field_get_callback( $response_data ) { 245 311 return 123; 312 } 313 314 /** 315 * @ticket 56481 316 */ 317 public function test_get_items_with_head_request_should_not_prepare_post_types_data() { 318 $request = new WP_REST_Request( 'HEAD', '/wp/v2/types' ); 319 $hook_name = 'rest_prepare_post_type'; 320 $filter = new MockAction(); 321 $callback = array( $filter, 'filter' ); 322 add_filter( $hook_name, $callback ); 323 $response = rest_get_server()->dispatch( $request ); 324 remove_filter( $hook_name, $callback ); 325 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 326 $this->assertSame( 0, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' ); 327 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 246 328 } 247 329 -
trunk/tests/phpunit/tests/rest-api/rest-posts-controller.php
r59801 r59899 275 275 276 276 /** 277 * @ticket 56481 278 */ 279 public function test_get_items_with_head_request_should_not_prepare_post_data() { 280 $request = new WP_REST_Request( 'HEAD', '/wp/v2/posts' ); 281 282 $hook_name = 'rest_prepare_post'; 283 $filter = new MockAction(); 284 $callback = array( $filter, 'filter' ); 285 286 add_filter( $hook_name, $callback ); 287 $response = rest_get_server()->dispatch( $request ); 288 remove_filter( $hook_name, $callback ); 289 290 $this->assertNotWPError( $response ); 291 $response = rest_ensure_response( $response ); 292 293 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 294 295 $headers = $response->get_headers(); 296 $this->assertSame( 0, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' ); 297 $this->assertArrayHasKey( 'Link', $headers, 'The "Link" header should be present in the response.' ); 298 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 299 } 300 301 /** 277 302 * A valid query that returns 0 results should return an empty JSON list. 303 * In case of a HEAD request, the response should not contain a body. 278 304 * 305 * @dataProvider data_readable_http_methods 279 306 * @link https://github.com/WP-API/WP-API/issues/862 280 */ 281 public function test_get_items_empty_query() { 282 $request = new WP_REST_Request( 'GET', '/wp/v2/posts' ); 307 * @ticket 56481 308 * 309 * @covers WP_REST_Posts_Controller::get_items 310 * 311 * @param string $method The HTTP method to use. 312 */ 313 public function test_get_items_empty_query( $method ) { 314 $request = new WP_REST_Request( $method, '/wp/v2/posts' ); 283 315 $request->set_query_params( 284 316 array( … … 288 320 $response = rest_get_server()->dispatch( $request ); 289 321 290 $this->assertEmpty( $response->get_data() ); 291 $this->assertSame( 200, $response->get_status() ); 292 } 293 294 public function test_get_items_author_query() { 322 if ( $request->is_method( 'HEAD' ) ) { 323 $this->assertNull( $response->get_data(), 'Failed asserting that response data is null for HEAD request.' ); 324 } else { 325 $this->assertSame( array(), $response->get_data(), 'Failed asserting that response data is an empty array for GET request.' ); 326 } 327 328 $headers = $response->get_headers(); 329 $this->assertSame( 0, $headers['X-WP-Total'], 'Failed asserting that X-WP-Total header is 0.' ); 330 $this->assertSame( 0, $headers['X-WP-TotalPages'], 'Failed asserting that X-WP-TotalPages header is 0.' ); 331 } 332 333 /** 334 * @dataProvider data_readable_http_methods 335 * @ticket 56481 336 * 337 * @param string $method The HTTP method to use. 338 */ 339 public function test_get_items_author_query( $method ) { 295 340 self::factory()->post->create( array( 'post_author' => self::$editor_id ) ); 296 341 self::factory()->post->create( array( 'post_author' => self::$author_id ) ); … … 299 344 300 345 // All posts in the database. 301 $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );346 $request = new WP_REST_Request( $method, '/wp/v2/posts' ); 302 347 $request->set_param( 'per_page', self::$per_page ); 303 348 $response = rest_get_server()->dispatch( $request ); 304 349 $this->assertSame( 200, $response->get_status() ); 305 $this->assertCount( $total_posts, $response->get_data() ); 350 if ( $request->is_method( 'get' ) ) { 351 $this->assertCount( $total_posts, $response->get_data() ); 352 353 } else { 354 $this->assertNull( $response->get_data(), 'Failed asserting that response data is null for HEAD request.' ); 355 $headers = $response->get_headers(); 356 $this->assertSame( $total_posts, $headers['X-WP-Total'] ); 357 } 306 358 307 359 // Limit to editor and author. 308 $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );360 $request = new WP_REST_Request( $method, '/wp/v2/posts' ); 309 361 $request->set_param( 'author', array( self::$editor_id, self::$author_id ) ); 310 362 $response = rest_get_server()->dispatch( $request ); 311 363 $this->assertSame( 200, $response->get_status() ); 312 364 $data = $response->get_data(); 313 $this->assertCount( 2, $data ); 314 $this->assertSameSets( array( self::$editor_id, self::$author_id ), wp_list_pluck( $data, 'author' ) ); 365 if ( $request->is_method( 'get' ) ) { 366 $this->assertCount( 2, $data ); 367 $this->assertSameSets( array( self::$editor_id, self::$author_id ), wp_list_pluck( $data, 'author' ) ); 368 } else { 369 $this->assertNull( $data, 'Failed asserting that response data is null for HEAD request.' ); 370 $headers = $response->get_headers(); 371 $this->assertSame( 2, $headers['X-WP-Total'], 'Failed asserting that X-WP-Total header is 2.' ); 372 } 315 373 316 374 // Limit to editor. 317 $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );375 $request = new WP_REST_Request( $method, '/wp/v2/posts' ); 318 376 $request->set_param( 'author', self::$editor_id ); 319 377 $response = rest_get_server()->dispatch( $request ); 320 378 $this->assertSame( 200, $response->get_status() ); 321 379 $data = $response->get_data(); 322 $this->assertCount( 1, $data ); 323 $this->assertSame( self::$editor_id, $data[0]['author'] ); 324 } 325 326 public function test_get_items_author_exclude_query() { 380 if ( $request->is_method( 'get' ) ) { 381 $this->assertCount( 1, $data ); 382 $this->assertSame( self::$editor_id, $data[0]['author'] ); 383 } else { 384 $this->assertNull( $data, 'Failed asserting that response data is null for HEAD request.' ); 385 $headers = $response->get_headers(); 386 $this->assertSame( 1, $headers['X-WP-Total'], 'Failed asserting that X-WP-Total header is 1.' ); 387 } 388 } 389 390 /** 391 * @dataProvider data_readable_http_methods 392 * @ticket 56481 393 * 394 * @param string $method The HTTP method to use. 395 */ 396 public function test_get_items_author_exclude_query( $method ) { 327 397 self::factory()->post->create( array( 'post_author' => self::$editor_id ) ); 328 398 self::factory()->post->create( array( 'post_author' => self::$author_id ) ); … … 331 401 332 402 // All posts in the database. 333 $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );403 $request = new WP_REST_Request( $method, '/wp/v2/posts' ); 334 404 $request->set_param( 'per_page', self::$per_page ); 335 405 $response = rest_get_server()->dispatch( $request ); 336 406 $this->assertSame( 200, $response->get_status() ); 337 $this->assertCount( $total_posts, $response->get_data() ); 407 if ( $request->is_method( 'get' ) ) { 408 $this->assertCount( $total_posts, $response->get_data() ); 409 } else { 410 $this->assertNull( $response->get_data(), 'Failed asserting that response data is null for HEAD request.' ); 411 $headers = $response->get_headers(); 412 $this->assertSame( $total_posts, $headers['X-WP-Total'], 'Failed asserting that the number of posts is correct.' ); 413 } 338 414 339 415 // Exclude editor and author. 340 $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );416 $request = new WP_REST_Request( $method, '/wp/v2/posts' ); 341 417 $request->set_param( 'per_page', self::$per_page ); 342 418 $request->set_param( 'author_exclude', array( self::$editor_id, self::$author_id ) ); … … 344 420 $this->assertSame( 200, $response->get_status() ); 345 421 $data = $response->get_data(); 346 $this->assertCount( $total_posts - 2, $data ); 347 $this->assertNotEquals( self::$editor_id, $data[0]['author'] ); 348 $this->assertNotEquals( self::$author_id, $data[0]['author'] ); 422 if ( $request->is_method( 'get' ) ) { 423 $this->assertCount( $total_posts - 2, $data ); 424 $this->assertNotEquals( self::$editor_id, $data[0]['author'] ); 425 $this->assertNotEquals( self::$author_id, $data[0]['author'] ); 426 } else { 427 $this->assertNull( $response->get_data(), 'Failed asserting that response data is null for HEAD request.' ); 428 $headers = $response->get_headers(); 429 $this->assertSame( $total_posts - 2, $headers['X-WP-Total'], 'Failed asserting that the number of posts is correct.' ); 430 } 349 431 350 432 // Exclude editor. 351 $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );433 $request = new WP_REST_Request( $method, '/wp/v2/posts' ); 352 434 $request->set_param( 'per_page', self::$per_page ); 353 435 $request->set_param( 'author_exclude', self::$editor_id ); … … 355 437 $this->assertSame( 200, $response->get_status() ); 356 438 $data = $response->get_data(); 357 $this->assertCount( $total_posts - 1, $data ); 358 $this->assertNotEquals( self::$editor_id, $data[0]['author'] ); 359 $this->assertNotEquals( self::$editor_id, $data[1]['author'] ); 439 if ( $request->is_method( 'get' ) ) { 440 $this->assertCount( $total_posts - 1, $data ); 441 $this->assertNotEquals( self::$editor_id, $data[0]['author'] ); 442 $this->assertNotEquals( self::$editor_id, $data[1]['author'] ); 443 } else { 444 $this->assertNull( $response->get_data(), 'Failed asserting that response data is null for HEAD request.' ); 445 $headers = $response->get_headers(); 446 $this->assertSame( $total_posts - 1, $headers['X-WP-Total'], 'Failed asserting that the number of posts is correct.' ); 447 } 360 448 361 449 // Invalid 'author_exclude' should error. 362 $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );450 $request = new WP_REST_Request( $method, '/wp/v2/posts' ); 363 451 $request->set_param( 'author_exclude', 'invalid' ); 364 452 $response = rest_get_server()->dispatch( $request ); … … 366 454 } 367 455 368 public function test_get_items_include_query() { 456 /** 457 * @dataProvider data_readable_http_methods 458 * @ticket 56481 459 * 460 * @param string $method The HTTP method to use. 461 */ 462 public function test_get_items_include_query( $method ) { 369 463 $id1 = self::factory()->post->create( 370 464 array( … … 380 474 ); 381 475 382 $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );476 $request = new WP_REST_Request( $method, '/wp/v2/posts' ); 383 477 384 478 // Order defaults to date descending. … … 386 480 $response = rest_get_server()->dispatch( $request ); 387 481 $data = $response->get_data(); 388 $this->assertCount( 2, $data ); 389 $this->assertSame( $id2, $data[0]['id'] ); 482 if ( $request->is_method( 'get' ) ) { 483 $this->assertCount( 2, $data ); 484 $this->assertSame( $id2, $data[0]['id'] ); 485 } else { 486 $this->assertNull( $data, 'Failed asserting that response data is null for HEAD request.' ); 487 $headers = $response->get_headers(); 488 $this->assertSame( 2, $headers['X-WP-Total'], 'Failed asserting that the number of posts is correct.' ); 489 } 490 390 491 $this->assertPostsOrderedBy( '{posts}.post_date DESC' ); 391 492 … … 394 495 $response = rest_get_server()->dispatch( $request ); 395 496 $data = $response->get_data(); 396 $this->assertCount( 2, $data ); 397 $this->assertSame( $id1, $data[0]['id'] ); 497 if ( $request->is_method( 'get' ) ) { 498 $this->assertCount( 2, $data ); 499 $this->assertSame( $id1, $data[0]['id'] ); 500 } else { 501 $this->assertNull( $data, 'Failed asserting that response data is null for HEAD request.' ); 502 $headers = $response->get_headers(); 503 $this->assertSame( 2, $headers['X-WP-Total'], 'Failed asserting that the number of posts is correct.' ); 504 } 505 398 506 $this->assertPostsOrderedBy( "FIELD({posts}.ID,$id1,$id2)" ); 399 507 400 508 // Invalid 'include' should error. 401 $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );509 $request = new WP_REST_Request( $method, '/wp/v2/posts' ); 402 510 $request->set_param( 'include', 'invalid' ); 403 511 $response = rest_get_server()->dispatch( $request ); … … 1730 1838 } 1731 1839 1732 public function test_get_items_pagination_headers() { 1840 /** 1841 * @dataProvider data_readable_http_methods 1842 * @ticket 56481 1843 * 1844 * @param string $method HTTP method to use. 1845 */ 1846 public function test_get_items_pagination_headers( $method ) { 1733 1847 $total_posts = self::$total_posts; 1734 1848 $total_pages = (int) ceil( $total_posts / 10 ); 1735 1849 1736 1850 // Start of the index. 1737 $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );1851 $request = new WP_REST_Request( $method, '/wp/v2/posts' ); 1738 1852 $response = rest_get_server()->dispatch( $request ); 1739 1853 $headers = $response->get_headers(); … … 1753 1867 ++$total_posts; 1754 1868 ++$total_pages; 1755 $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );1869 $request = new WP_REST_Request( $method, '/wp/v2/posts' ); 1756 1870 $request->set_param( 'page', 3 ); 1757 1871 $response = rest_get_server()->dispatch( $request ); … … 1775 1889 1776 1890 // Last page. 1777 $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );1891 $request = new WP_REST_Request( $method, '/wp/v2/posts' ); 1778 1892 $request->set_param( 'page', $total_pages ); 1779 1893 $response = rest_get_server()->dispatch( $request ); … … 1791 1905 1792 1906 // Out of bounds. 1793 $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );1907 $request = new WP_REST_Request( $method, '/wp/v2/posts' ); 1794 1908 $request->set_param( 'page', 100 ); 1795 1909 $response = rest_get_server()->dispatch( $request ); … … 1799 1913 // With query params. 1800 1914 $total_pages = (int) ceil( $total_posts / 5 ); 1801 $request = new WP_REST_Request( 'GET', '/wp/v2/posts' );1915 $request = new WP_REST_Request( $method, '/wp/v2/posts' ); 1802 1916 $request->set_query_params( 1803 1917 array( … … 1826 1940 ); 1827 1941 $this->assertStringContainsString( '<' . $next_link . '>; rel="next"', $headers['Link'] ); 1942 } 1943 1944 /** 1945 * Data provider intended to provide HTTP method names for testing GET and HEAD requests. 1946 * 1947 * @return array 1948 */ 1949 public static function data_readable_http_methods() { 1950 return array( 1951 'GET request' => array( 'GET' ), 1952 'HEAD request' => array( 'HEAD' ), 1953 ); 1954 } 1955 1956 /** 1957 * @dataProvider data_readable_http_methods 1958 * @ticket 56481 1959 * 1960 * @param string $method HTTP method to use. 1961 */ 1962 public function test_get_items_only_fetches_ids_for_head_requests( $method ) { 1963 $is_head_request = 'HEAD' === $method; 1964 $request = new WP_REST_Request( $method, '/wp/v2/posts' ); 1965 1966 $filter = new MockAction(); 1967 1968 add_filter( 'posts_pre_query', array( $filter, 'filter' ), 10, 2 ); 1969 1970 $response = rest_get_server()->dispatch( $request ); 1971 1972 $this->assertSame( 200, $response->get_status() ); 1973 if ( $is_head_request ) { 1974 $this->assertEmpty( $response->get_data() ); 1975 } else { 1976 $this->assertNotEmpty( $response->get_data() ); 1977 } 1978 1979 $args = $filter->get_args(); 1980 $this->assertTrue( isset( $args[0][1] ), 'Query parameters were not captured.' ); 1981 $this->assertInstanceOf( WP_Query::class, $args[0][1], 'Query parameters were not captured.' ); 1982 1983 /** @var WP_Query $query */ 1984 $query = $args[0][1]; 1985 1986 if ( $is_head_request ) { 1987 $this->assertArrayHasKey( 'fields', $query->query, 'The fields parameter is not set in the query vars.' ); 1988 $this->assertSame( 'ids', $query->query['fields'], 'The query must fetch only post IDs.' ); 1989 $this->assertArrayHasKey( 'fields', $query->query_vars, 'The fields parameter is not set in the query vars.' ); 1990 $this->assertSame( 'ids', $query->query_vars['fields'], 'The query must fetch only post IDs.' ); 1991 $this->assertArrayHasKey( 'update_post_term_cache', $query->query_vars, 'The "update_post_term_cache" parameter is missing in the query vars.' ); 1992 $this->assertFalse( $query->query_vars['update_post_term_cache'], 'The "update_post_term_cache" parameter must be false for HEAD requests.' ); 1993 $this->assertArrayHasKey( 'update_post_meta_cache', $query->query_vars, 'The "update_post_meta_cache" parameter is missing in the query vars.' ); 1994 $this->assertFalse( $query->query_vars['update_post_meta_cache'], 'The "update_post_meta_cache" parameter must be false for HEAD requests.' ); 1995 } else { 1996 $this->assertTrue( ! array_key_exists( 'fields', $query->query ) || 'ids' !== $query->query['fields'], 'The fields parameter should not be forced to "ids" for non-HEAD requests.' ); 1997 $this->assertTrue( ! array_key_exists( 'fields', $query->query_vars ) || 'ids' !== $query->query_vars['fields'], 'The fields parameter should not be forced to "ids" for non-HEAD requests.' ); 1998 $this->assertArrayHasKey( 'update_post_term_cache', $query->query_vars, 'The "update_post_term_cache" parameter is missing in the query vars.' ); 1999 $this->assertTrue( $query->query_vars['update_post_term_cache'], 'The "update_post_term_cache" parameter must be true for non-HEAD requests.' ); 2000 $this->assertArrayHasKey( 'update_post_meta_cache', $query->query_vars, 'The "update_post_meta_cache" parameter is missing in the query vars.' ); 2001 $this->assertTrue( $query->query_vars['update_post_meta_cache'], 'The "update_post_meta_cache" parameter must be true for non-HEAD requests.' ); 2002 } 2003 2004 if ( ! $is_head_request ) { 2005 return; 2006 } 2007 2008 global $wpdb; 2009 $posts_table = preg_quote( $wpdb->posts, '/' ); 2010 $pattern = '/^SELECT\s+SQL_CALC_FOUND_ROWS\s+' . $posts_table . '\.ID\s+FROM\s+' . $posts_table . '\s+WHERE/i'; 2011 2012 // Assert that the SQL query only fetches the ID column. 2013 $this->assertMatchesRegularExpression( $pattern, $query->request, 'The SQL query does not match the expected string.' ); 1828 2014 } 1829 2015 … … 1972 2158 1973 2159 $this->check_get_post_response( $response, 'view' ); 2160 } 2161 2162 /** 2163 * @dataProvider data_readable_http_methods 2164 * @ticket 56481 2165 * 2166 * @param string $method The HTTP method to use. 2167 */ 2168 public function test_get_item_should_allow_adding_headers_via_filter( $method ) { 2169 $request = new WP_REST_Request( $method, sprintf( '/wp/v2/posts/%d', self::$post_id ) ); 2170 2171 $hook_name = 'rest_prepare_' . get_post_type( self::$post_id ); 2172 $filter = new MockAction(); 2173 $callback = array( $filter, 'filter' ); 2174 add_filter( $hook_name, $callback ); 2175 $header_filter = new class() { 2176 public static function add_custom_header( $response ) { 2177 $response->header( 'X-Test-Header', 'Test' ); 2178 2179 return $response; 2180 } 2181 }; 2182 add_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 2183 $response = rest_get_server()->dispatch( $request ); 2184 remove_filter( $hook_name, $callback ); 2185 remove_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 2186 2187 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 2188 $this->assertSame( 1, $filter->get_call_count(), 'The "' . $hook_name . '" filter was not called when it should be for GET/HEAD requests.' ); 2189 $headers = $response->get_headers(); 2190 $this->assertArrayHasKey( 'Link', $headers, 'The "Link" header should be present in the response.' ); 2191 $this->assertArrayHasKey( 'X-Test-Header', $headers, 'The "X-Test-Header" header should be present in the response.' ); 2192 $this->assertSame( 'Test', $headers['X-Test-Header'], 'The "X-Test-Header" header value should be equal to "Test".' ); 2193 if ( 'HEAD' !== $method ) { 2194 return null; 2195 } 2196 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 1974 2197 } 1975 2198 -
trunk/tests/phpunit/tests/rest-api/rest-request.php
r55562 r59899 1082 1082 $this->assertSame( 'rest_invalid_param', $valid->get_error_code() ); 1083 1083 } 1084 1085 /** 1086 * Tests that WP_REST_Request::is_method() correctly detects the request method, 1087 * regardless of case sensitivity. 1088 * 1089 * @dataProvider data_is_method_should_detect_method_ignoring_case 1090 * @ticket 56481 1091 * 1092 * @param string $method The expected HTTP method of the request. 1093 * @param string $input_method The HTTP method to check against. 1094 * @param bool $expected The expected result of the is_method() check. 1095 */ 1096 public function test_is_method_should_detect_method_ignoring_case( $method, $input_method, $expected ) { 1097 $request = new WP_REST_Request(); 1098 $request->set_method( $method ); 1099 $result = $request->is_method( $input_method ); 1100 1101 $this->assertSame( $expected, $result, 'Failed asserting that the WP_REST_Request::is_method() method correctly detects the request method.' ); 1102 } 1103 1104 /** 1105 * Provides test cases for verifying HTTP method comparison is case-insensitive. 1106 * 1107 * @return array 1108 */ 1109 public function data_is_method_should_detect_method_ignoring_case() { 1110 return array( 1111 // GET. 1112 'GET same case' => array( 'GET', 'GET', true ), 1113 'GET different case' => array( 'GET', 'get', true ), 1114 'GET different case #2' => array( 'GET', 'get', true ), 1115 'GET different case #3' => array( 'GET', 'gEt', true ), 1116 'GET wrong method' => array( 'GET', 'POST', false ), 1117 // POST. 1118 'POST same case' => array( 'POST', 'POST', true ), 1119 'POST different case' => array( 'POST', 'post', true ), 1120 'POST different case #2' => array( 'POST', 'pOsT', true ), 1121 'POST wrong method' => array( 'POST', 'GET', false ), 1122 // HEAD. 1123 'HEAD same case' => array( 'HEAD', 'HEAD', true ), 1124 'HEAD different case' => array( 'HEAD', 'head', true ), 1125 'HEAD different case #2' => array( 'HEAD', 'HeAd', true ), 1126 'HEAD wrong method' => array( 'HEAD', 'GET', false ), 1127 ); 1128 } 1084 1129 } -
trunk/tests/phpunit/tests/rest-api/rest-revisions-controller.php
r59630 r59899 163 163 } 164 164 165 public function test_get_items_no_permission() { 165 /** 166 * @ticket 56481 167 */ 168 public function test_get_items_with_head_request_should_not_prepare_revisions_data() { 169 wp_set_current_user( self::$editor_id ); 170 171 $hook_name = 'rest_prepare_revision'; 172 $filter = new MockAction(); 173 $callback = array( $filter, 'filter' ); 174 175 add_filter( $hook_name, $callback ); 176 $request = new WP_REST_Request( 'HEAD', '/wp/v2/posts/' . self::$post_id . '/revisions' ); 177 $response = rest_get_server()->dispatch( $request ); 178 remove_filter( $hook_name, $callback ); 179 180 $this->assertNotWPError( $response ); 181 $response = rest_ensure_response( $response ); 182 183 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 184 $this->assertSame( 0, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' ); 185 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 186 } 187 188 /** 189 * @dataProvider data_readable_http_methods 190 * @ticket 56481 191 * 192 * @param string $method The HTTP method to use. 193 */ 194 public function test_get_items_no_permission( $method ) { 166 195 wp_set_current_user( 0 ); 167 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/revisions' );196 $request = new WP_REST_Request( $method, '/wp/v2/posts/' . self::$post_id . '/revisions' ); 168 197 $response = rest_get_server()->dispatch( $request ); 169 198 … … 174 203 } 175 204 176 public function test_get_items_missing_parent() { 177 wp_set_current_user( self::$editor_id ); 178 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER . '/revisions' ); 205 /** 206 * Data provider intended to provide HTTP method names for testing GET and HEAD requests. 207 * 208 * @return array 209 */ 210 public static function data_readable_http_methods() { 211 return array( 212 'GET request' => array( 'GET' ), 213 'HEAD request' => array( 'HEAD' ), 214 ); 215 } 216 217 /** 218 * @dataProvider data_readable_http_methods 219 * @ticket 56481 220 * 221 * @param string $method The HTTP method to use. 222 */ 223 public function test_get_items_missing_parent( $method ) { 224 wp_set_current_user( self::$editor_id ); 225 $request = new WP_REST_Request( $method, '/wp/v2/posts/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER . '/revisions' ); 179 226 $response = rest_get_server()->dispatch( $request ); 180 227 $this->assertErrorResponse( 'rest_post_invalid_parent', $response, 404 ); 181 228 } 182 229 183 public function test_get_items_invalid_parent_post_type() { 184 wp_set_current_user( self::$editor_id ); 185 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$page_id . '/revisions' ); 230 /** 231 * @dataProvider data_readable_http_methods 232 * @ticket 56481 233 * 234 * @param string $method The HTTP method to use. 235 */ 236 public function test_get_items_invalid_parent_post_type( $method ) { 237 wp_set_current_user( self::$editor_id ); 238 $request = new WP_REST_Request( $method, '/wp/v2/posts/' . self::$page_id . '/revisions' ); 186 239 $response = rest_get_server()->dispatch( $request ); 187 240 $this->assertErrorResponse( 'rest_post_invalid_parent', $response, 404 ); … … 214 267 } 215 268 269 /** 270 * @dataProvider data_readable_http_methods 271 * @ticket 56481 272 * 273 * @param string $method The HTTP method to use. 274 */ 275 public function test_get_item_should_allow_adding_headers_via_filter( $method ) { 276 wp_set_current_user( self::$editor_id ); 277 $request = new WP_REST_Request( $method, '/wp/v2/posts/' . self::$post_id . '/revisions/' . $this->revision_id1 ); 278 279 $hook_name = 'rest_prepare_revision'; 280 $filter = new MockAction(); 281 $callback = array( $filter, 'filter' ); 282 add_filter( $hook_name, $callback ); 283 $header_filter = new class() { 284 public static function add_custom_header( $response ) { 285 $response->header( 'X-Test-Header', 'Test' ); 286 287 return $response; 288 } 289 }; 290 add_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 291 $response = rest_get_server()->dispatch( $request ); 292 remove_filter( $hook_name, $callback ); 293 remove_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 294 295 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 296 $this->assertSame( 1, $filter->get_call_count(), 'The "' . $hook_name . '" filter was not called when it should be for GET/HEAD requests.' ); 297 $headers = $response->get_headers(); 298 $this->assertArrayHasKey( 'X-Test-Header', $headers, 'The "X-Test-Header" header should be present in the response.' ); 299 $this->assertSame( 'Test', $headers['X-Test-Header'], 'The "X-Test-Header" header value should be equal to "Test".' ); 300 if ( 'GET' === $method ) { 301 return null; 302 } 303 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 304 } 305 216 306 public function test_get_item_embed_context() { 217 307 wp_set_current_user( self::$editor_id ); … … 232 322 } 233 323 234 public function test_get_item_no_permission() { 324 /** 325 * @dataProvider data_readable_http_methods 326 * @ticket 56481 327 * 328 * @param string $method The HTTP method to use. 329 */ 330 public function test_get_item_no_permission( $method ) { 235 331 wp_set_current_user( 0 ); 236 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/revisions/' . $this->revision_id1 );332 $request = new WP_REST_Request( $method, '/wp/v2/posts/' . self::$post_id . '/revisions/' . $this->revision_id1 ); 237 333 238 334 $response = rest_get_server()->dispatch( $request ); … … 243 339 } 244 340 245 public function test_get_item_missing_parent() { 246 wp_set_current_user( self::$editor_id ); 247 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER . '/revisions/' . $this->revision_id1 ); 341 /** 342 * @dataProvider data_readable_http_methods 343 * @ticket 56481 344 * 345 * @param string $method The HTTP method to use. 346 */ 347 public function test_get_item_missing_parent( $method ) { 348 wp_set_current_user( self::$editor_id ); 349 $request = new WP_REST_Request( $method, '/wp/v2/posts/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER . '/revisions/' . $this->revision_id1 ); 248 350 $response = rest_get_server()->dispatch( $request ); 249 351 $this->assertErrorResponse( 'rest_post_invalid_parent', $response, 404 ); 250 352 } 251 353 252 public function test_get_item_invalid_parent_post_type() { 253 wp_set_current_user( self::$editor_id ); 254 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$page_id . '/revisions/' . $this->revision_id1 ); 354 /** 355 * @dataProvider data_readable_http_methods 356 * @ticket 56481 357 * 358 * @param string $method The HTTP method to use. 359 */ 360 public function test_get_item_invalid_parent_post_type( $method ) { 361 wp_set_current_user( self::$editor_id ); 362 $request = new WP_REST_Request( $method, '/wp/v2/posts/' . self::$page_id . '/revisions/' . $this->revision_id1 ); 255 363 $response = rest_get_server()->dispatch( $request ); 256 364 $this->assertErrorResponse( 'rest_post_invalid_parent', $response, 404 ); … … 270 378 271 379 /** 380 * @dataProvider data_readable_http_methods 272 381 * @ticket 59875 273 */ 274 public function test_get_item_invalid_parent_id() { 275 wp_set_current_user( self::$editor_id ); 276 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/revisions/' . $this->revision_2_1_id ); 382 * @ticket 56481 383 * 384 * @param string $method The HTTP method to use. 385 */ 386 public function test_get_item_invalid_parent_id( $method ) { 387 wp_set_current_user( self::$editor_id ); 388 $request = new WP_REST_Request( $method, '/wp/v2/posts/' . self::$post_id . '/revisions/' . $this->revision_2_1_id ); 277 389 $response = rest_get_server()->dispatch( $request ); 278 390 $this->assertErrorResponse( 'rest_revision_parent_id_mismatch', $response, 404 ); … … 511 623 * Test the pagination header of the first page. 512 624 * 513 * @ticket 40510 514 */ 515 public function test_get_items_pagination_header_of_the_first_page() { 625 * @dataProvider data_readable_http_methods 626 * @ticket 40510 627 * @ticket 56481 628 * 629 * @param string $method The HTTP method to use. 630 */ 631 public function test_get_items_pagination_header_of_the_first_page( $method ) { 516 632 wp_set_current_user( self::$editor_id ); 517 633 … … 521 637 $page = 1; // First page. 522 638 523 $request = new WP_REST_Request( 'GET', $rest_route );639 $request = new WP_REST_Request( $method, $rest_route ); 524 640 $request->set_query_params( 525 641 array( … … 546 662 * Test the pagination header of the last page. 547 663 * 548 * @ticket 40510 549 */ 550 public function test_get_items_pagination_header_of_the_last_page() { 664 * @dataProvider data_readable_http_methods 665 * @ticket 40510 666 * @ticket 56481 667 * 668 * @param string $method The HTTP method to use. 669 */ 670 public function test_get_items_pagination_header_of_the_last_page( $method ) { 551 671 wp_set_current_user( self::$editor_id ); 552 672 … … 556 676 $page = 2; // Last page. 557 677 558 $request = new WP_REST_Request( 'GET', $rest_route );678 $request = new WP_REST_Request( $method, $rest_route ); 559 679 $request->set_query_params( 560 680 array( … … 577 697 } 578 698 699 579 700 /** 580 701 * Test that invalid 'per_page' query should error. 581 702 * 582 * @ticket 40510 583 */ 584 public function test_get_items_invalid_per_page_should_error() { 703 * @dataProvider data_readable_http_methods 704 * @ticket 40510 705 * @ticket 56481 706 * 707 * @param string $method The HTTP method to use. 708 */ 709 public function test_get_items_invalid_per_page_should_error( $method ) { 585 710 wp_set_current_user( self::$editor_id ); 586 711 … … 589 714 $expected_status = 400; 590 715 591 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/revisions' );716 $request = new WP_REST_Request( $method, '/wp/v2/posts/' . self::$post_id . '/revisions' ); 592 717 $request->set_param( 'per_page', $per_page ); 593 718 $response = rest_get_server()->dispatch( $request ); … … 598 723 * Test that out of bounds 'page' query should error. 599 724 * 600 * @ticket 40510 601 */ 602 public function test_get_items_out_of_bounds_page_should_error() { 725 * @dataProvider data_readable_http_methods 726 * @ticket 40510 727 * @ticket 56481 728 * 729 * @param string $method The HTTP method to use. 730 */ 731 public function test_get_items_out_of_bounds_page_should_error( $method ) { 603 732 wp_set_current_user( self::$editor_id ); 604 733 … … 609 738 $expected_status = 400; 610 739 611 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/revisions' );740 $request = new WP_REST_Request( $method, '/wp/v2/posts/' . self::$post_id . '/revisions' ); 612 741 $request->set_query_params( 613 742 array( … … 623 752 * Test that impossibly high 'page' query should error. 624 753 * 625 * @ticket 40510 626 */ 627 public function test_get_items_invalid_max_pages_should_error() { 754 * @dataProvider data_readable_http_methods 755 * @ticket 40510 756 * @ticket 56481 757 * 758 * @param string $method The HTTP method to use. 759 */ 760 public function test_get_items_invalid_max_pages_should_error( $method ) { 628 761 wp_set_current_user( self::$editor_id ); 629 762 … … 633 766 $expected_status = 400; 634 767 635 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/revisions' );768 $request = new WP_REST_Request( $method, '/wp/v2/posts/' . self::$post_id . '/revisions' ); 636 769 $request->set_query_params( 637 770 array( … … 771 904 * Test that out of bound 'offset' query should error. 772 905 * 773 * @ticket 40510 774 */ 775 public function test_get_items_out_of_bound_offset_should_error() { 906 * @dataProvider data_readable_http_methods 907 * @ticket 40510 908 * @ticket 56481 909 * 910 * @param string $method The HTTP method to use. 911 */ 912 public function test_get_items_out_of_bound_offset_should_error( $method ) { 776 913 wp_set_current_user( self::$editor_id ); 777 914 … … 781 918 $expected_status = 400; 782 919 783 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/revisions' );920 $request = new WP_REST_Request( $method, '/wp/v2/posts/' . self::$post_id . '/revisions' ); 784 921 $request->set_query_params( 785 922 array( … … 795 932 * Test that impossible high number for 'offset' query should error. 796 933 * 797 * @ticket 40510 798 */ 799 public function test_get_items_impossible_high_number_offset_should_error() { 934 * @dataProvider data_readable_http_methods 935 * @ticket 40510 936 * @ticket 56481 937 * 938 * @param string $method The HTTP method to use. 939 */ 940 public function test_get_items_impossible_high_number_offset_should_error( $method ) { 800 941 wp_set_current_user( self::$editor_id ); 801 942 … … 805 946 $expected_status = 400; 806 947 807 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/revisions' );948 $request = new WP_REST_Request( $method, '/wp/v2/posts/' . self::$post_id . '/revisions' ); 808 949 $request->set_query_params( 809 950 array( … … 819 960 * Test that invalid 'offset' query should error. 820 961 * 821 * @ticket 40510 822 */ 823 public function test_get_items_invalid_offset_should_error() { 962 * @dataProvider data_readable_http_methods 963 * @ticket 40510 964 * @ticket 56481 965 * 966 * @param string $method The HTTP method to use. 967 */ 968 public function test_get_items_invalid_offset_should_error( $method ) { 824 969 wp_set_current_user( self::$editor_id ); 825 970 … … 829 974 $expected_status = 400; 830 975 831 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/revisions' );976 $request = new WP_REST_Request( $method, '/wp/v2/posts/' . self::$post_id . '/revisions' ); 832 977 $request->set_query_params( 833 978 array( -
trunk/tests/phpunit/tests/rest-api/rest-search-controller.php
r57839 r59899 162 162 163 163 /** 164 * Test pagination headers. 165 * 166 * @dataProvider data_readable_http_methods 167 * @ticket 56481 168 * 169 * @param string $method HTTP method to use. 170 */ 171 public function test_get_items_pagination_headers( $method ) { 172 $total_posts = count( self::$my_title_post_ids ) + count( self::$my_title_page_ids ) + count( self::$my_content_post_ids ); 173 $per_page = 3; 174 $total_pages = (int) ceil( $total_posts / $per_page ); 175 176 // Start of the index. 177 $response = $this->do_request_with_params( 178 array( 179 'per_page' => $per_page, 180 ), 181 $method 182 ); 183 $headers = $response->get_headers(); 184 $this->assertSame( $total_posts, $headers['X-WP-Total'] ); 185 $this->assertSame( $total_pages, $headers['X-WP-TotalPages'] ); 186 187 $next_link = add_query_arg( 188 array( 189 'per_page' => $per_page, 190 'page' => 2, 191 ), 192 rest_url( '/wp/v2/search' ) 193 ); 194 $this->assertStringNotContainsString( 'rel="prev"', $headers['Link'] ); 195 $this->assertStringContainsString( '<' . $next_link . '>; rel="next"', $headers['Link'] ); 196 197 $response = $this->do_request_with_params( 198 array( 199 'per_page' => $per_page, 200 'page' => 3, 201 ), 202 $method 203 ); 204 $headers = $response->get_headers(); 205 $this->assertSame( $total_posts, $headers['X-WP-Total'] ); 206 $this->assertSame( $total_pages, $headers['X-WP-TotalPages'] ); 207 $prev_link = add_query_arg( 208 array( 209 'per_page' => $per_page, 210 'page' => 2, 211 ), 212 rest_url( '/wp/v2/search' ) 213 ); 214 $this->assertStringContainsString( '<' . $prev_link . '>; rel="prev"', $headers['Link'] ); 215 $next_link = add_query_arg( 216 array( 217 'per_page' => $per_page, 218 'page' => 4, 219 ), 220 rest_url( '/wp/v2/search' ) 221 ); 222 $this->assertStringContainsString( '<' . $next_link . '>; rel="next"', $headers['Link'] ); 223 224 // Last page. 225 $response = $this->do_request_with_params( 226 array( 227 'per_page' => $per_page, 228 'page' => $total_pages, 229 ), 230 $method 231 ); 232 $headers = $response->get_headers(); 233 $this->assertSame( $total_posts, $headers['X-WP-Total'] ); 234 $this->assertSame( $total_pages, $headers['X-WP-TotalPages'] ); 235 $prev_link = add_query_arg( 236 array( 237 'per_page' => $per_page, 238 'page' => $total_pages - 1, 239 ), 240 rest_url( '/wp/v2/search' ) 241 ); 242 $this->assertStringContainsString( '<' . $prev_link . '>; rel="prev"', $headers['Link'] ); 243 $this->assertStringNotContainsString( 'rel="next"', $headers['Link'] ); 244 } 245 246 /** 247 * Data provider intended to provide HTTP method names for testing GET and HEAD requests. 248 * 249 * @return array 250 */ 251 public static function data_readable_http_methods() { 252 return array( 253 'GET request' => array( 'GET' ), 254 'HEAD request' => array( 'HEAD' ), 255 ); 256 } 257 258 /** 164 259 * Search through all content with a low limit. 165 260 */ … … 240 335 /** 241 336 * Search through an invalid type 242 */ 243 public function test_get_items_search_type_invalid() { 337 * 338 * @dataProvider data_readable_http_methods 339 * @ticket 56481 340 * 341 * @param string $method HTTP method to use. 342 */ 343 public function test_get_items_search_type_invalid( $method ) { 244 344 $response = $this->do_request_with_params( 245 345 array( 246 346 'per_page' => 100, 247 347 'type' => 'invalid', 248 ) 348 ), 349 $method 249 350 ); 250 351 … … 254 355 /** 255 356 * Search through posts of an invalid post type. 357 * 358 * @dataProvider data_readable_http_methods 359 * @ticket 56481 360 * 361 * @param string $method HTTP method to use. 256 362 */ 257 363 public function test_get_items_search_type_post_subtype_invalid() { … … 463 569 /** 464 570 * Tests that non-public post types are not allowed. 465 */ 466 public function test_non_public_post_type() { 571 * 572 * @dataProvider data_readable_http_methods 573 * @ticket 56481 574 * 575 * @param string $method HTTP method to use. 576 */ 577 public function test_non_public_post_type( $method ) { 467 578 $response = $this->do_request_with_params( 468 579 array( 469 580 'type' => 'post', 470 581 'subtype' => 'post,nav_menu_item', 471 ) 582 ), 583 $method 472 584 ); 473 585 $this->assertErrorResponse( 'rest_invalid_param', $response, 400 ); … … 633 745 * Search through posts of an invalid post type. 634 746 * 747 * 748 * @dataProvider data_readable_http_methods 635 749 * @ticket 51458 636 */ 637 public function test_get_items_search_term_subtype_invalid() { 750 * @ticket 56481 751 * 752 * @param string $method HTTP method to use. 753 */ 754 public function test_get_items_search_term_subtype_invalid( $method ) { 638 755 $response = $this->do_request_with_params( 639 756 array( … … 641 758 'type' => 'term', 642 759 'subtype' => 'invalid', 643 ) 760 ), 761 $method 644 762 ); 645 763 … … 891 1009 892 1010 /** 1011 * @dataProvider data_readable_http_methods 893 1012 * @ticket 60771 894 */ 895 public function test_sanitize_subtypes_validates_type() { 1013 * @ticket 56481 1014 * 1015 * @param string $method HTTP method to use. 1016 */ 1017 public function test_sanitize_subtypes_validates_type( $method ) { 896 1018 $response = $this->do_request_with_params( 897 1019 array( 898 1020 'subtype' => 'page', 899 1021 'type' => array( 'invalid' ), 900 ) 1022 ), 1023 $method 901 1024 ); 902 1025 -
trunk/tests/phpunit/tests/rest-api/rest-sidebars-controller.php
r58876 r59899 153 153 154 154 /** 155 * @ticket 41683 156 */ 157 public function test_get_items_no_permission() { 155 * @ticket 56481 156 */ 157 public function test_get_items_with_head_request_should_not_prepare_sidebar_data() { 158 wp_widgets_init(); 159 160 $request = new WP_REST_Request( 'HEAD', '/wp/v2/sidebars' ); 161 162 $hook_name = 'rest_prepare_sidebar'; 163 $filter = new MockAction(); 164 $callback = array( $filter, 'filter' ); 165 166 add_filter( $hook_name, $callback ); 167 $response = rest_get_server()->dispatch( $request ); 168 remove_filter( $hook_name, $callback ); 169 170 $this->assertNotWPError( $response ); 171 172 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 173 $this->assertSame( 0, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' ); 174 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 175 } 176 177 /** 178 * @dataProvider data_readable_http_methods 179 * @ticket 41683 180 * @ticket 56481 181 * 182 * @param string $method HTTP method to use. 183 */ 184 public function test_get_items_no_permission( $method ) { 158 185 wp_set_current_user( 0 ); 159 $request = new WP_REST_Request( 'GET', '/wp/v2/sidebars' );186 $request = new WP_REST_Request( $method, '/wp/v2/sidebars' ); 160 187 $response = rest_get_server()->dispatch( $request ); 161 188 $this->assertErrorResponse( 'rest_cannot_manage_widgets', $response, 401 ); … … 502 529 503 530 /** 504 * @ticket 41683 505 */ 506 public function test_get_item_no_permission() { 531 * @dataProvider data_readable_http_methods 532 * @ticket 56481 533 * 534 * @param string $method The HTTP method to use. 535 */ 536 public function test_get_item_should_allow_adding_headers_via_filter( $method ) { 537 $hook_name = 'rest_prepare_sidebar'; 538 $filter = new MockAction(); 539 $callback = array( $filter, 'filter' ); 540 add_filter( $hook_name, $callback ); 541 $header_filter = new class() { 542 public static function add_custom_header( $response ) { 543 $response->header( 'X-Test-Header', 'Test' ); 544 545 return $response; 546 } 547 }; 548 add_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 549 550 $this->setup_sidebar( 551 'sidebar-1', 552 array( 553 'name' => 'Test sidebar', 554 ) 555 ); 556 557 $request = new WP_REST_Request( $method, '/wp/v2/sidebars/sidebar-1' ); 558 $response = rest_get_server()->dispatch( $request ); 559 remove_filter( $hook_name, $callback ); 560 remove_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 561 562 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 563 $this->assertSame( 1, $filter->get_call_count(), 'The "' . $hook_name . '" filter was not called when it should be for GET/HEAD requests.' ); 564 $headers = $response->get_headers(); 565 $this->assertArrayHasKey( 'X-Test-Header', $headers, 'The "X-Test-Header" header should be present in the response.' ); 566 $this->assertSame( 'Test', $headers['X-Test-Header'], 'The "X-Test-Header" header value should be equal to "Test".' ); 567 if ( 'HEAD' !== $method ) { 568 return null; 569 } 570 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 571 } 572 573 /** 574 * Data provider intended to provide HTTP method names for testing GET and HEAD requests. 575 * 576 * @return array 577 */ 578 public static function data_readable_http_methods() { 579 return array( 580 'GET request' => array( 'GET' ), 581 'HEAD request' => array( 'HEAD' ), 582 ); 583 } 584 585 /** 586 * @dataProvider data_readable_http_methods 587 * @ticket 41683 588 * @ticket 56481 589 * 590 * @param string $method The HTTP method to use. 591 */ 592 public function test_get_item_no_permission( $method ) { 507 593 wp_set_current_user( 0 ); 508 594 $this->setup_sidebar( … … 513 599 ); 514 600 515 $request = new WP_REST_Request( 'GET', '/wp/v2/sidebars/sidebar-1' );601 $request = new WP_REST_Request( $method, '/wp/v2/sidebars/sidebar-1' ); 516 602 $response = rest_get_server()->dispatch( $request ); 517 603 $this->assertErrorResponse( 'rest_cannot_manage_widgets', $response, 401 ); … … 553 639 554 640 /** 555 * @ticket 41683 556 */ 557 public function test_get_item_wrong_permission_author() { 641 * @dataProvider data_readable_http_methods 642 * @ticket 41683 643 * @ticket 56481 644 * 645 * @param string $method The HTTP method to use. 646 */ 647 public function test_get_item_wrong_permission_author( $method ) { 558 648 wp_set_current_user( self::$author_id ); 559 649 $this->setup_sidebar( … … 564 654 ); 565 655 566 $request = new WP_REST_Request( 'GET', '/wp/v2/sidebars/sidebar-1' );656 $request = new WP_REST_Request( $method, '/wp/v2/sidebars/sidebar-1' ); 567 657 $response = rest_get_server()->dispatch( $request ); 568 658 $this->assertErrorResponse( 'rest_cannot_manage_widgets', $response, 403 ); -
trunk/tests/phpunit/tests/rest-api/rest-tags-controller.php
r59458 r59899 628 628 } 629 629 630 public function test_get_terms_pagination_headers() { 630 /** 631 * @dataProvider data_readable_http_methods 632 * @ticket 56481 633 * 634 * @param string $method HTTP method to use. 635 */ 636 public function test_get_terms_pagination_headers( $method ) { 631 637 $total_tags = self::$total_tags; 632 638 $total_pages = (int) ceil( $total_tags / 10 ); 633 639 634 640 // Start of the index. 635 $request = new WP_REST_Request( 'GET', '/wp/v2/tags' );641 $request = new WP_REST_Request( $method, '/wp/v2/tags' ); 636 642 $response = rest_get_server()->dispatch( $request ); 637 643 $headers = $response->get_headers(); … … 1503 1509 $this->check_taxonomy_term( $tag, $data, $response->get_links() ); 1504 1510 } 1511 1512 /** 1513 * @dataProvider data_readable_http_methods 1514 * @ticket 56481 1515 * 1516 * @param string $method HTTP method to use. 1517 */ 1518 public function test_get_items_only_fetches_ids_for_head_requests( $method ) { 1519 $is_head_request = 'HEAD' === $method; 1520 $request = new WP_REST_Request( $method, '/wp/v2/tags' ); 1521 1522 $filter = new MockAction(); 1523 1524 add_filter( 'terms_pre_query', array( $filter, 'filter' ), 10, 2 ); 1525 1526 $response = rest_get_server()->dispatch( $request ); 1527 1528 $this->assertSame( 200, $response->get_status() ); 1529 if ( $is_head_request ) { 1530 $this->assertEmpty( $response->get_data() ); 1531 } else { 1532 $this->assertNotEmpty( $response->get_data() ); 1533 } 1534 1535 $args = $filter->get_args(); 1536 $this->assertTrue( isset( $args[0][1] ), 'Query parameters were not captured.' ); 1537 $this->assertInstanceOf( WP_Term_Query::class, $args[0][1], 'Query parameters were not captured.' ); 1538 1539 /** @var WP_Term_Query $query */ 1540 $query = $args[0][1]; 1541 1542 if ( $is_head_request ) { 1543 $this->assertArrayHasKey( 'fields', $query->query_vars, 'The fields parameter is not set in the query vars.' ); 1544 $this->assertSame( 'ids', $query->query_vars['fields'], 'The query must fetch only term IDs.' ); 1545 $this->assertArrayHasKey( 'update_term_meta_cache', $query->query_vars, 'The update_term_meta_cache key is missing in the query vars.' ); 1546 $this->assertFalse( $query->query_vars['update_term_meta_cache'], 'The update_term_meta_cache value should be false for HEAD requests.' ); 1547 } else { 1548 $this->assertTrue( 1549 ! array_key_exists( 'fields', $query->query_vars ) || 'ids' !== $query->query_vars['fields'], 1550 'The fields parameter should not be forced to "ids" for non-HEAD requests.' 1551 ); 1552 $this->assertArrayHasKey( 'update_term_meta_cache', $query->query_vars, 'The update_term_meta_cache key is missing in the query vars.' ); 1553 $this->assertTrue( $query->query_vars['update_term_meta_cache'], 'The update_term_meta_cache value should be true for HEAD requests.' ); 1554 } 1555 1556 if ( ! $is_head_request ) { 1557 return; 1558 } 1559 1560 global $wpdb; 1561 $terms_table = preg_quote( $wpdb->terms, '/' ); 1562 1563 $pattern = '/SELECT\s+t\.term_id.+FROM\s+' . $terms_table . '\s+AS\s+t\s+INNER\s+JOIN/is'; 1564 1565 // Assert that the SQL query only fetches the term_id column. 1566 $this->assertMatchesRegularExpression( $pattern, $query->request, 'The SQL query does not match the expected string.' ); 1567 } 1568 1569 /** 1570 * Data provider intended to provide HTTP method names for testing GET and HEAD requests. 1571 * 1572 * @return array 1573 */ 1574 public static function data_readable_http_methods() { 1575 return array( 1576 'GET request' => array( 'GET' ), 1577 'HEAD request' => array( 'HEAD' ), 1578 ); 1579 } 1580 1581 /** 1582 * @dataProvider data_readable_http_methods 1583 * @ticket 56481 1584 * 1585 * @param string $method The HTTP method to use. 1586 */ 1587 public function test_get_item_should_allow_adding_headers_via_filter( string $method ) { 1588 $tag_id = self::factory()->tag->create(); 1589 1590 $request = new WP_REST_Request( $method, sprintf( '/wp/v2/tags/%d', $tag_id ) ); 1591 1592 $hook_name = 'rest_prepare_post_tag'; 1593 1594 $filter = new MockAction(); 1595 $callback = array( $filter, 'filter' ); 1596 add_filter( $hook_name, $callback ); 1597 $header_filter = new class() { 1598 public static function add_custom_header( $response ) { 1599 $response->header( 'X-Test-Header', 'Test' ); 1600 1601 return $response; 1602 } 1603 }; 1604 add_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 1605 $response = rest_get_server()->dispatch( $request ); 1606 remove_filter( $hook_name, $callback ); 1607 remove_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 1608 1609 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 1610 $this->assertSame( 1, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' ); 1611 $headers = $response->get_headers(); 1612 $this->assertArrayHasKey( 'X-Test-Header', $headers, 'The "X-Test-Header" header should be present in the response.' ); 1613 $this->assertSame( 'Test', $headers['X-Test-Header'], 'The "X-Test-Header" header value should be equal to "Test".' ); 1614 if ( 'HEAD' !== $method ) { 1615 return null; 1616 } 1617 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 1618 } 1505 1619 } -
trunk/tests/phpunit/tests/rest-api/rest-taxonomies-controller.php
r56746 r59899 61 61 } 62 62 63 /** 64 * @ticket 56481 65 */ 66 public function test_get_items_with_head_request_should_not_prepare_taxonomy_data() { 67 $request = new WP_REST_Request( 'HEAD', '/wp/v2/taxonomies' ); 68 $hook_name = 'rest_prepare_taxonomy'; 69 $filter = new MockAction(); 70 $callback = array( $filter, 'filter' ); 71 add_filter( $hook_name, $callback ); 72 $response = rest_get_server()->dispatch( $request ); 73 remove_filter( $hook_name, $callback ); 74 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 75 $this->assertSame( 0, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' ); 76 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 77 } 78 63 79 public function test_get_items_context_edit() { 64 80 wp_set_current_user( self::$contributor_id ); … … 80 96 } 81 97 82 public function test_get_items_invalid_permission_for_context() { 98 99 /** 100 * @dataProvider data_readable_http_methods 101 * @ticket 56481 102 * 103 * @param string $method HTTP method to use. 104 */ 105 public function test_get_items_invalid_permission_for_context( $method ) { 83 106 wp_set_current_user( 0 ); 84 $request = new WP_REST_Request( 'GET', '/wp/v2/taxonomies' );107 $request = new WP_REST_Request( $method, '/wp/v2/taxonomies' ); 85 108 $request->set_param( 'context', 'edit' ); 86 109 $response = rest_get_server()->dispatch( $request ); 87 110 $this->assertErrorResponse( 'rest_cannot_view', $response, 401 ); 111 } 112 113 /** 114 * Data provider intended to provide HTTP method names for testing GET and HEAD requests. 115 * 116 * @return array 117 */ 118 public static function data_readable_http_methods() { 119 return array( 120 'GET request' => array( 'GET' ), 121 'HEAD request' => array( 'HEAD' ), 122 ); 88 123 } 89 124 … … 95 130 } 96 131 97 public function test_get_taxonomies_for_invalid_type() { 98 $request = new WP_REST_Request( 'GET', '/wp/v2/taxonomies' ); 132 /** 133 * @dataProvider data_readable_http_methods 134 * @ticket 56481 135 * 136 * @param string $method HTTP method to use. 137 */ 138 public function test_get_taxonomies_for_invalid_type( $method ) { 139 $request = new WP_REST_Request( $method, '/wp/v2/taxonomies' ); 99 140 $request->set_param( 'type', 'wingding' ); 100 141 $response = rest_get_server()->dispatch( $request ); 101 142 $this->assertSame( 200, $response->get_status() ); 143 if ( 'HEAD' === $method ) { 144 return null; 145 } 102 146 $data = $response->get_data(); 103 147 $this->assertSame( '{}', json_encode( $data ) ); … … 108 152 $response = rest_get_server()->dispatch( $request ); 109 153 $this->check_taxonomy_object_response( 'view', $response ); 154 } 155 156 /** 157 * @dataProvider data_readable_http_methods 158 * @ticket 56481 159 * 160 * @param string $method The HTTP method to use. 161 */ 162 public function test_get_item_should_allow_adding_headers_via_filter( $method ) { 163 $request = new WP_REST_Request( 'HEAD', '/wp/v2/taxonomies/category' ); 164 $hook_name = 'rest_prepare_taxonomy'; 165 $filter = new MockAction(); 166 $callback = array( $filter, 'filter' ); 167 add_filter( $hook_name, $callback ); 168 $header_filter = new class() { 169 public static function add_custom_header( $response ) { 170 $response->header( 'X-Test-Header', 'Test' ); 171 172 return $response; 173 } 174 }; 175 add_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 176 $response = rest_get_server()->dispatch( $request ); 177 remove_filter( $hook_name, $callback ); 178 remove_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 179 180 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 181 $this->assertSame( 1, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' ); 182 $headers = $response->get_headers(); 183 $this->assertArrayHasKey( 'X-Test-Header', $headers, 'The "X-Test-Header" header should be present in the response.' ); 184 $this->assertSame( 'Test', $headers['X-Test-Header'], 'The "X-Test-Header" header value should be equal to "Test".' ); 185 if ( 'HEAD' !== $method ) { 186 return null; 187 } 188 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 110 189 } 111 190 … … 119 198 } 120 199 121 public function test_get_item_invalid_permission_for_context() { 200 /** 201 * @dataProvider data_readable_http_methods 202 * @ticket 56481 203 * 204 * @param string $method HTTP method to use. 205 */ 206 public function test_get_item_invalid_permission_for_context( $method ) { 122 207 wp_set_current_user( 0 ); 123 $request = new WP_REST_Request( 'GET', '/wp/v2/taxonomies/category' );208 $request = new WP_REST_Request( $method, '/wp/v2/taxonomies/category' ); 124 209 $request->set_param( 'context', 'edit' ); 125 210 $response = rest_get_server()->dispatch( $request ); … … 127 212 } 128 213 129 public function test_get_invalid_taxonomy() { 130 $request = new WP_REST_Request( 'GET', '/wp/v2/taxonomies/invalid' ); 214 /** 215 * @dataProvider data_readable_http_methods 216 * @ticket 56481 217 * 218 * @param string $method HTTP method to use. 219 */ 220 public function test_get_invalid_taxonomy( $method ) { 221 $request = new WP_REST_Request( $method, '/wp/v2/taxonomies/invalid' ); 131 222 $response = rest_get_server()->dispatch( $request ); 132 223 $this->assertErrorResponse( 'rest_taxonomy_invalid', $response, 404 ); 133 224 } 134 225 135 public function test_get_non_public_taxonomy_not_authenticated() { 226 /** 227 * @dataProvider data_readable_http_methods 228 * @ticket 56481 229 * 230 * @param string $method HTTP method to use. 231 */ 232 public function test_get_non_public_taxonomy_not_authenticated( $method ) { 136 233 register_taxonomy( 'api-private', 'post', array( 'public' => false ) ); 137 234 138 $request = new WP_REST_Request( 'GET', '/wp/v2/taxonomies/api-private' );235 $request = new WP_REST_Request( $method, '/wp/v2/taxonomies/api-private' ); 139 236 $response = rest_get_server()->dispatch( $request ); 140 237 $this->assertErrorResponse( 'rest_forbidden', $response, 401 ); 141 238 } 142 239 143 public function test_get_non_public_taxonomy_no_permission() { 240 /** 241 * @dataProvider data_readable_http_methods 242 * @ticket 56481 243 * 244 * @param string $method HTTP method to use. 245 */ 246 public function test_get_non_public_taxonomy_no_permission( $method ) { 144 247 wp_set_current_user( self::$contributor_id ); 145 248 register_taxonomy( 'api-private', 'post', array( 'public' => false ) ); 146 249 147 $request = new WP_REST_Request( 'GET', '/wp/v2/taxonomies/api-private' );250 $request = new WP_REST_Request( $method, '/wp/v2/taxonomies/api-private' ); 148 251 $response = rest_get_server()->dispatch( $request ); 149 252 $this->assertErrorResponse( 'rest_forbidden', $response, 403 ); -
trunk/tests/phpunit/tests/rest-api/rest-users-controller.php
r59892 r59899 235 235 } 236 236 237 public function test_get_items_with_edit_context() { 238 wp_set_current_user( self::$user ); 239 240 $request = new WP_REST_Request( 'GET', '/wp/v2/users' ); 237 /** 238 * @dataProvider data_readable_http_methods 239 * @ticket 56481 240 * 241 * @param string $method HTTP method to use. 242 */ 243 public function test_get_items_with_edit_context( $method ) { 244 wp_set_current_user( self::$user ); 245 246 $request = new WP_REST_Request( $method, '/wp/v2/users' ); 241 247 $request->set_param( 'context', 'edit' ); 242 248 $response = rest_get_server()->dispatch( $request ); 243 249 244 $this->assertSame( 200, $response->get_status() ); 250 $this->assertSame( 251 200, 252 $response->get_status(), 253 sprintf( 'Expected HTTP status code 200 but got %s.', $response->get_status() ) 254 ); 255 256 if ( 'HEAD' === $method ) { 257 $this->assertNull( $response->get_data(), 'Expected null response data for HEAD request, but received non-null data.' ); 258 return null; 259 } 245 260 246 261 $all_data = $response->get_data(); … … 250 265 } 251 266 252 public function test_get_items_with_edit_context_without_permission() { 267 /** 268 * Data provider intended to provide HTTP method names for testing GET and HEAD requests. 269 * 270 * @return array 271 */ 272 public static function data_readable_http_methods() { 273 return array( 274 'GET request' => array( 'GET' ), 275 'HEAD request' => array( 'HEAD' ), 276 ); 277 } 278 279 /** 280 * @dataProvider data_readable_http_methods 281 * @ticket 56481 282 * 283 * @param string $method HTTP method to use. 284 */ 285 public function test_get_items_with_edit_context_without_permission( $method ) { 253 286 // Test with a user not logged in. 254 $request = new WP_REST_Request( 'GET', '/wp/v2/users' );287 $request = new WP_REST_Request( $method, '/wp/v2/users' ); 255 288 $request->set_param( 'context', 'edit' ); 256 289 $response = rest_get_server()->dispatch( $request ); … … 262 295 wp_set_current_user( self::$editor ); 263 296 264 $request = new WP_REST_Request( 'GET', '/wp/v2/users' );297 $request = new WP_REST_Request( $method, '/wp/v2/users' ); 265 298 $request->set_param( 'context', 'edit' ); 266 299 $response = rest_get_server()->dispatch( $request ); … … 320 353 } 321 354 322 public function test_get_items_pagination_headers() { 355 /** 356 * @dataProvider data_readable_http_methods 357 * @ticket 56481 358 * 359 * @param string $method HTTP method to use. 360 */ 361 public function test_get_items_pagination_headers( $method ) { 323 362 $total_users = self::$total_users; 324 363 $total_pages = (int) ceil( $total_users / 10 ); … … 327 366 328 367 // Start of the index. 329 $request = new WP_REST_Request( 'GET', '/wp/v2/users' );368 $request = new WP_REST_Request( $method, '/wp/v2/users' ); 330 369 $response = rest_get_server()->dispatch( $request ); 331 370 $headers = $response->get_headers(); … … 345 384 ++$total_users; 346 385 ++$total_pages; 347 $request = new WP_REST_Request( 'GET', '/wp/v2/users' );386 $request = new WP_REST_Request( $method, '/wp/v2/users' ); 348 387 $request->set_param( 'page', 3 ); 349 388 $response = rest_get_server()->dispatch( $request ); … … 367 406 368 407 // Last page. 369 $request = new WP_REST_Request( 'GET', '/wp/v2/users' );408 $request = new WP_REST_Request( $method, '/wp/v2/users' ); 370 409 $request->set_param( 'page', $total_pages ); 371 410 $response = rest_get_server()->dispatch( $request ); … … 383 422 384 423 // Out of bounds. 385 $request = new WP_REST_Request( 'GET', '/wp/v2/users' );424 $request = new WP_REST_Request( $method, '/wp/v2/users' ); 386 425 $request->set_param( 'page', 100 ); 387 426 $response = rest_get_server()->dispatch( $request ); … … 412 451 } 413 452 414 public function test_get_items_page() { 415 wp_set_current_user( self::$user ); 416 417 $request = new WP_REST_Request( 'GET', '/wp/v2/users' ); 453 /** 454 * @dataProvider data_readable_http_methods 455 * @ticket 56481 456 * 457 * @param string $method HTTP method to use. 458 */ 459 public function test_get_items_page( $method ) { 460 wp_set_current_user( self::$user ); 461 462 $request = new WP_REST_Request( $method, '/wp/v2/users' ); 418 463 $request->set_param( 'per_page', 5 ); 419 464 $request->set_param( 'page', 2 ); 420 465 $response = rest_get_server()->dispatch( $request ); 421 $this->assertCount( 5, $response->get_data() ); 466 467 if ( 'HEAD' !== $method ) { 468 $this->assertCount( 5, $response->get_data() ); 469 } 470 422 471 $prev_link = add_query_arg( 423 472 array( … … 1266 1315 } 1267 1316 1268 public function test_get_current_user() { 1269 wp_set_current_user( self::$user ); 1270 1271 $request = new WP_REST_Request( 'GET', '/wp/v2/users/me' ); 1317 /** 1318 * @dataProvider data_readable_http_methods 1319 * @ticket 56481 1320 * 1321 * @param string $method HTTP method to use. 1322 */ 1323 public function test_get_current_user( $method ) { 1324 wp_set_current_user( self::$user ); 1325 1326 $request = new WP_REST_Request( $method, '/wp/v2/users/me' ); 1272 1327 $response = rest_get_server()->dispatch( $request ); 1273 1328 $this->assertSame( 200, $response->get_status() ); 1274 $this->check_get_user_response( $response, 'view' );1275 1276 1329 $headers = $response->get_headers(); 1277 1330 $this->assertArrayNotHasKey( 'Location', $headers ); 1278 1331 1332 if ( 'HEAD' === $method ) { 1333 // HEAD responses only contain headers. Bail. 1334 return null; 1335 } 1336 $this->check_get_user_response( $response, 'view' ); 1279 1337 $links = $response->get_links(); 1280 1338 $this->assertSame( rest_url( 'wp/v2/users/' . self::$user ), $links['self'][0]['href'] ); … … 3159 3217 } 3160 3218 3219 /** 3220 * @dataProvider data_readable_http_methods 3221 * @ticket 56481 3222 * 3223 * @param string $method The HTTP method to use. 3224 */ 3225 public function test_get_item_should_allow_adding_headers_via_filter( $method ) { 3226 wp_set_current_user( self::$user ); 3227 $request = new WP_REST_Request( $method, sprintf( '/wp/v2/users/%d', self::$user ) ); 3228 3229 $hook_name = 'rest_prepare_user'; 3230 3231 $filter = new MockAction(); 3232 $callback = array( $filter, 'filter' ); 3233 add_filter( $hook_name, $callback ); 3234 $header_filter = new class() { 3235 public static function add_custom_header( $response ) { 3236 $response->header( 'X-Test-Header', 'Test' ); 3237 3238 return $response; 3239 } 3240 }; 3241 add_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 3242 $response = rest_get_server()->dispatch( $request ); 3243 remove_filter( $hook_name, $callback ); 3244 remove_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 3245 3246 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 3247 $this->assertSame( 1, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' ); 3248 $headers = $response->get_headers(); 3249 $this->assertArrayHasKey( 'X-Test-Header', $headers, 'The "X-Test-Header" header should be present in the response.' ); 3250 $this->assertSame( 'Test', $headers['X-Test-Header'], 'The "X-Test-Header" header value should be equal to "Test".' ); 3251 if ( 'HEAD' !== $method ) { 3252 return null; 3253 } 3254 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 3255 } 3256 3257 /** 3258 * @dataProvider data_readable_http_methods 3259 * @ticket 56481 3260 * 3261 * @param string $method HTTP method to use. 3262 */ 3263 public function test_get_items_only_fetches_ids_for_head_requests( $method ) { 3264 $is_head_request = 'HEAD' === $method; 3265 $request = new WP_REST_Request( $method, '/wp/v2/users' ); 3266 3267 $filter = new MockAction(); 3268 3269 add_filter( 'pre_user_query', array( $filter, 'filter' ), 10, 2 ); 3270 3271 $response = rest_get_server()->dispatch( $request ); 3272 3273 $this->assertSame( 200, $response->get_status() ); 3274 if ( $is_head_request ) { 3275 $this->assertNull( $response->get_data() ); 3276 } else { 3277 $this->assertNotEmpty( $response->get_data() ); 3278 } 3279 3280 $args = $filter->get_args(); 3281 $this->assertTrue( isset( $args[0][0] ), 'Query parameters were not captured.' ); 3282 $this->assertInstanceOf( WP_User_Query::class, $args[0][0], 'Query parameters were not captured.' ); 3283 3284 /** @var WP_User $query */ 3285 $query = $args[0][0]; 3286 3287 if ( $is_head_request ) { 3288 $this->assertArrayHasKey( 'fields', $query->query_vars, 'The fields parameter is not set in the query vars.' ); 3289 $this->assertSame( 'id', $query->query_vars['fields'], 'The query must fetch only user IDs.' ); 3290 } else { 3291 $this->assertTrue( 3292 ! array_key_exists( 'fields', $query->query_vars ) || 'id' !== $query->query_vars['fields'], 3293 'The fields parameter should not be forced to "id" for non-HEAD requests.' 3294 ); 3295 } 3296 3297 if ( ! $is_head_request ) { 3298 return; 3299 } 3300 3301 global $wpdb; 3302 $users_table = preg_quote( $wpdb->users, '/' ); 3303 $pattern = '/SELECT SQL_CALC_FOUND_ROWS wptests_users.ID\n\s+FROM\s+' . $users_table . '/is'; 3304 3305 // Assert that the SQL query only fetches the id column. 3306 $this->assertMatchesRegularExpression( $pattern, $query->request, 'The SQL query does not match the expected string.' ); 3307 } 3308 3161 3309 protected function check_user_data( $user, $data, $context, $links ) { 3162 3310 $this->assertSame( $user->ID, $data['id'] ); -
trunk/tests/phpunit/tests/rest-api/rest-widget-types-controller.php
r56559 r59899 123 123 124 124 /** 125 * @ticket 56481 126 */ 127 public function test_get_items_with_head_request_should_not_prepare_widget_types_data() { 128 wp_set_current_user( self::$admin_id ); 129 $request = new WP_REST_Request( 'HEAD', '/wp/v2/widget-types' ); 130 $response = rest_get_server()->dispatch( $request ); 131 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 132 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 133 } 134 135 /** 125 136 * @ticket 53303 126 137 */ … … 183 194 184 195 /** 196 * @dataProvider data_readable_http_methods 197 * @ticket 56481 198 * 199 * @param string $method The HTTP method to use. 200 */ 201 public function test_get_item_should_allow_adding_headers_via_filter( $method ) { 202 $widget_name = 'calendar'; 203 wp_set_current_user( self::$admin_id ); 204 $request = new WP_REST_Request( $method, '/wp/v2/widget-types/' . $widget_name ); 205 206 $hook_name = 'rest_prepare_widget_type'; 207 $filter = new MockAction(); 208 $callback = array( $filter, 'filter' ); 209 add_filter( $hook_name, $callback ); 210 $header_filter = new class() { 211 public static function add_custom_header( $response ) { 212 $response->header( 'X-Test-Header', 'Test' ); 213 214 return $response; 215 } 216 }; 217 add_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 218 $response = rest_get_server()->dispatch( $request ); 219 remove_filter( $hook_name, $callback ); 220 remove_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 221 222 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 223 $this->assertSame( 1, $filter->get_call_count(), 'The "' . $hook_name . '" filter was not called when it should be for GET/HEAD requests.' ); 224 $headers = $response->get_headers(); 225 $this->assertArrayHasKey( 'X-Test-Header', $headers, 'The "X-Test-Header" header should be present in the response.' ); 226 $this->assertSame( 'Test', $headers['X-Test-Header'], 'The "X-Test-Header" header value should be equal to "Test".' ); 227 if ( 'HEAD' !== $method ) { 228 return null; 229 } 230 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 231 } 232 233 /** 234 * Data provider intended to provide HTTP method names for testing GET and HEAD requests. 235 * 236 * @return array 237 */ 238 public static function data_readable_http_methods() { 239 return array( 240 'GET request' => array( 'GET' ), 241 'HEAD request' => array( 'HEAD' ), 242 ); 243 } 244 245 /** 185 246 * @ticket 41683 186 247 */ … … 201 262 202 263 /** 203 * @ticket 41683 204 */ 205 public function test_get_widget_invalid_name() { 264 * @dataProvider data_readable_http_methods 265 * @ticket 41683 266 * @ticket 56481 267 * 268 * @param string $method HTTP method to use. 269 */ 270 public function test_get_widget_invalid_name( $method ) { 206 271 $widget_type = 'fake'; 207 272 wp_set_current_user( self::$admin_id ); 208 $request = new WP_REST_Request( 'GET', '/wp/v2/widget-types/' . $widget_type );273 $request = new WP_REST_Request( $method, '/wp/v2/widget-types/' . $widget_type ); 209 274 $response = rest_get_server()->dispatch( $request ); 210 275 … … 252 317 253 318 /** 254 * @ticket 41683 255 */ 256 public function test_get_items_wrong_permission() { 319 * @dataProvider data_readable_http_methods 320 * @ticket 41683 321 * @ticket 56481 322 * 323 * @param string $method HTTP method to use. 324 */ 325 public function test_get_items_wrong_permission( $method ) { 257 326 wp_set_current_user( self::$subscriber_id ); 258 $request = new WP_REST_Request( 'GET', '/wp/v2/widget-types' );327 $request = new WP_REST_Request( $method, '/wp/v2/widget-types' ); 259 328 $response = rest_get_server()->dispatch( $request ); 260 329 $this->assertErrorResponse( 'rest_cannot_manage_widgets', $response, 403 ); … … 262 331 263 332 /** 264 * @ticket 41683 265 */ 266 public function test_get_item_wrong_permission() { 333 * @dataProvider data_readable_http_methods 334 * @ticket 41683 335 * @ticket 56481 336 * 337 * @param string $method HTTP method to use. 338 */ 339 public function test_get_item_wrong_permission( $method ) { 267 340 wp_set_current_user( self::$subscriber_id ); 268 $request = new WP_REST_Request( 'GET', '/wp/v2/widget-types/calendar' );341 $request = new WP_REST_Request( $method, '/wp/v2/widget-types/calendar' ); 269 342 $response = rest_get_server()->dispatch( $request ); 270 343 $this->assertErrorResponse( 'rest_cannot_manage_widgets', $response, 403 ); … … 272 345 273 346 /** 274 * @ticket 41683 275 */ 276 public function test_get_items_no_permission() { 347 * @dataProvider data_readable_http_methods 348 * @ticket 41683 349 * @ticket 56481 350 * 351 * @param string $method HTTP method to use. 352 */ 353 public function test_get_items_no_permission( $method ) { 277 354 wp_set_current_user( 0 ); 278 $request = new WP_REST_Request( 'GET', '/wp/v2/widget-types' );355 $request = new WP_REST_Request( $method, '/wp/v2/widget-types' ); 279 356 $response = rest_get_server()->dispatch( $request ); 280 357 $this->assertErrorResponse( 'rest_cannot_manage_widgets', $response, 401 ); … … 282 359 283 360 /** 284 * @ticket 41683 285 */ 286 public function test_get_item_no_permission() { 361 * @dataProvider data_readable_http_methods 362 * @ticket 41683 363 * @ticket 56481 364 * 365 * @param string $method HTTP method to use. 366 */ 367 public function test_get_item_no_permission( $method ) { 287 368 wp_set_current_user( 0 ); 288 $request = new WP_REST_Request( 'GET', '/wp/v2/widget-types/calendar' );369 $request = new WP_REST_Request( $method, '/wp/v2/widget-types/calendar' ); 289 370 $response = rest_get_server()->dispatch( $request ); 290 371 $this->assertErrorResponse( 'rest_cannot_manage_widgets', $response, 401 ); -
trunk/tests/phpunit/tests/rest-api/rest-widgets-controller.php
r58097 r59899 229 229 230 230 /** 231 * @ticket 41683 232 */ 233 public function test_get_items_no_permission() { 231 * @dataProvider data_readable_http_methods 232 * @ticket 41683 233 * @ticket 56481 234 * 235 * @param string $method The HTTP method to use. 236 */ 237 public function test_get_items_no_permission( $method ) { 234 238 wp_set_current_user( 0 ); 235 $request = new WP_REST_Request( 'GET', '/wp/v2/widgets' );239 $request = new WP_REST_Request( $method, '/wp/v2/widgets' ); 236 240 $response = rest_get_server()->dispatch( $request ); 237 241 $this->assertErrorResponse( 'rest_cannot_manage_widgets', $response, 401 ); 242 } 243 244 /** 245 * Data provider intended to provide HTTP method names for testing GET and HEAD requests. 246 * 247 * @return array 248 */ 249 public static function data_readable_http_methods() { 250 return array( 251 'GET request' => array( 'GET' ), 252 'HEAD request' => array( 'HEAD' ), 253 ); 238 254 } 239 255 … … 333 349 334 350 /** 335 * @ticket 41683 336 */ 337 public function test_get_items_wrong_permission_author() { 351 * @dataProvider data_readable_http_methods 352 * @ticket 41683 353 * @ticket 56481 354 * 355 * @param string $method The HTTP method to use. 356 */ 357 public function test_get_items_wrong_permission_author( $method ) { 338 358 wp_set_current_user( self::$author_id ); 339 $request = new WP_REST_Request( 'GET', '/wp/v2/widgets' );359 $request = new WP_REST_Request( $method, '/wp/v2/widgets' ); 340 360 $response = rest_get_server()->dispatch( $request ); 341 361 $this->assertErrorResponse( 'rest_cannot_manage_widgets', $response, 403 ); … … 378 398 $request = new WP_REST_Request( 'GET', '/wp/v2/widgets' ); 379 399 $response = rest_get_server()->dispatch( $request ); 380 $data = $response->get_data(); 381 $data = $this->remove_links( $data ); 400 remove_filter( 'pre_http_request', array( $this, 'mocked_rss_response' ) ); 401 $data = $response->get_data(); 402 $data = $this->remove_links( $data ); 382 403 $this->assertSameSets( 383 404 array( … … 405 426 406 427 $wp_widget_factory->widgets['WP_Widget_RSS']->widget_options['show_instance_in_rest'] = true; 428 } 429 430 /** 431 * @dataProvider data_readable_http_methods 432 * @ticket 56481 433 * 434 * @param string $method The HTTP method to use. 435 */ 436 public function test_get_items_with_head_request_should_not_prepare_widget_data( $method ) { 437 $block_content = '<!-- wp:paragraph --><p>Block test</p><!-- /wp:paragraph -->'; 438 439 $this->setup_widget( 440 'rss', 441 1, 442 array( 443 'title' => 'RSS test', 444 'url' => 'https://wordpress.org/news/feed', 445 ) 446 ); 447 $this->setup_widget( 448 'block', 449 1, 450 array( 451 'content' => $block_content, 452 ) 453 ); 454 $this->setup_sidebar( 455 'sidebar-1', 456 array( 457 'name' => 'Test sidebar', 458 ), 459 array( 'block-1', 'rss-1', 'testwidget' ) 460 ); 461 462 $request = new WP_REST_Request( 'HEAD', '/wp/v2/widgets' ); 463 464 $hook_name = 'rest_prepare_post'; 465 $filter = new MockAction(); 466 $callback = array( $filter, 'filter' ); 467 468 add_filter( $hook_name, $callback ); 469 $response = rest_get_server()->dispatch( $request ); 470 remove_filter( $hook_name, $callback ); 471 472 $this->assertNotWPError( $response ); 473 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 474 $this->assertSame( 0, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' ); 475 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 407 476 } 408 477 … … 529 598 530 599 /** 531 * @ticket 41683 532 */ 533 public function test_get_item_no_permission() { 600 * @dataProvider data_readable_http_methods 601 * @ticket 56481 602 * 603 * @param string $method The HTTP method to use. 604 */ 605 public function test_get_item_should_allow_adding_headers_via_filter( $method ) { 606 $this->setup_widget( 607 'text', 608 1, 609 array( 610 'text' => 'Custom text test', 611 ) 612 ); 613 $this->setup_sidebar( 614 'sidebar-1', 615 array( 616 'name' => 'Test sidebar', 617 ), 618 array( 'text-1' ) 619 ); 620 621 $request = new WP_REST_Request( $method, '/wp/v2/widgets/text-1' ); 622 623 $hook_name = 'rest_prepare_widget'; 624 $filter = new MockAction(); 625 $callback = array( $filter, 'filter' ); 626 add_filter( $hook_name, $callback ); 627 $header_filter = new class() { 628 public static function add_custom_header( $response ) { 629 $response->header( 'X-Test-Header', 'Test' ); 630 631 return $response; 632 } 633 }; 634 add_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 635 $response = rest_get_server()->dispatch( $request ); 636 remove_filter( $hook_name, $callback ); 637 remove_filter( $hook_name, array( $header_filter, 'add_custom_header' ) ); 638 639 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 640 $this->assertSame( 1, $filter->get_call_count(), 'The "' . $hook_name . '" filter was not called when it should be for GET/HEAD requests.' ); 641 $headers = $response->get_headers(); 642 $this->assertArrayHasKey( 'X-Test-Header', $headers, 'The "X-Test-Header" header should be present in the response.' ); 643 $this->assertSame( 'Test', $headers['X-Test-Header'], 'The "X-Test-Header" header value should be equal to "Test".' ); 644 if ( 'HEAD' !== $method ) { 645 return null; 646 } 647 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 648 } 649 650 /** 651 * @dataProvider data_readable_http_methods 652 * @ticket 41683 653 * @ticket 56481 654 * 655 * @param string $method The HTTP method to use. 656 */ 657 public function test_get_item_no_permission( $method ) { 534 658 wp_set_current_user( 0 ); 535 659 … … 549 673 ); 550 674 551 $request = new WP_REST_Request( 'GET', '/wp/v2/widgets/text-1' );675 $request = new WP_REST_Request( $method, '/wp/v2/widgets/text-1' ); 552 676 $response = rest_get_server()->dispatch( $request ); 553 677 $this->assertErrorResponse( 'rest_cannot_manage_widgets', $response, 401 ); … … 555 679 556 680 /** 557 * @ticket 41683 558 */ 559 public function test_get_item_wrong_permission_author() { 681 * @dataProvider data_readable_http_methods 682 * @ticket 41683 683 * @ticket 56481 684 * 685 * @param string $method The HTTP method to use. 686 */ 687 public function test_get_item_wrong_permission_author( $method ) { 560 688 wp_set_current_user( self::$author_id ); 561 689 $this->setup_widget( … … 573 701 ); 574 702 575 $request = new WP_REST_Request( 'GET', '/wp/v2/widgets/text-1' );703 $request = new WP_REST_Request( $method, '/wp/v2/widgets/text-1' ); 576 704 $response = rest_get_server()->dispatch( $request ); 577 705 $this->assertErrorResponse( 'rest_cannot_manage_widgets', $response, 403 ); -
trunk/tests/phpunit/tests/rest-api/wpRestBlockPatternCategoriesController.php
r56492 r59899 125 125 126 126 /** 127 * @ticket 56481 128 */ 129 public function test_get_items_with_head_request_should_not_prepare_block_pattern_categories_data() { 130 wp_set_current_user( self::$admin_id ); 131 $request = new WP_REST_Request( 'HEAD', static::REQUEST_ROUTE ); 132 $response = rest_get_server()->dispatch( $request ); 133 $this->assertSame( 200, $response->get_status(), 'The response status should be 200.' ); 134 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 135 } 136 137 /** 127 138 * Verify capability check for unauthorized request (not logged in). 128 139 */ -
trunk/tests/phpunit/tests/rest-api/wpRestTemplateAutosavesController.php
r59605 r59899 34 34 */ 35 35 const TEMPLATE_PART_POST_TYPE = 'wp_template_part'; 36 37 /** 38 * @var string 39 */ 40 const PARENT_POST_TYPE = 'wp_template'; 36 41 37 42 /** … … 294 299 295 300 /** 301 * @ticket 56481 302 */ 303 public function test_get_items_should_return_no_response_body_for_head_requests() { 304 wp_set_current_user( self::$admin_id ); 305 $autosave_post_id = wp_create_post_autosave( 306 array( 307 'post_content' => 'Autosave content.', 308 'post_ID' => self::$template_post->ID, 309 'post_type' => self::PARENT_POST_TYPE, 310 ) 311 ); 312 313 $request = new WP_REST_Request( 314 'HEAD', 315 '/wp/v2/templates/' . self::TEST_THEME . '/' . self::TEMPLATE_NAME . '/autosaves' 316 ); 317 $response = rest_get_server()->dispatch( $request ); 318 $this->assertSame( 200, $response->get_status(), 'Response status is 200.' ); 319 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 320 } 321 322 /** 296 323 * Data provider for test_get_items_with_data_provider. 297 324 * … … 425 452 ) 426 453 ); 454 } 455 456 /** 457 * @ticket 56481 458 */ 459 public function test_get_item_should_return_no_response_body_for_head_requests() { 460 wp_set_current_user( self::$admin_id ); 461 462 $autosave_post_id = wp_create_post_autosave( 463 array( 464 'post_content' => 'Autosave content.', 465 'post_ID' => self::$template_post->ID, 466 'post_type' => self::PARENT_POST_TYPE, 467 ) 468 ); 469 470 $request = new WP_REST_Request( 'HEAD', '/wp/v2/templates/' . self::TEST_THEME . '/' . self::TEMPLATE_NAME . '/autosaves/' . $autosave_post_id ); 471 $response = rest_get_server()->dispatch( $request ); 472 $this->assertSame( 200, $response->get_status(), 'Response status is 200.' ); 473 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 427 474 } 428 475 -
trunk/tests/phpunit/tests/rest-api/wpRestTemplateRevisionsController.php
r59630 r59899 427 427 ); 428 428 } 429 /** 430 * @ticket 56481 431 */ 432 public function test_get_items_should_return_no_response_body_for_head_requests() { 433 wp_set_current_user( self::$admin_id ); 434 $request = new WP_REST_Request( 435 'HEAD', 436 '/wp/v2/templates/' . self::TEST_THEME . '/' . self::TEMPLATE_NAME . '/revisions' 437 ); 438 $response = rest_get_server()->dispatch( $request ); 439 $this->assertSame( 200, $response->get_status(), 'Response status is 200.' ); 440 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 441 } 429 442 430 443 /** … … 432 445 * @covers WP_REST_Template_Revisions_Controller::get_items_permissions_check 433 446 * @ticket 56922 447 * @ticket 56481 434 448 * 435 449 * @param string $rest_base Base part of the REST API endpoint to test. 436 450 * @param string $template_id Template ID to use in the test. 437 */ 438 public function test_get_items_endpoint_should_return_unauthorized_https_status_code_for_unauthorized_request( $rest_base, $template_id ) { 451 * @param string $method HTTP method to use. 452 */ 453 public function test_get_items_endpoint_should_return_unauthorized_https_status_code_for_unauthorized_request( $rest_base, $template_id, $method ) { 439 454 wp_set_current_user( 0 ); 440 $request = new WP_REST_Request( 'GET', '/wp/v2/' . $rest_base . '/' . $template_id . '/revisions' );455 $request = new WP_REST_Request( $method, '/wp/v2/' . $rest_base . '/' . $template_id . '/revisions' ); 441 456 $response = rest_get_server()->dispatch( $request ); 442 457 $this->assertErrorResponse( 'rest_cannot_read', $response, WP_Http::UNAUTHORIZED ); … … 450 465 public function data_get_items_endpoint_should_return_unauthorized_https_status_code_for_unauthorized_request() { 451 466 return array( 452 'templates' => array( 'templates', self::TEST_THEME . '//' . self::TEMPLATE_NAME ), 453 'template parts' => array( 'template-parts', self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME ), 467 'templates, GET request' => array( 'templates', self::TEST_THEME . '//' . self::TEMPLATE_NAME, 'GET' ), 468 'templates, HEAD request' => array( 'templates', self::TEST_THEME . '//' . self::TEMPLATE_NAME, 'HEAD' ), 469 'template parts, GET request' => array( 'template-parts', self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME, 'GET' ), 470 'template parts, HEAD request' => array( 'template-parts', self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME, 'HEAD' ), 454 471 ); 455 472 } … … 459 476 * @covers WP_REST_Template_Revisions_Controller::get_items_permissions_check 460 477 * @ticket 56922 478 * @ticket 56481 461 479 * 462 480 * @param string $rest_base Base part of the REST API endpoint to test. 463 481 * @param string $template_id Template ID to use in the test. 464 */ 465 public function test_get_items_endpoint_should_return_forbidden_https_status_code_for_users_with_insufficient_permissions( $rest_base, string $template_id ) { 482 * @param string $method HTTP method to use. 483 */ 484 public function test_get_items_endpoint_should_return_forbidden_https_status_code_for_users_with_insufficient_permissions( $rest_base, string $template_id, $method ) { 466 485 wp_set_current_user( self::$contributor_id ); 467 $request = new WP_REST_Request( 'GET', '/wp/v2/' . $rest_base . '/' . $template_id . '/revisions' );486 $request = new WP_REST_Request( $method, '/wp/v2/' . $rest_base . '/' . $template_id . '/revisions' ); 468 487 $response = rest_get_server()->dispatch( $request ); 469 488 $this->assertErrorResponse( 'rest_cannot_read', $response, WP_Http::FORBIDDEN ); … … 477 496 public function data_get_items_endpoint_should_return_forbidden_https_status_code_for_users_with_insufficient_permissions() { 478 497 return array( 479 'templates' => array( 'templates', self::TEST_THEME . '//' . self::TEMPLATE_NAME ), 480 'template parts' => array( 'template-parts', self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME ), 498 'templates, GET request' => array( 'templates', self::TEST_THEME . '//' . self::TEMPLATE_NAME, 'GET' ), 499 'templates, HEAD request' => array( 'templates', self::TEST_THEME . '//' . self::TEMPLATE_NAME, 'HEAD' ), 500 'template parts, GET request' => array( 'template-parts', self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME, 'GET' ), 501 'template parts, HEAD request' => array( 'template-parts', self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME, 'HEAD' ), 481 502 ); 482 503 } … … 598 619 599 620 /** 621 * @ticket 56481 622 */ 623 public function test_get_item_should_return_no_response_body_for_head_requests() { 624 wp_set_current_user( self::$admin_id ); 625 $revisions = wp_get_post_revisions( self::$template_post, array( 'fields' => 'ids' ) ); 626 $revision_id = array_shift( $revisions ); 627 $request = new WP_REST_Request( 'HEAD', '/wp/v2/templates/' . self::TEST_THEME . '/' . self::TEMPLATE_NAME . '/revisions/' . $revision_id ); 628 $response = rest_get_server()->dispatch( $request ); 629 $this->assertSame( 200, $response->get_status(), 'Response status is 200.' ); 630 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 631 } 632 633 /** 600 634 * Data provider for test_get_item_with_data_provider. 601 635 * … … 613 647 * @covers WP_REST_Template_Revisions_Controller::get_item 614 648 * @ticket 56922 649 * @ticket 56481 615 650 * 616 651 * @param string $parent_post_property_name A class property name that contains the parent post object. 617 652 * @param string $rest_base Base part of the REST API endpoint to test. 618 */ 619 public function test_get_item_not_found( $parent_post_property_name, $rest_base ) { 653 * @param string $method HTTP method to use. 654 */ 655 public function test_get_item_not_found( $parent_post_property_name, $rest_base, $method ) { 620 656 wp_set_current_user( self::$admin_id ); 621 657 … … 625 661 $revision_id = array_shift( $revisions ); 626 662 627 $request = new WP_REST_Request( 'GET', '/wp/v2/' . $rest_base . '/invalid//parent/revisions/' . $revision_id );663 $request = new WP_REST_Request( $method, '/wp/v2/' . $rest_base . '/invalid//parent/revisions/' . $revision_id ); 628 664 $response = rest_get_server()->dispatch( $request ); 629 665 $this->assertErrorResponse( 'rest_post_invalid_parent', $response, WP_Http::NOT_FOUND ); … … 637 673 public function data_get_item_not_found() { 638 674 return array( 639 'templates' => array( 'template_post', 'templates' ), 640 'template parts' => array( 'template_part_post', 'template-parts' ), 675 'templates, GET request' => array( 'template_post', 'templates', 'GET' ), 676 'templates, HEAD request' => array( 'template_post', 'templates', 'HEAD' ), 677 'template parts, GET request' => array( 'template_part_post', 'template-parts', 'GET' ), 678 'template parts, HEAD request' => array( 'template_part_post', 'template-parts', 'HEAD' ), 641 679 ); 642 680 } … … 646 684 * @covers WP_REST_Template_Revisions_Controller::get_item 647 685 * @ticket 59875 686 * @ticket 56481 648 687 * 649 688 * @param string $parent_post_property_name A class property name that contains the parent post object. … … 651 690 * @param string $rest_base Base part of the REST API endpoint to test. 652 691 * @param string $template_id Template ID to use in the test. 653 */ 654 public function test_get_item_invalid_parent_id( $parent_post_property_name, $actual_parent_post_property_name, $rest_base, $template_id ) { 692 * @param string $method HTTP method to use. 693 */ 694 public function test_get_item_invalid_parent_id( $parent_post_property_name, $actual_parent_post_property_name, $rest_base, $template_id, $method ) { 655 695 wp_set_current_user( self::$admin_id ); 656 696 … … 660 700 $revision_id = array_shift( $revisions ); 661 701 662 $request = new WP_REST_Request( 'GET', '/wp/v2/' . $rest_base . '/' . $template_id . '/revisions/' . $revision_id );702 $request = new WP_REST_Request( $method, '/wp/v2/' . $rest_base . '/' . $template_id . '/revisions/' . $revision_id ); 663 703 664 704 $response = rest_get_server()->dispatch( $request ); … … 676 716 public function data_get_item_invalid_parent_id() { 677 717 return array( 678 'templates '=> array(718 'templates, GET request' => array( 679 719 'template_post', 680 720 'template_post_2', 681 721 'templates', 682 722 self::TEST_THEME . '//' . self::TEMPLATE_NAME_2, 683 ), 684 'template parts' => array( 723 'GET', 724 ), 725 'templates, HEAD request' => array( 726 'template_post', 727 'template_post_2', 728 'templates', 729 self::TEST_THEME . '//' . self::TEMPLATE_NAME_2, 730 'HEAD', 731 ), 732 'template parts, GET request' => array( 685 733 'template_part_post', 686 734 'template_part_post_2', 687 735 'template-parts', 688 736 self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME_2, 737 'GET', 738 ), 739 'template parts, HEAD request' => array( 740 'template_part_post', 741 'template_part_post_2', 742 'template-parts', 743 self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME_2, 744 'HEAD', 689 745 ), 690 746 ); -
trunk/tests/phpunit/tests/rest-api/wpRestTemplatesController.php
r59201 r59899 177 177 178 178 /** 179 * @ticket 56481 180 * 181 * @covers WP_REST_Templates_Controller::get_items 182 */ 183 public function test_get_items_should_return_no_response_body_for_head_requests() { 184 wp_set_current_user( self::$admin_id ); 185 $request = new WP_REST_Request( 'HEAD', '/wp/v2/templates' ); 186 $response = rest_get_server()->dispatch( $request ); 187 $this->assertSame( 200, $response->get_status(), 'Response status is 200.' ); 188 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 189 } 190 191 /** 179 192 * @covers WP_REST_Templates_Controller::get_items 180 193 */ … … 269 282 270 283 /** 284 * @ticket 56481 285 * 286 * @covers WP_REST_Templates_Controller::get_item 287 * @covers WP_REST_Templates_Controller::prepare_item_for_response 288 */ 289 public function test_get_item_should_return_no_response_body_for_head_requests() { 290 wp_set_current_user( self::$admin_id ); 291 $request = new WP_REST_Request( 'HEAD', '/wp/v2/templates/default//my_template' ); 292 $response = rest_get_server()->dispatch( $request ); 293 $this->assertSame( 200, $response->get_status(), 'Response status is 200.' ); 294 $this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' ); 295 } 296 297 /** 271 298 * @covers WP_REST_Templates_Controller::get_item 272 299 */ … … 311 338 wp_set_current_user( self::$subscriber_id ); 312 339 $request = new WP_REST_Request( 'GET', '/wp/v2/templates/default//my_template' ); 313 $response = rest_get_server()->dispatch( $request );314 340 $response = rest_get_server()->dispatch( $request ); 315 341 $this->assertErrorResponse( 'rest_cannot_manage_templates', $response, 403 );
Note: See TracChangeset
for help on using the changeset viewer.