Make WordPress Core


Ignore:
Timestamp:
01/15/2025 12:44:43 PM (20 months ago)
Author:
swissspidy
Message:

REST API: Improve autosave and revision endpoints for templates and template parts.

Fixes those endpoints for file-based templates and template parts, as templates based on theme files can't be revisioned or autosaved.

Props antonvlasenko, swissspidy, spacedmonkey, kadamwhite.
Fixes #61970.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/tests/phpunit/tests/rest-api/wpRestTemplateRevisionsController.php

    r59073 r59605  
    2828         * @var string
    2929         */
    30         const PARENT_POST_TYPE = 'wp_template';
     30        const TEMPLATE_PART_NAME = 'my_template_part';
     31
     32        /**
     33         * @var string
     34         */
     35        const TEMPLATE_PART_NAME_2 = 'my_template_part_2';
     36
     37        /**
     38         * @var string
     39         */
     40        const TEMPLATE_POST_TYPE = 'wp_template';
     41
     42        /**
     43         * @var string
     44         */
     45        const TEMPLATE_PART_POST_TYPE = 'wp_template_part';
    3146
    3247        /**
     
    6782
    6883        /**
     84         * Template part post.
     85         *
     86         * @since 6.7.0
     87         *
     88         * @var WP_Post
     89         */
     90        private static $template_part_post;
     91
     92        /**
     93         * Template part post.
     94         *
     95         * @since 6.7.0
     96         *
     97         * @var WP_Post
     98         */
     99        private static $template_part_post_2;
     100
     101        /**
    69102         * @var array
    70103         */
    71         private static $revisions = array();
     104        private static $template_revisions = array();
     105
     106        /**
     107         * @var array
     108         */
     109        private static $template_part_revisions = array();
    72110
    73111        /**
     
    93131                self::$template_post = $factory->post->create_and_get(
    94132                        array(
    95                                 'post_type'    => self::PARENT_POST_TYPE,
     133                                'post_type'    => self::TEMPLATE_POST_TYPE,
    96134                                'post_name'    => self::TEMPLATE_NAME,
    97135                                'post_title'   => 'My Template',
     
    107145                wp_set_post_terms( self::$template_post->ID, self::TEST_THEME, 'wp_theme' );
    108146
    109                 // Update post to create a new revisions.
    110                 self::$revisions[] = _wp_put_post_revision(
    111                         array(
    112                                 'ID'           => self::$template_post->ID,
    113                                 'post_content' => 'Content revision #2',
    114                         )
    115                 );
    116 
    117                 // Update post to create a new revisions.
    118                 self::$revisions[] = _wp_put_post_revision(
    119                         array(
    120                                 'ID'           => self::$template_post->ID,
    121                                 'post_content' => 'Content revision #3',
    122                         )
    123                 );
    124 
    125                 // Update post to create a new revisions.
    126                 self::$revisions[] = _wp_put_post_revision(
    127                         array(
    128                                 'ID'           => self::$template_post->ID,
    129                                 'post_content' => 'Content revision #4',
    130                         )
    131                 );
    132 
    133                 // Update post to create a new revisions.
    134                 self::$revisions[] = _wp_put_post_revision(
    135                         array(
    136                                 'ID'           => self::$template_post->ID,
    137                                 'post_content' => 'Content revision #5',
    138                         )
    139                 );
     147                // Update post to create new revisions.
     148                foreach ( range( 2, 5 ) as $revision_index ) {
     149                        self::$template_revisions[] = _wp_put_post_revision(
     150                                array(
     151                                        'ID'           => self::$template_post->ID,
     152                                        'post_content' => 'Content revision #' . $revision_index,
     153                                )
     154                        );
     155                }
    140156
    141157                // Create a new template post to test the get_item method.
    142158                self::$template_post_2 = $factory->post->create_and_get(
    143159                        array(
    144                                 'post_type'    => self::PARENT_POST_TYPE,
     160                                'post_type'    => self::TEMPLATE_POST_TYPE,
    145161                                'post_name'    => self::TEMPLATE_NAME_2,
    146162                                'post_title'   => 'My Template 2',
     
    155171                );
    156172                wp_set_post_terms( self::$template_post_2->ID, self::TEST_THEME, 'wp_theme' );
     173
     174                // Set up template part post.
     175                self::$template_part_post = $factory->post->create_and_get(
     176                        array(
     177                                'post_type'    => self::TEMPLATE_PART_POST_TYPE,
     178                                'post_name'    => self::TEMPLATE_PART_NAME,
     179                                'post_title'   => 'My template part',
     180                                'post_content' => 'Content',
     181                                'post_excerpt' => 'Description of my template part',
     182                                'tax_input'    => array(
     183                                        'wp_theme'              => array(
     184                                                self::TEST_THEME,
     185                                        ),
     186                                        'wp_template_part_area' => array(
     187                                                WP_TEMPLATE_PART_AREA_HEADER,
     188                                        ),
     189                                ),
     190                        )
     191                );
     192                wp_set_post_terms( self::$template_part_post->ID, self::TEST_THEME, 'wp_theme' );
     193                wp_set_post_terms( self::$template_part_post->ID, WP_TEMPLATE_PART_AREA_HEADER, 'wp_template_part_area' );
     194
     195                // Update post to create new revisions.
     196                foreach ( range( 2, 5 ) as $revision_index ) {
     197                        self::$template_part_revisions[] = _wp_put_post_revision(
     198                                array(
     199                                        'ID'           => self::$template_part_post->ID,
     200                                        'post_content' => 'Content revision #' . $revision_index,
     201                                )
     202                        );
     203                }
     204
     205                // Set up template part post.
     206                self::$template_part_post_2 = $factory->post->create_and_get(
     207                        array(
     208                                'post_type'    => self::TEMPLATE_PART_POST_TYPE,
     209                                'post_name'    => self::TEMPLATE_PART_NAME_2,
     210                                'post_title'   => 'My template part 2',
     211                                'post_content' => 'Content 2',
     212                                'post_excerpt' => 'Description of my template part 2',
     213                                'tax_input'    => array(
     214                                        'wp_theme'              => array(
     215                                                self::TEST_THEME,
     216                                        ),
     217                                        'wp_template_part_area' => array(
     218                                                WP_TEMPLATE_PART_AREA_HEADER,
     219                                        ),
     220                                ),
     221                        )
     222                );
     223                wp_set_post_terms( self::$template_part_post_2->ID, self::TEST_THEME, 'wp_theme' );
     224                wp_set_post_terms( self::$template_part_post_2->ID, WP_TEMPLATE_PART_AREA_HEADER, 'wp_template_part_area' );
    157225        }
    158226
     
    162230        public static function wpTearDownAfterClass() {
    163231                // Also deletes revisions.
    164                 foreach ( self::$revisions as $revision ) {
    165                         wp_delete_post( $revision, true );
     232                foreach ( self::$template_revisions as $template_revision ) {
     233                        wp_delete_post( $template_revision, true );
     234                }
     235
     236                foreach ( self::$template_part_revisions as $template_part_revision ) {
     237                        wp_delete_post( $template_part_revision, true );
    166238                }
    167239        }
     
    196268
    197269        /**
     270         * @coversNothing
     271         * @ticket 56922
     272         */
     273        public function test_context_param() {
     274                // A proper data provider cannot be used because this method's signature must match the parent method.
     275                // Therefore, actual tests are performed in the test_context_param_with_data_provider method.
     276                $this->assertTrue( true );
     277        }
     278
     279        /**
     280         * @dataProvider data_context_param_with_data_provider
    198281         * @covers WP_REST_Template_Revisions_Controller::get_context_param
    199282         * @ticket 56922
    200          */
    201         public function test_context_param() {
     283         *
     284         * @param string $rest_base   Base part of the REST API endpoint to test.
     285         * @param string $template_id Template ID to use in the test.
     286         */
     287        public function test_context_param_with_data_provider( $rest_base, $template_id ) {
    202288                // Collection.
    203                 $request  = new WP_REST_Request( 'OPTIONS', '/wp/v2/templates/' . self::TEST_THEME . '/' . self::TEMPLATE_NAME . '/revisions' );
     289                $request  = new WP_REST_Request( 'OPTIONS', '/wp/v2/' . $rest_base . '/' . $template_id . '/revisions' );
    204290                $response = rest_get_server()->dispatch( $request );
    205291                $data     = $response->get_data();
     
    216302
    217303                // Single.
    218                 $request  = new WP_REST_Request( 'OPTIONS', '/wp/v2/templates/' . self::TEST_THEME . '/' . self::TEMPLATE_NAME . '/revisions/1' );
     304                $request  = new WP_REST_Request( 'OPTIONS', '/wp/v2/' . $rest_base . '/' . $template_id . '/revisions/1' );
    219305                $response = rest_get_server()->dispatch( $request );
    220306                $data     = $response->get_data();
     
    237323
    238324        /**
     325         * Data provider for test_context_param.
     326         *
     327         * @return array
     328         */
     329        public function data_context_param_with_data_provider() {
     330                return array(
     331                        'templates'      => array( 'templates', self::TEST_THEME . '//' . self::TEMPLATE_NAME ),
     332                        'template parts' => array( 'template-parts', self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME ),
     333                );
     334        }
     335
     336        /**
     337         * @coversNothing
     338         * @ticket 56922
     339         */
     340        public function test_get_items() {
     341                // A proper data provider cannot be used because this method's signature must match the parent method.
     342                // Therefore, actual tests are performed in the test_get_items_with_data_provider method.
     343                $this->assertTrue( true );
     344        }
     345
     346        /**
     347         * @dataProvider data_get_items_with_data_provider
    239348         * @covers WP_REST_Template_Revisions_Controller::get_items
    240349         * @ticket 56922
    241          */
    242         public function test_get_items() {
     350         *
     351         * @param string $parent_post_property_name A class property name that contains the parent post object.
     352         * @param string $rest_base                 Base part of the REST API endpoint to test.
     353         * @param string $template_id               Template ID to use in the test.
     354         */
     355        public function test_get_items_with_data_provider( $parent_post_property_name, $rest_base, $template_id ) {
    243356                wp_set_current_user( self::$admin_id );
     357                $parent_post = self::$$parent_post_property_name;
     358
    244359                $request   = new WP_REST_Request(
    245360                        'GET',
    246                         '/wp/v2/templates/' . self::TEST_THEME . '/' . self::TEMPLATE_NAME . '/revisions'
     361                        '/wp/v2/' . $rest_base . '/' . $template_id . '/revisions'
    247362                );
    248363                $response  = rest_get_server()->dispatch( $request );
    249364                $revisions = $response->get_data();
     365                $this->assertSame( WP_Http::OK, $response->get_status(), 'Response is expected to have a status code of 200.' );
    250366
    251367                $this->assertCount(
     
    256372
    257373                $this->assertSame(
    258                         self::$template_post->ID,
     374                        $parent_post->ID,
    259375                        $revisions[0]['parent'],
    260376                        'Failed asserting that the parent ID of the revision matches the template post ID.'
     
    267383
    268384                $this->assertSame(
    269                         self::$template_post->ID,
     385                        $parent_post->ID,
    270386                        $revisions[1]['parent'],
    271387                        'Failed asserting that the parent ID of the revision matches the template post ID.'
     
    278394
    279395                $this->assertSame(
    280                         self::$template_post->ID,
     396                        $parent_post->ID,
    281397                        $revisions[2]['parent'],
    282398                        'Failed asserting that the parent ID of the revision matches the template post ID.'
     
    289405
    290406                $this->assertSame(
    291                         self::$template_post->ID,
     407                        $parent_post->ID,
    292408                        $revisions[3]['parent'],
    293409                        'Failed asserting that the parent ID of the revision matches the template post ID.'
     
    300416        }
    301417
    302 
    303         /**
     418        /**
     419         * Data provider for test_get_items_with_data_provider.
     420         *
     421         * @return array
     422         */
     423        public function data_get_items_with_data_provider() {
     424                return array(
     425                        'templates'      => array( 'template_post', 'templates', self::TEST_THEME . '//' . self::TEMPLATE_NAME ),
     426                        'template parts' => array( 'template_part_post', 'template-parts', self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME ),
     427                );
     428        }
     429
     430        /**
     431         * @dataProvider data_get_items_endpoint_should_return_unauthorized_https_status_code_for_unauthorized_request
    304432         * @covers WP_REST_Template_Revisions_Controller::get_items_permissions_check
    305433         * @ticket 56922
    306          */
    307         public function test_get_items_endpoint_should_return_unauthorized_https_status_code_for_unauthorized_request() {
     434         *
     435         * @param string $rest_base   Base part of the REST API endpoint to test.
     436         * @param string $template_id Template ID to use in the test.
     437         */
     438        public function test_get_items_endpoint_should_return_unauthorized_https_status_code_for_unauthorized_request( $rest_base, $template_id ) {
    308439                wp_set_current_user( 0 );
    309                 $request  = new WP_REST_Request( 'GET', '/wp/v2/templates/' . self::TEST_THEME . '/' . self::TEMPLATE_NAME . '/revisions' );
     440                $request  = new WP_REST_Request( 'GET', '/wp/v2/' . $rest_base . '/' . $template_id . '/revisions' );
    310441                $response = rest_get_server()->dispatch( $request );
    311442                $this->assertErrorResponse( 'rest_cannot_read', $response, WP_Http::UNAUTHORIZED );
     
    313444
    314445        /**
     446         * Data provider for test_get_items_endpoint_should_return_unauthorized_https_status_code_for_unauthorized_request.
     447         *
     448         * @return array
     449         */
     450        public function data_get_items_endpoint_should_return_unauthorized_https_status_code_for_unauthorized_request() {
     451                return array(
     452                        'templates'      => array( 'templates', self::TEST_THEME . '//' . self::TEMPLATE_NAME ),
     453                        'template parts' => array( 'template-parts', self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME ),
     454                );
     455        }
     456
     457        /**
     458         * @dataProvider data_get_items_endpoint_should_return_forbidden_https_status_code_for_users_with_insufficient_permissions
    315459         * @covers WP_REST_Template_Revisions_Controller::get_items_permissions_check
    316460         * @ticket 56922
    317          */
    318         public function test_get_items_endpoint_should_return_forbidden_https_status_code_for_users_with_insufficient_permissions() {
     461         *
     462         * @param string $rest_base   Base part of the REST API endpoint to test.
     463         * @param string $template_id Template ID to use in the test.
     464         */
     465        public function test_get_items_endpoint_should_return_forbidden_https_status_code_for_users_with_insufficient_permissions( $rest_base, string $template_id ) {
    319466                wp_set_current_user( self::$contributor_id );
    320                 $request  = new WP_REST_Request( 'GET', '/wp/v2/templates/' . self::TEST_THEME . '/' . self::TEMPLATE_NAME . '/revisions' );
     467                $request  = new WP_REST_Request( 'GET', '/wp/v2/' . $rest_base . '/' . $template_id . '/revisions' );
    321468                $response = rest_get_server()->dispatch( $request );
    322469                $this->assertErrorResponse( 'rest_cannot_read', $response, WP_Http::FORBIDDEN );
     
    324471
    325472        /**
     473         * Data provider for test_get_items_endpoint_should_return_unauthorized_https_status_code_for_unauthorized_request.
     474         *
     475         * @return array
     476         */
     477        public function data_get_items_endpoint_should_return_forbidden_https_status_code_for_users_with_insufficient_permissions() {
     478                return array(
     479                        'templates'      => array( 'templates', self::TEST_THEME . '//' . self::TEMPLATE_NAME ),
     480                        'template parts' => array( 'template-parts', self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME ),
     481                );
     482        }
     483
     484        /**
     485         * @dataProvider data_get_items_for_templates_based_on_theme_files_should_return_bad_response_status
     486         * @ticket 61970
     487         *
     488         * @param string $rest_base   Base part of the REST API endpoint to test.
     489         * @param string $template_id Template ID to use in the test.
     490         */
     491        public function test_get_items_for_templates_based_on_theme_files_should_return_bad_response_status( $rest_base, $template_id ) {
     492                wp_set_current_user( self::$admin_id );
     493                switch_theme( 'block-theme' );
     494
     495                $request = new WP_REST_Request( 'GET', '/wp/v2/' . $rest_base . '/' . $template_id . '/revisions' );
     496
     497                $response = rest_get_server()->dispatch( $request );
     498                $this->assertErrorResponse(
     499                        'rest_invalid_template',
     500                        $response,
     501                        WP_Http::BAD_REQUEST,
     502                        sprintf( 'Response is expected to have a status code of %d.', WP_Http::BAD_REQUEST )
     503                );
     504        }
     505
     506        /**
     507         * Data provider for test_get_items_for_templates_based_on_theme_files_should_return_bad_response_status.
     508         *
     509         * @return array
     510         */
     511        public function data_get_items_for_templates_based_on_theme_files_should_return_bad_response_status() {
     512                return array(
     513                        'templates'      => array( 'templates', self::TEST_THEME . '//page-home' ),
     514                        'template parts' => array( 'template-parts', self::TEST_THEME . '//small-header' ),
     515                );
     516        }
     517
     518        /**
     519         * @dataProvider data_get_item_for_templates_based_on_theme_files_should_return_bad_response_status
     520         * @ticket 56922
     521         *
     522         * @param string $rest_base   Base part of the REST API endpoint to test.
     523         * @param string $template_id Template ID to use in the test.
     524         */
     525        public function test_get_item_for_templates_based_on_theme_files_should_return_bad_response_status( $rest_base, $template_id ) {
     526                wp_set_current_user( self::$admin_id );
     527                switch_theme( 'block-theme' );
     528
     529                $request = new WP_REST_Request( 'GET', '/wp/v2/' . $rest_base . '/' . $template_id . '/revisions/1' );
     530
     531                $response = rest_get_server()->dispatch( $request );
     532                $this->assertErrorResponse(
     533                        'rest_invalid_template',
     534                        $response,
     535                        WP_Http::BAD_REQUEST,
     536                        sprintf( 'Response is expected to have a status code of %d.', WP_Http::BAD_REQUEST )
     537                );
     538        }
     539
     540        /**
     541         * Data provider for test_get_item_for_templates_based_on_theme_files_should_return_bad_response_status.
     542         *
     543         * @return array
     544         */
     545        public function data_get_item_for_templates_based_on_theme_files_should_return_bad_response_status() {
     546                return array(
     547                        'templates'      => array( 'templates', self::TEST_THEME . '//page-home' ),
     548                        'template parts' => array( 'template-parts', self::TEST_THEME . '//small-header' ),
     549                );
     550        }
     551
     552        /**
     553         * @coversNothing
     554         * @ticket 56922
     555         */
     556        public function test_get_item() {
     557                // A proper data provider cannot be used because this method's signature must match the parent method.
     558                // Therefore, actual tests are performed in the test_get_item_with_data_provider method.
     559                $this->assertTrue( true );
     560        }
     561
     562        /**
     563         * @dataProvider data_get_item_with_data_provider
    326564         * @covers WP_REST_Template_Revisions_Controller::get_item
    327565         * @ticket 56922
    328          */
    329         public function test_get_item() {
     566         *
     567         * @param string  $parent_post_property_name  A class property name that contains the parent post object.
     568         * @param string  $rest_base                  Base part of the REST API endpoint to test.
     569         * @param string  $template_id                Template ID to use in the test.
     570         */
     571        public function test_get_item_with_data_provider( $parent_post_property_name, $rest_base, $template_id ) {
    330572                wp_set_current_user( self::$admin_id );
    331573
    332                 $revisions   = wp_get_post_revisions( self::$template_post, array( 'fields' => 'ids' ) );
     574                $parent_post = self::$$parent_post_property_name;
     575
     576                $revisions   = wp_get_post_revisions( $parent_post, array( 'fields' => 'ids' ) );
    333577                $revision_id = array_shift( $revisions );
    334578
    335                 $request  = new WP_REST_Request( 'GET', '/wp/v2/templates/' . self::TEST_THEME . '/' . self::TEMPLATE_NAME . '/revisions/' . $revision_id );
     579                $request  = new WP_REST_Request( 'GET', '/wp/v2/' . $rest_base . '/' . $template_id . '/revisions/' . $revision_id );
    336580                $response = rest_get_server()->dispatch( $request );
    337581                $revision = $response->get_data();
     
    344588                );
    345589                $this->assertSame(
    346                         self::$template_post->ID,
     590                        $parent_post->ID,
    347591                        $revision['parent'],
    348592                        sprintf(
     
    354598
    355599        /**
     600         * Data provider for test_get_item_with_data_provider.
     601         *
     602         * @return array
     603         */
     604        public function data_get_item_with_data_provider() {
     605                return array(
     606                        'templates'      => array( 'template_post', 'templates', self::TEST_THEME . '//' . self::TEMPLATE_NAME ),
     607                        'template parts' => array( 'template_part_post', 'template-parts', self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME ),
     608                );
     609        }
     610
     611        /**
     612         * @dataProvider data_get_item_not_found
    356613         * @covers WP_REST_Template_Revisions_Controller::get_item
    357614         * @ticket 56922
    358          */
    359         public function test_get_item_not_found() {
     615         *
     616         * @param string  $parent_post_property_name  A class property name that contains the parent post object.
     617         * @param string  $rest_base                  Base part of the REST API endpoint to test.
     618         */
     619        public function test_get_item_not_found( $parent_post_property_name, $rest_base ) {
    360620                wp_set_current_user( self::$admin_id );
    361621
    362                 $revisions   = wp_get_post_revisions( self::$template_post, array( 'fields' => 'ids' ) );
     622                $parent_post = self::$$parent_post_property_name;
     623
     624                $revisions   = wp_get_post_revisions( $parent_post, array( 'fields' => 'ids' ) );
    363625                $revision_id = array_shift( $revisions );
    364626
    365                 $request  = new WP_REST_Request( 'GET', '/wp/v2/templates/invalid//parent/revisions/' . $revision_id );
     627                $request  = new WP_REST_Request( 'GET', '/wp/v2/' . $rest_base . '/invalid//parent/revisions/' . $revision_id );
    366628                $response = rest_get_server()->dispatch( $request );
    367629                $this->assertErrorResponse( 'rest_post_invalid_parent', $response, WP_Http::NOT_FOUND );
     
    369631
    370632        /**
     633         * Data provider for test_get_item_not_found.
     634         *
     635         * @return array
     636         */
     637        public function data_get_item_not_found() {
     638                return array(
     639                        'templates'      => array( 'template_post', 'templates' ),
     640                        'template parts' => array( 'template_part_post', 'template-parts' ),
     641                );
     642        }
     643
     644        /**
     645         * @dataProvider data_get_item_invalid_parent_id
     646         * @covers WP_REST_Template_Revisions_Controller::get_item
    371647         * @ticket 59875
    372          */
    373         public function test_get_item_invalid_parent_id() {
     648         *
     649         * @param string $parent_post_property_name        A class property name that contains the parent post object.
     650         * @param string $actual_parent_post_property_name A class property name that contains the parent post object.
     651         * @param string $rest_base                        Base part of the REST API endpoint to test.
     652         * @param string $template_id                      Template ID to use in the test.
     653         */
     654        public function test_get_item_invalid_parent_id( $parent_post_property_name, $actual_parent_post_property_name, $rest_base, $template_id ) {
    374655                wp_set_current_user( self::$admin_id );
    375                 $revisions   = wp_get_post_revisions( self::$template_post, array( 'fields' => 'ids' ) );
    376                 $revision_id = array_shift( $revisions );
    377 
    378                 $request = new WP_REST_Request( 'GET', '/wp/v2/templates/' . self::TEST_THEME . '/' . self::TEMPLATE_NAME_2 . '/revisions/' . $revision_id );
     656
     657                $parent_post        = self::$$parent_post_property_name;
     658                $actual_parent_post = self::$$actual_parent_post_property_name;
     659                $revisions          = wp_get_post_revisions( $parent_post, array( 'fields' => 'ids' ) );
     660                $revision_id        = array_shift( $revisions );
     661
     662                $request = new WP_REST_Request( 'GET', '/wp/v2/' . $rest_base . '/' . $template_id . '/revisions/' . $revision_id );
    379663
    380664                $response = rest_get_server()->dispatch( $request );
    381665                $this->assertErrorResponse( 'rest_revision_parent_id_mismatch', $response, 404 );
    382666
    383                 $expected_message = 'The revision does not belong to the specified parent with id of "' . self::$template_post_2->ID . '"';
     667                $expected_message = 'The revision does not belong to the specified parent with id of "' . $actual_parent_post->ID . '"';
    384668                $this->assertSame( $expected_message, $response->as_error()->get_error_messages()[0], 'The message must contain the correct parent ID.' );
    385669        }
    386670
    387671        /**
     672         * Data provider for test_get_item_invalid_parent_id.
     673         *
     674         * @return array
     675         */
     676        public function data_get_item_invalid_parent_id() {
     677                return array(
     678                        'templates'      => array(
     679                                'template_post',
     680                                'template_post_2',
     681                                'templates',
     682                                self::TEST_THEME . '//' . self::TEMPLATE_NAME_2,
     683                        ),
     684                        'template parts' => array(
     685                                'template_part_post',
     686                                'template_part_post_2',
     687                                'template-parts',
     688                                self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME_2,
     689                        ),
     690                );
     691        }
     692
     693        /**
     694         * @coversNothing
     695         * @ticket 56922
     696         */
     697        public function test_prepare_item() {
     698                // A proper data provider cannot be used because this method's signature must match the parent method.
     699                // Therefore, actual tests are performed in the test_prepare_item_with_data_provider method.
     700                $this->assertTrue( true );
     701        }
     702
     703        /**
     704         * @dataProvider data_prepare_item_with_data_provider
    388705         * @covers WP_REST_Template_Revisions_Controller::prepare_item_for_response
    389706         * @ticket 56922
    390          */
    391         public function test_prepare_item() {
    392                 $revisions   = wp_get_post_revisions( self::$template_post, array( 'fields' => 'ids' ) );
     707         *
     708         * @param string $parent_post_property_name A class property name that contains the parent post object.
     709         * @param string $rest_base                 Base part of the REST API endpoint to test.
     710         * @param string $template_id               Template ID to use in the test.
     711         */
     712        public function test_prepare_item_with_data_provider( $parent_post_property_name, $rest_base, $template_id ) {
     713                $parent_post = self::$$parent_post_property_name;
     714                $revisions   = wp_get_post_revisions( $parent_post, array( 'fields' => 'ids' ) );
    393715                $revision_id = array_shift( $revisions );
    394716                $post        = get_post( $revision_id );
    395                 $request     = new WP_REST_Request( 'GET', '/wp/v2/templates/' . self::TEST_THEME . '/' . self::TEMPLATE_NAME . '/revisions/' . $revision_id );
    396                 $controller  = new WP_REST_Template_Revisions_Controller( self::PARENT_POST_TYPE );
     717                $request     = new WP_REST_Request( 'GET', '/wp/v2/' . $rest_base . '/' . $template_id . '/revisions/' . $revision_id );
     718                $controller  = new WP_REST_Template_Revisions_Controller( $parent_post->post_type );
    397719                $response    = $controller->prepare_item_for_response( $post, $request );
    398720                $this->assertInstanceOf(
     
    410732                );
    411733                $this->assertSame(
    412                         self::$template_post->ID,
     734                        $parent_post->ID,
    413735                        $revision['parent'],
    414736                        sprintf(
    415737                                'Failed asserting that the parent id of the revision is the same as %s.',
    416                                 self::$template_post->ID
     738                                $parent_post->ID
    417739                        )
    418740                );
     
    422744
    423745                $this->assertStringEndsWith(
    424                         self::TEST_THEME . '//' . self::TEMPLATE_NAME . '/revisions/' . $revision_id,
     746                        $template_id . '/revisions/' . $revision_id,
    425747                        $links['self'][0]['href'],
    426748                        sprintf(
    427749                                'Failed asserting that the self link ends with %s.',
    428                                 self::TEST_THEME . '//' . self::TEMPLATE_NAME . '/revisions/' . $revision_id
     750                                $template_id . '/revisions/' . $revision_id
    429751                        )
    430752                );
    431753
    432754                $this->assertStringEndsWith(
    433                         self::TEST_THEME . '//' . self::TEMPLATE_NAME,
     755                        $template_id,
    434756                        $links['parent'][0]['href'],
    435757                        sprintf(
    436758                                'Failed asserting that the parent link ends with %s.',
    437                                 self::TEST_THEME . '//' . self::TEMPLATE_NAME
    438                         )
    439                 );
    440         }
    441 
    442         /**
     759                                $template_id
     760                        )
     761                );
     762        }
     763
     764        /**
     765         * Data provider for test_prepare_item_with_data_provider.
     766         *
     767         * @return array
     768         */
     769        public function data_prepare_item_with_data_provider() {
     770                return array(
     771                        'templates'      => array( 'template_post', 'templates', self::TEST_THEME . '//' . self::TEMPLATE_NAME ),
     772                        'template parts' => array( 'template_part_post', 'template-parts', self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME ),
     773                );
     774        }
     775
     776        /**
     777         * @coversNothing
     778         * @ticket 56922
     779         */
     780        public function test_get_item_schema() {
     781                // A proper data provider cannot be used because this method's signature must match the parent method.
     782                // Therefore, actual tests are performed in the test_prepare_item_with_data_provider method.
     783                $this->assertTrue( true );
     784        }
     785
     786        /**
     787         * @dataProvider data_get_item_schema_with_data_provider
    443788         * @covers WP_REST_Template_Revisions_Controller::get_item_schema
    444789         * @ticket 56922
    445          */
    446         public function test_get_item_schema() {
    447                 $request    = new WP_REST_Request( 'OPTIONS', '/wp/v2/templates/' . self::TEST_THEME . '/' . self::TEMPLATE_NAME . '/revisions' );
     790         *
     791         * @param string $rest_base             Base part of the REST API endpoint to test.
     792         * @param string $template_id           Template ID to use in the test.
     793         * @param int    $properties_count      Number of properties to check for in the schema.
     794         * @param array  $additional_properties Additional properties to check for in the schema.
     795         */
     796        public function test_get_item_schema_with_data_provider( $rest_base, $template_id, $properties_count, $additional_properties = array() ) {
     797                $request    = new WP_REST_Request( 'OPTIONS', '/wp/v2/' . $rest_base . '/' . $template_id . '/revisions' );
    448798                $response   = rest_get_server()->dispatch( $request );
    449799                $data       = $response->get_data();
    450800                $properties = $data['schema']['properties'];
    451801
    452                 $this->assertCount( 19, $properties );
     802                $this->assertCount( $properties_count, $properties );
    453803                $this->assertArrayHasKey( 'id', $properties, 'ID key should exist in properties.' );
    454804                $this->assertArrayHasKey( 'slug', $properties, 'Slug key should exist in properties.' );
     
    464814                $this->assertArrayHasKey( 'author', $properties, 'author key should exist in properties.' );
    465815                $this->assertArrayHasKey( 'modified', $properties, 'modified key should exist in properties.' );
    466                 $this->assertArrayHasKey( 'is_custom', $properties, 'is_custom key should exist in properties.' );
    467816                $this->assertArrayHasKey( 'parent', $properties, 'Parent key should exist in properties.' );
    468817                $this->assertArrayHasKey( 'author_text', $properties, 'author_text key should exist in properties.' );
    469818                $this->assertArrayHasKey( 'original_source', $properties, 'original_source key should exist in properties.' );
    470                 $this->assertArrayHasKey( 'plugin', $properties, 'plugin key should exist in properties.' );
     819
     820                foreach ( $additional_properties as $additional_property ) {
     821                        $this->assertArrayHasKey( $additional_property, $properties, $additional_property . ' key should exist in properties.' );
     822                }
     823        }
     824
     825        /**
     826         * Data provider for data_get_item_schema_with_data_provider.
     827         *
     828         * @return array
     829         */
     830        public function data_get_item_schema_with_data_provider() {
     831                return array(
     832                        'templates'      => array(
     833                                'templates',
     834                                self::TEST_THEME . '//' . self::TEMPLATE_NAME,
     835                                19,
     836                                array( 'is_custom', 'plugin' ),
     837                        ),
     838                        'template parts' => array(
     839                                'template-parts',
     840                                self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME,
     841                                18,
     842                                array( 'area' ),
     843                        ),
     844                );
    471845        }
    472846
     
    498872
    499873        /**
     874         * @coversNothing
     875         * @ticket 56922
     876         */
     877        public function test_delete_item() {
     878                // A proper data provider cannot be used because this method's signature must match the parent method.
     879                // Therefore, actual tests are performed in the test_delete_item_with_data_provider method.
     880                $this->assertTrue( true );
     881        }
     882
     883        /**
     884         * @dataProvider data_delete_item_with_data_provider
    500885         * @covers WP_REST_Templates_Controller::delete_item
    501886         * @ticket 56922
    502          */
    503         public function test_delete_item() {
     887         *
     888         * @param string $parent_post_property_name A class property name that contains the parent post object.
     889         * @param string $revisions_property_name   A class property name that contains the revisions array.
     890         * @param string $rest_base                 Base part of the REST API endpoint to test.
     891         * @param string $template_id               Template ID to use in the test.
     892         */
     893        public function test_delete_item_with_data_provider( $parent_post_property_name, $revisions_property_name, $rest_base, $template_id ) {
    504894                wp_set_current_user( self::$admin_id );
    505895
    506                 $revision_id       = _wp_put_post_revision( self::$template_post );
    507                 self::$revisions[] = $revision_id;
    508 
    509                 $request = new WP_REST_Request( 'DELETE', '/wp/v2/templates/' . self::TEST_THEME . '/' . self::TEMPLATE_NAME . '/revisions/' . $revision_id );
     896                $parent_post = self::$$parent_post_property_name;
     897                $revisions   = self::$$revisions_property_name;
     898
     899                $revision_id = _wp_put_post_revision( $parent_post );
     900                $revisions[] = $revision_id;
     901
     902                $request = new WP_REST_Request( 'DELETE', '/wp/v2/' . $rest_base . '/' . $template_id . '/revisions/' . $revision_id );
    510903                $request->set_param( 'force', true );
    511904                $response = rest_get_server()->dispatch( $request );
     
    516909
    517910        /**
     911         * Data provider for test_delete_item_with_data_provider.
     912         *
     913         * @return array
     914         */
     915        public function data_delete_item_with_data_provider() {
     916                return array(
     917                        'templates'      => array(
     918                                'template_post',
     919                                'template_revisions',
     920                                'templates',
     921                                self::TEST_THEME . '//' . self::TEMPLATE_NAME,
     922                        ),
     923                        'template parts' => array(
     924                                'template_part_post',
     925                                'template_part_revisions',
     926                                'template-parts',
     927                                self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME,
     928                        ),
     929                );
     930        }
     931
     932        /**
     933         * @dataProvider data_delete_item_incorrect_permission
    518934         * @covers WP_REST_Templates_Controller::delete_item
    519935         * @ticket 56922
    520          */
    521         public function test_delete_item_incorrect_permission() {
     936         *
     937         * @param string $parent_post_property_name A class property name that contains the parent post object.
     938         * @param string $revisions_property_name   A class property name that contains the revisions array.
     939         * @param string $rest_base                 Base part of the REST API endpoint to test.
     940         * @param string $template_id               Template ID to use in the test.
     941         */
     942        public function test_delete_item_incorrect_permission( $parent_post_property_name, $revisions_property_name, $rest_base, $template_id ) {
    522943                wp_set_current_user( self::$contributor_id );
    523                 $revision_id       = _wp_put_post_revision( self::$template_post );
    524                 self::$revisions[] = $revision_id;
    525 
    526                 $request = new WP_REST_Request( 'DELETE', '/wp/v2/templates/' . self::TEST_THEME . '/' . self::TEMPLATE_NAME . '/revisions/' . $revision_id );
     944                $parent_post = self::$$parent_post_property_name;
     945                $revisions   = self::$$revisions_property_name;
     946
     947                $revision_id = _wp_put_post_revision( $parent_post );
     948                $revisions[] = $revision_id;
     949
     950                $request = new WP_REST_Request( 'DELETE', '/wp/v2/' . $rest_base . '/' . $template_id . '/revisions/' . $revision_id );
    527951                $request->set_param( 'force', true );
    528952                $response = rest_get_server()->dispatch( $request );
     
    531955
    532956        /**
     957         * Data provider for test_delete_item_with_data_provider.
     958         *
     959         * @return array
     960         */
     961        public function data_delete_item_incorrect_permission() {
     962                return array(
     963                        'templates'      => array(
     964                                'template_post',
     965                                'template_revisions',
     966                                'templates',
     967                                self::TEST_THEME . '//' . self::TEMPLATE_NAME,
     968                        ),
     969                        'template parts' => array(
     970                                'template_part_post',
     971                                'template_part_revisions',
     972                                'template-parts',
     973                                self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME,
     974                        ),
     975                );
     976        }
     977
     978        /**
     979         * @dataProvider data_delete_item_no_permission
    533980         * @covers WP_REST_Templates_Controller::delete_item
    534981         * @ticket 56922
    535          */
    536         public function test_delete_item_no_permission() {
     982         *
     983         * @param string $parent_post_property_name A class property name that contains the parent post object.
     984         * @param string $revisions_property_name   A class property name that contains the revisions array.
     985         * @param string $rest_base                 Base part of the REST API endpoint to test.
     986         * @param string $template_id               Template ID to use in the test.
     987         */
     988        public function test_delete_item_no_permission( $parent_post_property_name, $revisions_property_name, $rest_base, $template_id ) {
    537989                wp_set_current_user( 0 );
    538                 $revision_id       = _wp_put_post_revision( self::$template_post );
    539                 self::$revisions[] = $revision_id;
    540 
    541                 $request = new WP_REST_Request( 'DELETE', '/wp/v2/templates/' . self::TEST_THEME . '/' . self::TEMPLATE_NAME . '/revisions/' . $revision_id );
     990
     991                $parent_post = self::$$parent_post_property_name;
     992                $revisions   = self::$$revisions_property_name;
     993
     994                $revision_id = _wp_put_post_revision( $parent_post );
     995                $revisions[] = $revision_id;
     996
     997                $request = new WP_REST_Request( 'DELETE', '/wp/v2/' . $rest_base . '/' . $template_id . '/revisions/' . $revision_id );
    542998                $request->set_param( 'force', true );
    543999                $response = rest_get_server()->dispatch( $request );
     
    5461002
    5471003        /**
     1004         * Data provider for test_delete_item_no_permission.
     1005         *
     1006         * @return array
     1007         */
     1008        public function data_delete_item_no_permission() {
     1009                return array(
     1010                        'templates'      => array(
     1011                                'template_post',
     1012                                'template_revisions',
     1013                                'templates',
     1014                                self::TEST_THEME . '//' . self::TEMPLATE_NAME,
     1015                        ),
     1016                        'template parts' => array(
     1017                                'template_part_post',
     1018                                'template_part_revisions',
     1019                                'template-parts',
     1020                                self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME,
     1021                        ),
     1022                );
     1023        }
     1024
     1025        /**
     1026         * @dataProvider data_delete_item_not_found
    5481027         * @covers WP_REST_Template_Revisions_Controller::get_item
    5491028         * @ticket 56922
    550          */
    551         public function test_delete_item_not_found() {
     1029         *
     1030         * @param string $parent_post_property_name A class property name that contains the parent post object.
     1031         * @param string $revisions_property_name   A class property name that contains the revisions array.
     1032         * @param string $rest_base                 Base part of the REST API endpoint to test.
     1033         */
     1034        public function test_delete_item_not_found( $parent_post_property_name, $revisions_property_name, $rest_base ) {
    5521035                wp_set_current_user( self::$admin_id );
    5531036
    554                 $revision_id       = _wp_put_post_revision( self::$template_post );
    555                 self::$revisions[] = $revision_id;
    556 
    557                 $request = new WP_REST_Request( 'DELETE', '/wp/v2/templates/invalid//parent/revisions/' . $revision_id );
     1037                $parent_post = self::$$parent_post_property_name;
     1038                $revisions   = self::$$revisions_property_name;
     1039
     1040                $revision_id = _wp_put_post_revision( $parent_post );
     1041                $revisions[] = $revision_id;
     1042
     1043                $request = new WP_REST_Request( 'DELETE', '/wp/v2/' . $rest_base . '/invalid//parent/revisions/' . $revision_id );
    5581044                $request->set_param( 'force', true );
    5591045                $response = rest_get_server()->dispatch( $request );
    5601046                $this->assertErrorResponse( 'rest_post_invalid_parent', $response, WP_Http::NOT_FOUND );
    5611047        }
     1048
     1049        /**
     1050         * Data provider for test_delete_item_not_found.
     1051         *
     1052         * @return array
     1053         */
     1054        public function data_delete_item_not_found() {
     1055                return array(
     1056                        'templates'      => array(
     1057                                'template_post',
     1058                                'template_revisions',
     1059                                'templates',
     1060                        ),
     1061                        'template parts' => array(
     1062                                'template_part_post',
     1063                                'template_part_revisions',
     1064                                'template-parts',
     1065                        ),
     1066                );
     1067        }
    5621068}
Note: See TracChangeset for help on using the changeset viewer.