Changeset 62952
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php
r62928 r62952 596 596 * @since 4.7.0 597 597 * @since 5.9.0 Renamed `$post` to `$item` to match parent class for PHP 8 named parameter support. 598 * 599 * @global WP_Post $post Global post object. 598 * @since 7.1.0 The global post is now restored to its previous value before returning. 599 * 600 * @global WP_Post|null $post Global post object. 600 601 * 601 602 * @param WP_Post $item Post revision object. … … 604 605 */ 605 606 public function prepare_item_for_response( $item, $request ) { 607 /* 608 * Save the previous global post so it can be restored before returning. 609 * Preparing the revision sets up the global post and post data, which 610 * must not leak into the rest of the request (e.g. the autosaves endpoint 611 * is preloaded in the block editor, where a leaked global post can cause 612 * the editor to be initialized with the wrong post). 613 * 614 * Note that $post is intentionally not declared as a global here. It must 615 * remain local to this method so that a filter which reassigns the global 616 * post while the response is being prepared (for example on 'the_content') 617 * cannot change which post the remaining fields are read from. 618 */ 619 $previous_post = isset( $GLOBALS['post'] ) && $GLOBALS['post'] instanceof WP_Post ? $GLOBALS['post'] : null; 620 606 621 // Restores the more descriptive, specific name for use within this method. 607 622 $post = $item; … … 614 629 if ( $request->is_method( 'HEAD' ) ) { 615 630 /** This filter is documented in wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php */ 616 return apply_filters( 'rest_prepare_revision', new WP_REST_Response( array() ), $post, $request ); 631 $response = apply_filters( 'rest_prepare_revision', new WP_REST_Response( array() ), $post, $request ); 632 633 $this->restore_post_data( $previous_post ); 634 635 return $response; 617 636 } 618 637 … … 718 737 * @param WP_REST_Request $request Request used to generate the response. 719 738 */ 720 return apply_filters( 'rest_prepare_revision', $response, $post, $request ); 739 $response = apply_filters( 'rest_prepare_revision', $response, $post, $request ); 740 741 $this->restore_post_data( $previous_post ); 742 743 return $response; 744 } 745 746 /** 747 * Restores the global post to its previous value after preparing a revision. 748 * 749 * Preparing a revision overwrites the global post and post data via 750 * setup_postdata(). This restores the global post that was in place 751 * beforehand so the change does not leak into the rest of the request. 752 * 753 * Only the global post is guaranteed to be restored. When there was no 754 * previous global post and the main query has no post either, which is the 755 * usual state during a REST request, wp_reset_postdata() has nothing to 756 * restore from, so the remaining globals set by setup_postdata() (such as 757 * $id, $authordata and $pages) are left describing the revision. Clearing 758 * those would mean unsetting each one by hand, which is beyond what is 759 * needed to keep the global post from leaking. 760 * 761 * @since 7.1.0 762 * 763 * @param WP_Post|null $previous_post The global post to restore, or null if there was none. 764 */ 765 private function restore_post_data( ?WP_Post $previous_post ): void { 766 if ( $previous_post ) { 767 $GLOBALS['post'] = $previous_post; 768 setup_postdata( $previous_post ); 769 return; 770 } 771 772 /* 773 * There was no global post to restore, so clear the revision's post data. 774 * This runs before clearing the global post because wp_reset_postdata() 775 * repopulates it from the main query whenever that query has a post. Note 776 * that it is a no-op when the main query has no post, in which case only 777 * the global post below is cleared. 778 */ 779 wp_reset_postdata(); 780 781 /* 782 * Assigned rather than unset so that any `global $post` binding made before 783 * this request keeps pointing at the global. Unsetting removes the entry from 784 * the symbol table, which detaches those bindings, and a later write through 785 * one of them would no longer be visible to get_post(). 786 */ 787 $GLOBALS['post'] = null; 721 788 } 722 789 -
trunk/tests/phpunit/tests/rest-api/rest-autosaves-controller.php
r62334 r62952 10 10 */ 11 11 class WP_Test_REST_Autosaves_Controller extends WP_Test_REST_Post_Type_Controller_Testcase { 12 protected static $post_id;13 protected static $page_id;14 protected static $draft_page_id;15 16 protected static $autosave_post_id;17 protected static $autosave_page_id;18 19 protected static $editor_id;20 protected static $contributor_id;21 22 protected static $parent_page_id;23 protected static $child_page_id;24 protected static $child_draft_page_id;25 26 private $post_autosave;12 protected static int $post_id; 13 protected static int $page_id; 14 protected static int $draft_page_id; 15 16 protected static int $autosave_post_id; 17 protected static int $autosave_page_id; 18 19 protected static int $editor_id; 20 protected static int $contributor_id; 21 22 protected static int $parent_page_id; 23 protected static int $child_page_id; 24 protected static int $child_draft_page_id; 25 26 private WP_Post $post_autosave; 27 27 28 28 protected function set_post_data( $args = array() ) { … … 732 732 } 733 733 734 public function test_get_item_sets_up_postdata() { 735 wp_set_current_user( self::$editor_id ); 736 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id ); 737 rest_get_server()->dispatch( $request ); 738 739 $post = get_post(); 740 $parent_post_id = wp_is_post_revision( $post->ID ); 741 742 $this->assertSame( $post->ID, self::$autosave_post_id ); 743 $this->assertSame( $parent_post_id, self::$post_id ); 734 /** 735 * The autosave's postdata should be set up while preparing the response, 736 * so rendered fields reflect the autosave, without leaking into the global 737 * post after the request completes. 738 * 739 * @ticket 65495 740 * 741 * @global int|null $id ID from the set up global post data. 742 * 743 * @covers WP_REST_Autosaves_Controller::prepare_item_for_response 744 */ 745 public function test_get_item_sets_up_postdata_without_leaking_global_post() { 746 global $id; 747 748 // Populate the global $wp_query with the post and set it up. 749 wp_set_current_user( self::$editor_id ); 750 query_posts( array( 'p' => self::$post_id ) ); 751 the_post(); 752 753 // Assert initial state. 754 $post = get_post(); 755 $this->assertInstanceOf( WP_Post::class, $post, 'The global post should be set up before the request.' ); 756 $this->assertSame( self::$post_id, $post->ID, 'The global post should be the parent post before the request.' ); 757 $this->assertSame( self::$post_id, $id, 'The global $id should be the parent post ID before the request.' ); 758 759 // Make the request to get the autosave. 760 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/autosaves/' . self::$autosave_post_id ); 761 $response = rest_get_server()->dispatch( $request ); 762 $this->assertSame( 200, $response->get_status() ); 763 $data = $response->get_data(); 764 $this->assertIsArray( $data ); 765 $this->assertArrayHasKey( 'title', $data ); 766 $this->assertIsArray( $data['title'] ); 767 $this->assertSame( get_the_title( self::$autosave_post_id ), $data['title']['rendered'], 'Expected the rendered title to reflect the autosave, proving postdata was set up during preparation.' ); 768 769 // The global post is restored to the post that was set before the request. 770 $post = get_post(); 771 $this->assertInstanceOf( WP_Post::class, $post, 'The global post should still be set after the request.' ); 772 $this->assertSame( self::$post_id, $post->ID, 'The global post should be restored to the post that was set before the request.' ); 773 $this->assertSame( self::$post_id, $id, 'The global $id should be restored to the post that was set before the request.' ); 744 774 } 745 775 -
trunk/tests/phpunit/tests/rest-api/rest-revisions-controller.php
r59985 r62952 9 9 */ 10 10 class WP_Test_REST_Revisions_Controller extends WP_Test_REST_Controller_Testcase { 11 protected static $post_id; 12 protected static $post_id_2; 13 protected static $page_id; 14 15 protected static $editor_id; 16 protected static $contributor_id; 17 18 private $total_revisions; 11 protected static int $post_id; 12 protected static int $post_id_2; 13 protected static int $page_id; 14 15 protected static int $editor_id; 16 protected static int $contributor_id; 17 18 private int $total_revisions; 19 19 20 private $revisions; 20 private $revision_1; 21 private $revision_id1; 22 private $revision_2; 23 private $revision_id2; 24 private $revision_3; 25 private $revision_id3; 26 private $revision_2_1_id; 21 22 private WP_Post $revision_1; 23 private int $revision_id1; 24 private WP_Post $revision_2; 25 private int $revision_id2; 26 private WP_Post $revision_3; 27 private int $revision_id3; 28 private int $revision_2_1_id; 27 29 28 30 public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) { … … 265 267 $this->assertSameSets( $fields, array_keys( $data ) ); 266 268 $this->assertSame( self::$editor_id, $data['author'] ); 269 } 270 271 /** 272 * Preparing a revision must not leak the revision into the global post. 273 * 274 * @ticket 65495 275 * 276 * @global int|null $id ID from the set up global post data. 277 * 278 * @covers WP_REST_Revisions_Controller::prepare_item_for_response 279 */ 280 public function test_get_items_restores_global_post() { 281 global $id; 282 283 // Populate the global $wp_query with the post and set it up. 284 wp_set_current_user( self::$editor_id ); 285 query_posts( array( 'p' => self::$post_id ) ); 286 the_post(); 287 288 // Assert initial state. 289 $post = get_post(); 290 $this->assertInstanceOf( WP_Post::class, $post, 'The global post should be set up before the request.' ); 291 $this->assertSame( self::$post_id, $post->ID, 'The global post should be the parent post before the request.' ); 292 $this->assertSame( self::$post_id, $id, 'The global $id should be the parent post ID before the request.' ); 293 294 // Capture the arguments the rest_prepare_revision filter receives. 295 $mock = new MockAction(); 296 add_filter( 'rest_prepare_revision', array( $mock, 'filter' ), 10, 3 ); 297 298 // Make the request to get revisions. 299 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/revisions' ); 300 $request->set_param( 'context', 'edit' ); 301 $response = rest_get_server()->dispatch( $request ); 302 303 $this->assertSame( 200, $response->get_status() ); 304 305 // The filter is passed each revision, not the global post restored afterwards. 306 $this->check_rest_prepare_revision_filter_args( 307 $mock, 308 array( $this->revision_id3, $this->revision_id2, $this->revision_id1 ), 309 $request 310 ); 311 312 // The global post is restored to the post that was set before the request. 313 $post = get_post(); 314 $this->assertInstanceOf( WP_Post::class, $post, 'The global post should still be set after the request.' ); 315 $this->assertSame( self::$post_id, $post->ID, 'The global post should be restored to the post that was set before the request.' ); 316 $this->assertSame( self::$post_id, $id, 'The global $id should be restored to the post that was set before the request.' ); 317 } 318 319 /** 320 * Preparing a revision for a HEAD request must also restore the global post. 321 * 322 * The collection endpoint short-circuits before preparing items for HEAD 323 * requests, so the single revision endpoint is used to reach the HEAD 324 * branch of prepare_item_for_response(). 325 * 326 * @ticket 65495 327 * 328 * @global int|null $id ID from the set up global post data. 329 * 330 * @covers WP_REST_Revisions_Controller::prepare_item_for_response 331 */ 332 public function test_get_item_head_request_restores_global_post() { 333 global $id; 334 335 // Populate the global $wp_query with the post and set it up. 336 wp_set_current_user( self::$editor_id ); 337 query_posts( array( 'p' => self::$post_id ) ); 338 the_post(); 339 340 // Assert initial state. 341 $post = get_post(); 342 $this->assertInstanceOf( WP_Post::class, $post, 'The global post should be set up before the request.' ); 343 $this->assertSame( self::$post_id, $post->ID, 'The global post should be the parent post before the request.' ); 344 $this->assertSame( self::$post_id, $id, 'The global $id should be the parent post ID before the request.' ); 345 346 // Capture the arguments the rest_prepare_revision filter receives. 347 $mock = new MockAction(); 348 add_filter( 'rest_prepare_revision', array( $mock, 'filter' ), 10, 3 ); 349 350 // Make the HEAD request to get a revision. 351 $request = new WP_REST_Request( 'HEAD', '/wp/v2/posts/' . self::$post_id . '/revisions/' . $this->revision_id1 ); 352 $request->set_param( 'context', 'edit' ); 353 $response = rest_get_server()->dispatch( $request ); 354 $this->assertSame( 200, $response->get_status() ); 355 356 // The filter is passed the revision, not the global post restored afterwards. 357 $this->check_rest_prepare_revision_filter_args( $mock, array( $this->revision_id1 ), $request ); 358 359 // The global post is restored to the post that was set before the request. 360 $post = get_post(); 361 $this->assertInstanceOf( WP_Post::class, $post, 'The global post should still be set after the request.' ); 362 $this->assertSame( self::$post_id, $post->ID, 'The global post should be restored to the post that was set before the request.' ); 363 $this->assertSame( self::$post_id, $id, 'The global $id should be restored to the post that was set before the request.' ); 364 } 365 366 /** 367 * When there is no global post before the request, none should be set afterwards. 368 * 369 * @ticket 65495 370 * 371 * @global WP_Query|null $wp_query The global WP_Query. 372 * 373 * @covers WP_REST_Revisions_Controller::prepare_item_for_response 374 */ 375 public function test_get_items_without_global_post_leaves_it_unset() { 376 global $wp_query; 377 378 // Leave the global $wp_query without a post, so there is no post data to restore. 379 wp_set_current_user( self::$editor_id ); 380 $this->assertInstanceOf( WP_Query::class, $wp_query, 'The WP_Query global must be set for wp_reset_postdata() to have anything to restore from.' ); 381 $this->assertNull( get_post(), 'The global post should not have been initially set.' ); 382 383 // Capture the arguments the rest_prepare_revision filter receives. 384 $mock = new MockAction(); 385 add_filter( 'rest_prepare_revision', array( $mock, 'filter' ), 10, 3 ); 386 387 // Make the request to get a revision. 388 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/revisions' ); 389 $request->set_param( 'context', 'edit' ); 390 $response = rest_get_server()->dispatch( $request ); 391 $this->assertSame( 200, $response->get_status() ); 392 393 // The filter is passed each revision, even though there is no global post to restore. 394 $this->check_rest_prepare_revision_filter_args( 395 $mock, 396 array( $this->revision_id3, $this->revision_id2, $this->revision_id1 ), 397 $request 398 ); 399 400 /* 401 * Note: At this point, the global $id is still populated because there was no $wp_query->post to begin with, 402 * so WP_Query::reset_postdata() has nothing to set it to. It does not null out any globals when there is no post. 403 */ 404 $this->assertNull( get_post(), 'The global post should not be set when there was none before the request.' ); 405 } 406 407 /** 408 * A main query with a post must not cause a global post to be set where there was none. 409 * 410 * The restore calls wp_reset_postdata() to clear the revision's post data, and that 411 * repopulates the global post from the main query. The global post must be unset 412 * afterwards so the request does not introduce one that was not there before. 413 * 414 * @ticket 65495 415 * 416 * @global WP_Query|null $wp_query The global WP_Query. 417 * @global int|null $id ID from the set up global post data. 418 * 419 * @covers WP_REST_Revisions_Controller::prepare_item_for_response 420 */ 421 public function test_get_items_without_global_post_leaves_it_unset_when_main_query_has_post() { 422 global $wp_query, $id; 423 424 /* 425 * Populate the main query with the post, but do not run the loop, so the main 426 * query has a post to restore from while the global post remains unset. 427 */ 428 wp_set_current_user( self::$editor_id ); 429 query_posts( array( 'p' => self::$post_id ) ); 430 431 // Assert initial state. 432 $this->assertInstanceOf( WP_Query::class, $wp_query, 'The WP_Query global must be set for wp_reset_postdata() to have anything to restore from.' ); 433 $this->assertInstanceOf( WP_Post::class, $wp_query->post, 'The main query should have a post for wp_reset_postdata() to restore from.' ); 434 $this->assertSame( self::$post_id, $wp_query->post->ID, 'The main query should have the parent post before the request.' ); 435 $this->assertNull( get_post(), 'The global post should not have been initially set.' ); 436 437 // Make the request to get revisions. 438 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/revisions' ); 439 $request->set_param( 'context', 'edit' ); 440 $response = rest_get_server()->dispatch( $request ); 441 $this->assertSame( 200, $response->get_status() ); 442 443 $this->assertNull( get_post(), 'The global post should not be set when there was none before the request, even though the main query has a post.' ); 444 $this->assertSame( self::$post_id, $id, 'The remaining post data should be reset to the main query post rather than left on the revision.' ); 445 } 446 447 /** 448 * A filter that reassigns the global post must not change the revision being prepared. 449 * 450 * The revision is held in a method-local variable rather than the global post, so a 451 * filter which swaps the global out mid-preparation (as a plugin running a secondary 452 * loop on 'the_content' may do) cannot retarget the fields prepared after it. 453 * 454 * @ticket 65495 455 * 456 * @covers WP_REST_Revisions_Controller::prepare_item_for_response 457 */ 458 public function test_prepare_item_for_response_is_unaffected_by_a_filter_reassigning_the_global_post() { 459 wp_set_current_user( self::$editor_id ); 460 461 $decoy_post = get_post( self::$post_id_2 ); 462 $this->assertInstanceOf( WP_Post::class, $decoy_post ); 463 $this->assertNotSame( $this->revision_1->post_excerpt, $decoy_post->post_excerpt, 'The decoy post must have a different excerpt for this test to be meaningful.' ); 464 465 // Simulate a plugin that leaves a different post in the global while filtering the content. 466 add_filter( 467 'the_content', 468 static function ( $content ) use ( $decoy_post ) { 469 $GLOBALS['post'] = $decoy_post; 470 return $content; 471 } 472 ); 473 474 // Capture the post the rest_prepare_revision filter receives. 475 $mock = new MockAction(); 476 add_filter( 'rest_prepare_revision', array( $mock, 'filter' ), 10, 3 ); 477 478 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/revisions/' . $this->revision_id1 ); 479 $request->set_param( 'context', 'edit' ); 480 $response = rest_get_server()->dispatch( $request ); 481 482 $this->assertSame( 200, $response->get_status() ); 483 484 // Fields prepared after 'the_content' still come from the revision. 485 $data = $response->get_data(); 486 $this->assertIsArray( $data ); 487 $this->assertArrayHasKey( 'excerpt', $data ); 488 $this->assertIsArray( $data['excerpt'] ); 489 $this->assertSame( $this->revision_id1, $data['id'], 'The prepared id should be the revision, not the post left in the global by the filter.' ); 490 $this->assertSame( $this->revision_1->post_excerpt, $data['excerpt']['raw'], 'The prepared excerpt should come from the revision, not the post left in the global by the filter.' ); 491 492 // The filter is still passed the revision. 493 $this->check_rest_prepare_revision_filter_args( $mock, array( $this->revision_id1 ), $request ); 494 } 495 496 /** 497 * Clearing the global post must not detach an existing `global $post` binding. 498 * 499 * `global $post` binds a caller to the global symbol table entry. Unsetting that 500 * entry detaches the binding, so a caller which sets the post after the request 501 * would be writing somewhere get_post() can no longer see. Note that the caller's 502 * own `global $post` is what creates the entry as null, which is why there is no 503 * previous global post to restore here. 504 * 505 * @ticket 65495 506 * 507 * @global WP_Post|null $post Global post object. 508 * 509 * @covers WP_REST_Revisions_Controller::prepare_item_for_response 510 */ 511 public function test_prepare_item_for_response_does_not_detach_an_existing_global_post_binding() { 512 // Bind to the global post the way a caller does before dispatching a request. 513 global $post; 514 515 wp_set_current_user( self::$editor_id ); 516 $this->assertNull( $post, 'The global post should not be set before the request.' ); 517 518 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/revisions/' . $this->revision_id1 ); 519 $request->set_param( 'context', 'edit' ); 520 $response = rest_get_server()->dispatch( $request ); 521 $this->assertSame( 200, $response->get_status() ); 522 523 // The caller sets the global post, expecting template tags to pick it up. 524 $post = get_post( self::$post_id ); 525 526 $global_post = get_post(); 527 $this->assertInstanceOf( WP_Post::class, $global_post, 'get_post() should see the post set through the binding after the request.' ); 528 $this->assertSame( self::$post_id, $global_post->ID, 'get_post() should return the post the caller set, not a stale or detached value.' ); 267 529 } 268 530 … … 602 864 } 603 865 866 /** 867 * Checks the arguments the rest_prepare_revision filter received. 868 * 869 * The filter must be passed the revision that was prepared. Restoring the 870 * global post afterwards must not replace it with the previous global post. 871 * 872 * @param MockAction $mock Mock registered on the rest_prepare_revision filter. 873 * @param int[] $revision_ids Expected revision IDs, in the order the filter is expected to fire. 874 * @param WP_REST_Request $request Request the revisions were prepared for. 875 */ 876 private function check_rest_prepare_revision_filter_args( MockAction $mock, array $revision_ids, WP_REST_Request $request ): void { 877 $filter_args = $mock->get_args(); 878 879 $this->assertCount( count( $revision_ids ), $filter_args, 'The rest_prepare_revision filter should fire once per prepared revision.' ); 880 881 foreach ( $filter_args as $index => $args ) { 882 $call = 'Filter call ' . $index . ': '; 883 884 $this->assertCount( 3, $args, $call . 'the filter should receive three arguments.' ); 885 $this->assertInstanceOf( WP_REST_Response::class, $args[0], $call . 'the first argument should be the response.' ); 886 $this->assertInstanceOf( WP_Post::class, $args[1], $call . 'the second argument should be a post object.' ); 887 $this->assertSame( 'revision', $args[1]->post_type, $call . 'the second argument should be a revision, not the restored global post.' ); 888 $this->assertSame( $revision_ids[ $index ], $args[1]->ID, $call . 'the second argument should be the revision that was prepared.' ); 889 $this->assertSame( $request, $args[2], $call . 'the third argument should be the request.' ); 890 } 891 } 892 604 893 protected function check_get_revision_response( $response, $revision ) { 605 894 if ( $response instanceof WP_REST_Response ) { … … 640 929 } 641 930 642 public function test_get_item_sets_up_postdata() { 643 wp_set_current_user( self::$editor_id ); 644 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/revisions/' . $this->revision_id1 ); 645 rest_get_server()->dispatch( $request ); 646 647 $post = get_post(); 648 $parent_post_id = wp_is_post_revision( $post->ID ); 649 650 $this->assertSame( $post->ID, $this->revision_id1 ); 651 $this->assertSame( $parent_post_id, self::$post_id ); 931 /** 932 * The revision's postdata should be set up while preparing the response, 933 * so rendered fields reflect the revision, without leaking into the global 934 * post after the request completes. 935 * 936 * @ticket 65495 937 * 938 * @global int|null $id ID from the set up global post data. 939 * 940 * @covers WP_REST_Revisions_Controller::prepare_item_for_response 941 */ 942 public function test_get_item_sets_up_postdata_without_leaking_global_post() { 943 global $id; 944 945 // Populate the global $wp_query with the post and set it up. 946 wp_set_current_user( self::$editor_id ); 947 query_posts( array( 'p' => self::$post_id ) ); 948 the_post(); 949 950 // Assert initial state. 951 $post = get_post(); 952 $this->assertInstanceOf( WP_Post::class, $post, 'The global post should be set up before the request.' ); 953 $this->assertSame( self::$post_id, $post->ID, 'The global post should be the parent post before the request.' ); 954 $this->assertSame( self::$post_id, $id, 'The global $id should be the parent post ID before the request.' ); 955 956 // Capture the arguments the rest_prepare_revision filter receives. 957 $mock = new MockAction(); 958 add_filter( 'rest_prepare_revision', array( $mock, 'filter' ), 10, 3 ); 959 960 // Make the request to get a revision. 961 $request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/revisions/' . $this->revision_id1 ); 962 $response = rest_get_server()->dispatch( $request ); 963 $this->assertSame( 200, $response->get_status() ); 964 965 // The filter is passed the revision, not the global post restored afterwards. 966 $this->check_rest_prepare_revision_filter_args( $mock, array( $this->revision_id1 ), $request ); 967 968 $data = $response->get_data(); 969 $this->assertIsArray( $data ); 970 $this->assertArrayHasKey( 'title', $data ); 971 $this->assertIsArray( $data['title'] ); 972 $this->assertSame( get_the_title( $this->revision_id1 ), $data['title']['rendered'], 'Expected the rendered title to reflect the revision, proving postdata was set up during preparation.' ); 973 974 // The global post is restored to the post that was set before the request. 975 $post = get_post(); 976 $this->assertInstanceOf( WP_Post::class, $post, 'The global post should still be set after the request.' ); 977 $this->assertSame( self::$post_id, $post->ID, 'The global post should be restored to the post that was set before the request.' ); 978 $this->assertSame( self::$post_id, $id, 'The global $id should be restored to the post that was set before the request.' ); 652 979 } 653 980
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)