Ticket #45098: 45098.3.diff
| File 45098.3.diff, 65.6 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 ebc3d9a053..e1d8919c8d 100644
a b function create_initial_rest_routes() { 250 250 $controller = new WP_REST_Search_Controller( $search_handlers ); 251 251 $controller->register_routes(); 252 252 253 // Block Renderer. 254 $controller = new WP_REST_Block_Renderer_Controller; 255 $controller->register_routes(); 256 253 257 // Settings. 254 258 $controller = new WP_REST_Settings_Controller; 255 259 $controller->register_routes(); … … function create_initial_rest_routes() { 257 261 // Themes. 258 262 $controller = new WP_REST_Themes_Controller; 259 263 $controller->register_routes(); 264 260 265 } 261 266 262 267 /** -
new file src/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-block-renderer-controller.php new file mode 100644 index 0000000000..a4f17283c5
- + 1 <?php 2 /** 3 * Block Renderer REST API: WP_REST_Block_Renderer_Controller class 4 * 5 * @package WordPress 6 * @subpackage REST_API 7 * @since 5.0.0 8 */ 9 10 /** 11 * Controller which provides REST endpoint for rendering a block. 12 * 13 * @since 5.0.0 14 * 15 * @see WP_REST_Controller 16 */ 17 class WP_REST_Block_Renderer_Controller extends WP_REST_Controller { 18 19 /** 20 * Constructs the controller. 21 * 22 * @since 5.0.0 23 */ 24 public function __construct() { 25 $this->namespace = 'wp/v2'; 26 $this->rest_base = 'block-renderer'; 27 } 28 29 /** 30 * Registers the necessary REST API routes, one for each dynamic block. 31 * 32 * @since 5.0.0 33 */ 34 public function register_routes() { 35 $block_types = WP_Block_Type_Registry::get_instance()->get_all_registered(); 36 37 foreach ( $block_types as $block_type ) { 38 if ( ! $block_type->is_dynamic() ) { 39 continue; 40 } 41 42 register_rest_route( 43 $this->namespace, 44 '/' . $this->rest_base . '/(?P<name>' . $block_type->name . ')', 45 array( 46 'args' => array( 47 'name' => array( 48 'description' => __( 'Unique registered name for the block.' ), 49 'type' => 'string', 50 ), 51 ), 52 array( 53 'methods' => WP_REST_Server::READABLE, 54 'callback' => array( $this, 'get_item' ), 55 'permission_callback' => array( $this, 'get_item_permissions_check' ), 56 'args' => array( 57 'context' => $this->get_context_param( array( 'default' => 'view' ) ), 58 'attributes' => array( 59 /* translators: %s is the name of the block */ 60 'description' => sprintf( __( 'Attributes for %s block' ), $block_type->name ), 61 'type' => 'object', 62 'additionalProperties' => false, 63 'properties' => $block_type->get_attributes(), 64 ), 65 'post_id' => array( 66 'description' => __( 'ID of the post context.' ), 67 'type' => 'integer', 68 ), 69 ), 70 ), 71 'schema' => array( $this, 'get_public_item_schema' ), 72 ) 73 ); 74 } 75 } 76 77 /** 78 * Checks if a given request has access to read blocks. 79 * 80 * @since 5.0.0 81 * 82 * @param WP_REST_Request $request Request. 83 * @return true|WP_Error True if the request has read access, WP_Error object otherwise. 84 */ 85 public function get_item_permissions_check( $request ) { 86 global $post; 87 88 $post_id = isset( $request['post_id'] ) ? intval( $request['post_id'] ) : 0; 89 90 if ( 0 < $post_id ) { 91 $post = get_post( $post_id ); 92 93 if ( ! $post || ! current_user_can( 'edit_post', $post->ID ) ) { 94 return new WP_Error( 95 'block_cannot_read', 96 __( 'Sorry, you are not allowed to read blocks of this post' ), 97 array( 98 'status' => rest_authorization_required_code(), 99 ) 100 ); 101 } 102 } else { 103 if ( ! current_user_can( 'edit_posts' ) ) { 104 return new WP_Error( 105 'block_cannot_read', 106 __( 'Sorry, you are not allowed to read blocks as this user.' ), 107 array( 108 'status' => rest_authorization_required_code(), 109 ) 110 ); 111 } 112 } 113 114 return true; 115 } 116 117 /** 118 * Returns block output from block's registered render_callback. 119 * 120 * @since 5.0.0 121 * 122 * @param WP_REST_Request $request Full details about the request. 123 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure. 124 */ 125 public function get_item( $request ) { 126 global $post; 127 128 $post_id = isset( $request['post_id'] ) ? intval( $request['post_id'] ) : 0; 129 130 if ( 0 < $post_id ) { 131 $post = get_post( $post_id ); 132 133 // Set up postdata since this will be needed if post_id was set. 134 setup_postdata( $post ); 135 } 136 $registry = WP_Block_Type_Registry::get_instance(); 137 $block = $registry->get_registered( $request['name'] ); 138 139 if ( null === $block ) { 140 return new WP_Error( 141 'block_invalid', 142 __( 'Invalid block.' ), 143 array( 144 'status' => 404, 145 ) 146 ); 147 } 148 149 $data = array( 150 'rendered' => $block->render( $request->get_param( 'attributes' ) ), 151 ); 152 return rest_ensure_response( $data ); 153 } 154 155 /** 156 * Retrieves block's output schema, conforming to JSON Schema. 157 * 158 * @since 5.0.0 159 * 160 * @return array Item schema data. 161 */ 162 public function get_item_schema() { 163 return array( 164 '$schema' => 'http://json-schema.org/schema#', 165 'title' => 'rendered-block', 166 'type' => 'object', 167 'properties' => array( 168 'rendered' => array( 169 'description' => __( 'The rendered block.' ), 170 'type' => 'string', 171 'required' => true, 172 'context' => array( 'edit' ), 173 ), 174 ), 175 ); 176 } 177 } -
new file src/wp-includes/rest-api/endpoints/class-wp-rest-blocks-controller.php
diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-blocks-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-blocks-controller.php new file mode 100644 index 0000000000..66a2e7adad
- + 1 <?php 2 /** 3 * Reusable blocks REST API: WP_REST_Blocks_Controller class 4 * 5 * @package WordPress 6 * @subpackage REST_API 7 * @since 5.0.0 8 */ 9 10 /** 11 * Controller which provides a REST endpoint for the editor to read, create, 12 * edit and delete reusable blocks. Blocks are stored as posts with the wp_block 13 * post type. 14 * 15 * @since 5.0.0 16 * 17 * @see WP_REST_Posts_Controller 18 * @see WP_REST_Controller 19 */ 20 class WP_REST_Blocks_Controller extends WP_REST_Posts_Controller { 21 22 /** 23 * Checks if a block can be read. 24 * 25 * @since 5.0.0 26 * 27 * @param object $post Post object that backs the block. 28 * @return bool Whether the block can be read. 29 */ 30 public function check_read_permission( $post ) { 31 // Ensure that the user is logged in and has the read_blocks capability. 32 $post_type = get_post_type_object( $post->post_type ); 33 if ( ! current_user_can( $post_type->cap->read_post, $post->ID ) ) { 34 return false; 35 } 36 37 return parent::check_read_permission( $post ); 38 } 39 } -
src/wp-settings.php
diff --git a/src/wp-settings.php b/src/wp-settings.php index f711b9167b..efefa1b214 100644
a b require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-terms-controller.p 235 235 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-users-controller.php' ); 236 236 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-comments-controller.php' ); 237 237 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-search-controller.php' ); 238 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-blocks-controller.php' ); 239 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-block-renderer-controller.php' ); 238 240 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-settings-controller.php' ); 239 241 require( ABSPATH . WPINC . '/rest-api/endpoints/class-wp-rest-themes-controller.php' ); 240 242 require( ABSPATH . WPINC . '/rest-api/fields/class-wp-rest-meta-fields.php' ); -
new file tests/phpunit/tests/rest-api/rest-block-renderer-controller.php
diff --git a/tests/phpunit/tests/rest-api/rest-block-renderer-controller.php b/tests/phpunit/tests/rest-api/rest-block-renderer-controller.php new file mode 100644 index 0000000000..472e448b10
- + 1 <?php 2 /** 3 * WP_REST_Block_Renderer_Controller tests. 4 * 5 * @package WordPress 6 * @subpackage REST_API 7 * @since 5.0.0 8 */ 9 10 /** 11 * Tests for WP_REST_Block_Renderer_Controller. 12 * 13 * @since 5.0.0 14 * 15 * @covers WP_REST_Block_Renderer_Controller 16 * 17 * @group restapi-blocks 18 * @group restapi 19 */ 20 class REST_Block_Renderer_Controller_Test extends WP_Test_REST_Controller_Testcase { 21 22 /** 23 * The REST API route for the block renderer. 24 * 25 * @since 5.0.0 26 * 27 * @var string 28 */ 29 protected static $rest_api_route = '/wp/v2/block-renderer/'; 30 31 /** 32 * Test block's name. 33 * 34 * @since 5.0.0 35 * 36 * @var string 37 */ 38 protected static $block_name = 'core/test-block'; 39 40 /** 41 * Test post context block's name. 42 * 43 * @since 5.0.0 44 * 45 * @var string 46 */ 47 protected static $context_block_name = 'core/context-test-block'; 48 49 /** 50 * Test API user's ID. 51 * 52 * @since 5.0.0 53 * 54 * @var int 55 */ 56 protected static $user_id; 57 58 /** 59 * Test post ID. 60 * 61 * @since 5.0.0 62 * 63 * @var int 64 */ 65 protected static $post_id; 66 67 /** 68 * Author test user ID. 69 * 70 * @since 5.0.0 71 * 72 * @var int 73 */ 74 protected static $author_id; 75 76 /** 77 * Create test data before the tests run. 78 * 79 * @since 5.0.0 80 * 81 * @param WP_UnitTest_Factory $factory Helper that lets us create fake data. 82 */ 83 public static function wpSetUpBeforeClass( $factory ) { 84 self::$user_id = $factory->user->create( 85 array( 86 'role' => 'editor', 87 ) 88 ); 89 90 self::$author_id = $factory->user->create( 91 array( 92 'role' => 'author', 93 ) 94 ); 95 96 self::$post_id = $factory->post->create( 97 array( 98 'post_title' => 'Test Post', 99 ) 100 ); 101 } 102 103 /** 104 * Delete test data after our tests run. 105 * 106 * @since 5.0.0 107 */ 108 public static function wpTearDownAfterClass() { 109 self::delete_user( self::$user_id ); 110 } 111 112 /** 113 * Set up each test method. 114 * 115 * @since 5.0.0 116 */ 117 public function setUp() { 118 $this->register_test_block(); 119 $this->register_post_context_test_block(); 120 parent::setUp(); 121 } 122 123 /** 124 * Tear down each test method. 125 * 126 * @since 5.0.0 127 */ 128 public function tearDown() { 129 WP_Block_Type_Registry::get_instance()->unregister( self::$block_name ); 130 WP_Block_Type_Registry::get_instance()->unregister( self::$context_block_name ); 131 parent::tearDown(); 132 } 133 134 /** 135 * Register test block. 136 * 137 * @since 5.0.0 138 */ 139 public function register_test_block() { 140 register_block_type( 141 self::$block_name, 142 array( 143 'attributes' => array( 144 'some_string' => array( 145 'type' => 'string', 146 'default' => 'some_default', 147 ), 148 'some_int' => array( 149 'type' => 'integer', 150 ), 151 'some_array' => array( 152 'type' => 'array', 153 'items' => array( 154 'type' => 'integer', 155 ), 156 ), 157 ), 158 'render_callback' => array( $this, 'render_test_block' ), 159 ) 160 ); 161 } 162 163 /** 164 * Register test block with post_id as attribute for post context test. 165 * 166 * @since 5.0.0 167 */ 168 public function register_post_context_test_block() { 169 register_block_type( 170 self::$context_block_name, 171 array( 172 'attributes' => array(), 173 'render_callback' => array( $this, 'render_post_context_test_block' ), 174 ) 175 ); 176 } 177 178 /** 179 * Test render callback. 180 * 181 * @since 5.0.0 182 * 183 * @param array $attributes Props. 184 * @return string Rendered attributes, which is here just JSON. 185 */ 186 public function render_test_block( $attributes ) { 187 return wp_json_encode( $attributes ); 188 } 189 190 /** 191 * Test render callback for testing post context. 192 * 193 * @since 5.0.0 194 * 195 * @return string 196 */ 197 public function render_post_context_test_block() { 198 return get_the_title(); 199 } 200 201 /** 202 * Check that the route was registered properly. 203 * 204 * @ticket 45098 205 * 206 * @covers WP_REST_Block_Renderer_Controller::register_routes() 207 */ 208 public function test_register_routes() { 209 $dynamic_block_names = get_dynamic_block_names(); 210 $this->assertContains( self::$block_name, $dynamic_block_names ); 211 212 $routes = rest_get_server()->get_routes(); 213 foreach ( $dynamic_block_names as $dynamic_block_name ) { 214 $this->assertArrayHasKey( self::$rest_api_route . "(?P<name>$dynamic_block_name)", $routes ); 215 } 216 } 217 218 /** 219 * Test getting item without permissions. 220 * 221 * @ticket 45098 222 * 223 * @covers WP_REST_Block_Renderer_Controller::get_item() 224 */ 225 public function test_get_item_without_permissions() { 226 wp_set_current_user( 0 ); 227 228 $request = new WP_REST_Request( 'GET', self::$rest_api_route . self::$block_name ); 229 $request->set_param( 'context', 'edit' ); 230 231 $response = rest_get_server()->dispatch( $request ); 232 233 $this->assertErrorResponse( 'block_cannot_read', $response, rest_authorization_required_code() ); 234 } 235 236 /** 237 * Test getting item without 'edit' context. 238 * 239 * @ticket 45098 240 */ 241 public function test_get_item_with_invalid_context() { 242 wp_set_current_user( self::$user_id ); 243 244 $request = new WP_REST_Request( 'GET', self::$rest_api_route . self::$block_name ); 245 $response = rest_get_server()->dispatch( $request ); 246 247 $this->assertErrorResponse( 'rest_invalid_param', $response, 400 ); 248 } 249 250 /** 251 * Test getting item with invalid block name. 252 * 253 * @ticket 45098 254 * 255 * @covers WP_REST_Block_Renderer_Controller::get_item() 256 */ 257 public function test_get_item_invalid_block_name() { 258 wp_set_current_user( self::$user_id ); 259 $request = new WP_REST_Request( 'GET', self::$rest_api_route . 'core/123' ); 260 261 $request->set_param( 'context', 'edit' ); 262 $response = rest_get_server()->dispatch( $request ); 263 264 $this->assertErrorResponse( 'rest_no_route', $response, 404 ); 265 } 266 267 /** 268 * Check getting item with an invalid param provided. 269 * 270 * @ticket 45098 271 * 272 * @covers WP_REST_Block_Renderer_Controller::get_item() 273 */ 274 public function test_get_item_invalid_attribute() { 275 wp_set_current_user( self::$user_id ); 276 $request = new WP_REST_Request( 'GET', self::$rest_api_route . self::$block_name ); 277 $request->set_param( 'context', 'edit' ); 278 $request->set_param( 279 'attributes', 280 array( 281 'some_string' => array( 'no!' ), 282 ) 283 ); 284 $response = rest_get_server()->dispatch( $request ); 285 $this->assertEquals( 400, $response->get_status() ); 286 } 287 288 /** 289 * Check getting item with an invalid param provided. 290 * 291 * @ticket 45098 292 * 293 * @covers WP_REST_Block_Renderer_Controller::get_item() 294 */ 295 public function test_get_item_unrecognized_attribute() { 296 wp_set_current_user( self::$user_id ); 297 $request = new WP_REST_Request( 'GET', self::$rest_api_route . self::$block_name ); 298 $request->set_param( 'context', 'edit' ); 299 $request->set_param( 300 'attributes', 301 array( 302 'unrecognized' => 'yes', 303 ) 304 ); 305 $response = rest_get_server()->dispatch( $request ); 306 $this->assertEquals( 400, $response->get_status() ); 307 } 308 309 /** 310 * Check getting item with default attributes provided. 311 * 312 * @ticket 45098 313 * 314 * @covers WP_REST_Block_Renderer_Controller::get_item() 315 */ 316 public function test_get_item_default_attributes() { 317 wp_set_current_user( self::$user_id ); 318 319 $block_type = WP_Block_Type_Registry::get_instance()->get_registered( self::$block_name ); 320 $defaults = array(); 321 foreach ( $block_type->attributes as $key => $attribute ) { 322 $defaults[ $key ] = isset( $attribute['default'] ) ? $attribute['default'] : null; 323 } 324 325 $request = new WP_REST_Request( 'GET', self::$rest_api_route . self::$block_name ); 326 $request->set_param( 'context', 'edit' ); 327 $request->set_param( 'attributes', array() ); 328 $response = rest_get_server()->dispatch( $request ); 329 $this->assertEquals( 200, $response->get_status() ); 330 $data = $response->get_data(); 331 332 $this->assertEquals( $defaults, json_decode( $data['rendered'], true ) ); 333 $this->assertEquals( 334 json_decode( $block_type->render( $defaults ) ), 335 json_decode( $data['rendered'] ) 336 ); 337 } 338 339 /** 340 * Check getting item with attributes provided. 341 * 342 * @ticket 45098 343 * 344 * @covers WP_REST_Block_Renderer_Controller::get_item() 345 */ 346 public function test_get_item() { 347 wp_set_current_user( self::$user_id ); 348 349 $block_type = WP_Block_Type_Registry::get_instance()->get_registered( self::$block_name ); 350 $attributes = array( 351 'some_int' => '123', 352 'some_string' => 'foo', 353 'some_array' => array( 1, '2', 3 ), 354 ); 355 356 $expected_attributes = $attributes; 357 $expected_attributes['some_int'] = (int) $expected_attributes['some_int']; 358 $expected_attributes['some_array'] = array_map( 'intval', $expected_attributes['some_array'] ); 359 360 $request = new WP_REST_Request( 'GET', self::$rest_api_route . self::$block_name ); 361 $request->set_param( 'context', 'edit' ); 362 $request->set_param( 'attributes', $attributes ); 363 $response = rest_get_server()->dispatch( $request ); 364 $this->assertEquals( 200, $response->get_status() ); 365 $data = $response->get_data(); 366 367 $this->assertEquals( $expected_attributes, json_decode( $data['rendered'], true ) ); 368 $this->assertEquals( 369 json_decode( $block_type->render( $attributes ), true ), 370 json_decode( $data['rendered'], true ) 371 ); 372 } 373 374 375 376 /** 377 * Check success response for getting item with layout attribute provided. 378 * 379 * @ticket 45098 380 */ 381 public function test_get_item_with_layout() { 382 wp_set_current_user( self::$user_id ); 383 384 $attributes = array( 385 'layout' => 'foo', 386 ); 387 388 $request = new WP_REST_Request( 'GET', self::$rest_api_route . self::$block_name ); 389 $request->set_param( 'context', 'edit' ); 390 $request->set_param( 'attributes', $attributes ); 391 $response = rest_get_server()->dispatch( $request ); 392 $this->assertEquals( 200, $response->get_status() ); 393 } 394 395 /** 396 * Test getting item with post context. 397 * 398 * @ticket 45098 399 */ 400 public function test_get_item_with_post_context() { 401 wp_set_current_user( self::$user_id ); 402 403 $expected_title = 'Test Post'; 404 $request = new WP_REST_Request( 'GET', self::$rest_api_route . self::$context_block_name ); 405 $request->set_param( 'context', 'edit' ); 406 407 // Test without post ID. 408 $response = rest_get_server()->dispatch( $request ); 409 410 $this->assertEquals( 200, $response->get_status() ); 411 $data = $response->get_data(); 412 413 $this->assertTrue( empty( $data['rendered'] ) ); 414 415 // Now test with post ID. 416 $request->set_param( 'post_id', self::$post_id ); 417 $response = rest_get_server()->dispatch( $request ); 418 419 $this->assertEquals( 200, $response->get_status() ); 420 $data = $response->get_data(); 421 422 $this->assertEquals( $expected_title, $data['rendered'] ); 423 } 424 425 /** 426 * Test getting item with invalid post ID. 427 * 428 * @ticket 45098 429 */ 430 public function test_get_item_without_permissions_invalid_post() { 431 wp_set_current_user( self::$user_id ); 432 433 $request = new WP_REST_Request( 'GET', self::$rest_api_route . self::$context_block_name ); 434 $request->set_param( 'context', 'edit' ); 435 436 // Test with invalid post ID. 437 $request->set_param( 'post_id', PHP_INT_MAX ); 438 $response = rest_get_server()->dispatch( $request ); 439 440 $this->assertErrorResponse( 'block_cannot_read', $response, 403 ); 441 } 442 443 /** 444 * Test getting item without permissions to edit context post. 445 * 446 * @ticket 45098 447 */ 448 public function test_get_item_without_permissions_cannot_edit_post() { 449 wp_set_current_user( self::$author_id ); 450 451 $request = new WP_REST_Request( 'GET', self::$rest_api_route . self::$context_block_name ); 452 $request->set_param( 'context', 'edit' ); 453 454 // Test with private post ID. 455 $request->set_param( 'post_id', self::$post_id ); 456 $response = rest_get_server()->dispatch( $request ); 457 458 $this->assertErrorResponse( 'block_cannot_read', $response, 403 ); 459 } 460 461 /** 462 * Get item schema. 463 * 464 * @ticket 45098 465 * 466 * @covers WP_REST_Block_Renderer_Controller::get_item_schema() 467 */ 468 public function test_get_item_schema() { 469 $request = new WP_REST_Request( 'OPTIONS', self::$rest_api_route . self::$block_name ); 470 $response = rest_get_server()->dispatch( $request ); 471 $data = $response->get_data(); 472 473 $this->assertEqualSets( array( 'GET' ), $data['endpoints'][0]['methods'] ); 474 $this->assertEqualSets( 475 array( 'name', 'context', 'attributes', 'post_id' ), 476 array_keys( $data['endpoints'][0]['args'] ) 477 ); 478 $this->assertEquals( 'object', $data['endpoints'][0]['args']['attributes']['type'] ); 479 480 $this->assertArrayHasKey( 'schema', $data ); 481 $this->assertEquals( 'rendered-block', $data['schema']['title'] ); 482 $this->assertEquals( 'object', $data['schema']['type'] ); 483 $this->arrayHasKey( 'rendered', $data['schema']['properties'] ); 484 $this->arrayHasKey( 'string', $data['schema']['properties']['rendered']['type'] ); 485 $this->assertEquals( array( 'edit' ), $data['schema']['properties']['rendered']['context'] ); 486 } 487 488 /** 489 * The update_item() method does not exist for block rendering. 490 */ 491 public function test_update_item() { 492 $this->markTestSkipped( 'Controller does not implement update_item().' ); 493 } 494 495 /** 496 * The create_item() method does not exist for block rendering. 497 */ 498 public function test_create_item() { 499 $this->markTestSkipped( 'Controller does not implement create_item().' ); 500 } 501 502 /** 503 * The delete_item() method does not exist for block rendering. 504 */ 505 public function test_delete_item() { 506 $this->markTestSkipped( 'Controller does not implement delete_item().' ); 507 } 508 509 /** 510 * The get_items() method does not exist for block rendering. 511 */ 512 public function test_get_items() { 513 $this->markTestSkipped( 'Controller does not implement get_items().' ); 514 } 515 516 /** 517 * The context_param() method does not exist for block rendering. 518 */ 519 public function test_context_param() { 520 $this->markTestSkipped( 'Controller does not implement context_param().' ); 521 } 522 523 /** 524 * The prepare_item() method does not exist for block rendering. 525 */ 526 public function test_prepare_item() { 527 $this->markTestSkipped( 'Controller does not implement prepare_item().' ); 528 } 529 } -
new file tests/phpunit/tests/rest-api/rest-blocks-controller.php
diff --git a/tests/phpunit/tests/rest-api/rest-blocks-controller.php b/tests/phpunit/tests/rest-api/rest-blocks-controller.php new file mode 100644 index 0000000000..70798b2756
- + 1 <?php 2 /** 3 * WP_REST_Blocks_Controller tests 4 * 5 * @package WordPress 6 * @subpackage REST_API 7 * @since 5.0.0 8 */ 9 10 /** 11 * Tests for WP_REST_Blocks_Controller. 12 * 13 * @since 5.0.0 14 * 15 * @see WP_Test_REST_Controller_Testcase 16 * 17 * @group restapi-blocks 18 * @group restapi 19 */ 20 class REST_Blocks_Controller_Test extends WP_UnitTestCase { 21 22 /** 23 * Our fake block's post ID. 24 * 25 * @since 5.0.0 26 * 27 * @var int 28 */ 29 protected static $post_id; 30 31 /** 32 * Our fake user's ID. 33 * 34 * @since 5.0.0 35 * 36 * @var int 37 */ 38 protected static $user_id; 39 40 /** 41 * Create fake data before our tests run. 42 * 43 * @since 5.0.0 44 * 45 * @param WP_UnitTest_Factory $factory Helper that lets us create fake data. 46 */ 47 public static function wpSetUpBeforeClass( $factory ) { 48 self::$post_id = wp_insert_post( 49 array( 50 'post_type' => 'wp_block', 51 'post_status' => 'publish', 52 'post_title' => 'My cool block', 53 'post_content' => '<!-- wp:core/paragraph --><p>Hello!</p><!-- /wp:core/paragraph -->', 54 ) 55 ); 56 57 self::$user_id = $factory->user->create( 58 array( 59 'role' => 'editor', 60 ) 61 ); 62 } 63 64 /** 65 * Delete our fake data after our tests run. 66 * 67 * @since 5.0.0 68 */ 69 public static function wpTearDownAfterClass() { 70 wp_delete_post( self::$post_id ); 71 72 self::delete_user( self::$user_id ); 73 } 74 75 /** 76 * Test cases for test_capabilities(). 77 * 78 * @since 5.0.0 79 */ 80 public function data_capabilities() { 81 return array( 82 array( 'create', 'editor', 201 ), 83 array( 'create', 'author', 201 ), 84 array( 'create', 'contributor', 403 ), 85 array( 'create', null, 401 ), 86 87 array( 'read', 'editor', 200 ), 88 array( 'read', 'author', 200 ), 89 array( 'read', 'contributor', 200 ), 90 array( 'read', null, 401 ), 91 92 array( 'update_delete_own', 'editor', 200 ), 93 array( 'update_delete_own', 'author', 200 ), 94 array( 'update_delete_own', 'contributor', 403 ), 95 96 array( 'update_delete_others', 'editor', 200 ), 97 array( 'update_delete_others', 'author', 403 ), 98 array( 'update_delete_others', 'contributor', 403 ), 99 array( 'update_delete_others', null, 401 ), 100 ); 101 } 102 103 /** 104 * Exhaustively check that each role either can or cannot create, edit, 105 * update, and delete reusable blocks. 106 * 107 * @ticket 45098 108 * 109 * @dataProvider data_capabilities 110 * 111 * @param string $action Action to perform in the test. 112 * @param string $role User role to test. 113 * @param int $expected_status Expected HTTP response status. 114 */ 115 public function test_capabilities( $action, $role, $expected_status ) { 116 if ( $role ) { 117 $user_id = $this->factory->user->create( array( 'role' => $role ) ); 118 wp_set_current_user( $user_id ); 119 } else { 120 wp_set_current_user( 0 ); 121 } 122 123 switch ( $action ) { 124 case 'create': 125 $request = new WP_REST_Request( 'POST', '/wp/v2/blocks' ); 126 $request->set_body_params( 127 array( 128 'title' => 'Test', 129 'content' => '<!-- wp:core/paragraph --><p>Test</p><!-- /wp:core/paragraph -->', 130 ) 131 ); 132 133 $response = rest_get_server()->dispatch( $request ); 134 $this->assertEquals( $expected_status, $response->get_status() ); 135 136 break; 137 138 case 'read': 139 $request = new WP_REST_Request( 'GET', '/wp/v2/blocks/' . self::$post_id ); 140 141 $response = rest_get_server()->dispatch( $request ); 142 $this->assertEquals( $expected_status, $response->get_status() ); 143 144 break; 145 146 case 'update_delete_own': 147 $post_id = wp_insert_post( 148 array( 149 'post_type' => 'wp_block', 150 'post_status' => 'publish', 151 'post_title' => 'My cool block', 152 'post_content' => '<!-- wp:core/paragraph --><p>Hello!</p><!-- /wp:core/paragraph -->', 153 'post_author' => $user_id, 154 ) 155 ); 156 157 $request = new WP_REST_Request( 'PUT', '/wp/v2/blocks/' . $post_id ); 158 $request->set_body_params( 159 array( 160 'title' => 'Test', 161 'content' => '<!-- wp:core/paragraph --><p>Test</p><!-- /wp:core/paragraph -->', 162 ) 163 ); 164 165 $response = rest_get_server()->dispatch( $request ); 166 $this->assertEquals( $expected_status, $response->get_status() ); 167 168 $request = new WP_REST_Request( 'DELETE', '/wp/v2/blocks/' . $post_id ); 169 170 $response = rest_get_server()->dispatch( $request ); 171 $this->assertEquals( $expected_status, $response->get_status() ); 172 173 wp_delete_post( $post_id ); 174 175 break; 176 177 case 'update_delete_others': 178 $request = new WP_REST_Request( 'PUT', '/wp/v2/blocks/' . self::$post_id ); 179 $request->set_body_params( 180 array( 181 'title' => 'Test', 182 'content' => '<!-- wp:core/paragraph --><p>Test</p><!-- /wp:core/paragraph -->', 183 ) 184 ); 185 186 $response = rest_get_server()->dispatch( $request ); 187 $this->assertEquals( $expected_status, $response->get_status() ); 188 189 $request = new WP_REST_Request( 'DELETE', '/wp/v2/blocks/' . self::$post_id ); 190 191 $response = rest_get_server()->dispatch( $request ); 192 $this->assertEquals( $expected_status, $response->get_status() ); 193 194 break; 195 196 default: 197 $this->fail( "'$action' is not a valid action." ); 198 } 199 200 if ( isset( $user_id ) ) { 201 self::delete_user( $user_id ); 202 } 203 } 204 } -
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 70330b7f03..e9de00aa4f 100644
a b class WP_Test_REST_Schema_Initialization extends WP_Test_REST_TestCase { 99 99 '/wp/v2/pages/(?P<parent>[\\d]+)/autosaves/(?P<id>[\\d]+)', 100 100 '/wp/v2/media', 101 101 '/wp/v2/media/(?P<id>[\\d]+)', 102 '/wp/v2/blocks', 103 '/wp/v2/blocks/(?P<id>[\d]+)', 104 '/wp/v2/blocks/(?P<parent>[\d]+)/autosaves', 105 '/wp/v2/blocks/(?P<parent>[\d]+)/autosaves/(?P<id>[\d]+)', 102 106 '/wp/v2/types', 103 107 '/wp/v2/types/(?P<type>[\\w-]+)', 104 108 '/wp/v2/statuses', -
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 8a236da00d..8576875105 100644
a b mockedApiResponse.Schema = { 2271 2271 } 2272 2272 ] 2273 2273 }, 2274 "/wp/v2/blocks": { 2275 "namespace": "wp/v2", 2276 "methods": [ 2277 "GET", 2278 "POST" 2279 ], 2280 "endpoints": [ 2281 { 2282 "methods": [ 2283 "GET" 2284 ], 2285 "args": { 2286 "context": { 2287 "required": false, 2288 "default": "view", 2289 "enum": [ 2290 "view", 2291 "embed", 2292 "edit" 2293 ], 2294 "description": "Scope under which the request is made; determines fields present in response.", 2295 "type": "string" 2296 }, 2297 "page": { 2298 "required": false, 2299 "default": 1, 2300 "description": "Current page of the collection.", 2301 "type": "integer" 2302 }, 2303 "per_page": { 2304 "required": false, 2305 "default": 10, 2306 "description": "Maximum number of items to be returned in result set.", 2307 "type": "integer" 2308 }, 2309 "search": { 2310 "required": false, 2311 "description": "Limit results to those matching a string.", 2312 "type": "string" 2313 }, 2314 "after": { 2315 "required": false, 2316 "description": "Limit response to posts published after a given ISO8601 compliant date.", 2317 "type": "string" 2318 }, 2319 "before": { 2320 "required": false, 2321 "description": "Limit response to posts published before a given ISO8601 compliant date.", 2322 "type": "string" 2323 }, 2324 "exclude": { 2325 "required": false, 2326 "default": [], 2327 "description": "Ensure result set excludes specific IDs.", 2328 "type": "array", 2329 "items": { 2330 "type": "integer" 2331 } 2332 }, 2333 "include": { 2334 "required": false, 2335 "default": [], 2336 "description": "Limit result set to specific IDs.", 2337 "type": "array", 2338 "items": { 2339 "type": "integer" 2340 } 2341 }, 2342 "offset": { 2343 "required": false, 2344 "description": "Offset the result set by a specific number of items.", 2345 "type": "integer" 2346 }, 2347 "order": { 2348 "required": false, 2349 "default": "desc", 2350 "enum": [ 2351 "asc", 2352 "desc" 2353 ], 2354 "description": "Order sort attribute ascending or descending.", 2355 "type": "string" 2356 }, 2357 "orderby": { 2358 "required": false, 2359 "default": "date", 2360 "enum": [ 2361 "author", 2362 "date", 2363 "id", 2364 "include", 2365 "modified", 2366 "parent", 2367 "relevance", 2368 "slug", 2369 "include_slugs", 2370 "title" 2371 ], 2372 "description": "Sort collection by object attribute.", 2373 "type": "string" 2374 }, 2375 "slug": { 2376 "required": false, 2377 "description": "Limit result set to posts with one or more specific slugs.", 2378 "type": "array", 2379 "items": { 2380 "type": "string" 2381 } 2382 }, 2383 "status": { 2384 "required": false, 2385 "default": "publish", 2386 "description": "Limit result set to posts assigned one or more statuses.", 2387 "type": "array", 2388 "items": { 2389 "enum": [ 2390 "publish", 2391 "future", 2392 "draft", 2393 "pending", 2394 "private", 2395 "trash", 2396 "auto-draft", 2397 "inherit", 2398 "request-pending", 2399 "request-confirmed", 2400 "request-failed", 2401 "request-completed", 2402 "any" 2403 ], 2404 "type": "string" 2405 } 2406 } 2407 } 2408 }, 2409 { 2410 "methods": [ 2411 "POST" 2412 ], 2413 "args": { 2414 "date": { 2415 "required": false, 2416 "description": "The date the object was published, in the site's timezone.", 2417 "type": "string" 2418 }, 2419 "date_gmt": { 2420 "required": false, 2421 "description": "The date the object was published, as GMT.", 2422 "type": "string" 2423 }, 2424 "slug": { 2425 "required": false, 2426 "description": "An alphanumeric identifier for the object unique to its type.", 2427 "type": "string" 2428 }, 2429 "status": { 2430 "required": false, 2431 "enum": [ 2432 "publish", 2433 "future", 2434 "draft", 2435 "pending", 2436 "private" 2437 ], 2438 "description": "A named status for the object.", 2439 "type": "string" 2440 }, 2441 "password": { 2442 "required": false, 2443 "description": "A password to protect access to the content and excerpt.", 2444 "type": "string" 2445 }, 2446 "title": { 2447 "required": false, 2448 "description": "The title for the object.", 2449 "type": "object" 2450 }, 2451 "content": { 2452 "required": false, 2453 "description": "The content for the object.", 2454 "type": "object" 2455 }, 2456 "template": { 2457 "required": false, 2458 "description": "The theme file to use to display the object.", 2459 "type": "string" 2460 } 2461 } 2462 } 2463 ], 2464 "_links": { 2465 "self": "http://example.org/index.php?rest_route=/wp/v2/blocks" 2466 } 2467 }, 2468 "/wp/v2/blocks/(?P<id>[\\d]+)": { 2469 "namespace": "wp/v2", 2470 "methods": [ 2471 "GET", 2472 "POST", 2473 "PUT", 2474 "PATCH", 2475 "DELETE" 2476 ], 2477 "endpoints": [ 2478 { 2479 "methods": [ 2480 "GET" 2481 ], 2482 "args": { 2483 "id": { 2484 "required": false, 2485 "description": "Unique identifier for the object.", 2486 "type": "integer" 2487 }, 2488 "context": { 2489 "required": false, 2490 "default": "view", 2491 "enum": [ 2492 "view", 2493 "embed", 2494 "edit" 2495 ], 2496 "description": "Scope under which the request is made; determines fields present in response.", 2497 "type": "string" 2498 }, 2499 "password": { 2500 "required": false, 2501 "description": "The password for the post if it is password protected.", 2502 "type": "string" 2503 } 2504 } 2505 }, 2506 { 2507 "methods": [ 2508 "POST", 2509 "PUT", 2510 "PATCH" 2511 ], 2512 "args": { 2513 "id": { 2514 "required": false, 2515 "description": "Unique identifier for the object.", 2516 "type": "integer" 2517 }, 2518 "date": { 2519 "required": false, 2520 "description": "The date the object was published, in the site's timezone.", 2521 "type": "string" 2522 }, 2523 "date_gmt": { 2524 "required": false, 2525 "description": "The date the object was published, as GMT.", 2526 "type": "string" 2527 }, 2528 "slug": { 2529 "required": false, 2530 "description": "An alphanumeric identifier for the object unique to its type.", 2531 "type": "string" 2532 }, 2533 "status": { 2534 "required": false, 2535 "enum": [ 2536 "publish", 2537 "future", 2538 "draft", 2539 "pending", 2540 "private" 2541 ], 2542 "description": "A named status for the object.", 2543 "type": "string" 2544 }, 2545 "password": { 2546 "required": false, 2547 "description": "A password to protect access to the content and excerpt.", 2548 "type": "string" 2549 }, 2550 "title": { 2551 "required": false, 2552 "description": "The title for the object.", 2553 "type": "object" 2554 }, 2555 "content": { 2556 "required": false, 2557 "description": "The content for the object.", 2558 "type": "object" 2559 }, 2560 "template": { 2561 "required": false, 2562 "description": "The theme file to use to display the object.", 2563 "type": "string" 2564 } 2565 } 2566 }, 2567 { 2568 "methods": [ 2569 "DELETE" 2570 ], 2571 "args": { 2572 "id": { 2573 "required": false, 2574 "description": "Unique identifier for the object.", 2575 "type": "integer" 2576 }, 2577 "force": { 2578 "required": false, 2579 "default": false, 2580 "description": "Whether to bypass trash and force deletion.", 2581 "type": "boolean" 2582 } 2583 } 2584 } 2585 ] 2586 }, 2587 "/wp/v2/blocks/(?P<parent>[\\d]+)/autosaves": { 2588 "namespace": "wp/v2", 2589 "methods": [ 2590 "GET", 2591 "POST" 2592 ], 2593 "endpoints": [ 2594 { 2595 "methods": [ 2596 "GET" 2597 ], 2598 "args": { 2599 "parent": { 2600 "required": false, 2601 "description": "The ID for the parent of the object.", 2602 "type": "integer" 2603 }, 2604 "context": { 2605 "required": false, 2606 "default": "view", 2607 "enum": [ 2608 "view", 2609 "embed", 2610 "edit" 2611 ], 2612 "description": "Scope under which the request is made; determines fields present in response.", 2613 "type": "string" 2614 }, 2615 "page": { 2616 "required": false, 2617 "default": 1, 2618 "description": "Current page of the collection.", 2619 "type": "integer" 2620 }, 2621 "per_page": { 2622 "required": false, 2623 "description": "Maximum number of items to be returned in result set.", 2624 "type": "integer" 2625 }, 2626 "search": { 2627 "required": false, 2628 "description": "Limit results to those matching a string.", 2629 "type": "string" 2630 }, 2631 "exclude": { 2632 "required": false, 2633 "default": [], 2634 "description": "Ensure result set excludes specific IDs.", 2635 "type": "array", 2636 "items": { 2637 "type": "integer" 2638 } 2639 }, 2640 "include": { 2641 "required": false, 2642 "default": [], 2643 "description": "Limit result set to specific IDs.", 2644 "type": "array", 2645 "items": { 2646 "type": "integer" 2647 } 2648 }, 2649 "offset": { 2650 "required": false, 2651 "description": "Offset the result set by a specific number of items.", 2652 "type": "integer" 2653 }, 2654 "order": { 2655 "required": false, 2656 "default": "desc", 2657 "enum": [ 2658 "asc", 2659 "desc" 2660 ], 2661 "description": "Order sort attribute ascending or descending.", 2662 "type": "string" 2663 }, 2664 "orderby": { 2665 "required": false, 2666 "default": "date", 2667 "enum": [ 2668 "date", 2669 "id", 2670 "include", 2671 "relevance", 2672 "slug", 2673 "include_slugs", 2674 "title" 2675 ], 2676 "description": "Sort collection by object attribute.", 2677 "type": "string" 2678 } 2679 } 2680 }, 2681 { 2682 "methods": [ 2683 "POST" 2684 ], 2685 "args": { 2686 "parent": { 2687 "required": false, 2688 "description": "The ID for the parent of the object.", 2689 "type": "integer" 2690 }, 2691 "author": { 2692 "required": false, 2693 "description": "The ID for the author of the object.", 2694 "type": "integer" 2695 }, 2696 "date": { 2697 "required": false, 2698 "description": "The date the object was published, in the site's timezone.", 2699 "type": "string" 2700 }, 2701 "date_gmt": { 2702 "required": false, 2703 "description": "The date the object was published, as GMT.", 2704 "type": "string" 2705 }, 2706 "id": { 2707 "required": false, 2708 "description": "Unique identifier for the object.", 2709 "type": "integer" 2710 }, 2711 "modified": { 2712 "required": false, 2713 "description": "The date the object was last modified, in the site's timezone.", 2714 "type": "string" 2715 }, 2716 "modified_gmt": { 2717 "required": false, 2718 "description": "The date the object was last modified, as GMT.", 2719 "type": "string" 2720 }, 2721 "slug": { 2722 "required": false, 2723 "description": "An alphanumeric identifier for the object unique to its type.", 2724 "type": "string" 2725 }, 2726 "title": { 2727 "required": false, 2728 "description": "The title for the object.", 2729 "type": "object" 2730 }, 2731 "content": { 2732 "required": false, 2733 "description": "The content for the object.", 2734 "type": "object" 2735 } 2736 } 2737 } 2738 ] 2739 }, 2740 "/wp/v2/blocks/(?P<parent>[\\d]+)/autosaves/(?P<id>[\\d]+)": { 2741 "namespace": "wp/v2", 2742 "methods": [ 2743 "GET" 2744 ], 2745 "endpoints": [ 2746 { 2747 "methods": [ 2748 "GET" 2749 ], 2750 "args": { 2751 "parent": { 2752 "required": false, 2753 "description": "The ID for the parent of the object.", 2754 "type": "integer" 2755 }, 2756 "id": { 2757 "required": false, 2758 "description": "The ID for the object.", 2759 "type": "integer" 2760 }, 2761 "context": { 2762 "required": false, 2763 "default": "view", 2764 "enum": [ 2765 "view", 2766 "embed", 2767 "edit" 2768 ], 2769 "description": "Scope under which the request is made; determines fields present in response.", 2770 "type": "string" 2771 } 2772 } 2773 } 2774 ] 2775 }, 2274 2776 "/wp/v2/types": { 2275 2777 "namespace": "wp/v2", 2276 2778 "methods": [ … … mockedApiResponse.Schema = { 3862 4364 "self": "http://example.org/index.php?rest_route=/wp/v2/search" 3863 4365 } 3864 4366 }, 4367 "/wp/v2/block-renderer/(?P<name>core/block)": { 4368 "namespace": "wp/v2", 4369 "methods": [ 4370 "GET" 4371 ], 4372 "endpoints": [ 4373 { 4374 "methods": [ 4375 "GET" 4376 ], 4377 "args": { 4378 "name": { 4379 "required": false, 4380 "description": "Unique registered name for the block.", 4381 "type": "string" 4382 }, 4383 "context": { 4384 "required": false, 4385 "default": "view", 4386 "enum": [ 4387 "edit" 4388 ], 4389 "description": "Scope under which the request is made; determines fields present in response.", 4390 "type": "string" 4391 }, 4392 "attributes": { 4393 "required": false, 4394 "description": "Attributes for core/block block", 4395 "type": "object" 4396 }, 4397 "post_id": { 4398 "required": false, 4399 "description": "ID of the post context.", 4400 "type": "integer" 4401 } 4402 } 4403 } 4404 ] 4405 }, 4406 "/wp/v2/block-renderer/(?P<name>core/latest-comments)": { 4407 "namespace": "wp/v2", 4408 "methods": [ 4409 "GET" 4410 ], 4411 "endpoints": [ 4412 { 4413 "methods": [ 4414 "GET" 4415 ], 4416 "args": { 4417 "name": { 4418 "required": false, 4419 "description": "Unique registered name for the block.", 4420 "type": "string" 4421 }, 4422 "context": { 4423 "required": false, 4424 "default": "view", 4425 "enum": [ 4426 "edit" 4427 ], 4428 "description": "Scope under which the request is made; determines fields present in response.", 4429 "type": "string" 4430 }, 4431 "attributes": { 4432 "required": false, 4433 "description": "Attributes for core/latest-comments block", 4434 "type": "object" 4435 }, 4436 "post_id": { 4437 "required": false, 4438 "description": "ID of the post context.", 4439 "type": "integer" 4440 } 4441 } 4442 } 4443 ] 4444 }, 4445 "/wp/v2/block-renderer/(?P<name>core/archives)": { 4446 "namespace": "wp/v2", 4447 "methods": [ 4448 "GET" 4449 ], 4450 "endpoints": [ 4451 { 4452 "methods": [ 4453 "GET" 4454 ], 4455 "args": { 4456 "name": { 4457 "required": false, 4458 "description": "Unique registered name for the block.", 4459 "type": "string" 4460 }, 4461 "context": { 4462 "required": false, 4463 "default": "view", 4464 "enum": [ 4465 "edit" 4466 ], 4467 "description": "Scope under which the request is made; determines fields present in response.", 4468 "type": "string" 4469 }, 4470 "attributes": { 4471 "required": false, 4472 "description": "Attributes for core/archives block", 4473 "type": "object" 4474 }, 4475 "post_id": { 4476 "required": false, 4477 "description": "ID of the post context.", 4478 "type": "integer" 4479 } 4480 } 4481 } 4482 ] 4483 }, 4484 "/wp/v2/block-renderer/(?P<name>core/categories)": { 4485 "namespace": "wp/v2", 4486 "methods": [ 4487 "GET" 4488 ], 4489 "endpoints": [ 4490 { 4491 "methods": [ 4492 "GET" 4493 ], 4494 "args": { 4495 "name": { 4496 "required": false, 4497 "description": "Unique registered name for the block.", 4498 "type": "string" 4499 }, 4500 "context": { 4501 "required": false, 4502 "default": "view", 4503 "enum": [ 4504 "edit" 4505 ], 4506 "description": "Scope under which the request is made; determines fields present in response.", 4507 "type": "string" 4508 }, 4509 "attributes": { 4510 "required": false, 4511 "description": "Attributes for core/categories block", 4512 "type": "object" 4513 }, 4514 "post_id": { 4515 "required": false, 4516 "description": "ID of the post context.", 4517 "type": "integer" 4518 } 4519 } 4520 } 4521 ] 4522 }, 4523 "/wp/v2/block-renderer/(?P<name>core/latest-posts)": { 4524 "namespace": "wp/v2", 4525 "methods": [ 4526 "GET" 4527 ], 4528 "endpoints": [ 4529 { 4530 "methods": [ 4531 "GET" 4532 ], 4533 "args": { 4534 "name": { 4535 "required": false, 4536 "description": "Unique registered name for the block.", 4537 "type": "string" 4538 }, 4539 "context": { 4540 "required": false, 4541 "default": "view", 4542 "enum": [ 4543 "edit" 4544 ], 4545 "description": "Scope under which the request is made; determines fields present in response.", 4546 "type": "string" 4547 }, 4548 "attributes": { 4549 "required": false, 4550 "description": "Attributes for core/latest-posts block", 4551 "type": "object" 4552 }, 4553 "post_id": { 4554 "required": false, 4555 "description": "ID of the post context.", 4556 "type": "integer" 4557 } 4558 } 4559 } 4560 ] 4561 }, 4562 "/wp/v2/block-renderer/(?P<name>core/shortcode)": { 4563 "namespace": "wp/v2", 4564 "methods": [ 4565 "GET" 4566 ], 4567 "endpoints": [ 4568 { 4569 "methods": [ 4570 "GET" 4571 ], 4572 "args": { 4573 "name": { 4574 "required": false, 4575 "description": "Unique registered name for the block.", 4576 "type": "string" 4577 }, 4578 "context": { 4579 "required": false, 4580 "default": "view", 4581 "enum": [ 4582 "edit" 4583 ], 4584 "description": "Scope under which the request is made; determines fields present in response.", 4585 "type": "string" 4586 }, 4587 "attributes": { 4588 "required": false, 4589 "description": "Attributes for core/shortcode block", 4590 "type": "object" 4591 }, 4592 "post_id": { 4593 "required": false, 4594 "description": "ID of the post context.", 4595 "type": "integer" 4596 } 4597 } 4598 } 4599 ] 4600 }, 3865 4601 "/wp/v2/settings": { 3866 4602 "namespace": "wp/v2", 3867 4603 "methods": [ … … mockedApiResponse.postRevisions = [ 4339 5075 } 4340 5076 }, 4341 5077 { 4342 "author": 389,5078 "author": 404, 4343 5079 "date": "2017-02-14T00:00:00", 4344 5080 "date_gmt": "2017-02-14T00:00:00", 4345 "id": 3671 0,5081 "id": 36717, 4346 5082 "modified": "2017-02-14T00:00:00", 4347 5083 "modified_gmt": "2017-02-14T00:00:00", 4348 "parent": 367 09,4349 "slug": "367 09-revision-v1",5084 "parent": 36716, 5085 "slug": "36716-revision-v1", 4350 5086 "guid": { 4351 "rendered": "http://example.org/?p=3671 0"5087 "rendered": "http://example.org/?p=36717" 4352 5088 }, 4353 5089 "title": { 4354 5090 "rendered": "REST API Client Fixture: Post" … … mockedApiResponse.postRevisions = [ 4362 5098 "_links": { 4363 5099 "parent": [ 4364 5100 { 4365 "href": "http://example.org/index.php?rest_route=/wp/v2/posts/367 09"5101 "href": "http://example.org/index.php?rest_route=/wp/v2/posts/36716" 4366 5102 } 4367 5103 ] 4368 5104 } … … mockedApiResponse.revision = { 4394 5130 4395 5131 mockedApiResponse.postAutosaves = [ 4396 5132 { 4397 "author": 389,5133 "author": 404, 4398 5134 "date": "2017-02-14T00:00:00", 4399 5135 "date_gmt": "2017-02-14T00:00:00", 4400 "id": 3671 1,5136 "id": 36718, 4401 5137 "modified": "2017-02-14T00:00:00", 4402 5138 "modified_gmt": "2017-02-14T00:00:00", 4403 "parent": 367 09,4404 "slug": "367 09-autosave-v1",5139 "parent": 36716, 5140 "slug": "36716-autosave-v1", 4405 5141 "guid": { 4406 "rendered": "http://example.org/?p=3671 1"5142 "rendered": "http://example.org/?p=36718" 4407 5143 }, 4408 5144 "title": { 4409 5145 "rendered": "" … … mockedApiResponse.postAutosaves = [ 4417 5153 "_links": { 4418 5154 "parent": [ 4419 5155 { 4420 "href": "http://example.org/index.php?rest_route=/wp/v2/posts/367 09"5156 "href": "http://example.org/index.php?rest_route=/wp/v2/posts/36716" 4421 5157 } 4422 5158 ] 4423 5159 } … … mockedApiResponse.postAutosaves = [ 4425 5161 ]; 4426 5162 4427 5163 mockedApiResponse.autosave = { 4428 "author": 389,5164 "author": 404, 4429 5165 "date": "2017-02-14T00:00:00", 4430 5166 "date_gmt": "2017-02-14T00:00:00", 4431 "id": 3671 1,5167 "id": 36718, 4432 5168 "modified": "2017-02-14T00:00:00", 4433 5169 "modified_gmt": "2017-02-14T00:00:00", 4434 "parent": 367 09,4435 "slug": "367 09-autosave-v1",5170 "parent": 36716, 5171 "slug": "36716-autosave-v1", 4436 5172 "guid": { 4437 "rendered": "http://example.org/?p=3671 1"5173 "rendered": "http://example.org/?p=36718" 4438 5174 }, 4439 5175 "title": { 4440 5176 "rendered": "" … … mockedApiResponse.pageRevisions = [ 4599 5335 } 4600 5336 }, 4601 5337 { 4602 "author": 389,5338 "author": 404, 4603 5339 "date": "2017-02-14T00:00:00", 4604 5340 "date_gmt": "2017-02-14T00:00:00", 4605 "id": 367 13,5341 "id": 36720, 4606 5342 "modified": "2017-02-14T00:00:00", 4607 5343 "modified_gmt": "2017-02-14T00:00:00", 4608 "parent": 3671 2,4609 "slug": "3671 2-revision-v1",5344 "parent": 36719, 5345 "slug": "36719-revision-v1", 4610 5346 "guid": { 4611 "rendered": "http://example.org/?p=367 13"5347 "rendered": "http://example.org/?p=36720" 4612 5348 }, 4613 5349 "title": { 4614 5350 "rendered": "REST API Client Fixture: Page" … … mockedApiResponse.pageRevisions = [ 4622 5358 "_links": { 4623 5359 "parent": [ 4624 5360 { 4625 "href": "http://example.org/index.php?rest_route=/wp/v2/pages/3671 2"5361 "href": "http://example.org/index.php?rest_route=/wp/v2/pages/36719" 4626 5362 } 4627 5363 ] 4628 5364 } … … mockedApiResponse.pageRevision = { 4654 5390 4655 5391 mockedApiResponse.pageAutosaves = [ 4656 5392 { 4657 "author": 389,5393 "author": 404, 4658 5394 "date": "2017-02-14T00:00:00", 4659 5395 "date_gmt": "2017-02-14T00:00:00", 4660 "id": 367 14,5396 "id": 36721, 4661 5397 "modified": "2017-02-14T00:00:00", 4662 5398 "modified_gmt": "2017-02-14T00:00:00", 4663 "parent": 3671 2,4664 "slug": "3671 2-autosave-v1",5399 "parent": 36719, 5400 "slug": "36719-autosave-v1", 4665 5401 "guid": { 4666 "rendered": "http://example.org/?p=367 14"5402 "rendered": "http://example.org/?p=36721" 4667 5403 }, 4668 5404 "title": { 4669 5405 "rendered": "" … … mockedApiResponse.pageAutosaves = [ 4677 5413 "_links": { 4678 5414 "parent": [ 4679 5415 { 4680 "href": "http://example.org/index.php?rest_route=/wp/v2/pages/3671 2"5416 "href": "http://example.org/index.php?rest_route=/wp/v2/pages/36719" 4681 5417 } 4682 5418 ] 4683 5419 } … … mockedApiResponse.pageAutosaves = [ 4685 5421 ]; 4686 5422 4687 5423 mockedApiResponse.pageAutosave = { 4688 "author": 389,5424 "author": 404, 4689 5425 "date": "2017-02-14T00:00:00", 4690 5426 "date_gmt": "2017-02-14T00:00:00", 4691 "id": 367 14,5427 "id": 36721, 4692 5428 "modified": "2017-02-14T00:00:00", 4693 5429 "modified_gmt": "2017-02-14T00:00:00", 4694 "parent": 3671 2,4695 "slug": "3671 2-autosave-v1",5430 "parent": 36719, 5431 "slug": "36719-autosave-v1", 4696 5432 "guid": { 4697 "rendered": "http://example.org/?p=367 14"5433 "rendered": "http://example.org/?p=36721" 4698 5434 }, 4699 5435 "title": { 4700 5436 "rendered": "" … … mockedApiResponse.TypesCollection = { 4890 5626 } 4891 5627 ] 4892 5628 } 5629 }, 5630 "wp_block": { 5631 "description": "", 5632 "hierarchical": false, 5633 "name": "Blocks", 5634 "slug": "wp_block", 5635 "taxonomies": [], 5636 "rest_base": "blocks", 5637 "_links": { 5638 "collection": [ 5639 { 5640 "href": "http://example.org/index.php?rest_route=/wp/v2/types" 5641 } 5642 ], 5643 "wp:items": [ 5644 { 5645 "href": "http://example.org/index.php?rest_route=/wp/v2/blocks" 5646 } 5647 ], 5648 "curies": [ 5649 { 5650 "name": "wp", 5651 "href": "https://api.w.org/{rel}", 5652 "templated": true 5653 } 5654 ] 5655 } 4893 5656 } 4894 5657 }; 4895 5658