Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revisions Controller: return single revision only when it matches the parent id #5655

Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@ public function get_item_permissions_check( $request ) {
* Retrieves one revision from the collection.
*
* @since 4.7.0
* @since 6.5.0 Added a condition to check that parent id matches revision parent id.
*
* @param WP_REST_Request $request Full details about the request.
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
Expand All @@ -402,6 +403,15 @@ public function get_item( $request ) {
return $revision;
}

if ( (int) $parent->ID !== (int) $revision->post_parent ) {
return new WP_Error(
spacedmonkey marked this conversation as resolved.
Show resolved Hide resolved
'rest_revision_parent_id_mismatch',
/* translators: %d: A post id. */
sprintf( __( 'The revision does not belong to the specified parent with id of "%d"' ), $parent->ID ),
array( 'status' => 404 )
);
}

$response = $this->prepare_item_for_response( $revision, $request );
return rest_ensure_response( $response );
}
Expand Down
51 changes: 49 additions & 2 deletions tests/phpunit/tests/rest-api/rest-revisions-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*/
class WP_Test_REST_Revisions_Controller extends WP_Test_REST_Controller_Testcase {
protected static $post_id;
ramonjd marked this conversation as resolved.
Show resolved Hide resolved
protected static $post_id_2;
protected static $page_id;

protected static $editor_id;
Expand All @@ -22,10 +23,12 @@ class WP_Test_REST_Revisions_Controller extends WP_Test_REST_Controller_Testcase
private $revision_id2;
private $revision_3;
private $revision_id3;
private $revision_2_1_id;

public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
self::$post_id = $factory->post->create();
self::$page_id = $factory->post->create( array( 'post_type' => 'page' ) );
self::$post_id = $factory->post->create();
self::$post_id_2 = $factory->post->create();
self::$page_id = $factory->post->create( array( 'post_type' => 'page' ) );

self::$editor_id = $factory->user->create(
array(
Expand Down Expand Up @@ -57,12 +60,25 @@ public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
'ID' => self::$post_id,
)
);
wp_update_post(
array(
'post_content' => 'A second post.',
'ID' => self::$post_id_2,
)
);
wp_update_post(
array(
'post_content' => 'A second post. How prolific.',
'ID' => self::$post_id_2,
)
);
wp_set_current_user( 0 );
}

public static function wpTearDownAfterClass() {
// Also deletes revisions.
wp_delete_post( self::$post_id, true );
wp_delete_post( self::$post_id_2, true );
wp_delete_post( self::$page_id, true );

self::delete_user( self::$editor_id );
Expand All @@ -72,6 +88,7 @@ public static function wpTearDownAfterClass() {
public function set_up() {
parent::set_up();

// Set first post revision vars.
$revisions = wp_get_post_revisions( self::$post_id );
$this->total_revisions = count( $revisions );
$this->revisions = $revisions;
Expand All @@ -81,6 +98,11 @@ public function set_up() {
$this->revision_id2 = $this->revision_2->ID;
$this->revision_3 = array_pop( $revisions );
$this->revision_id3 = $this->revision_3->ID;

// Set second post revision vars.
$revisions = wp_get_post_revisions( self::$post_id_2 );
$post_2_revision = array_pop( $revisions );
$this->revision_2_1_id = $post_2_revision->ID;
}

public function _filter_map_meta_cap_remove_no_allow_revisions( $caps, $cap, $user_id, $args ) {
Expand Down Expand Up @@ -234,6 +256,31 @@ public function test_get_item_invalid_parent_post_type() {
$this->assertErrorResponse( 'rest_post_invalid_parent', $response, 404 );
}

/**
ramonjd marked this conversation as resolved.
Show resolved Hide resolved
* @ticket 59875
*/
public function test_get_item_valid_parent_id() {
ramonjd marked this conversation as resolved.
Show resolved Hide resolved
wp_set_current_user( self::$editor_id );
$request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/revisions/' . $this->revision_id1 );
$response = rest_get_server()->dispatch( $request );
$data = $response->get_data();
$this->assertSame( self::$post_id, $data['parent'], "The returned revision's id should match the parent id." );
$this->check_get_revision_response( $response, $this->revision_1 );
}

/**
* @ticket 59875
*/
public function test_get_item_invalid_parent_id() {
wp_set_current_user( self::$editor_id );
$request = new WP_REST_Request( 'GET', '/wp/v2/posts/' . self::$post_id . '/revisions/' . $this->revision_2_1_id );
$response = rest_get_server()->dispatch( $request );
$this->assertErrorResponse( 'rest_revision_parent_id_mismatch', $response, 404 );

$expected_message = 'The revision does not belong to the specified parent with id of "' . self::$post_id . '"';
$this->assertSame( $expected_message, $response->as_error()->get_error_messages()[0], 'The message must contain the correct parent ID.' );
}

public function test_delete_item() {
wp_set_current_user( self::$editor_id );
$request = new WP_REST_Request( 'DELETE', '/wp/v2/posts/' . self::$post_id . '/revisions/' . $this->revision_id1 );
Expand Down
51 changes: 51 additions & 0 deletions tests/phpunit/tests/rest-api/wpRestTemplateRevisionsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ class Tests_REST_wpRestTemplateRevisionsController extends WP_Test_REST_Controll
*/
const TEMPLATE_NAME = 'my_template';

/**
* @var string
*/
const TEMPLATE_NAME_2 = 'my_template_2';

/**
* @var string
*/
Expand Down Expand Up @@ -51,6 +56,15 @@ class Tests_REST_wpRestTemplateRevisionsController extends WP_Test_REST_Controll
*/
private static $template_post;

/**
* Template post.
*
* @since 6.5.0
*
* @var WP_Post
*/
private static $template_post_2;

/**
* @var array
*/
Expand Down Expand Up @@ -123,6 +137,26 @@ public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
'post_content' => 'Content revision #5',
)
);

// Create a new template post to test the get_item method.
self::$template_post_2 = $factory->post->create_and_get(
array(
'post_type' => self::PARENT_POST_TYPE,
'post_name' => self::TEMPLATE_NAME_2,
'post_title' => 'My Template 2',
'post_content' => 'Content 2',
'post_excerpt' => 'Description of my template 2',
'tax_input' => array(
'wp_theme' => array(
self::TEST_THEME,
),
),
)
);
wp_set_post_terms( self::$template_post_2->ID, self::TEST_THEME, 'wp_theme' );

var_dump( self::$template_post->ID );
var_dump( self::$template_post_2->ID );
}

/**
Expand Down Expand Up @@ -336,6 +370,23 @@ public function test_get_item_not_found() {
$this->assertErrorResponse( 'rest_post_invalid_parent', $response, WP_Http::NOT_FOUND );
}

/**
* @ticket 59875
*/
public function test_get_item_invalid_parent_id() {
wp_set_current_user( self::$admin_id );
$revisions = wp_get_post_revisions( self::$template_post, array( 'fields' => 'ids' ) );
$revision_id = array_shift( $revisions );

$request = new WP_REST_Request( 'GET', '/wp/v2/templates/' . self::TEST_THEME . '/' . self::TEMPLATE_NAME_2 . '/revisions/' . $revision_id );

$response = rest_get_server()->dispatch( $request );
$this->assertErrorResponse( 'rest_revision_parent_id_mismatch', $response, 404 );

$expected_message = 'The revision does not belong to the specified parent with id of "' . self::$template_post_2->ID . '"';
$this->assertSame( $expected_message, $response->as_error()->get_error_messages()[0], 'The message must contain the correct parent ID.' );
}

/**
* @covers WP_REST_Template_Revisions_Controller::prepare_item_for_response
* @ticket 56922
Expand Down