Ticket #43316: 43316.20.diff
File 43316.20.diff, 86.4 KB (added by , 6 years ago) |
---|
-
src/wp-includes/rest-api.php
diff --git a/src/wp-includes/rest-api.php b/src/wp-includes/rest-api.php index e1403d71bd..1025836de5 100644
a b function create_initial_rest_routes() { 193 193 $revisions_controller = new WP_REST_Revisions_Controller( $post_type->name ); 194 194 $revisions_controller->register_routes(); 195 195 } 196 197 if ( 'attachment' !== $post_type->name ) { 198 $autosaves_controller = new WP_REST_Autosaves_Controller( $post_type->name ); 199 $autosaves_controller->register_routes(); 200 } 201 196 202 } 197 203 198 204 // Post types. … … function create_initial_rest_routes() { 233 239 // Settings. 234 240 $controller = new WP_REST_Settings_Controller; 235 241 $controller->register_routes(); 236 237 // Themes.238 $controller = new WP_REST_Themes_Controller;239 $controller->register_routes();240 242 } 241 243 242 244 /** -
new file src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-autosaves-controller.php new file mode 100644 index 0000000000..0f650821e3
- + 1 <?php 2 /** 3 * REST API: WP_REST_Autosaves_Controller class. 4 * 5 * @package WordPress 6 * @subpackage REST_API 7 * @since 5.0.0 8 */ 9 10 /** 11 * Core class used to access autosaves via the REST API. 12 * 13 * @since 5.0.0 14 * 15 * @see WP_REST_Controller 16 */ 17 class WP_REST_Autosaves_Controller extends WP_REST_Revisions_Controller { 18 19 /** 20 * Parent post type. 21 * 22 * @since 5.0.0 23 * @var string 24 */ 25 private $parent_post_type; 26 27 /** 28 * Parent post controller. 29 * 30 * @since 5.0.0 31 * @var WP_REST_Controller 32 */ 33 private $parent_controller; 34 35 /** 36 * Revision controller. 37 * 38 * @since 5.0.0 39 * @var WP_REST_Controller 40 */ 41 private $revisions_controller; 42 43 /** 44 * The base of the parent controller's route. 45 * 46 * @since 5.0.0 47 * @var string 48 */ 49 private $parent_base; 50 51 /** 52 * Constructor. 53 * 54 * @since 5.0.0 55 * 56 * @param string $parent_post_type Post type of the parent. 57 */ 58 public function __construct( $parent_post_type ) { 59 $this->parent_post_type = $parent_post_type; 60 $post_type_object = get_post_type_object( $parent_post_type ); 61 62 // Ensure that post type-specific controller logic is available. 63 $parent_controller_class = ! empty( $post_type_object->rest_controller_class ) ? $post_type_object->rest_controller_class : 'WP_REST_Posts_Controller'; 64 65 $this->parent_controller = new $parent_controller_class( $post_type_object->name ); 66 $this->revisions_controller = new WP_REST_Revisions_Controller( $parent_post_type ); 67 $this->rest_namespace = 'wp/v2'; 68 $this->rest_base = 'autosaves'; 69 $this->parent_base = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name; 70 } 71 72 /** 73 * Registers routes for autosaves. 74 * 75 * @since 5.0.0 76 * 77 * @see register_rest_route() 78 */ 79 public function register_routes() { 80 register_rest_route( 81 $this->rest_namespace, 82 '/' . $this->parent_base . '/(?P<parent>[\d]+)/' . $this->rest_base, 83 array( 84 'args' => array( 85 'parent' => array( 86 'description' => __( 'The ID for the parent of the object.', 'gutenberg' ), 87 'type' => 'integer', 88 ), 89 ), 90 array( 91 'methods' => WP_REST_Server::READABLE, 92 'callback' => array( $this, 'get_items' ), 93 'permission_callback' => array( $this->revisions_controller, 'get_items_permissions_check' ), 94 'args' => $this->get_collection_params(), 95 ), 96 array( 97 'methods' => WP_REST_Server::CREATABLE, 98 'callback' => array( $this, 'create_item' ), 99 'permission_callback' => array( $this, 'create_item_permissions_check' ), 100 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), 101 ), 102 'schema' => array( $this, 'get_public_item_schema' ), 103 ) 104 ); 105 106 register_rest_route( 107 $this->rest_namespace, 108 '/' . $this->parent_base . '/(?P<parent>[\d]+)/' . $this->rest_base . '/(?P<id>[\d]+)', 109 array( 110 'args' => array( 111 'parent' => array( 112 'description' => __( 'The ID for the parent of the object.', 'gutenberg' ), 113 'type' => 'integer', 114 ), 115 'id' => array( 116 'description' => __( 'The ID for the object.', 'gutenberg' ), 117 'type' => 'integer', 118 ), 119 ), 120 array( 121 'methods' => WP_REST_Server::READABLE, 122 'callback' => array( $this, 'get_item' ), 123 'permission_callback' => array( $this->revisions_controller, 'get_item_permissions_check' ), 124 'args' => array( 125 'context' => $this->get_context_param( array( 'default' => 'view' ) ), 126 ), 127 ), 128 'schema' => array( $this, 'get_public_item_schema' ), 129 ) 130 ); 131 132 } 133 134 /** 135 * Get the parent post. 136 * 137 * @since 5.0.0 138 * 139 * @param int $parent_id Supplied ID. 140 * @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise. 141 */ 142 protected function get_parent( $parent_id ) { 143 return $this->revisions_controller->get_parent( $parent_id ); 144 } 145 146 /** 147 * Checks if a given request has access to create an autosave revision. 148 * 149 * Autosave revisions inherit permissions from the parent post, 150 * check if the current user has permission to edit the post. 151 * 152 * @since 5.0.0 153 * 154 * @param WP_REST_Request $request Full details about the request. 155 * @return true|WP_Error True if the request has access to create the item, WP_Error object otherwise. 156 */ 157 public function create_item_permissions_check( $request ) { 158 $id = $request->get_param( 'id' ); 159 if ( empty( $id ) ) { 160 return new WP_Error( 'rest_post_invalid_id', __( 'Invalid item ID.', 'gutenberg' ), array( 'status' => 404 ) ); 161 } 162 163 return $this->parent_controller->update_item_permissions_check( $request ); 164 } 165 166 /** 167 * Creates, updates or deletes an autosave revision. 168 * 169 * @since 5.0.0 170 * 171 * @param WP_REST_Request $request Full details about the request. 172 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 173 */ 174 public function create_item( $request ) { 175 176 $post = get_post( $request->get_param( 'id' ) ); 177 178 if ( is_wp_error( $post ) ) { 179 return $post; 180 } 181 182 $prepared_post = $this->parent_controller->prepare_item_for_database( $request ); 183 $prepared_post->ID = $post->ID; 184 $user_id = get_current_user_id(); 185 186 if ( ( 'draft' === $post->post_status || 'auto-draft' === $post->post_status ) && $post->post_author == $user_id ) { 187 // Draft posts for the same author: autosaving updates the post and does not create a revision. 188 // Convert the post object to an array and add slashes, wp_update_post expects escaped array. 189 $autosave_id = wp_update_post( wp_slash( (array) $prepared_post ), true ); 190 } else { 191 // Non-draft posts: create or update the post autosave. 192 $autosave_id = $this->create_post_autosave( (array) $prepared_post ); 193 } 194 195 if ( is_wp_error( $autosave_id ) ) { 196 return $autosave_id; 197 } 198 199 $autosave = get_post( $autosave_id ); 200 $request->set_param( 'context', 'edit' ); 201 202 $response = $this->prepare_item_for_response( $autosave, $request ); 203 $response = rest_ensure_response( $response ); 204 205 return $response; 206 } 207 208 /** 209 * Get the autosave, if the ID is valid. 210 * 211 * @since 5.0.0 212 * 213 * @param WP_REST_Request $request Full data about the request. 214 * @return WP_Post|WP_Error Revision post object if ID is valid, WP_Error otherwise. 215 */ 216 public function get_item( $request ) { 217 $parent_id = (int) $request->get_param( 'parent' ); 218 219 if ( $parent_id <= 0 ) { 220 return new WP_Error( 'rest_post_invalid_id', __( 'Invalid parent post ID.', 'gutenberg' ), array( 'status' => 404 ) ); 221 } 222 223 $autosave = wp_get_post_autosave( $parent_id ); 224 225 if ( ! $autosave ) { 226 return new WP_Error( 'rest_post_no_autosave', __( 'There is no autosave revision for this post.', 'gutenberg' ), array( 'status' => 404 ) ); 227 } 228 229 $response = $this->prepare_item_for_response( $autosave, $request ); 230 return $response; 231 } 232 233 /** 234 * Gets a collection of autosaves using wp_get_post_autosave. 235 * 236 * Contains the user's autosave, for empty if it doesn't exist. 237 * 238 * @since 5.0.0 239 * 240 * @param WP_REST_Request $request Full data about the request. 241 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 242 */ 243 public function get_items( $request ) { 244 $parent = $this->get_parent( $request->get_param( 'parent' ) ); 245 if ( is_wp_error( $parent ) ) { 246 return $parent; 247 } 248 249 $response = array(); 250 $parent_id = $parent->ID; 251 $revisions = wp_get_post_revisions( $parent_id, array( 'check_enabled' => false ) ); 252 253 foreach ( $revisions as $revision ) { 254 if ( false !== strpos( $revision->post_name, "{$parent_id}-autosave" ) ) { 255 $data = $this->prepare_item_for_response( $revision, $request ); 256 $response[] = $this->prepare_response_for_collection( $data ); 257 } 258 } 259 260 return rest_ensure_response( $response ); 261 } 262 263 264 /** 265 * Retrieves the autosave's schema, conforming to JSON Schema. 266 * 267 * @since 5.0.0 268 * 269 * @return array Item schema data. 270 */ 271 public function get_item_schema() { 272 $schema = $this->revisions_controller->get_item_schema(); 273 274 $schema['properties']['preview_link'] = array( 275 'description' => __( 'Preview link for the post.', 'gutenberg' ), 276 'type' => 'string', 277 'format' => 'uri', 278 'context' => array( 'edit' ), 279 'readonly' => true, 280 ); 281 282 return $schema; 283 } 284 285 /** 286 * Creates autosave for the specified post. 287 * 288 * From wp-admin/post.php. 289 * 290 * @since 5.0.0 291 * 292 * @param mixed $post_data Associative array containing the post data. 293 * @return mixed The autosave revision ID or WP_Error. 294 */ 295 public function create_post_autosave( $post_data ) { 296 297 $post_id = (int) $post_data['ID']; 298 $post = get_post( $post_id ); 299 300 if ( is_wp_error( $post ) ) { 301 return $post; 302 } 303 304 $user_id = get_current_user_id(); 305 306 // Store one autosave per author. If there is already an autosave, overwrite it. 307 $old_autosave = wp_get_post_autosave( $post_id, $user_id ); 308 309 if ( $old_autosave ) { 310 $new_autosave = _wp_post_revision_data( $post_data, true ); 311 $new_autosave['ID'] = $old_autosave->ID; 312 $new_autosave['post_author'] = $user_id; 313 314 // If the new autosave has the same content as the post, delete the autosave. 315 $autosave_is_different = false; 316 317 foreach ( array_intersect( array_keys( $new_autosave ), array_keys( _wp_post_revision_fields( $post ) ) ) as $field ) { 318 if ( normalize_whitespace( $new_autosave[ $field ] ) != normalize_whitespace( $post->$field ) ) { 319 $autosave_is_different = true; 320 break; 321 } 322 } 323 324 if ( ! $autosave_is_different ) { 325 wp_delete_post_revision( $old_autosave->ID ); 326 return new WP_Error( 'rest_autosave_no_changes', __( 'There is nothing to save. The autosave and the post content are the same.', 'gutenberg' ), array( 'status' => 400 ) ); 327 } 328 329 /** 330 * This filter is documented in wp-admin/post.php. 331 */ 332 do_action( 'wp_creating_autosave', $new_autosave ); 333 334 // wp_update_post expects escaped array. 335 return wp_update_post( wp_slash( $new_autosave ) ); 336 } 337 338 // Create the new autosave as a special post revision. 339 return _wp_put_post_revision( $post_data, true ); 340 } 341 342 /** 343 * Prepares the revision for the REST response. 344 * 345 * @since 5.0.0 346 * 347 * @param WP_Post $post Post revision object. 348 * @param WP_REST_Request $request Request object. 349 * 350 * @return WP_REST_Response Response object. 351 */ 352 public function prepare_item_for_response( $post, $request ) { 353 354 $response = $this->revisions_controller->prepare_item_for_response( $post, $request ); 355 356 $schema = $this->get_item_schema(); 357 358 if ( ! empty( $schema['properties']['preview_link'] ) ) { 359 $parent_id = wp_is_post_autosave( $post ); 360 $preview_post_id = false === $parent_id ? $post->ID : $parent_id; 361 $preview_query_args = array(); 362 363 if ( false !== $parent_id ) { 364 $preview_query_args['preview_id'] = $parent_id; 365 $preview_query_args['preview_nonce'] = wp_create_nonce( 'post_preview_' . $parent_id ); 366 } 367 368 $response->data['preview_link'] = get_preview_post_link( $preview_post_id, $preview_query_args ); 369 } 370 371 $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; 372 $response->data = $this->filter_response_by_context( $response->data, $context ); 373 374 /** 375 * Filters a revision returned from the API. 376 * 377 * Allows modification of the revision right before it is returned. 378 * 379 * @since 5.0.0 380 * 381 * @param WP_REST_Response $response The response object. 382 * @param WP_Post $post The original revision object. 383 * @param WP_REST_Request $request Request used to generate the response. 384 */ 385 return apply_filters( 'rest_prepare_autosave', $response, $post, $request ); 386 } 387 } -
src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-controller.php index 04bd1580f7..3bc6b59091 100644
a b abstract class WP_REST_Controller { 385 385 386 386 $additional_fields = $this->get_additional_fields(); 387 387 388 $requested_fields = $this->get_fields_for_response( $request );389 390 388 foreach ( $additional_fields as $field_name => $field_options ) { 391 389 392 390 if ( ! $field_options['get_callback'] ) { 393 391 continue; 394 392 } 395 393 396 if ( ! in_array( $field_name, $requested_fields, true ) ) {397 continue;398 }399 400 394 $object[ $field_name ] = call_user_func( $field_options['get_callback'], $object, $field_name, $request, $this->get_object_type() ); 401 395 } 402 396 -
deleted file src/wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-themes-controller.php deleted file mode 100644 index 4aa7db4f6f..0000000000
+ - 1 <?php2 /**3 * REST API: WP_REST_Themes_Controller class4 *5 * @package WordPress6 * @subpackage REST_API7 * @since 5.0.08 */9 10 /**11 * Core class used to manage themes via the REST API.12 *13 * @since 5.0.014 *15 * @see WP_REST_Controller16 */17 class WP_REST_Themes_Controller extends WP_REST_Controller {18 19 /**20 * Constructor.21 *22 * @since 5.0.023 */24 public function __construct() {25 $this->namespace = 'wp/v2';26 $this->rest_base = 'themes';27 }28 29 /**30 * Registers the routes for the objects of the controller.31 *32 * @since 5.0.033 *34 * @see register_rest_route()35 */36 public function register_routes() {37 register_rest_route(38 $this->namespace,39 '/' . $this->rest_base,40 array(41 array(42 'methods' => WP_REST_Server::READABLE,43 'callback' => array( $this, 'get_items' ),44 'permission_callback' => array( $this, 'get_items_permissions_check' ),45 'args' => $this->get_collection_params(),46 ),47 'schema' => array( $this, 'get_item_schema' ),48 )49 );50 }51 52 /**53 * Checks if a given request has access to read the theme.54 *55 * @since 5.0.056 *57 * @param WP_REST_Request $request Full details about the request.58 * @return true|WP_Error True if the request has read access for the item, otherwise WP_Error object.59 */60 public function get_items_permissions_check( $request ) {61 if ( ! is_user_logged_in() || ! current_user_can( 'edit_posts' ) ) {62 return new WP_Error( 'rest_user_cannot_view', __( 'Sorry, you are not allowed to view themes.' ), array( 'status' => rest_authorization_required_code() ) );63 }64 65 return true;66 }67 68 /**69 * Retrieves a collection of themes.70 *71 * @since 5.0.072 *73 * @param WP_REST_Request $request Full details about the request.74 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.75 */76 public function get_items( $request ) {77 // Retrieve the list of registered collection query parameters.78 $registered = $this->get_collection_params();79 $themes = array();80 81 if ( isset( $registered['status'], $request['status'] ) && in_array( 'active', $request['status'], true ) ) {82 $active_theme = wp_get_theme();83 $active_theme = $this->prepare_item_for_response( $active_theme, $request );84 $themes[] = $this->prepare_response_for_collection( $active_theme );85 }86 87 $response = rest_ensure_response( $themes );88 89 $response->header( 'X-WP-Total', count( $themes ) );90 $response->header( 'X-WP-TotalPages', count( $themes ) );91 92 return $response;93 }94 95 /**96 * Prepares a single theme output for response.97 *98 * @since 5.0.099 *100 * @param WP_Theme $theme Theme object.101 * @param WP_REST_Request $request Request object.102 * @return WP_REST_Response Response object.103 */104 public function prepare_item_for_response( $theme, $request ) {105 $data = array();106 $fields = $this->get_fields_for_response( $request );107 108 if ( in_array( 'theme_supports', $fields, true ) ) {109 $formats = get_theme_support( 'post-formats' );110 $formats = is_array( $formats ) ? array_values( $formats[0] ) : array();111 $formats = array_merge( array( 'standard' ), $formats );112 $data['theme_supports']['formats'] = $formats;113 114 $data['theme_supports']['post-thumbnails'] = false;115 $post_thumbnails = get_theme_support( 'post-thumbnails' );116 117 if ( $post_thumbnails ) {118 // $post_thumbnails can contain a nested array of post types.119 // e.g. array( array( 'post', 'page' ) ).120 $data['theme_supports']['post-thumbnails'] = is_array( $post_thumbnails ) ? $post_thumbnails[0] : true;121 }122 }123 124 $data = $this->add_additional_fields_to_object( $data, $request );125 126 // Wrap the data in a response object.127 $response = rest_ensure_response( $data );128 129 /**130 * Filters theme data returned from the REST API.131 *132 * @since 5.0.0133 *134 * @param WP_REST_Response $response The response object.135 * @param WP_Theme $theme Theme object used to create response.136 * @param WP_REST_Request $request Request object.137 */138 return apply_filters( 'rest_prepare_theme', $response, $theme, $request );139 }140 141 /**142 * Retrieves the theme's schema, conforming to JSON Schema.143 *144 * @since 5.0.0145 *146 * @return array Item schema data.147 */148 public function get_item_schema() {149 $schema = array(150 '$schema' => 'http://json-schema.org/draft-04/schema#',151 'title' => 'theme',152 'type' => 'object',153 'properties' => array(154 'theme_supports' => array(155 'description' => __( 'Features supported by this theme.' ),156 'type' => 'array',157 'readonly' => true,158 'properties' => array(159 'formats' => array(160 'description' => __( 'Post formats supported.' ),161 'type' => 'array',162 'readonly' => true,163 ),164 'post-thumbnails' => array(165 'description' => __( 'Whether the theme supports post thumbnails.' ),166 'type' => array( 'array', 'bool' ),167 'readonly' => true,168 ),169 ),170 ),171 ),172 );173 174 return $this->add_additional_fields_schema( $schema );175 }176 177 /**178 * Retrieves the search params for the themes collection.179 *180 * @since 5.0.0181 *182 * @return array Collection parameters.183 */184 public function get_collection_params() {185 $query_params = parent::get_collection_params();186 187 $query_params['status'] = array(188 'description' => __( 'Limit result set to themes assigned one or more statuses.' ),189 'type' => 'array',190 'items' => array(191 'enum' => array( 'active' ),192 'type' => 'string',193 ),194 'required' => true,195 'sanitize_callback' => array( $this, 'sanitize_theme_status' ),196 );197 198 /**199 * Filter collection parameters for the themes controller.200 *201 * @since 5.0.0202 *203 * @param array $query_params JSON Schema-formatted collection parameters.204 */205 return apply_filters( 'rest_themes_collection_params', $query_params );206 }207 208 /**209 * Sanitizes and validates the list of theme status.210 *211 * @since 5.0.0212 *213 * @param string|array $statuses One or more theme statuses.214 * @param WP_REST_Request $request Full details about the request.215 * @param string $parameter Additional parameter to pass to validation.216 * @return array|WP_Error A list of valid statuses, otherwise WP_Error object.217 */218 public function sanitize_theme_status( $statuses, $request, $parameter ) {219 $statuses = wp_parse_slug_list( $statuses );220 221 foreach ( $statuses as $status ) {222 $result = rest_validate_request_arg( $status, $request, $parameter );223 224 if ( is_wp_error( $result ) ) {225 return $result;226 }227 }228 229 return $statuses;230 }231 } -
src/wp-settings.php
diff --git a/src/wp-settings.php b/src/wp-settings.php index 44c8a91a07..f4f2ba0d88 100644
a b require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-attachments-contro 229 229 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-post-types-controller.php' ); 230 230 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-post-statuses-controller.php' ); 231 231 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-revisions-controller.php' ); 232 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-autosaves-controller.php' ); 232 233 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-taxonomies-controller.php' ); 233 234 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-terms-controller.php' ); 234 235 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-users-controller.php' ); 235 236 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-comments-controller.php' ); 236 237 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-settings-controller.php' ); 237 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-themes-controller.php' );238 238 require( ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-meta-fields.php' ); 239 239 require( ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-comment-meta-fields.php' ); 240 240 require( ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-post-meta-fields.php' ); -
new file tests/phpunit/tests/rest-api/rest-autosaves-controller.php
diff --git a/tests/phpunit/tests/rest-api/rest-autosaves-controller.php b/tests/phpunit/tests/rest-api/rest-autosaves-controller.php new file mode 100644 index 0000000000..6805b61552
- + 1 <?php 2 /** 3 * Unit tests covering WP_REST_Autosaves_Controller functionality. 4 * 5 * @package WordPress 6 * @subpackage REST API 7 */ 8 9 /** 10 * @group restapi-autosave 11 * @group restapi 12 */ 13 class WP_Test_REST_Autosaves_Controller extends WP_Test_REST_Post_Type_Controller_Testcase { 14 protected static $post_id; 15 protected static $page_id; 16 17 protected static $autosave_post_id; 18 protected static $autosave_page_id; 19 20 protected static $editor_id; 21 protected static $contributor_id; 22 23 protected function set_post_data( $args = array() ) { 24 $defaults = array( 25 'title' => 'Post Title', 26 'content' => 'Post content', 27 'excerpt' => 'Post excerpt', 28 'name' => 'test', 29 'author' => get_current_user_id(), 30 ); 31 32 return wp_parse_args( $args, $defaults ); 33 } 34 35 protected function check_create_autosave_response( $response ) { 36 $this->assertNotInstanceOf( 'WP_Error', $response ); 37 $response = rest_ensure_response( $response ); 38 $data = $response->get_data(); 39 40 $this->assertArrayHasKey( 'content', $data ); 41 $this->assertArrayHasKey( 'excerpt', $data ); 42 $this->assertArrayHasKey( 'title', $data ); 43 } 44 45 public static function wpSetUpBeforeClass( $factory ) { 46 self::$post_id = $factory->post->create(); 47 self::$page_id = $factory->post->create( array( 'post_type' => 'page' ) ); 48 49 self::$editor_id = $factory->user->create( 50 array( 51 'role' => 'editor', 52 ) 53 ); 54 self::$contributor_id = $factory->user->create( 55 array( 56 'role' => 'contributor', 57 ) 58 ); 59 60 wp_set_current_user( self::$editor_id ); 61 62 // Create an autosave. 63 self::$autosave_post_id = wp_create_post_autosave( 64 array( 65 'post_content' => 'This content is better.', 66 'post_ID' => self::$post_id, 67 'post_type' => 'post', 68 ) 69 ); 70 71 self::$autosave_page_id = wp_create_post_autosave( 72 array( 73 'post_content' => 'This content is better.', 74 'post_ID' => self::$page_id, 75 'post_type' => 'post', 76 ) 77 ); 78 79 } 80 81 public static function wpTearDownAfterClass() { 82 // Also deletes revisions. 83 wp_delete_post( self::$post_id, true ); 84 wp_delete_post( self::$page_id, true ); 85 86 self::delete_user( self::$editor_id ); 87 self::delete_user( self::$contributor_id ); 88 } 89 90 public function setUp() { 91 parent::setUp(); 92 wp_set_current_user( self::$editor_id ); 93 94 $this->post_autosave = wp_get_post_autosave( self::$post_id ); 95 } 96 97 public function test_register_routes() { 98 $routes = rest_get_server()->get_routes(); 99 $this->assertArrayHasKey( '/wp/v2/posts/(?P<parent>[\d]+)/autosaves', $routes ); 100 $this->assertArrayHasKey( '/wp/v2/posts/(?P<parent>[\d]+)/autosaves/(?P<id>[\d]+)', $routes ); 101 $this->assertArrayHasKey( '/wp/v2/pages/(?P<parent>[\d]+)/autosaves', $routes ); 102 $this->assertArrayHasKey( '/wp/v2/pages/(?P<parent>[\d]+)/autosaves/(?P<id>[\d]+)', $routes ); 103 } 104 105 public function test_context_param() { 106 // Collection 107 $request = new WP_REST_Request( 'OPTIONS', '/wp/v2/posts/' . self::$post_id . '/autosaves' ); 108 $response = rest_get_server()->dispatch( $request ); 109 $data = $response->get_data(); 110 $this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] ); 111 $this->assertEqualSets( array( 'view', 'edit', 'embed' ), $data['endpoints'][0]['args']['context']['enum'] ); 112 // Single 113 $request = new WP_REST_Request( 'OPTIONS', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id ); 114 $response = rest_get_server()->dispatch( $request ); 115 $data = $response->get_data(); 116 $this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] ); 117 $this->assertEqualSets( array( 'view', 'edit', 'embed' ), $data['endpoints'][0]['args']['context']['enum'] ); } 118 119 public function test_get_items() { 120 wp_set_current_user( self::$editor_id ); 121 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves' ); 122 $response = rest_get_server()->dispatch( $request ); 123 $data = $response->get_data(); 124 $this->assertEquals( 200, $response->get_status() ); 125 $this->assertCount( 1, $data ); 126 127 $this->assertEquals( self::$autosave_post_id, $data[0]['id'] ); 128 129 $this->check_get_autosave_response( $data[0], $this->post_autosave ); 130 } 131 132 public function test_get_items_no_permission() { 133 wp_set_current_user( 0 ); 134 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves' ); 135 $response = rest_get_server()->dispatch( $request ); 136 $this->assertErrorResponse( 'rest_cannot_read', $response, 401 ); 137 wp_set_current_user( self::$contributor_id ); 138 $response = rest_get_server()->dispatch( $request ); 139 $this->assertErrorResponse( 'rest_cannot_read', $response, 403 ); 140 } 141 142 public function test_get_items_missing_parent() { 143 wp_set_current_user( self::$editor_id ); 144 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER . '/autosaves' ); 145 $response = rest_get_server()->dispatch( $request ); 146 $this->assertErrorResponse( 'rest_post_invalid_parent', $response, 404 ); 147 } 148 149 public function test_get_items_invalid_parent_post_type() { 150 wp_set_current_user( self::$editor_id ); 151 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$page_id . '/autosaves' ); 152 $response = rest_get_server()->dispatch( $request ); 153 $this->assertErrorResponse( 'rest_post_invalid_parent', $response, 404 ); 154 } 155 156 public function test_get_item() { 157 wp_set_current_user( self::$editor_id ); 158 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id ); 159 $response = rest_get_server()->dispatch( $request ); 160 $this->assertEquals( 200, $response->get_status() ); 161 $data = $response->get_data(); 162 163 $this->check_get_autosave_response( $response, $this->post_autosave ); 164 $fields = array( 165 'author', 166 'date', 167 'date_gmt', 168 'modified', 169 'modified_gmt', 170 'guid', 171 'id', 172 'parent', 173 'slug', 174 'title', 175 'excerpt', 176 'content', 177 ); 178 $this->assertEqualSets( $fields, array_keys( $data ) ); 179 $this->assertSame( self::$editor_id, $data['author'] ); 180 } 181 182 public function test_get_item_embed_context() { 183 wp_set_current_user( self::$editor_id ); 184 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id ); 185 $request->set_param( 'context', 'embed' ); 186 $response = rest_get_server()->dispatch( $request ); 187 $fields = array( 188 'author', 189 'date', 190 'id', 191 'parent', 192 'slug', 193 'title', 194 'excerpt', 195 ); 196 $data = $response->get_data(); 197 $this->assertEqualSets( $fields, array_keys( $data ) ); 198 } 199 200 public function test_get_item_no_permission() { 201 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id ); 202 wp_set_current_user( self::$contributor_id ); 203 $response = rest_get_server()->dispatch( $request ); 204 $this->assertErrorResponse( 'rest_cannot_read', $response, 403 ); 205 } 206 207 public function test_get_item_missing_parent() { 208 wp_set_current_user( self::$editor_id ); 209 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER . '/autosaves/' . self::$autosave_post_id ); 210 $response = rest_get_server()->dispatch( $request ); 211 $this->assertErrorResponse( 'rest_post_invalid_parent', $response, 404 ); 212 213 } 214 215 public function test_get_item_invalid_parent_post_type() { 216 wp_set_current_user( self::$editor_id ); 217 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$page_id . '/autosaves' ); 218 $response = rest_get_server()->dispatch( $request ); 219 $this->assertErrorResponse( 'rest_post_invalid_parent', $response, 404 ); 220 } 221 222 public function test_delete_item() { 223 // Doesn't exist. 224 } 225 226 public function test_prepare_item() { 227 wp_set_current_user( self::$editor_id ); 228 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id ); 229 $response = rest_get_server()->dispatch( $request ); 230 $this->assertEquals( 200, $response->get_status() ); 231 $this->check_get_autosave_response( $response, $this->post_autosave ); 232 } 233 234 public function test_get_item_schema() { 235 $request = new WP_REST_Request( 'OPTIONS', '/wp/v2/posts/' . self::$post_id . '/autosaves' ); 236 $response = rest_get_server()->dispatch( $request ); 237 $data = $response->get_data(); 238 $properties = $data['schema']['properties']; 239 $this->assertEquals( 13, count( $properties ) ); 240 $this->assertArrayHasKey( 'author', $properties ); 241 $this->assertArrayHasKey( 'content', $properties ); 242 $this->assertArrayHasKey( 'date', $properties ); 243 $this->assertArrayHasKey( 'date_gmt', $properties ); 244 $this->assertArrayHasKey( 'excerpt', $properties ); 245 $this->assertArrayHasKey( 'guid', $properties ); 246 $this->assertArrayHasKey( 'id', $properties ); 247 $this->assertArrayHasKey( 'modified', $properties ); 248 $this->assertArrayHasKey( 'modified_gmt', $properties ); 249 $this->assertArrayHasKey( 'parent', $properties ); 250 $this->assertArrayHasKey( 'slug', $properties ); 251 $this->assertArrayHasKey( 'title', $properties ); 252 } 253 254 public function test_create_item() { 255 wp_set_current_user( self::$editor_id ); 256 257 $request = new WP_REST_Request( 'POST', '/wp/v2/posts/' . self::$post_id . '/autosaves' ); 258 $request->add_header( 'content-type', 'application/x-www-form-urlencoded' ); 259 260 $params = $this->set_post_data( 261 array( 262 'id' => self::$post_id, 263 ) 264 ); 265 $request->set_body_params( $params ); 266 $response = rest_get_server()->dispatch( $request ); 267 268 $this->check_create_autosave_response( $response ); 269 } 270 271 public function test_update_item() { 272 wp_set_current_user( self::$editor_id ); 273 $request = new WP_REST_Request( 'POST', '/wp/v2/posts/' . self::$post_id . '/autosaves' ); 274 $request->add_header( 'content-type', 'application/x-www-form-urlencoded' ); 275 276 $params = $this->set_post_data( 277 array( 278 'id' => self::$post_id, 279 'author' => self::$contributor_id, 280 ) 281 ); 282 283 $request->set_body_params( $params ); 284 $response = rest_get_server()->dispatch( $request ); 285 286 $this->check_create_autosave_response( $response ); 287 } 288 289 public function test_update_item_nopriv() { 290 wp_set_current_user( self::$contributor_id ); 291 292 $request = new WP_REST_Request( 'POST', '/wp/v2/posts/' . self::$post_id . '/autosaves' ); 293 $request->add_header( 'content-type', 'application/x-www-form-urlencoded' ); 294 295 $params = $this->set_post_data( 296 array( 297 'id' => self::$post_id, 298 'author' => self::$editor_id, 299 ) 300 ); 301 302 $request->set_body_params( $params ); 303 $response = rest_get_server()->dispatch( $request ); 304 305 $this->assertErrorResponse( 'rest_cannot_edit', $response, 403 ); 306 } 307 308 public function test_rest_autosave_published_post() { 309 wp_set_current_user( self::$editor_id ); 310 311 $request = new WP_REST_Request( 'POST', '/wp/v2/posts/' . self::$post_id . '/autosaves' ); 312 $request->add_header( 'content-type', 'application/json' ); 313 314 $current_post = get_post( self::$post_id ); 315 316 $autosave_data = $this->set_post_data( 317 array( 318 'id' => self::$post_id, 319 'content' => 'Updated post \ content', 320 'excerpt' => $current_post->post_excerpt, 321 'title' => $current_post->post_title, 322 ) 323 ); 324 325 $request->set_body( wp_json_encode( $autosave_data ) ); 326 $response = rest_get_server()->dispatch( $request ); 327 $new_data = $response->get_data(); 328 329 $this->assertEquals( $current_post->ID, $new_data['parent'] ); 330 $this->assertEquals( $current_post->post_title, $new_data['title']['raw'] ); 331 $this->assertEquals( $current_post->post_excerpt, $new_data['excerpt']['raw'] ); 332 // Updated post_content 333 $this->assertNotEquals( $current_post->post_content, $new_data['content']['raw'] ); 334 335 $autosave_post = wp_get_post_autosave( self::$post_id ); 336 $this->assertEquals( $autosave_data['title'], $autosave_post->post_title ); 337 $this->assertEquals( $autosave_data['content'], $autosave_post->post_content ); 338 $this->assertEquals( $autosave_data['excerpt'], $autosave_post->post_excerpt ); 339 } 340 341 public function test_rest_autosave_draft_post_same_author() { 342 wp_set_current_user( self::$editor_id ); 343 344 $post_data = array( 345 'post_content' => 'Test post content', 346 'post_title' => 'Test post title', 347 'post_excerpt' => 'Test post excerpt', 348 ); 349 $post_id = wp_insert_post( $post_data ); 350 351 $autosave_data = array( 352 'id' => $post_id, 353 'content' => 'Updated post \ content', 354 'title' => 'Updated post title', 355 ); 356 357 $request = new WP_REST_Request( 'POST', '/wp/v2/posts/' . self::$post_id . '/autosaves' ); 358 $request->add_header( 'content-type', 'application/json' ); 359 $request->set_body( wp_json_encode( $autosave_data ) ); 360 361 $response = rest_get_server()->dispatch( $request ); 362 $new_data = $response->get_data(); 363 $post = get_post( $post_id ); 364 365 $this->assertEquals( $post_id, $new_data['id'] ); 366 // The draft post should be updated. 367 $this->assertEquals( $autosave_data['content'], $new_data['content']['raw'] ); 368 $this->assertEquals( $autosave_data['title'], $new_data['title']['raw'] ); 369 $this->assertEquals( $autosave_data['content'], $post->post_content ); 370 $this->assertEquals( $autosave_data['title'], $post->post_title ); 371 372 // Not updated. 373 $this->assertEquals( $post_data['post_excerpt'], $post->post_excerpt ); 374 375 wp_delete_post( $post_id ); 376 } 377 378 public function test_rest_autosave_draft_post_different_author() { 379 wp_set_current_user( self::$editor_id ); 380 381 $post_data = array( 382 'post_content' => 'Test post content', 383 'post_title' => 'Test post title', 384 'post_excerpt' => 'Test post excerpt', 385 'post_author' => self::$editor_id + 1, 386 ); 387 $post_id = wp_insert_post( $post_data ); 388 389 $autosave_data = array( 390 'id' => $post_id, 391 'content' => 'Updated post content', 392 'excerpt' => $post_data['post_excerpt'], 393 'title' => $post_data['post_title'], 394 ); 395 396 $request = new WP_REST_Request( 'POST', '/wp/v2/posts/' . self::$post_id . '/autosaves' ); 397 $request->add_header( 'content-type', 'application/json' ); 398 $request->set_body( wp_json_encode( $autosave_data ) ); 399 400 $response = rest_get_server()->dispatch( $request ); 401 $new_data = $response->get_data(); 402 $current_post = get_post( $post_id ); 403 404 $this->assertEquals( $current_post->ID, $new_data['parent'] ); 405 406 // The draft post shouldn't change. 407 $this->assertEquals( $current_post->post_title, $post_data['post_title'] ); 408 $this->assertEquals( $current_post->post_content, $post_data['post_content'] ); 409 $this->assertEquals( $current_post->post_excerpt, $post_data['post_excerpt'] ); 410 411 $autosave_post = wp_get_post_autosave( $post_id ); 412 413 // No changes 414 $this->assertEquals( $current_post->post_title, $autosave_post->post_title ); 415 $this->assertEquals( $current_post->post_excerpt, $autosave_post->post_excerpt ); 416 417 // Has changes 418 $this->assertEquals( $autosave_data['content'], $autosave_post->post_content ); 419 420 wp_delete_post( $post_id ); 421 } 422 423 public function test_get_additional_field_registration() { 424 $schema = array( 425 'type' => 'integer', 426 'description' => 'Some integer of mine', 427 'enum' => array( 1, 2, 3, 4 ), 428 'context' => array( 'view', 'edit' ), 429 ); 430 431 register_rest_field( 432 'post-revision', 'my_custom_int', array( 433 'schema' => $schema, 434 'get_callback' => array( $this, 'additional_field_get_callback' ), 435 'update_callback' => array( $this, 'additional_field_update_callback' ), 436 ) 437 ); 438 439 $request = new WP_REST_Request( 'OPTIONS', '/wp/v2/posts/' . self::$post_id . '/autosaves' ); 440 441 $response = rest_get_server()->dispatch( $request ); 442 $data = $response->get_data(); 443 444 $this->assertArrayHasKey( 'my_custom_int', $data['schema']['properties'] ); 445 $this->assertEquals( $schema, $data['schema']['properties']['my_custom_int'] ); 446 447 wp_set_current_user( 1 ); 448 449 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id ); 450 451 $response = rest_get_server()->dispatch( $request ); 452 $this->assertArrayHasKey( 'my_custom_int', $response->data ); 453 454 global $wp_rest_additional_fields; 455 $wp_rest_additional_fields = array(); 456 } 457 458 public function additional_field_get_callback( $object ) { 459 return get_post_meta( $object['id'], 'my_custom_int', true ); 460 } 461 462 public function additional_field_update_callback( $value, $post ) { 463 update_post_meta( $post->ID, 'my_custom_int', $value ); 464 } 465 466 protected function check_get_autosave_response( $response, $autosave ) { 467 if ( $response instanceof WP_REST_Response ) { 468 $links = $response->get_links(); 469 $response = $response->get_data(); 470 } else { 471 $this->assertArrayHasKey( '_links', $response ); 472 $links = $response['_links']; 473 } 474 475 $this->assertEquals( $autosave->post_author, $response['author'] ); 476 477 $rendered_content = apply_filters( 'the_content', $autosave->post_content ); 478 $this->assertEquals( $rendered_content, $response['content']['rendered'] ); 479 480 $this->assertEquals( mysql_to_rfc3339( $autosave->post_date ), $response['date'] ); 481 $this->assertEquals( mysql_to_rfc3339( $autosave->post_date_gmt ), $response['date_gmt'] ); 482 483 $rendered_guid = apply_filters( 'get_the_guid', $autosave->guid, $autosave->ID ); 484 $this->assertEquals( $rendered_guid, $response['guid']['rendered'] ); 485 486 $this->assertEquals( $autosave->ID, $response['id'] ); 487 $this->assertEquals( mysql_to_rfc3339( $autosave->post_modified ), $response['modified'] ); 488 $this->assertEquals( mysql_to_rfc3339( $autosave->post_modified_gmt ), $response['modified_gmt'] ); 489 $this->assertEquals( $autosave->post_name, $response['slug'] ); 490 491 $rendered_title = get_the_title( $autosave->ID ); 492 $this->assertEquals( $rendered_title, $response['title']['rendered'] ); 493 494 $parent = get_post( $autosave->post_parent ); 495 $parent_controller = new WP_REST_Posts_Controller( $parent->post_type ); 496 $parent_object = get_post_type_object( $parent->post_type ); 497 $parent_base = ! empty( $parent_object->rest_base ) ? $parent_object->rest_base : $parent_object->name; 498 $this->assertEquals( rest_url( '/wp/v2/' . $parent_base . '/' . $autosave->post_parent ), $links['parent'][0]['href'] ); 499 } 500 501 public function test_get_item_sets_up_postdata() { 502 wp_set_current_user( self::$editor_id ); 503 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id ); 504 rest_get_server()->dispatch( $request ); 505 506 $post = get_post(); 507 $parent_post_id = wp_is_post_revision( $post->ID ); 508 509 $this->assertEquals( $post->ID, self::$autosave_post_id ); 510 $this->assertEquals( $parent_post_id, self::$post_id ); 511 } 512 513 } -
tests/phpunit/tests/rest-api/rest-controller.php
diff --git a/tests/phpunit/tests/rest-api/rest-controller.php b/tests/phpunit/tests/rest-api/rest-controller.php index b9144685ad..88941ec1ee 100644
a b class WP_Test_REST_Controller extends WP_Test_REST_TestCase { 213 213 'someinteger', 214 214 ), $fields ); 215 215 } 216 217 public function test_add_additional_fields_to_object_respects_fields_param() {218 $controller = new WP_REST_Test_Controller();219 $request = new WP_REST_Request( 'GET', '/wp/v2/testroute' );220 $schema = $controller->get_item_schema();221 $field = 'somefield';222 223 $listener = new MockAction();224 $method = 'action';225 226 register_rest_field(227 $schema['title'],228 $field,229 array(230 'get_callback' => array( $listener, $method ),231 'schema' => array(232 'type' => 'string',233 ),234 )235 );236 237 $item = array();238 239 $controller->prepare_item_for_response( $item, $request );240 241 $first_call_count = $listener->get_call_count( $method );242 243 $this->assertTrue( $first_call_count > 0 );244 245 $request->set_param( '_fields', 'somestring' );246 247 $controller->prepare_item_for_response( $item, $request );248 249 $this->assertSame( $first_call_count, $listener->get_call_count( $method ) );250 251 $request->set_param( '_fields', $field );252 253 $controller->prepare_item_for_response( $item, $request );254 255 $this->assertTrue( $listener->get_call_count( $method ) > $first_call_count );256 }257 216 } -
tests/phpunit/tests/rest-api/rest-schema-setup.php
diff --git a/tests/phpunit/tests/rest-api/rest-schema-setup.php b/tests/phpunit/tests/rest-api/rest-schema-setup.php index e51fcc796d..e19a46d47d 100644
a b class WP_Test_REST_Schema_Initialization extends WP_Test_REST_TestCase { 89 89 '/wp/v2/posts/(?P<id>[\\d]+)', 90 90 '/wp/v2/posts/(?P<parent>[\\d]+)/revisions', 91 91 '/wp/v2/posts/(?P<parent>[\\d]+)/revisions/(?P<id>[\\d]+)', 92 '/wp/v2/posts/(?P<parent>[\\d]+)/autosaves', 93 '/wp/v2/posts/(?P<parent>[\\d]+)/autosaves/(?P<id>[\\d]+)', 92 94 '/wp/v2/pages', 93 95 '/wp/v2/pages/(?P<id>[\\d]+)', 94 96 '/wp/v2/pages/(?P<parent>[\\d]+)/revisions', 95 97 '/wp/v2/pages/(?P<parent>[\\d]+)/revisions/(?P<id>[\\d]+)', 98 '/wp/v2/pages/(?P<parent>[\\d]+)/autosaves', 99 '/wp/v2/pages/(?P<parent>[\\d]+)/autosaves/(?P<id>[\\d]+)', 96 100 '/wp/v2/media', 97 101 '/wp/v2/media/(?P<id>[\\d]+)', 98 102 '/wp/v2/types', … … class WP_Test_REST_Schema_Initialization extends WP_Test_REST_TestCase { 111 115 '/wp/v2/comments', 112 116 '/wp/v2/comments/(?P<id>[\\d]+)', 113 117 '/wp/v2/settings', 114 '/wp/v2/themes',115 118 ); 116 119 117 120 $this->assertEquals( $expected_routes, $routes ); … … class WP_Test_REST_Schema_Initialization extends WP_Test_REST_TestCase { 154 157 $post_revisions = array_values( wp_get_post_revisions( $post_id ) ); 155 158 $post_revision_id = $post_revisions[ count( $post_revisions ) - 1 ]->ID; 156 159 160 // Create an autosave. 161 wp_create_post_autosave( 162 array( 163 'post_ID' => $post_id, 164 'post_content' => 'Autosave post content.', 165 'post_type' => 'post', 166 ) 167 ); 168 169 157 170 $page_id = $this->factory->post->create( array( 158 171 'post_type' => 'page', 159 172 'post_name' => 'restapi-client-fixture-page', … … class WP_Test_REST_Schema_Initialization extends WP_Test_REST_TestCase { 171 184 $page_revisions = array_values( wp_get_post_revisions( $page_id ) ); 172 185 $page_revision_id = $page_revisions[ count( $page_revisions ) - 1 ]->ID; 173 186 187 // Create an autosave. 188 wp_create_post_autosave( 189 array( 190 'post_ID' => $page_id, 191 'post_content' => 'Autosave page content.', 192 'post_type' => 'page', 193 ) 194 ); 195 174 196 $tag_id = $this->factory->tag->create( array( 175 197 'name' => 'REST API Client Fixture: Tag', 176 198 'slug' => 'restapi-client-fixture-tag', … … class WP_Test_REST_Schema_Initialization extends WP_Test_REST_TestCase { 256 278 'route' => '/wp/v2/posts/' . $post_id . '/revisions/' . $post_revision_id, 257 279 'name' => 'revision', 258 280 ), 281 array( 282 'route' => '/wp/v2/posts/' . $post_id . '/autosaves', 283 'name' => 'postAutosaves', 284 ), 285 array( 286 'route' => '/wp/v2/posts/' . $post_id . '/autosaves/' . $post_revision_id, 287 'name' => 'autosave', 288 ), 259 289 array( 260 290 'route' => '/wp/v2/pages', 261 291 'name' => 'PagesCollection', … … class WP_Test_REST_Schema_Initialization extends WP_Test_REST_TestCase { 272 302 'route' => '/wp/v2/pages/'. $page_id . '/revisions/' . $page_revision_id, 273 303 'name' => 'pageRevision', 274 304 ), 305 array( 306 'route' => '/wp/v2/pages/' . $page_id . '/autosaves', 307 'name' => 'pageAutosaves', 308 ), 309 array( 310 'route' => '/wp/v2/pages/' . $page_id . '/autosaves/' . $page_revision_id, 311 'name' => 'pageAutosave', 312 ), 275 313 array( 276 314 'route' => '/wp/v2/media', 277 315 'name' => 'MediaCollection', -
tests/phpunit/tests/rest-api/rest-test-controller.php
diff --git a/tests/phpunit/tests/rest-api/rest-test-controller.php b/tests/phpunit/tests/rest-api/rest-test-controller.php index a8c3fefe0a..5b90f76e44 100644
a b 10 10 * @group restapi 11 11 */ 12 12 class WP_REST_Test_Controller extends WP_REST_Controller { 13 /**14 * Prepares the item for the REST response.15 *16 * @param mixed $item WordPress representation of the item.17 * @param WP_REST_Request $request Request object.18 * @return WP_Error|WP_REST_Response Response object on success, or WP_Error object on failure.19 */20 public function prepare_item_for_response( $item, $request ) {21 $context = ! empty( $request['context'] ) ? $request['context'] : 'view';22 $item = $this->add_additional_fields_to_object( $item, $request );23 $item = $this->filter_response_by_context( $item, $context );24 $response = rest_ensure_response( $item );25 return $response;26 }27 13 28 14 /** 29 * Get the item's schema, conforming to JSON Schema.15 * Get the Post type's schema, conforming to JSON Schema 30 16 * 31 17 * @return array 32 18 */ … … class WP_REST_Test_Controller extends WP_REST_Controller { 86 72 ), 87 73 ); 88 74 89 return $ this->add_additional_fields_schema( $schema );75 return $schema; 90 76 } 91 77 92 78 } -
deleted file tests/phpunit/tests/rest-api/rest-themes-controller.php
diff --git a/tests/phpunit/tests/rest-api/rest-themes-controller.php b/tests/phpunit/tests/rest-api/rest-themes-controller.php deleted file mode 100644 index 590f91ec26..0000000000
+ - 1 <?php2 /**3 * Unit tests covering WP_REST_Themes_Controller functionality.4 *5 * @package WordPress6 * @subpackage REST API7 */8 9 /**10 * @group restapi-themes11 * @group restapi12 */13 class WP_Test_REST_Themes_Controller extends WP_Test_REST_Controller_Testcase {14 /**15 * Subscriber user ID.16 *17 * @since 5.0.018 *19 * @var int $subscriber_id20 */21 protected static $subscriber_id;22 23 /**24 * Contributor user ID.25 *26 * @since 5.0.027 *28 * @var int $contributor_id29 */30 protected static $contributor_id;31 32 /**33 * The current theme object.34 *35 * @since 5.0.036 *37 * @var WP_Theme $current_theme38 */39 protected static $current_theme;40 41 /**42 * The REST API route for themes.43 *44 * @since 5.0.045 *46 * @var string $themes_route47 */48 protected static $themes_route = '/wp/v2/themes';49 50 /**51 * Performs a REST API request for the active theme.52 *53 * @since 5.0.054 *55 * @param string $method Optional. Request method. Default GET.56 * @return WP_REST_Response The request's response.57 */58 protected function perform_active_theme_request( $method = 'GET' ) {59 $request = new WP_REST_Request( $method, self::$themes_route );60 $request->set_param( 'status', 'active' );61 62 return rest_get_server()->dispatch( $request );63 }64 65 /**66 * Check that common properties are included in a response.67 *68 * @since 5.0.069 *70 * @param WP_REST_Response $response Current REST API response.71 */72 protected function check_get_theme_response( $response ) {73 if ( $response instanceof WP_REST_Response ) {74 $headers = $response->get_headers();75 $response = $response->get_data();76 } else {77 $headers = array();78 }79 80 $this->assertArrayHasKey( 'X-WP-Total', $headers );81 $this->assertEquals( 1, $headers['X-WP-Total'] );82 $this->assertArrayHasKey( 'X-WP-TotalPages', $headers );83 $this->assertEquals( 1, $headers['X-WP-TotalPages'] );84 }85 86 /**87 * Set up class test fixtures.88 *89 * @since 5.0.090 *91 * @param WP_UnitTest_Factory $factory WordPress unit test factory.92 */93 public static function wpSetUpBeforeClass( $factory ) {94 self::$subscriber_id = $factory->user->create(95 array(96 'role' => 'subscriber',97 )98 );99 self::$contributor_id = $factory->user->create(100 array(101 'role' => 'contributor',102 )103 );104 self::$current_theme = wp_get_theme();105 106 wp_set_current_user( self::$contributor_id );107 }108 109 /**110 * Clean up test fixtures.111 *112 * @since 5.0.0113 */114 public static function wpTearDownAfterClass() {115 self::delete_user( self::$subscriber_id );116 self::delete_user( self::$contributor_id );117 }118 119 /**120 * Set up each test method.121 *122 * @since 5.0.0123 */124 public function setUp() {125 parent::setUp();126 127 wp_set_current_user( self::$contributor_id );128 }129 130 /**131 * Theme routes should be registered correctly.132 *133 * @ticket 45016134 */135 public function test_register_routes() {136 $routes = rest_get_server()->get_routes();137 $this->assertArrayHasKey( self::$themes_route, $routes );138 }139 140 /**141 * Test retrieving a collection of themes.142 *143 * @ticket 45016144 */145 public function test_get_items() {146 $response = self::perform_active_theme_request();147 148 $this->assertEquals( 200, $response->get_status() );149 $data = $response->get_data();150 151 $this->check_get_theme_response( $response );152 $fields = array(153 'theme_supports',154 );155 $this->assertEqualSets( $fields, array_keys( $data[0] ) );156 }157 158 /**159 * An error should be returned when the user does not have the edit_posts capability.160 *161 * @ticket 45016162 */163 public function test_get_items_no_permission() {164 wp_set_current_user( self::$subscriber_id );165 $response = self::perform_active_theme_request();166 $this->assertErrorResponse( 'rest_user_cannot_view', $response, 403 );167 }168 169 /**170 * Test an item is prepared for the response.171 *172 * @ticket 45016173 */174 public function test_prepare_item() {175 $response = self::perform_active_theme_request();176 $this->assertEquals( 200, $response->get_status() );177 $this->check_get_theme_response( $response );178 }179 180 /**181 * Verify the theme schema.182 *183 * @ticket 45016184 */185 public function test_get_item_schema() {186 $response = self::perform_active_theme_request( 'OPTIONS' );187 $data = $response->get_data();188 $properties = $data['schema']['properties'];189 $this->assertEquals( 1, count( $properties ) );190 $this->assertArrayHasKey( 'theme_supports', $properties );191 192 $this->assertEquals( 2, count( $properties['theme_supports']['properties'] ) );193 $this->assertArrayHasKey( 'formats', $properties['theme_supports']['properties'] );194 $this->assertArrayHasKey( 'post-thumbnails', $properties['theme_supports']['properties'] );195 }196 197 /**198 * Should include relevant data in the 'theme_supports' key.199 *200 * @ticket 45016201 */202 public function test_theme_supports_formats() {203 remove_theme_support( 'post-formats' );204 $response = self::perform_active_theme_request();205 $result = $response->get_data();206 $this->assertTrue( isset( $result[0]['theme_supports'] ) );207 $this->assertTrue( isset( $result[0]['theme_supports']['formats'] ) );208 $this->assertSame( array( 'standard' ), $result[0]['theme_supports']['formats'] );209 }210 211 /**212 * Test when a theme only supports some post formats.213 *214 * @ticket 45016215 */216 public function test_theme_supports_formats_non_default() {217 add_theme_support( 'post-formats', array( 'aside', 'video' ) );218 $response = self::perform_active_theme_request();219 $result = $response->get_data();220 $this->assertTrue( isset( $result[0]['theme_supports'] ) );221 $this->assertTrue( isset( $result[0]['theme_supports']['formats'] ) );222 $this->assertSame( array( 'standard', 'aside', 'video' ), $result[0]['theme_supports']['formats'] );223 }224 225 /**226 * Test when a theme does not support post thumbnails.227 *228 * @ticket 45016229 */230 public function test_theme_supports_post_thumbnails_false() {231 remove_theme_support( 'post-thumbnails' );232 $response = self::perform_active_theme_request();233 234 $result = $response->get_data();235 $this->assertTrue( isset( $result[0]['theme_supports'] ) );236 $this->assertTrue( isset( $result[0]['theme_supports']['post-thumbnails'] ) );237 $this->assertFalse( $result[0]['theme_supports']['post-thumbnails'] );238 }239 240 /**241 * Test when a theme supports all post thumbnails.242 *243 * @ticket 45016244 */245 public function test_theme_supports_post_thumbnails_true() {246 remove_theme_support( 'post-thumbnails' );247 add_theme_support( 'post-thumbnails' );248 $response = self::perform_active_theme_request();249 $result = $response->get_data();250 $this->assertTrue( isset( $result[0]['theme_supports'] ) );251 $this->assertTrue( $result[0]['theme_supports']['post-thumbnails'] );252 }253 254 /**255 * Test when a theme only supports post thumbnails for certain post types.256 *257 * @ticket 45016258 */259 public function test_theme_supports_post_thumbnails_array() {260 remove_theme_support( 'post-thumbnails' );261 add_theme_support( 'post-thumbnails', array( 'post' ) );262 $response = self::perform_active_theme_request();263 $result = $response->get_data();264 $this->assertTrue( isset( $result[0]['theme_supports'] ) );265 $this->assertEquals( array( 'post' ), $result[0]['theme_supports']['post-thumbnails'] );266 }267 268 /**269 * It should be possible to register custom fields to the endpoint.270 *271 * @ticket 45016272 */273 public function test_get_additional_field_registration() {274 $schema = array(275 'type' => 'integer',276 'description' => 'Some integer of mine',277 'enum' => array( 1, 2, 3, 4 ),278 );279 280 register_rest_field(281 'theme',282 'my_custom_int',283 array(284 'schema' => $schema,285 'get_callback' => array( $this, 'additional_field_get_callback' ),286 )287 );288 289 $response = self::perform_active_theme_request( 'OPTIONS' );290 $data = $response->get_data();291 292 $this->assertArrayHasKey( 'my_custom_int', $data['schema']['properties'] );293 $this->assertEquals( $schema, $data['schema']['properties']['my_custom_int'] );294 295 $response = self::perform_active_theme_request( 'GET' );296 $data = $response->get_data();297 $this->assertArrayHasKey( 'my_custom_int', $data[0] );298 $this->assertSame( 2, $data[0]['my_custom_int'] );299 300 global $wp_rest_additional_fields;301 $wp_rest_additional_fields = array();302 }303 304 /**305 * Return a value for the custom field.306 *307 * @since 5.0.0308 *309 * @param array $theme Theme data array.310 * @return int Additional field value.311 */312 public function additional_field_get_callback( $theme ) {313 return 2;314 }315 316 /**317 * The create_item() method does not exist for themes.318 */319 public function test_create_item() {}320 321 /**322 * The update_item() method does not exist for themes.323 */324 public function test_update_item() {}325 326 /**327 * The get_item() method does not exist for themes.328 */329 public function test_get_item() {}330 331 /**332 * The delete_item() method does not exist for themes.333 */334 public function test_delete_item() {}335 336 /**337 * Context is not supported for themes.338 */339 public function test_context_param() {}340 } -
tests/qunit/fixtures/wp-api-generated.js
diff --git a/tests/qunit/fixtures/wp-api-generated.js b/tests/qunit/fixtures/wp-api-generated.js index 6b9d530b46..524f31e5be 100644
a b mockedApiResponse.Schema = { 850 850 } 851 851 ] 852 852 }, 853 "/wp/v2/posts/(?P<parent>[\\d]+)/autosaves": { 854 "namespace": "wp/v2", 855 "methods": [ 856 "GET", 857 "POST" 858 ], 859 "endpoints": [ 860 { 861 "methods": [ 862 "GET" 863 ], 864 "args": { 865 "parent": { 866 "required": false, 867 "description": "The ID for the parent of the object.", 868 "type": "integer" 869 }, 870 "context": { 871 "required": false, 872 "default": "view", 873 "enum": [ 874 "view", 875 "embed", 876 "edit" 877 ], 878 "description": "Scope under which the request is made; determines fields present in response.", 879 "type": "string" 880 }, 881 "page": { 882 "required": false, 883 "default": 1, 884 "description": "Current page of the collection.", 885 "type": "integer" 886 }, 887 "per_page": { 888 "required": false, 889 "description": "Maximum number of items to be returned in result set.", 890 "type": "integer" 891 }, 892 "search": { 893 "required": false, 894 "description": "Limit results to those matching a string.", 895 "type": "string" 896 }, 897 "exclude": { 898 "required": false, 899 "default": [], 900 "description": "Ensure result set excludes specific IDs.", 901 "type": "array", 902 "items": { 903 "type": "integer" 904 } 905 }, 906 "include": { 907 "required": false, 908 "default": [], 909 "description": "Limit result set to specific IDs.", 910 "type": "array", 911 "items": { 912 "type": "integer" 913 } 914 }, 915 "offset": { 916 "required": false, 917 "description": "Offset the result set by a specific number of items.", 918 "type": "integer" 919 }, 920 "order": { 921 "required": false, 922 "default": "desc", 923 "enum": [ 924 "asc", 925 "desc" 926 ], 927 "description": "Order sort attribute ascending or descending.", 928 "type": "string" 929 }, 930 "orderby": { 931 "required": false, 932 "default": "date", 933 "enum": [ 934 "date", 935 "id", 936 "include", 937 "relevance", 938 "slug", 939 "include_slugs", 940 "title" 941 ], 942 "description": "Sort collection by object attribute.", 943 "type": "string" 944 } 945 } 946 }, 947 { 948 "methods": [ 949 "POST" 950 ], 951 "args": { 952 "parent": { 953 "required": false, 954 "description": "The ID for the parent of the object.", 955 "type": "integer" 956 }, 957 "author": { 958 "required": false, 959 "description": "The ID for the author of the object.", 960 "type": "integer" 961 }, 962 "date": { 963 "required": false, 964 "description": "The date the object was published, in the site's timezone.", 965 "type": "string" 966 }, 967 "date_gmt": { 968 "required": false, 969 "description": "The date the object was published, as GMT.", 970 "type": "string" 971 }, 972 "id": { 973 "required": false, 974 "description": "Unique identifier for the object.", 975 "type": "integer" 976 }, 977 "modified": { 978 "required": false, 979 "description": "The date the object was last modified, in the site's timezone.", 980 "type": "string" 981 }, 982 "modified_gmt": { 983 "required": false, 984 "description": "The date the object was last modified, as GMT.", 985 "type": "string" 986 }, 987 "slug": { 988 "required": false, 989 "description": "An alphanumeric identifier for the object unique to its type.", 990 "type": "string" 991 }, 992 "title": { 993 "required": false, 994 "description": "The title for the object.", 995 "type": "object" 996 }, 997 "content": { 998 "required": false, 999 "description": "The content for the object.", 1000 "type": "object" 1001 }, 1002 "excerpt": { 1003 "required": false, 1004 "description": "The excerpt for the object.", 1005 "type": "object" 1006 } 1007 } 1008 } 1009 ] 1010 }, 1011 "/wp/v2/posts/(?P<parent>[\\d]+)/autosaves/(?P<id>[\\d]+)": { 1012 "namespace": "wp/v2", 1013 "methods": [ 1014 "GET" 1015 ], 1016 "endpoints": [ 1017 { 1018 "methods": [ 1019 "GET" 1020 ], 1021 "args": { 1022 "parent": { 1023 "required": false, 1024 "description": "The ID for the parent of the object.", 1025 "type": "integer" 1026 }, 1027 "id": { 1028 "required": false, 1029 "description": "The ID for the object.", 1030 "type": "integer" 1031 }, 1032 "context": { 1033 "required": false, 1034 "default": "view", 1035 "enum": [ 1036 "view", 1037 "embed", 1038 "edit" 1039 ], 1040 "description": "Scope under which the request is made; determines fields present in response.", 1041 "type": "string" 1042 } 1043 } 1044 } 1045 ] 1046 }, 853 1047 "/wp/v2/pages": { 854 1048 "namespace": "wp/v2", 855 1049 "methods": [ … … mockedApiResponse.Schema = { 1294 1488 "force": { 1295 1489 "required": false, 1296 1490 "default": false, 1297 "description": "Whether to bypass trash and force deletion.", 1491 "description": "Whether to bypass trash and force deletion.", 1492 "type": "boolean" 1493 } 1494 } 1495 } 1496 ] 1497 }, 1498 "/wp/v2/pages/(?P<parent>[\\d]+)/revisions": { 1499 "namespace": "wp/v2", 1500 "methods": [ 1501 "GET" 1502 ], 1503 "endpoints": [ 1504 { 1505 "methods": [ 1506 "GET" 1507 ], 1508 "args": { 1509 "parent": { 1510 "required": false, 1511 "description": "The ID for the parent of the object.", 1512 "type": "integer" 1513 }, 1514 "context": { 1515 "required": false, 1516 "default": "view", 1517 "enum": [ 1518 "view", 1519 "embed", 1520 "edit" 1521 ], 1522 "description": "Scope under which the request is made; determines fields present in response.", 1523 "type": "string" 1524 }, 1525 "page": { 1526 "required": false, 1527 "default": 1, 1528 "description": "Current page of the collection.", 1529 "type": "integer" 1530 }, 1531 "per_page": { 1532 "required": false, 1533 "description": "Maximum number of items to be returned in result set.", 1534 "type": "integer" 1535 }, 1536 "search": { 1537 "required": false, 1538 "description": "Limit results to those matching a string.", 1539 "type": "string" 1540 }, 1541 "exclude": { 1542 "required": false, 1543 "default": [], 1544 "description": "Ensure result set excludes specific IDs.", 1545 "type": "array", 1546 "items": { 1547 "type": "integer" 1548 } 1549 }, 1550 "include": { 1551 "required": false, 1552 "default": [], 1553 "description": "Limit result set to specific IDs.", 1554 "type": "array", 1555 "items": { 1556 "type": "integer" 1557 } 1558 }, 1559 "offset": { 1560 "required": false, 1561 "description": "Offset the result set by a specific number of items.", 1562 "type": "integer" 1563 }, 1564 "order": { 1565 "required": false, 1566 "default": "desc", 1567 "enum": [ 1568 "asc", 1569 "desc" 1570 ], 1571 "description": "Order sort attribute ascending or descending.", 1572 "type": "string" 1573 }, 1574 "orderby": { 1575 "required": false, 1576 "default": "date", 1577 "enum": [ 1578 "date", 1579 "id", 1580 "include", 1581 "relevance", 1582 "slug", 1583 "include_slugs", 1584 "title" 1585 ], 1586 "description": "Sort collection by object attribute.", 1587 "type": "string" 1588 } 1589 } 1590 } 1591 ] 1592 }, 1593 "/wp/v2/pages/(?P<parent>[\\d]+)/revisions/(?P<id>[\\d]+)": { 1594 "namespace": "wp/v2", 1595 "methods": [ 1596 "GET", 1597 "DELETE" 1598 ], 1599 "endpoints": [ 1600 { 1601 "methods": [ 1602 "GET" 1603 ], 1604 "args": { 1605 "parent": { 1606 "required": false, 1607 "description": "The ID for the parent of the object.", 1608 "type": "integer" 1609 }, 1610 "id": { 1611 "required": false, 1612 "description": "Unique identifier for the object.", 1613 "type": "integer" 1614 }, 1615 "context": { 1616 "required": false, 1617 "default": "view", 1618 "enum": [ 1619 "view", 1620 "embed", 1621 "edit" 1622 ], 1623 "description": "Scope under which the request is made; determines fields present in response.", 1624 "type": "string" 1625 } 1626 } 1627 }, 1628 { 1629 "methods": [ 1630 "DELETE" 1631 ], 1632 "args": { 1633 "parent": { 1634 "required": false, 1635 "description": "The ID for the parent of the object.", 1636 "type": "integer" 1637 }, 1638 "id": { 1639 "required": false, 1640 "description": "Unique identifier for the object.", 1641 "type": "integer" 1642 }, 1643 "force": { 1644 "required": false, 1645 "default": false, 1646 "description": "Required to be true, as revisions do not support trashing.", 1298 1647 "type": "boolean" 1299 1648 } 1300 1649 } 1301 1650 } 1302 1651 ] 1303 1652 }, 1304 "/wp/v2/pages/(?P<parent>[\\d]+)/ revisions": {1653 "/wp/v2/pages/(?P<parent>[\\d]+)/autosaves": { 1305 1654 "namespace": "wp/v2", 1306 1655 "methods": [ 1307 "GET" 1656 "GET", 1657 "POST" 1308 1658 ], 1309 1659 "endpoints": [ 1310 1660 { … … mockedApiResponse.Schema = { 1393 1743 "type": "string" 1394 1744 } 1395 1745 } 1396 } 1397 ] 1398 }, 1399 "/wp/v2/pages/(?P<parent>[\\d]+)/revisions/(?P<id>[\\d]+)": { 1400 "namespace": "wp/v2", 1401 "methods": [ 1402 "GET", 1403 "DELETE" 1404 ], 1405 "endpoints": [ 1746 }, 1406 1747 { 1407 1748 "methods": [ 1408 " GET"1749 "POST" 1409 1750 ], 1410 1751 "args": { 1411 1752 "parent": { … … mockedApiResponse.Schema = { 1413 1754 "description": "The ID for the parent of the object.", 1414 1755 "type": "integer" 1415 1756 }, 1757 "author": { 1758 "required": false, 1759 "description": "The ID for the author of the object.", 1760 "type": "integer" 1761 }, 1762 "date": { 1763 "required": false, 1764 "description": "The date the object was published, in the site's timezone.", 1765 "type": "string" 1766 }, 1767 "date_gmt": { 1768 "required": false, 1769 "description": "The date the object was published, as GMT.", 1770 "type": "string" 1771 }, 1416 1772 "id": { 1417 1773 "required": false, 1418 1774 "description": "Unique identifier for the object.", 1419 1775 "type": "integer" 1420 1776 }, 1421 " context": {1777 "modified": { 1422 1778 "required": false, 1423 "default": "view", 1424 "enum": [ 1425 "view", 1426 "embed", 1427 "edit" 1428 ], 1429 "description": "Scope under which the request is made; determines fields present in response.", 1779 "description": "The date the object was last modified, in the site's timezone.", 1780 "type": "string" 1781 }, 1782 "modified_gmt": { 1783 "required": false, 1784 "description": "The date the object was last modified, as GMT.", 1430 1785 "type": "string" 1786 }, 1787 "slug": { 1788 "required": false, 1789 "description": "An alphanumeric identifier for the object unique to its type.", 1790 "type": "string" 1791 }, 1792 "title": { 1793 "required": false, 1794 "description": "The title for the object.", 1795 "type": "object" 1796 }, 1797 "content": { 1798 "required": false, 1799 "description": "The content for the object.", 1800 "type": "object" 1801 }, 1802 "excerpt": { 1803 "required": false, 1804 "description": "The excerpt for the object.", 1805 "type": "object" 1431 1806 } 1432 1807 } 1433 }, 1808 } 1809 ] 1810 }, 1811 "/wp/v2/pages/(?P<parent>[\\d]+)/autosaves/(?P<id>[\\d]+)": { 1812 "namespace": "wp/v2", 1813 "methods": [ 1814 "GET" 1815 ], 1816 "endpoints": [ 1434 1817 { 1435 1818 "methods": [ 1436 " DELETE"1819 "GET" 1437 1820 ], 1438 1821 "args": { 1439 1822 "parent": { … … mockedApiResponse.Schema = { 1443 1826 }, 1444 1827 "id": { 1445 1828 "required": false, 1446 "description": " Unique identifierfor the object.",1829 "description": "The ID for the object.", 1447 1830 "type": "integer" 1448 1831 }, 1449 " force": {1832 "context": { 1450 1833 "required": false, 1451 "default": false, 1452 "description": "Required to be true, as revisions do not support trashing.", 1453 "type": "boolean" 1834 "default": "view", 1835 "enum": [ 1836 "view", 1837 "embed", 1838 "edit" 1839 ], 1840 "description": "Scope under which the request is made; determines fields present in response.", 1841 "type": "string" 1454 1842 } 1455 1843 } 1456 1844 } … … mockedApiResponse.Schema = { 3517 3905 "_links": { 3518 3906 "self": "http://example.org/index.php?rest_route=/wp/v2/settings" 3519 3907 } 3520 },3521 "/wp/v2/themes": {3522 "namespace": "wp/v2",3523 "methods": [3524 "GET"3525 ],3526 "endpoints": [3527 {3528 "methods": [3529 "GET"3530 ],3531 "args": {3532 "context": {3533 "required": false,3534 "description": "Scope under which the request is made; determines fields present in response.",3535 "type": "string"3536 },3537 "page": {3538 "required": false,3539 "default": 1,3540 "description": "Current page of the collection.",3541 "type": "integer"3542 },3543 "per_page": {3544 "required": false,3545 "default": 10,3546 "description": "Maximum number of items to be returned in result set.",3547 "type": "integer"3548 },3549 "search": {3550 "required": false,3551 "description": "Limit results to those matching a string.",3552 "type": "string"3553 },3554 "status": {3555 "required": true,3556 "description": "Limit result set to themes assigned one or more statuses.",3557 "type": "array",3558 "items": {3559 "enum": [3560 "active"3561 ],3562 "type": "string"3563 }3564 }3565 }3566 }3567 ],3568 "_links": {3569 "self": "http://example.org/index.php?rest_route=/wp/v2/themes"3570 }3571 3908 } 3572 3909 } 3573 3910 }; … … mockedApiResponse.PostsCollection = [ 3774 4111 ], 3775 4112 "version-history": [ 3776 4113 { 3777 "count": 1,4114 "count": 2, 3778 4115 "href": "http://example.org/index.php?rest_route=/wp/v2/posts/4/revisions" 3779 4116 } 3780 4117 ], … … mockedApiResponse.postRevisions = [ 3865 4202 "guid": { 3866 4203 "rendered": "http://example.org/?p=5" 3867 4204 }, 4205 "title": { 4206 "rendered": "" 4207 }, 4208 "content": { 4209 "rendered": "<p>Autosave post content.</p>\n" 4210 }, 4211 "excerpt": { 4212 "rendered": "" 4213 }, 4214 "_links": { 4215 "parent": [ 4216 { 4217 "href": "http://example.org/index.php?rest_route=/wp/v2/posts/4" 4218 } 4219 ] 4220 } 4221 }, 4222 { 4223 "author": 67, 4224 "date": "2017-02-14T00:00:00", 4225 "date_gmt": "2017-02-14T00:00:00", 4226 "id": 456, 4227 "modified": "2017-02-14T00:00:00", 4228 "modified_gmt": "2017-02-14T00:00:00", 4229 "parent": 455, 4230 "slug": "455-revision-v1", 4231 "guid": { 4232 "rendered": "http://example.org/?p=456" 4233 }, 3868 4234 "title": { 3869 4235 "rendered": "REST API Client Fixture: Post" 3870 4236 }, … … mockedApiResponse.postRevisions = [ 3877 4243 "_links": { 3878 4244 "parent": [ 3879 4245 { 3880 "href": "http://example.org/index.php?rest_route=/wp/v2/posts/4 "4246 "href": "http://example.org/index.php?rest_route=/wp/v2/posts/455" 3881 4247 } 3882 4248 ] 3883 4249 } … … mockedApiResponse.revision = { 3907 4273 } 3908 4274 }; 3909 4275 4276 mockedApiResponse.postAutosaves = [ 4277 { 4278 "author": 67, 4279 "date": "2017-02-14T00:00:00", 4280 "date_gmt": "2017-02-14T00:00:00", 4281 "id": 457, 4282 "modified": "2017-02-14T00:00:00", 4283 "modified_gmt": "2017-02-14T00:00:00", 4284 "parent": 455, 4285 "slug": "455-autosave-v1", 4286 "guid": { 4287 "rendered": "http://example.org/?p=457" 4288 }, 4289 "title": { 4290 "rendered": "" 4291 }, 4292 "content": { 4293 "rendered": "<p>Autosave post content.</p>\n" 4294 }, 4295 "excerpt": { 4296 "rendered": "" 4297 }, 4298 "_links": { 4299 "parent": [ 4300 { 4301 "href": "http://example.org/index.php?rest_route=/wp/v2/posts/455" 4302 } 4303 ] 4304 } 4305 } 4306 ]; 4307 4308 mockedApiResponse.autosave = { 4309 "author": 67, 4310 "date": "2017-02-14T00:00:00", 4311 "date_gmt": "2017-02-14T00:00:00", 4312 "id": 457, 4313 "modified": "2017-02-14T00:00:00", 4314 "modified_gmt": "2017-02-14T00:00:00", 4315 "parent": 455, 4316 "slug": "455-autosave-v1", 4317 "guid": { 4318 "rendered": "http://example.org/?p=457" 4319 }, 4320 "title": { 4321 "rendered": "" 4322 }, 4323 "content": { 4324 "rendered": "<p>Autosave post content.</p>\n" 4325 }, 4326 "excerpt": { 4327 "rendered": "" 4328 } 4329 }; 4330 3910 4331 mockedApiResponse.PagesCollection = [ 3911 4332 { 3912 4333 "id": 6, … … mockedApiResponse.PagesCollection = [ 3966 4387 ], 3967 4388 "version-history": [ 3968 4389 { 3969 "count": 1,4390 "count": 2, 3970 4391 "href": "http://example.org/index.php?rest_route=/wp/v2/pages/6/revisions" 3971 4392 } 3972 4393 ], … … mockedApiResponse.pageRevisions = [ 4041 4462 "guid": { 4042 4463 "rendered": "http://example.org/?p=7" 4043 4464 }, 4465 "title": { 4466 "rendered": "" 4467 }, 4468 "content": { 4469 "rendered": "<p>Autosave page content.</p>\n" 4470 }, 4471 "excerpt": { 4472 "rendered": "" 4473 }, 4474 "_links": { 4475 "parent": [ 4476 { 4477 "href": "http://example.org/index.php?rest_route=/wp/v2/pages/6" 4478 } 4479 ] 4480 } 4481 }, 4482 { 4483 "author": 67, 4484 "date": "2017-02-14T00:00:00", 4485 "date_gmt": "2017-02-14T00:00:00", 4486 "id": 459, 4487 "modified": "2017-02-14T00:00:00", 4488 "modified_gmt": "2017-02-14T00:00:00", 4489 "parent": 458, 4490 "slug": "458-revision-v1", 4491 "guid": { 4492 "rendered": "http://example.org/?p=459" 4493 }, 4044 4494 "title": { 4045 4495 "rendered": "REST API Client Fixture: Page" 4046 4496 }, … … mockedApiResponse.pageRevisions = [ 4053 4503 "_links": { 4054 4504 "parent": [ 4055 4505 { 4056 "href": "http://example.org/index.php?rest_route=/wp/v2/pages/ 6"4506 "href": "http://example.org/index.php?rest_route=/wp/v2/pages/458" 4057 4507 } 4058 4508 ] 4059 4509 } … … mockedApiResponse.pageRevision = { 4083 4533 } 4084 4534 }; 4085 4535 4536 mockedApiResponse.pageAutosaves = [ 4537 { 4538 "author": 67, 4539 "date": "2017-02-14T00:00:00", 4540 "date_gmt": "2017-02-14T00:00:00", 4541 "id": 460, 4542 "modified": "2017-02-14T00:00:00", 4543 "modified_gmt": "2017-02-14T00:00:00", 4544 "parent": 458, 4545 "slug": "458-autosave-v1", 4546 "guid": { 4547 "rendered": "http://example.org/?p=460" 4548 }, 4549 "title": { 4550 "rendered": "" 4551 }, 4552 "content": { 4553 "rendered": "<p>Autosave page content.</p>\n" 4554 }, 4555 "excerpt": { 4556 "rendered": "" 4557 }, 4558 "_links": { 4559 "parent": [ 4560 { 4561 "href": "http://example.org/index.php?rest_route=/wp/v2/pages/458" 4562 } 4563 ] 4564 } 4565 } 4566 ]; 4567 4568 mockedApiResponse.pageAutosave = { 4569 "author": 67, 4570 "date": "2017-02-14T00:00:00", 4571 "date_gmt": "2017-02-14T00:00:00", 4572 "id": 460, 4573 "modified": "2017-02-14T00:00:00", 4574 "modified_gmt": "2017-02-14T00:00:00", 4575 "parent": 458, 4576 "slug": "458-autosave-v1", 4577 "guid": { 4578 "rendered": "http://example.org/?p=460" 4579 }, 4580 "title": { 4581 "rendered": "" 4582 }, 4583 "content": { 4584 "rendered": "<p>Autosave page content.</p>\n" 4585 }, 4586 "excerpt": { 4587 "rendered": "" 4588 } 4589 }; 4590 4086 4591 mockedApiResponse.MediaCollection = [ 4087 4592 { 4088 4593 "id": 8,