Ticket #43316: 43316.5.diff
File 43316.5.diff, 57.5 KB (added by , 7 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 0cce9fa62f..51e5e6f1a3 100644
a b function create_initial_rest_routes() { 192 192 if ( post_type_supports( $post_type->name, 'revisions' ) ) { 193 193 $revisions_controller = new WP_REST_Revisions_Controller( $post_type->name ); 194 194 $revisions_controller->register_routes(); 195 $controller = new WP_REST_Autosaves_Controller( $post_type->name ); 196 $controller->register_routes(); 195 197 } 196 198 } 197 199 -
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..e9bafbe40f
- + 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 controller. 29 * 30 * @since 5.0.0 31 * @var WP_REST_Controller 32 */ 33 private $parent_controller; 34 35 /** 36 * Parent controller. 37 * 38 * @since 5.0.0 39 * @var WP_REST_Controller 40 */ 41 private $revision_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 $this->parent_controller = new WP_REST_Posts_Controller( $parent_post_type ); 61 $this->revision_controller = new WP_REST_Revisions_Controller( $parent_post_type ); 62 $this->rest_namespace = 'wp/v2'; 63 $this->rest_base = 'autosaves'; 64 $post_type_object = get_post_type_object( $parent_post_type ); 65 $this->parent_base = ! empty( $post_type_object->rest_base ) ? $post_type_object->rest_base : $post_type_object->name; 66 } 67 68 /**o 69 * Registers routes for autosaves. 70 * 71 * @since 5.0.0 72 * 73 * @see register_rest_route() 74 */ 75 public function register_routes() { 76 register_rest_route( 77 $this->rest_namespace, '/' . $this->parent_base . '/(?P<parent>[\d]+)/' . $this->rest_base, array( 78 'args' => array( 79 'parent' => array( 80 'description' => __( 'The ID for the parent of the object.', 'gutenberg' ), 81 'type' => 'integer', 82 ), 83 ), 84 array( 85 'methods' => WP_REST_Server::READABLE, 86 'callback' => array( $this, 'get_items' ), 87 'permission_callback' => array( $this->revision_controller, 'get_items_permissions_check' ), 88 'args' => $this->get_collection_params(), 89 ), 90 array( 91 'methods' => WP_REST_Server::CREATABLE, 92 'callback' => array( $this, 'create_item' ), 93 'permission_callback' => array( $this->parent_controller, 'create_item_permissions_check' ), 94 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), 95 ), 96 'schema' => array( $this, 'get_public_item_schema' ), 97 ) 98 ); 99 100 register_rest_route( 101 $this->rest_namespace, '/' . $this->parent_base . '/(?P<parent>[\d]+)/' . $this->rest_base . '/(?P<id>[\d]+)', array( 102 'args' => array( 103 'parent' => array( 104 'description' => __( 'The ID for the parent of the object.', 'gutenberg' ), 105 'type' => 'integer', 106 ), 107 'id' => array( 108 'description' => __( 'Unique identifier for the object.', 'gutenberg' ), 109 'type' => 'integer', 110 ), 111 ), 112 array( 113 'methods' => WP_REST_Server::READABLE, 114 'callback' => array( $this, 'get_item' ), 115 'permission_callback' => array( $this->revision_controller, 'get_item_permissions_check' ), 116 'args' => array( 117 'context' => $this->get_context_param( array( 'default' => 'view' ) ), 118 ), 119 ), 120 array( 121 'methods' => WP_REST_Server::EDITABLE, 122 'callback' => array( $this, 'update_item' ), 123 'permission_callback' => '__return_true', //array( $this->parent_controller, 'update_item_permissions_check' ), 124 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), 125 ), 126 array( 127 'methods' => WP_REST_Server::DELETABLE, 128 'callback' => array( $this, 'delete_item' ), 129 'permission_callback' => array( $this->revision_controller, 'delete_item_permissions_check' ), 130 'args' => array( 131 'force' => array( 132 'type' => 'boolean', 133 'default' => false, 134 'description' => __( 'Required to be true, as autosaves do not support trashing.', 'gutenberg' ), 135 ), 136 ), 137 ), 138 array( 139 'methods' => WP_REST_Server::CREATABLE, 140 'callback' => array( $this, 'create_item' ), 141 'permission_callback' => array( $this->parent_controller, 'create_item_permissions_check' ), 142 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), 143 ), 144 'schema' => array( $this, 'get_public_item_schema' ), 145 ) 146 ); 147 148 } 149 150 /** 151 * Get the parent post, if the ID is valid. 152 * 153 * @since 4.7.2 154 * 155 * @param int $id Supplied ID. 156 * @return WP_Post|WP_Error Post object if ID is valid, WP_Error otherwise. 157 */ 158 protected function get_parent( $parent ) { 159 return $this->revision_controller->get_parent( $parent ); 160 } 161 /** 162 * Creates a single autosave. 163 * 164 * @since 5.0.0 165 * 166 * @param WP_REST_Request $request Full details about the request. 167 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 168 */ 169 public function create_item( $request ) { 170 171 // Map new fields onto the existing post data. 172 $parent = $this->get_parent( $request->get_param( 'parent' ) ); 173 $prepared_post = $this->parent_controller->prepare_item_for_database( $request ); 174 $prepared_post->ID = $parent->ID; 175 176 // If the parent post a draft, autosaving updates it and does not create a revision. 177 if ( 'draft' === $parent->post_status ) { 178 179 define( 'DOING_AUTOSAVE', true ); 180 $autosave_id = wp_update_post( (array) $prepared_post, true ); 181 182 if ( ! is_wp_error( $autosave_id ) ) { 183 $post = get_post( $autosave_id ); 184 } 185 } else { 186 187 // Non-draft posts - update the post, creating an autosave. 188 $autosave_id = $this->create_post_autosave( (array) $prepared_post ); 189 $post = get_post( $autosave_id ); 190 } 191 192 $request->set_param( 'context', 'edit' ); 193 194 $response = $this->prepare_item_for_response( $post, $request ); 195 $response = rest_ensure_response( $response ); 196 197 $response->set_status( 201 ); 198 $response->header( 'Location', rest_url( sprintf( '%s/%s/%d', $this->rest_namespace, $this->rest_base, $autosave_id ) ) ); 199 200 return $response; 201 } 202 203 /** 204 * Update an autosave, if the ID is valid. 205 * 206 * @since 5.0.0 207 * 208 * @param WP_REST_Request $request Full data about the request. 209 * @return WP_Post|WP_Error Revision post object if ID is valid, WP_Error otherwise. 210 */ 211 public function update_item( $request ) { 212 $parent = $request->get_param( 'parent' ); 213 $id = $request->get_param( 'id' ); 214 $error = new WP_Error( 'rest_post_invalid_id', __( 'Invalid autosave ID.', 'gutenberg' ), array( 'status' => 404 ) ); 215 if ( (int) $parent <= 0 ) { 216 return $error; 217 } 218 219 $prepared_post = $this->parent_controller->prepare_item_for_database( $request ); 220 $prepared_post->ID = $id; 221 $post_id = wp_update_post( (array) $prepared_post ); 222 $post = get_post( $post_id ); 223 $fields_update = $this->update_additional_fields_for_object( $post, $request ); 224 225 if ( is_wp_error( $fields_update ) ) { 226 return $fields_update; 227 } 228 229 $request->set_param( 'context', 'edit' ); 230 231 $response = $this->prepare_item_for_response( $post, $request ); 232 233 return rest_ensure_response( $response ); 234 } 235 /** 236 * Get the autosave, if the ID is valid. 237 * 238 * @since 5.0.0 239 * 240 * @param WP_REST_Request $request Full data about the request. 241 * @return WP_Post|WP_Error Revision post object if ID is valid, WP_Error otherwise. 242 */ 243 public function get_item( $request ) { 244 $parent = $request->get_param( 'parent' ); 245 $error = new WP_Error( 'rest_post_invalid_id', __( 'Invalid autosave ID.', 'gutenberg' ), array( 'status' => 404 ) ); 246 if ( (int) $parent <= 0 ) { 247 return $error; 248 } 249 $autosave = wp_get_post_autosave( (int) $parent ); 250 251 if ( empty( $autosave ) || empty( $autosave->ID ) || 'revision' !== $autosave->post_type ) { 252 return $error; 253 } 254 $autosave->post_parent = $parent; 255 $response = $this->prepare_item_for_response( $autosave, $request ); 256 257 return $response; 258 } 259 260 /** 261 * Gets a collection of autosaves using wp_get_post_autosave. 262 * 263 * Contains the user's autosave, for empty if it doesn't exist. 264 * 265 * @since 5.0.0 266 * 267 * @param WP_REST_Request $request Full data about the request. 268 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 269 */ 270 public function get_items( $request ) { 271 $parent = $this->get_parent( $request->get_param( 'parent' ) ); 272 if ( is_wp_error( $parent ) ) { 273 return $parent; 274 } 275 276 $autosave = wp_get_post_autosave( $request->get_param( 'parent' ) ); 277 278 if ( ! $autosave ) { 279 return array(); 280 } 281 282 $response = array(); 283 $data = $this->prepare_item_for_response( $autosave, $request ); 284 $response[] = $this->prepare_response_for_collection( $data ); 285 286 return rest_ensure_response( $response ); 287 } 288 289 290 /** 291 * Retrieves the autosave's schema, conforming to JSON Schema. 292 * 293 * @since 5.0.0 294 * 295 * @return array Item schema data. 296 */ 297 public function get_item_schema() { 298 return $this->revision_controller->get_item_schema(); 299 } 300 301 /** 302 * Creates autosave data for the specified post from $_POST data. 303 * 304 * From wp-admin/post.php. 305 * 306 * @since 2.6.0 307 * 308 * @param mixed $post_data Associative array containing the post data or int post ID. 309 * @return mixed The autosave revision ID. WP_Error or 0 on error. 310 */ 311 public function create_post_autosave( $post_data ) { 312 313 $post_id = (int) $post_data['ID']; 314 $post_author = get_current_user_id(); 315 316 // Store one autosave per author. If there is already an autosave, overwrite it. 317 $old_autosave = wp_get_post_autosave( $post_id, $post_author ); 318 if ( $old_autosave ) { 319 $new_autosave = _wp_post_revision_data( $post_data, true ); 320 $new_autosave['ID'] = $old_autosave->ID; 321 $new_autosave['post_author'] = $post_author; 322 323 // If the new autosave has the same content as the post, delete the autosave. 324 $post = get_post( $post_id ); 325 $autosave_is_different = false; 326 foreach ( array_intersect( array_keys( $new_autosave ), array_keys( _wp_post_revision_fields( $post ) ) ) as $field ) { 327 if ( normalize_whitespace( $new_autosave[ $field ] ) != normalize_whitespace( $post->$field ) ) { 328 $autosave_is_different = true; 329 break; 330 } 331 } 332 333 if ( ! $autosave_is_different ) { 334 wp_delete_post_revision( $old_autosave->ID ); 335 return 0; 336 } 337 338 /** 339 * This filter is documented in wp-admin/post.php. 340 */ 341 do_action( 'wp_creating_autosave', $new_autosave ); 342 343 return wp_update_post( $new_autosave ); 344 } 345 346 // _wp_put_post_revision() expects unescaped. 347 $post_data = wp_unslash( $post_data ); 348 349 // Otherwise create the new autosave as a special post revision. 350 return _wp_put_post_revision( $post_data, true ); 351 } 352 353 /** 354 * Prepares the revision for the REST response. 355 * 356 * @since 5.0.0 357 * 358 * @param WP_Post $post Post revision object. 359 * @param WP_REST_Request $request Request object. 360 * 361 * @return WP_REST_Response Response object. 362 */ 363 public function prepare_item_for_response( $post, $request ) { 364 $data = array(); 365 $response = $this->revision_controller->prepare_item_for_response( $post, $request ); 366 367 /** 368 * Filters a revision returned from the API. 369 * 370 * Allows modification of the revision right before it is returned. 371 * 372 * @since 5.0.0 373 * 374 * @param WP_REST_Response $response The response object. 375 * @param WP_Post $post The original revision object. 376 * @param WP_REST_Request $request Request used to generate the response. 377 */ 378 return apply_filters( 'rest_prepare_autosave', $response, $post, $request ); 379 380 } 381 382 } -
src/wp-settings.php
diff --git a/src/wp-settings.php b/src/wp-settings.php index 6edd3c98ca..b2c4189c64 100644
a b require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-attachments-contro 230 230 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-post-types-controller.php' ); 231 231 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-post-statuses-controller.php' ); 232 232 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-revisions-controller.php' ); 233 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-autosaves-controller.php' ); 233 234 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-taxonomies-controller.php' ); 234 235 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-terms-controller.php' ); 235 236 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-users-controller.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..2a99a0ab24
- + 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-autosaves 11 * @group restapi 12 */ 13 class WP_Test_REST_Autosaves_Controller extends WP_Test_REST_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 39 $this->assertEquals( 201, $response->get_status() ); 40 $headers = $response->get_headers(); 41 $this->assertArrayHasKey( 'Location', $headers ); 42 } 43 44 protected function check_update_autosave_response( $response ) { 45 $this->assertNotInstanceOf( 'WP_Error', $response ); 46 $response = rest_ensure_response( $response ); 47 48 $this->assertEquals( 200, $response->get_status() ); 49 $headers = $response->get_headers(); 50 $this->assertArrayNotHasKey( 'Location', $headers ); 51 } 52 53 54 public static function wpSetUpBeforeClass( $factory ) { 55 self::$post_id = $factory->post->create(); 56 self::$page_id = $factory->post->create( array( 'post_type' => 'page' ) ); 57 58 self::$editor_id = $factory->user->create( 59 array( 60 'role' => 'editor', 61 ) 62 ); 63 self::$contributor_id = $factory->user->create( 64 array( 65 'role' => 'contributor', 66 ) 67 ); 68 69 wp_set_current_user( self::$editor_id ); 70 71 // Create an autosave. 72 self::$autosave_post_id = wp_create_post_autosave( 73 array( 74 'post_content' => 'This content is better.', 75 'post_ID' => self::$post_id, 76 'post_type' => 'post', 77 ) 78 ); 79 80 self::$autosave_page_id = wp_create_post_autosave( 81 array( 82 'post_content' => 'This content is better.', 83 'post_ID' => self::$page_id, 84 'post_type' => 'post', 85 ) 86 ); 87 88 } 89 90 public static function wpTearDownAfterClass() { 91 // Also deletes revisions. 92 wp_delete_post( self::$post_id, true ); 93 wp_delete_post( self::$page_id, true ); 94 95 self::delete_user( self::$editor_id ); 96 self::delete_user( self::$contributor_id ); 97 } 98 99 public function setUp() { 100 parent::setUp(); 101 wp_set_current_user( self::$editor_id ); 102 103 $this->post_autosave = wp_get_post_autosave( self::$post_id ); 104 } 105 106 public function test_register_routes() { 107 $routes = rest_get_server()->get_routes(); 108 $this->assertArrayHasKey( '/wp/v2/posts/(?P<parent>[\d]+)/autosaves', $routes ); 109 $this->assertArrayHasKey( '/wp/v2/posts/(?P<parent>[\d]+)/autosaves/(?P<id>[\d]+)', $routes ); 110 $this->assertArrayHasKey( '/wp/v2/pages/(?P<parent>[\d]+)/autosaves', $routes ); 111 $this->assertArrayHasKey( '/wp/v2/pages/(?P<parent>[\d]+)/autosaves/(?P<id>[\d]+)', $routes ); 112 } 113 114 public function test_context_param() { 115 // Collection 116 $request = new WP_REST_Request( 'OPTIONS', '/wp/v2/posts/' . self::$post_id . '/autosaves' ); 117 $response = rest_get_server()->dispatch( $request ); 118 $data = $response->get_data(); 119 $this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] ); 120 $this->assertEqualSets( array( 'view', 'edit', 'embed' ), $data['endpoints'][0]['args']['context']['enum'] ); 121 // Single 122 $request = new WP_REST_Request( 'OPTIONS', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id ); 123 $response = rest_get_server()->dispatch( $request ); 124 $data = $response->get_data(); 125 $this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] ); 126 $this->assertEqualSets( array( 'view', 'edit', 'embed' ), $data['endpoints'][0]['args']['context']['enum'] ); } 127 128 public function test_get_items() { 129 wp_set_current_user( self::$editor_id ); 130 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves' ); 131 $response = rest_get_server()->dispatch( $request ); 132 $data = $response->get_data(); 133 $this->assertEquals( 200, $response->get_status() ); 134 $this->assertCount( 1, $data ); 135 136 $this->assertEquals( self::$autosave_post_id, $data[0]['id'] ); 137 138 $this->check_get_autosave_response( $data[0], $this->post_autosave ); 139 } 140 141 public function test_get_items_no_permission() { 142 wp_set_current_user( 0 ); 143 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves' ); 144 $response = rest_get_server()->dispatch( $request ); 145 $this->assertErrorResponse( 'rest_cannot_read', $response, 401 ); 146 wp_set_current_user( self::$contributor_id ); 147 $response = rest_get_server()->dispatch( $request ); 148 $this->assertErrorResponse( 'rest_cannot_read', $response, 403 ); 149 } 150 151 public function test_get_items_missing_parent() { 152 wp_set_current_user( self::$editor_id ); 153 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER . '/autosaves' ); 154 $response = rest_get_server()->dispatch( $request ); 155 $this->assertErrorResponse( 'rest_post_invalid_parent', $response, 404 ); 156 } 157 158 public function test_get_items_invalid_parent_post_type() { 159 wp_set_current_user( self::$editor_id ); 160 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$page_id . '/autosaves' ); 161 $response = rest_get_server()->dispatch( $request ); 162 $this->assertErrorResponse( 'rest_post_invalid_parent', $response, 404 ); 163 } 164 165 public function test_get_item() { 166 wp_set_current_user( self::$editor_id ); 167 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id ); 168 $response = rest_get_server()->dispatch( $request ); 169 $this->assertEquals( 200, $response->get_status() ); 170 $data = $response->get_data(); 171 172 $this->check_get_autosave_response( $response, $this->post_autosave ); 173 $fields = array( 174 'author', 175 'date', 176 'date_gmt', 177 'modified', 178 'modified_gmt', 179 'guid', 180 'id', 181 'parent', 182 'slug', 183 'title', 184 'excerpt', 185 'content', 186 ); 187 $this->assertEqualSets( $fields, array_keys( $data ) ); 188 $this->assertSame( self::$editor_id, $data['author'] ); 189 } 190 191 public function test_get_item_embed_context() { 192 wp_set_current_user( self::$editor_id ); 193 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id ); 194 $request->set_param( 'context', 'embed' ); 195 $response = rest_get_server()->dispatch( $request ); 196 $fields = array( 197 'author', 198 'date', 199 'id', 200 'parent', 201 'slug', 202 'title', 203 'excerpt', 204 ); 205 $data = $response->get_data(); 206 $this->assertEqualSets( $fields, array_keys( $data ) ); 207 } 208 209 public function test_get_item_no_permission() { 210 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id ); 211 wp_set_current_user( self::$contributor_id ); 212 $response = rest_get_server()->dispatch( $request ); 213 $this->assertErrorResponse( 'rest_cannot_read', $response, 403 ); 214 } 215 216 public function test_get_item_missing_parent() { 217 wp_set_current_user( self::$editor_id ); 218 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER . '/autosaves/' . self::$autosave_post_id ); 219 $response = rest_get_server()->dispatch( $request ); 220 $this->assertErrorResponse( 'rest_post_invalid_parent', $response, 404 ); 221 222 } 223 224 public function test_get_item_invalid_parent_post_type() { 225 wp_set_current_user( self::$editor_id ); 226 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$page_id . '/autosaves' ); 227 $response = rest_get_server()->dispatch( $request ); 228 $this->assertErrorResponse( 'rest_post_invalid_parent', $response, 404 ); 229 } 230 231 public function test_delete_item() { 232 wp_set_current_user( self::$editor_id ); 233 $request = new WP_REST_Request( 'DELETE', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id ); 234 $request->set_param( 'force', true ); 235 $response = rest_get_server()->dispatch( $request ); 236 $this->assertEquals( 200, $response->get_status() ); 237 $this->assertNull( get_post( self::$autosave_post_id ) ); 238 } 239 240 public function test_delete_item_no_trash() { 241 wp_set_current_user( self::$editor_id ); 242 243 $request = new WP_REST_Request( 'DELETE', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id ); 244 $response = rest_get_server()->dispatch( $request ); 245 $this->assertErrorResponse( 'rest_trash_not_supported', $response, 501 ); 246 247 $request->set_param( 'force', 'false' ); 248 $response = rest_get_server()->dispatch( $request ); 249 $this->assertErrorResponse( 'rest_trash_not_supported', $response, 501 ); 250 251 // Ensure the revision still exists 252 $this->assertNotNull( get_post( self::$autosave_post_id ) ); 253 } 254 255 public function test_delete_item_no_permission() { 256 wp_set_current_user( self::$contributor_id ); 257 $request = new WP_REST_Request( 'DELETE', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id ); 258 $response = rest_get_server()->dispatch( $request ); 259 $this->assertErrorResponse( 'rest_cannot_read', $response, 403 ); 260 } 261 262 public function test_prepare_item() { 263 wp_set_current_user( self::$editor_id ); 264 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id ); 265 $response = rest_get_server()->dispatch( $request ); 266 $this->assertEquals( 200, $response->get_status() ); 267 $this->check_get_autosave_response( $response, $this->post_autosave ); 268 } 269 270 public function test_get_item_schema() { 271 $request = new WP_REST_Request( 'OPTIONS', '/wp/v2/posts/' . self::$post_id . '/autosaves' ); 272 $response = rest_get_server()->dispatch( $request ); 273 $data = $response->get_data(); 274 $properties = $data['schema']['properties']; 275 $this->assertEquals( 12, count( $properties ) ); 276 $this->assertArrayHasKey( 'author', $properties ); 277 $this->assertArrayHasKey( 'content', $properties ); 278 $this->assertArrayHasKey( 'date', $properties ); 279 $this->assertArrayHasKey( 'date_gmt', $properties ); 280 $this->assertArrayHasKey( 'excerpt', $properties ); 281 $this->assertArrayHasKey( 'guid', $properties ); 282 $this->assertArrayHasKey( 'id', $properties ); 283 $this->assertArrayHasKey( 'modified', $properties ); 284 $this->assertArrayHasKey( 'modified_gmt', $properties ); 285 $this->assertArrayHasKey( 'parent', $properties ); 286 $this->assertArrayHasKey( 'slug', $properties ); 287 $this->assertArrayHasKey( 'title', $properties ); 288 } 289 290 public function test_create_item() { 291 292 wp_set_current_user( self::$editor_id ); 293 294 $request = new WP_REST_Request( 'POST', '/wp/v2/posts/' . self::$post_id . '/autosaves' ); 295 $request->add_header( 'content-type', 'application/x-www-form-urlencoded' ); 296 $params = $this->set_post_data(); 297 $request->set_body_params( $params ); 298 $response = rest_get_server()->dispatch( $request ); 299 300 $this->check_create_autosave_response( $response ); 301 } 302 303 public function test_update_item() { 304 wp_set_current_user( self::$editor_id ); 305 $request = new WP_REST_Request( 'POST', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id ); 306 $request->add_header( 'content-type', 'application/x-www-form-urlencoded' ); 307 $params = $this->set_post_data(); 308 $request->set_body_params( $params ); 309 $response = rest_get_server()->dispatch( $request ); 310 311 $this->check_update_autosave_response( $response ); 312 } 313 314 public function test_get_additional_field_registration() { 315 $schema = array( 316 'type' => 'integer', 317 'description' => 'Some integer of mine', 318 'enum' => array( 1, 2, 3, 4 ), 319 'context' => array( 'view', 'edit' ), 320 ); 321 322 register_rest_field( 323 'post-revision', 'my_custom_int', array( 324 'schema' => $schema, 325 'get_callback' => array( $this, 'additional_field_get_callback' ), 326 'update_callback' => array( $this, 'additional_field_update_callback' ), 327 ) 328 ); 329 330 $request = new WP_REST_Request( 'OPTIONS', '/wp/v2/posts/' . self::$post_id . '/autosaves' ); 331 332 $response = rest_get_server()->dispatch( $request ); 333 $data = $response->get_data(); 334 335 $this->assertArrayHasKey( 'my_custom_int', $data['schema']['properties'] ); 336 $this->assertEquals( $schema, $data['schema']['properties']['my_custom_int'] ); 337 338 wp_set_current_user( 1 ); 339 340 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id ); 341 342 $response = rest_get_server()->dispatch( $request ); 343 $this->assertArrayHasKey( 'my_custom_int', $response->data ); 344 345 global $wp_rest_additional_fields; 346 $wp_rest_additional_fields = array(); 347 } 348 349 public function additional_field_get_callback( $object ) { 350 return get_post_meta( $object['id'], 'my_custom_int', true ); 351 } 352 353 public function additional_field_update_callback( $value, $post ) { 354 update_post_meta( $post->ID, 'my_custom_int', $value ); 355 } 356 357 protected function check_get_autosave_response( $response, $autosave ) { 358 if ( $response instanceof WP_REST_Response ) { 359 $links = $response->get_links(); 360 $response = $response->get_data(); 361 } else { 362 $this->assertArrayHasKey( '_links', $response ); 363 $links = $response['_links']; 364 } 365 366 $this->assertEquals( $autosave->post_author, $response['author'] ); 367 368 $rendered_content = apply_filters( 'the_content', $autosave->post_content ); 369 $this->assertEquals( $rendered_content, $response['content']['rendered'] ); 370 371 $this->assertEquals( mysql_to_rfc3339( $autosave->post_date ), $response['date'] ); 372 $this->assertEquals( mysql_to_rfc3339( $autosave->post_date_gmt ), $response['date_gmt'] ); 373 374 $rendered_guid = apply_filters( 'get_the_guid', $autosave->guid, $autosave->ID ); 375 $this->assertEquals( $rendered_guid, $response['guid']['rendered'] ); 376 377 $this->assertEquals( $autosave->ID, $response['id'] ); 378 $this->assertEquals( mysql_to_rfc3339( $autosave->post_modified ), $response['modified'] ); 379 $this->assertEquals( mysql_to_rfc3339( $autosave->post_modified_gmt ), $response['modified_gmt'] ); 380 $this->assertEquals( $autosave->post_name, $response['slug'] ); 381 382 $rendered_title = get_the_title( $autosave->ID ); 383 $this->assertEquals( $rendered_title, $response['title']['rendered'] ); 384 385 $parent = get_post( $autosave->post_parent ); 386 $parent_controller = new WP_REST_Posts_Controller( $parent->post_type ); 387 $parent_object = get_post_type_object( $parent->post_type ); 388 $parent_base = ! empty( $parent_object->rest_base ) ? $parent_object->rest_base : $parent_object->name; 389 $this->assertEquals( rest_url( '/wp/v2/' . $parent_base . '/' . $autosave->post_parent ), $links['parent'][0]['href'] ); 390 } 391 392 public function test_get_item_sets_up_postdata() { 393 wp_set_current_user( self::$editor_id ); 394 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id ); 395 rest_get_server()->dispatch( $request ); 396 397 $post = get_post(); 398 $parent_post_id = wp_is_post_revision( $post->ID ); 399 400 $this->assertEquals( $post->ID, self::$autosave_post_id ); 401 $this->assertEquals( $parent_post_id, self::$post_id ); 402 } 403 404 } -
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 e5b3460122..e3271318b6 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 { 159 163 $post_revisions = array_values( wp_get_post_revisions( $post_id ) ); 160 164 $post_revision_id = $post_revisions[ count( $post_revisions ) - 1 ]->ID; 161 165 166 // Create an autosave. 167 wp_create_post_autosave( 168 array( 169 'post_ID' => $post_id, 170 'post_content' => 'Autosave post content.', 171 'post_type' => 'post', 172 ) 173 ); 174 162 175 $page_id = $this->factory->post->create( 163 176 array( 164 177 'post_type' => 'page', … … class WP_Test_REST_Schema_Initialization extends WP_Test_REST_TestCase { 180 193 $page_revisions = array_values( wp_get_post_revisions( $page_id ) ); 181 194 $page_revision_id = $page_revisions[ count( $page_revisions ) - 1 ]->ID; 182 195 196 // Create an autosave. 197 wp_create_post_autosave( 198 array( 199 'post_ID' => $page_id, 200 'post_content' => 'Autosave page content.', 201 'post_type' => 'page', 202 ) 203 ); 204 183 205 $tag_id = $this->factory->tag->create( 184 206 array( 185 207 'name' => 'REST API Client Fixture: Tag', … … class WP_Test_REST_Schema_Initialization extends WP_Test_REST_TestCase { 271 293 'route' => '/wp/v2/posts/' . $post_id . '/revisions/' . $post_revision_id, 272 294 'name' => 'revision', 273 295 ), 296 array( 297 'route' => '/wp/v2/posts/' . $post_id . '/autosaves', 298 'name' => 'postAutosaves', 299 ), 300 array( 301 'route' => '/wp/v2/posts/' . $post_id . '/autosaves/' . $post_revision_id, 302 'name' => 'autosave', 303 ), 274 304 array( 275 305 'route' => '/wp/v2/pages', 276 306 'name' => 'PagesCollection', … … class WP_Test_REST_Schema_Initialization extends WP_Test_REST_TestCase { 287 317 'route' => '/wp/v2/pages/' . $page_id . '/revisions/' . $page_revision_id, 288 318 'name' => 'pageRevision', 289 319 ), 320 array( 321 'route' => '/wp/v2/pages/' . $page_id . '/autosaves', 322 'name' => 'pageAutosaves', 323 ), 324 array( 325 'route' => '/wp/v2/pages/' . $page_id . '/autosaves/' . $page_revision_id, 326 'name' => 'pageAutosave', 327 ), 290 328 array( 291 329 'route' => '/wp/v2/media', 292 330 'name' => 'MediaCollection', -
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 583843fbc1..c70451fee5 100644
a b mockedApiResponse.Schema = { 783 783 } 784 784 ] 785 785 }, 786 "/wp/v2/posts/(?P<parent>[\\d]+)/autosaves": { 787 "namespace": "wp/v2", 788 "methods": [ 789 "GET", 790 "POST" 791 ], 792 "endpoints": [ 793 { 794 "methods": [ 795 "GET" 796 ], 797 "args": { 798 "parent": { 799 "required": false, 800 "description": "The ID for the parent of the object.", 801 "type": "integer" 802 }, 803 "context": { 804 "required": false, 805 "default": "view", 806 "enum": [ 807 "view", 808 "embed", 809 "edit" 810 ], 811 "description": "Scope under which the request is made; determines fields present in response.", 812 "type": "string" 813 } 814 } 815 }, 816 { 817 "methods": [ 818 "POST" 819 ], 820 "args": { 821 "parent": { 822 "required": false, 823 "description": "The ID for the parent of the object.", 824 "type": "integer" 825 }, 826 "author": { 827 "required": false, 828 "description": "The ID for the author of the object.", 829 "type": "integer" 830 }, 831 "date": { 832 "required": false, 833 "description": "The date the object was published, in the site's timezone.", 834 "type": "string" 835 }, 836 "date_gmt": { 837 "required": false, 838 "description": "The date the object was published, as GMT.", 839 "type": "string" 840 }, 841 "id": { 842 "required": false, 843 "description": "Unique identifier for the object.", 844 "type": "integer" 845 }, 846 "modified": { 847 "required": false, 848 "description": "The date the object was last modified, in the site's timezone.", 849 "type": "string" 850 }, 851 "modified_gmt": { 852 "required": false, 853 "description": "The date the object was last modified, as GMT.", 854 "type": "string" 855 }, 856 "slug": { 857 "required": false, 858 "description": "An alphanumeric identifier for the object unique to its type.", 859 "type": "string" 860 }, 861 "title": { 862 "required": false, 863 "description": "The title for the object.", 864 "type": "object" 865 }, 866 "content": { 867 "required": false, 868 "description": "The content for the object.", 869 "type": "object" 870 }, 871 "excerpt": { 872 "required": false, 873 "description": "The excerpt for the object.", 874 "type": "object" 875 } 876 } 877 } 878 ] 879 }, 880 "/wp/v2/posts/(?P<parent>[\\d]+)/autosaves/(?P<id>[\\d]+)": { 881 "namespace": "wp/v2", 882 "methods": [ 883 "GET", 884 "DELETE", 885 "POST" 886 ], 887 "endpoints": [ 888 { 889 "methods": [ 890 "GET" 891 ], 892 "args": { 893 "parent": { 894 "required": false, 895 "description": "The ID for the parent of the object.", 896 "type": "integer" 897 }, 898 "id": { 899 "required": false, 900 "description": "Unique identifier for the object.", 901 "type": "integer" 902 }, 903 "context": { 904 "required": false, 905 "default": "view", 906 "enum": [ 907 "view", 908 "embed", 909 "edit" 910 ], 911 "description": "Scope under which the request is made; determines fields present in response.", 912 "type": "string" 913 } 914 } 915 }, 916 { 917 "methods": [ 918 "DELETE" 919 ], 920 "args": { 921 "parent": { 922 "required": false, 923 "description": "The ID for the parent of the object.", 924 "type": "integer" 925 }, 926 "id": { 927 "required": false, 928 "description": "Unique identifier for the object.", 929 "type": "integer" 930 }, 931 "force": { 932 "required": false, 933 "default": false, 934 "description": "Required to be true, as autosaves do not support trashing.", 935 "type": "boolean" 936 } 937 } 938 }, 939 { 940 "methods": [ 941 "POST" 942 ], 943 "args": { 944 "parent": { 945 "required": false, 946 "description": "The ID for the parent of the object.", 947 "type": "integer" 948 }, 949 "id": { 950 "required": false, 951 "description": "Unique identifier for the object.", 952 "type": "integer" 953 }, 954 "author": { 955 "required": false, 956 "description": "The ID for the author of the object.", 957 "type": "integer" 958 }, 959 "date": { 960 "required": false, 961 "description": "The date the object was published, in the site's timezone.", 962 "type": "string" 963 }, 964 "date_gmt": { 965 "required": false, 966 "description": "The date the object was published, as GMT.", 967 "type": "string" 968 }, 969 "modified": { 970 "required": false, 971 "description": "The date the object was last modified, in the site's timezone.", 972 "type": "string" 973 }, 974 "modified_gmt": { 975 "required": false, 976 "description": "The date the object was last modified, as GMT.", 977 "type": "string" 978 }, 979 "slug": { 980 "required": false, 981 "description": "An alphanumeric identifier for the object unique to its type.", 982 "type": "string" 983 }, 984 "title": { 985 "required": false, 986 "description": "The title for the object.", 987 "type": "object" 988 }, 989 "content": { 990 "required": false, 991 "description": "The content for the object.", 992 "type": "object" 993 }, 994 "excerpt": { 995 "required": false, 996 "description": "The excerpt for the object.", 997 "type": "object" 998 } 999 } 1000 } 1001 ] 1002 }, 786 1003 "/wp/v2/pages": { 787 1004 "namespace": "wp/v2", 788 1005 "methods": [ … … mockedApiResponse.Schema = { 1321 1538 } 1322 1539 ] 1323 1540 }, 1541 "/wp/v2/pages/(?P<parent>[\\d]+)/autosaves": { 1542 "namespace": "wp/v2", 1543 "methods": [ 1544 "GET", 1545 "POST" 1546 ], 1547 "endpoints": [ 1548 { 1549 "methods": [ 1550 "GET" 1551 ], 1552 "args": { 1553 "parent": { 1554 "required": false, 1555 "description": "The ID for the parent of the object.", 1556 "type": "integer" 1557 }, 1558 "context": { 1559 "required": false, 1560 "default": "view", 1561 "enum": [ 1562 "view", 1563 "embed", 1564 "edit" 1565 ], 1566 "description": "Scope under which the request is made; determines fields present in response.", 1567 "type": "string" 1568 } 1569 } 1570 }, 1571 { 1572 "methods": [ 1573 "POST" 1574 ], 1575 "args": { 1576 "parent": { 1577 "required": false, 1578 "description": "The ID for the parent of the object.", 1579 "type": "integer" 1580 }, 1581 "author": { 1582 "required": false, 1583 "description": "The ID for the author of the object.", 1584 "type": "integer" 1585 }, 1586 "date": { 1587 "required": false, 1588 "description": "The date the object was published, in the site's timezone.", 1589 "type": "string" 1590 }, 1591 "date_gmt": { 1592 "required": false, 1593 "description": "The date the object was published, as GMT.", 1594 "type": "string" 1595 }, 1596 "id": { 1597 "required": false, 1598 "description": "Unique identifier for the object.", 1599 "type": "integer" 1600 }, 1601 "modified": { 1602 "required": false, 1603 "description": "The date the object was last modified, in the site's timezone.", 1604 "type": "string" 1605 }, 1606 "modified_gmt": { 1607 "required": false, 1608 "description": "The date the object was last modified, as GMT.", 1609 "type": "string" 1610 }, 1611 "slug": { 1612 "required": false, 1613 "description": "An alphanumeric identifier for the object unique to its type.", 1614 "type": "string" 1615 }, 1616 "title": { 1617 "required": false, 1618 "description": "The title for the object.", 1619 "type": "object" 1620 }, 1621 "content": { 1622 "required": false, 1623 "description": "The content for the object.", 1624 "type": "object" 1625 }, 1626 "excerpt": { 1627 "required": false, 1628 "description": "The excerpt for the object.", 1629 "type": "object" 1630 } 1631 } 1632 } 1633 ] 1634 }, 1635 "/wp/v2/pages/(?P<parent>[\\d]+)/autosaves/(?P<id>[\\d]+)": { 1636 "namespace": "wp/v2", 1637 "methods": [ 1638 "GET", 1639 "DELETE", 1640 "POST" 1641 ], 1642 "endpoints": [ 1643 { 1644 "methods": [ 1645 "GET" 1646 ], 1647 "args": { 1648 "parent": { 1649 "required": false, 1650 "description": "The ID for the parent of the object.", 1651 "type": "integer" 1652 }, 1653 "id": { 1654 "required": false, 1655 "description": "Unique identifier for the object.", 1656 "type": "integer" 1657 }, 1658 "context": { 1659 "required": false, 1660 "default": "view", 1661 "enum": [ 1662 "view", 1663 "embed", 1664 "edit" 1665 ], 1666 "description": "Scope under which the request is made; determines fields present in response.", 1667 "type": "string" 1668 } 1669 } 1670 }, 1671 { 1672 "methods": [ 1673 "DELETE" 1674 ], 1675 "args": { 1676 "parent": { 1677 "required": false, 1678 "description": "The ID for the parent of the object.", 1679 "type": "integer" 1680 }, 1681 "id": { 1682 "required": false, 1683 "description": "Unique identifier for the object.", 1684 "type": "integer" 1685 }, 1686 "force": { 1687 "required": false, 1688 "default": false, 1689 "description": "Required to be true, as autosaves do not support trashing.", 1690 "type": "boolean" 1691 } 1692 } 1693 }, 1694 { 1695 "methods": [ 1696 "POST" 1697 ], 1698 "args": { 1699 "parent": { 1700 "required": false, 1701 "description": "The ID for the parent of the object.", 1702 "type": "integer" 1703 }, 1704 "id": { 1705 "required": false, 1706 "description": "Unique identifier for the object.", 1707 "type": "integer" 1708 }, 1709 "author": { 1710 "required": false, 1711 "description": "The ID for the author of the object.", 1712 "type": "integer" 1713 }, 1714 "date": { 1715 "required": false, 1716 "description": "The date the object was published, in the site's timezone.", 1717 "type": "string" 1718 }, 1719 "date_gmt": { 1720 "required": false, 1721 "description": "The date the object was published, as GMT.", 1722 "type": "string" 1723 }, 1724 "modified": { 1725 "required": false, 1726 "description": "The date the object was last modified, in the site's timezone.", 1727 "type": "string" 1728 }, 1729 "modified_gmt": { 1730 "required": false, 1731 "description": "The date the object was last modified, as GMT.", 1732 "type": "string" 1733 }, 1734 "slug": { 1735 "required": false, 1736 "description": "An alphanumeric identifier for the object unique to its type.", 1737 "type": "string" 1738 }, 1739 "title": { 1740 "required": false, 1741 "description": "The title for the object.", 1742 "type": "object" 1743 }, 1744 "content": { 1745 "required": false, 1746 "description": "The content for the object.", 1747 "type": "object" 1748 }, 1749 "excerpt": { 1750 "required": false, 1751 "description": "The excerpt for the object.", 1752 "type": "object" 1753 } 1754 } 1755 } 1756 ] 1757 }, 1324 1758 "/wp/v2/media": { 1325 1759 "namespace": "wp/v2", 1326 1760 "methods": [ … … mockedApiResponse.postRevisions = [ 3669 4103 "guid": { 3670 4104 "rendered": "http://example.org/?p=4" 3671 4105 }, 4106 "title": { 4107 "rendered": "" 4108 }, 4109 "content": { 4110 "rendered": "<p>Autosave post content.</p>\n" 4111 }, 4112 "excerpt": { 4113 "rendered": "" 4114 }, 4115 "_links": { 4116 "parent": [ 4117 { 4118 "href": "http://example.org/index.php?rest_route=/wp/v2/posts/3" 4119 } 4120 ] 4121 } 4122 }, 4123 { 4124 "author": 59, 4125 "date": "2017-02-14T00:00:00", 4126 "date_gmt": "2017-02-14T00:00:00", 4127 "id": 427, 4128 "modified": "2017-02-14T00:00:00", 4129 "modified_gmt": "2017-02-14T00:00:00", 4130 "parent": 426, 4131 "slug": "426-revision-v1", 4132 "guid": { 4133 "rendered": "http://example.org/?p=427" 4134 }, 3672 4135 "title": { 3673 4136 "rendered": "REST API Client Fixture: Post" 3674 4137 }, … … mockedApiResponse.postRevisions = [ 3681 4144 "_links": { 3682 4145 "parent": [ 3683 4146 { 3684 "href": "http://example.org/index.php?rest_route=/wp/v2/posts/ 3"4147 "href": "http://example.org/index.php?rest_route=/wp/v2/posts/426" 3685 4148 } 3686 4149 ] 3687 4150 } … … mockedApiResponse.revision = { 3711 4174 } 3712 4175 }; 3713 4176 4177 mockedApiResponse.postAutosaves = [ 4178 { 4179 "author": 59, 4180 "date": "2017-02-14T00:00:00", 4181 "date_gmt": "2017-02-14T00:00:00", 4182 "id": 428, 4183 "modified": "2017-02-14T00:00:00", 4184 "modified_gmt": "2017-02-14T00:00:00", 4185 "parent": 426, 4186 "slug": "426-autosave-v1", 4187 "guid": { 4188 "rendered": "http://example.org/?p=428" 4189 }, 4190 "title": { 4191 "rendered": "" 4192 }, 4193 "content": { 4194 "rendered": "<p>Autosave post content.</p>\n" 4195 }, 4196 "excerpt": { 4197 "rendered": "" 4198 }, 4199 "_links": { 4200 "parent": [ 4201 { 4202 "href": "http://example.org/index.php?rest_route=/426" 4203 } 4204 ] 4205 } 4206 } 4207 ]; 4208 4209 mockedApiResponse.autosave = { 4210 "ID": 427, 4211 "post_author": "59", 4212 "post_date": "2018-03-10 16:46:38", 4213 "post_date_gmt": "2018-03-10 16:46:38", 4214 "post_content": "Updated post content.", 4215 "post_title": "REST API Client Fixture: Post", 4216 "post_excerpt": "REST API Client Fixture: Post", 4217 "post_status": "inherit", 4218 "comment_status": "closed", 4219 "ping_status": "closed", 4220 "post_password": "", 4221 "post_name": "426-revision-v1", 4222 "to_ping": "", 4223 "pinged": "", 4224 "post_modified": "2018-03-10 16:46:38", 4225 "post_modified_gmt": "2018-03-10 16:46:38", 4226 "post_content_filtered": "", 4227 "post_parent": 426, 4228 "guid": "http://example.org/?p=427", 4229 "menu_order": 0, 4230 "post_type": "revision", 4231 "post_mime_type": "", 4232 "comment_count": "0", 4233 "filter": "raw" 4234 }; 4235 3714 4236 mockedApiResponse.PagesCollection = [ 3715 4237 { 3716 4238 "id": 5, … … mockedApiResponse.pageRevisions = [ 3838 4360 "guid": { 3839 4361 "rendered": "http://example.org/?p=6" 3840 4362 }, 4363 "title": { 4364 "rendered": "" 4365 }, 4366 "content": { 4367 "rendered": "<p>Autosave page content.</p>\n" 4368 }, 4369 "excerpt": { 4370 "rendered": "" 4371 }, 4372 "_links": { 4373 "parent": [ 4374 { 4375 "href": "http://example.org/index.php?rest_route=/wp/v2/pages/5" 4376 } 4377 ] 4378 } 4379 }, 4380 { 4381 "author": 59, 4382 "date": "2017-02-14T00:00:00", 4383 "date_gmt": "2017-02-14T00:00:00", 4384 "id": 430, 4385 "modified": "2017-02-14T00:00:00", 4386 "modified_gmt": "2017-02-14T00:00:00", 4387 "parent": 429, 4388 "slug": "429-revision-v1", 4389 "guid": { 4390 "rendered": "http://example.org/?p=430" 4391 }, 3841 4392 "title": { 3842 4393 "rendered": "REST API Client Fixture: Page" 3843 4394 }, … … mockedApiResponse.pageRevisions = [ 3850 4401 "_links": { 3851 4402 "parent": [ 3852 4403 { 3853 "href": "http://example.org/index.php?rest_route=/wp/v2/pages/ 5"4404 "href": "http://example.org/index.php?rest_route=/wp/v2/pages/429" 3854 4405 } 3855 4406 ] 3856 4407 } … … mockedApiResponse.pageRevision = { 3880 4431 } 3881 4432 }; 3882 4433 4434 mockedApiResponse.pageAutosaves = [ 4435 { 4436 "author": 59, 4437 "date": "2017-02-14T00:00:00", 4438 "date_gmt": "2017-02-14T00:00:00", 4439 "id": 431, 4440 "modified": "2017-02-14T00:00:00", 4441 "modified_gmt": "2017-02-14T00:00:00", 4442 "parent": 429, 4443 "slug": "429-autosave-v1", 4444 "guid": { 4445 "rendered": "http://example.org/?p=431" 4446 }, 4447 "title": { 4448 "rendered": "" 4449 }, 4450 "content": { 4451 "rendered": "<p>Autosave page content.</p>\n" 4452 }, 4453 "excerpt": { 4454 "rendered": "" 4455 }, 4456 "_links": { 4457 "parent": [ 4458 { 4459 "href": "http://example.org/index.php?rest_route=/429" 4460 } 4461 ] 4462 } 4463 } 4464 ]; 4465 4466 mockedApiResponse.pageAutosave = { 4467 "ID": 430, 4468 "post_author": "59", 4469 "post_date": "2018-03-10 16:46:38", 4470 "post_date_gmt": "2018-03-10 16:46:38", 4471 "post_content": "Updated page content.", 4472 "post_title": "REST API Client Fixture: Page", 4473 "post_excerpt": "REST API Client Fixture: Page", 4474 "post_status": "inherit", 4475 "comment_status": "closed", 4476 "ping_status": "closed", 4477 "post_password": "", 4478 "post_name": "429-revision-v1", 4479 "to_ping": "", 4480 "pinged": "", 4481 "post_modified": "2018-03-10 16:46:38", 4482 "post_modified_gmt": "2018-03-10 16:46:38", 4483 "post_content_filtered": "", 4484 "post_parent": 429, 4485 "guid": "http://example.org/?p=430", 4486 "menu_order": 0, 4487 "post_type": "revision", 4488 "post_mime_type": "", 4489 "comment_count": "0", 4490 "filter": "raw" 4491 }; 4492 3883 4493 mockedApiResponse.MediaCollection = [ 3884 4494 { 3885 4495 "id": 7,