Make WordPress Core

Changeset 59605


Ignore:
Timestamp:
01/15/2025 12:44:43 PM (19 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:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-template-revisions-controller.php

    r58156 r59605  
    171171                                'rest_post_invalid_parent',
    172172                                __( 'Invalid template parent ID.' ),
    173                                 array( 'status' => 404 )
     173                                array( 'status' => WP_Http::NOT_FOUND )
     174                        );
     175                }
     176
     177                $parent_post_id = isset( $template->wp_id ) ? (int) $template->wp_id : 0;
     178
     179                if ( $parent_post_id <= 0 ) {
     180                        return new WP_Error(
     181                                'rest_invalid_template',
     182                                __( 'Templates based on theme files can\'t have revisions.' ),
     183                                array( 'status' => WP_Http::BAD_REQUEST )
    174184                        );
    175185                }
  • trunk/tests/phpunit/tests/rest-api/wpRestTemplateAutosavesController.php

    r59073 r59605  
    2323         * @var string
    2424         */
    25         const PARENT_POST_TYPE = 'wp_template';
     25        const TEMPLATE_PART_NAME = 'my_template_part';
     26
     27        /**
     28         * @var string
     29         */
     30        const TEMPLATE_POST_TYPE = 'wp_template';
     31
     32        /**
     33         * @var string
     34         */
     35        const TEMPLATE_PART_POST_TYPE = 'wp_template_part';
    2636
    2737        /**
     
    5363
    5464        /**
    55          * Create fake data before our tests run.
     65         * Template part post.
     66         *
     67         * @since 6.7.0
     68         *
     69         * @var WP_Post
     70         */
     71        private static $template_part_post;
     72
     73        /**
     74         * Create fake data before the tests run.
    5675         *
    5776         * @param WP_UnitTest_Factory $factory Helper that lets us create fake data.
     
    7493                self::$template_post = $factory->post->create_and_get(
    7594                        array(
    76                                 'post_type'    => self::PARENT_POST_TYPE,
     95                                'post_type'    => self::TEMPLATE_POST_TYPE,
    7796                                'post_name'    => self::TEMPLATE_NAME,
    78                                 'post_title'   => 'My Template',
     97                                'post_title'   => 'My template',
    7998                                'post_content' => 'Content',
    8099                                'post_excerpt' => 'Description of my template',
     
    87106                );
    88107                wp_set_post_terms( self::$template_post->ID, self::TEST_THEME, 'wp_theme' );
     108
     109                // Set up template part post.
     110                self::$template_part_post = $factory->post->create_and_get(
     111                        array(
     112                                'post_type'    => self::TEMPLATE_PART_POST_TYPE,
     113                                'post_name'    => self::TEMPLATE_PART_NAME,
     114                                'post_title'   => 'My template part',
     115                                'post_content' => 'Content',
     116                                'post_excerpt' => 'Description of my template part',
     117                                'tax_input'    => array(
     118                                        'wp_theme'              => array(
     119                                                self::TEST_THEME,
     120                                        ),
     121                                        'wp_template_part_area' => array(
     122                                                WP_TEMPLATE_PART_AREA_HEADER,
     123                                        ),
     124                                ),
     125                        )
     126                );
     127                wp_set_post_terms( self::$template_part_post->ID, self::TEST_THEME, 'wp_theme' );
     128                wp_set_post_terms( self::$template_part_post->ID, WP_TEMPLATE_PART_AREA_HEADER, 'wp_template_part_area' );
    89129        }
    90130
     
    118158
    119159        /**
     160         * @coversNothing
     161         * @ticket 56922
     162         */
     163        public function test_context_param() {
     164                // A proper data provider cannot be used because this method's signature must match the parent method.
     165                // Therefore, actual tests are performed in the test_context_param_with_data_provider method.
     166                $this->assertTrue( true );
     167        }
     168
     169        /**
     170         * @dataProvider data_context_param_with_data_provider
    120171         * @covers WP_REST_Template_Autosaves_Controller::get_context_param
    121172         * @ticket 56922
    122          */
    123         public function test_context_param() {
     173         *
     174         * @param string $rest_base   Base part of the REST API endpoint to test.
     175         * @param string $template_id Template ID to use in the test.
     176         */
     177        public function test_context_param_with_data_provider( $rest_base, $template_id ) {
    124178                // Collection.
    125                 $request  = new WP_REST_Request( 'OPTIONS', '/wp/v2/templates/' . self::TEST_THEME . '/' . self::TEMPLATE_NAME . '/autosaves' );
     179                $request  = new WP_REST_Request( 'OPTIONS', '/wp/v2/' . $rest_base . '/' . $template_id . '/autosaves' );
    126180                $response = rest_get_server()->dispatch( $request );
    127181                $data     = $response->get_data();
     
    145199
    146200                // Single.
    147                 $request  = new WP_REST_Request( 'OPTIONS', '/wp/v2/templates/' . self::TEST_THEME . '/' . self::TEMPLATE_NAME . '/autosaves/1' );
     201                $request  = new WP_REST_Request( 'OPTIONS', '/wp/v2/' . $rest_base . '/' . $template_id . '/autosaves/1' );
    148202                $response = rest_get_server()->dispatch( $request );
    149203                $data     = $response->get_data();
     
    166220
    167221        /**
     222         * Data provider for test_context_param_with_data_provider.
     223         *
     224         * @return array
     225         */
     226        public function data_context_param_with_data_provider() {
     227                return array(
     228                        'templates'      => array( 'templates', self::TEST_THEME . '//' . self::TEMPLATE_NAME ),
     229                        'template parts' => array( 'template-parts', self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME ),
     230                );
     231        }
     232
     233        /**
     234         * @coversNothing
     235         * @ticket 56922
     236         */
     237        public function test_get_items() {
     238                // A proper data provider cannot be used because this method's signature must match the parent method.
     239                // Therefore, actual tests are performed in the test_get_items_with_data_provider method.
     240                $this->assertTrue( true );
     241        }
     242
     243        /**
     244         * @dataProvider data_get_items_with_data_provider
    168245         * @covers WP_REST_Template_Autosaves_Controller::get_items
    169246         * @ticket 56922
    170          */
    171         public function test_get_items() {
     247         *
     248         * @param string $parent_post_property_name  A class property name that contains the parent post object.
     249         * @param string $rest_base                  Base part of the REST API endpoint to test.
     250         * @param string $template_id                Template ID to use in the test.
     251         */
     252        public function test_get_items_with_data_provider( $parent_post_property_name, $rest_base, $template_id ) {
    172253                wp_set_current_user( self::$admin_id );
     254                // Cannot access this property in the data provider because it is not initialized at the time of execution.
     255                $parent_post      = self::$$parent_post_property_name;
    173256                $autosave_post_id = wp_create_post_autosave(
    174257                        array(
    175258                                'post_content' => 'Autosave content.',
    176                                 'post_ID'      => self::$template_post->ID,
    177                                 'post_type'    => self::PARENT_POST_TYPE,
     259                                'post_ID'      => $parent_post->ID,
     260                                'post_type'    => $parent_post->post_type,
    178261                        )
    179262                );
     
    181264                $request   = new WP_REST_Request(
    182265                        'GET',
    183                         '/wp/v2/templates/' . self::TEST_THEME . '/' . self::TEMPLATE_NAME . '/autosaves'
     266                        '/wp/v2/' . $rest_base . '/' . $template_id . '/autosaves'
    184267                );
    185268                $response  = rest_get_server()->dispatch( $request );
    186269                $autosaves = $response->get_data();
     270                $this->assertSame( WP_Http::OK, $response->get_status(), 'Response is expected to have a status code of 200.' );
    187271
    188272                $this->assertCount(
     
    198282                );
    199283                $this->assertSame(
    200                         self::$template_post->ID,
     284                        $parent_post->ID,
    201285                        $autosaves[0]['parent'],
    202286                        'Failed asserting that the parent ID of the autosave matches the template post ID.'
     
    210294
    211295        /**
     296         * Data provider for test_get_items_with_data_provider.
     297         *
     298         * @return array
     299         */
     300        public function data_get_items_with_data_provider() {
     301                return array(
     302                        'templates'      => array( 'template_post', 'templates', self::TEST_THEME . '//' . self::TEMPLATE_NAME ),
     303                        'template parts' => array( 'template_part_post', 'template-parts', self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME ),
     304                );
     305        }
     306
     307        /**
     308         * @dataProvider data_get_items_for_templates_based_on_theme_files_should_return_bad_response_status
     309         * @ticket 61970
     310         *
     311         * @param string $rest_base   Base part of the REST API endpoint to test.
     312         * @param string $template_id Template ID to use in the test.
     313         */
     314        public function test_get_items_for_templates_based_on_theme_files_should_return_bad_response_status( $rest_base, $template_id ) {
     315                wp_set_current_user( self::$admin_id );
     316                switch_theme( 'block-theme' );
     317
     318                $request = new WP_REST_Request( 'GET', '/wp/v2/' . $rest_base . '/' . $template_id . '/autosaves' );
     319
     320                $response = rest_get_server()->dispatch( $request );
     321                $this->assertErrorResponse(
     322                        'rest_invalid_template',
     323                        $response,
     324                        WP_Http::BAD_REQUEST,
     325                        sprintf( 'Response is expected to have a status code of %d.', WP_Http::BAD_REQUEST )
     326                );
     327        }
     328
     329        /**
     330         * Data provider for test_get_items_for_templates_based_on_theme_files_should_return_bad_response_status.
     331         *
     332         * @return array
     333         */
     334        public function data_get_items_for_templates_based_on_theme_files_should_return_bad_response_status() {
     335                return array(
     336                        'templates'      => array( 'templates', self::TEST_THEME . '//page-home' ),
     337                        'template parts' => array( 'template-parts', self::TEST_THEME . '//small-header' ),
     338                );
     339        }
     340
     341        /**
     342         * @dataProvider data_get_item_for_templates_based_on_theme_files_should_return_bad_response_status
     343         * @ticket 56922
     344         *
     345         * @param string $rest_base   Base part of the REST API endpoint to test.
     346         * @param string $template_id Template ID to use in the test.
     347         */
     348        public function test_get_item_for_templates_based_on_theme_files_should_return_bad_response_status( $rest_base, $template_id ) {
     349                wp_set_current_user( self::$admin_id );
     350                switch_theme( 'block-theme' );
     351
     352                $request = new WP_REST_Request( 'GET', '/wp/v2/' . $rest_base . '/' . $template_id . '/autosaves/1' );
     353
     354                $response = rest_get_server()->dispatch( $request );
     355                $this->assertErrorResponse(
     356                        'rest_invalid_template',
     357                        $response,
     358                        WP_Http::BAD_REQUEST,
     359                        sprintf( 'Response is expected to have a status code of %d.', WP_Http::BAD_REQUEST )
     360                );
     361        }
     362
     363        /**
     364         * Data provider for test_get_item_for_templates_based_on_theme_files_should_return_bad_response_status.
     365         *
     366         * @return array
     367         */
     368        public function data_get_item_for_templates_based_on_theme_files_should_return_bad_response_status() {
     369                return array(
     370                        'templates'      => array( 'templates', self::TEST_THEME . '//page-home' ),
     371                        'template parts' => array( 'template-parts', self::TEST_THEME . '//small-header' ),
     372                );
     373        }
     374
     375        /**
     376         * @coversNothing
     377         * @ticket 56922
     378         */
     379        public function test_get_item() {
     380                // A proper data provider cannot be used because this method's signature must match the parent method.
     381                // Therefore, actual tests are performed in the test_get_item_with_data_provider method.
     382                $this->assertTrue( true );
     383        }
     384
     385        /**
     386         * @dataProvider data_get_item_with_data_provider
    212387         * @covers WP_REST_Template_Autosaves_Controller::get_item
    213388         * @ticket 56922
    214          */
    215         public function test_get_item() {
     389         *
     390         * @param string  $parent_post_property_name  A class property name that contains the parent post object.
     391         * @param string  $rest_base                  Base part of the REST API endpoint to test.
     392         * @param string  $template_id                Template ID to use in the test.
     393         */
     394        public function test_get_item_with_data_provider( $parent_post_property_name, $rest_base, $template_id ) {
    216395                wp_set_current_user( self::$admin_id );
     396
     397                $parent_post = self::$$parent_post_property_name;
    217398
    218399                $autosave_post_id = wp_create_post_autosave(
    219400                        array(
    220401                                'post_content' => 'Autosave content.',
    221                                 'post_ID'      => self::$template_post->ID,
    222                                 'post_type'    => self::PARENT_POST_TYPE,
    223                         )
    224                 );
    225 
    226                 $request  = new WP_REST_Request( 'GET', '/wp/v2/templates/' . self::TEST_THEME . '/' . self::TEMPLATE_NAME . '/autosaves/' . $autosave_post_id );
    227                 $response = rest_get_server()->dispatch( $request );
     402                                'post_ID'      => $parent_post->ID,
     403                                'post_type'    => $parent_post->post_type,
     404                        )
     405                );
     406
     407                $request  = new WP_REST_Request( 'GET', '/wp/v2/' . $rest_base . '/' . $template_id . '/autosaves/' . $autosave_post_id );
     408                $response = rest_get_server()->dispatch( $request );
     409
     410                $this->assertSame( WP_Http::OK, $response->get_status(), 'Response is expected to have a status code of 200.' );
    228411                $autosave = $response->get_data();
    229412
     
    235418                );
    236419                $this->assertSame(
    237                         self::$template_post->ID,
     420                        $parent_post->ID,
    238421                        $autosave['parent'],
    239422                        sprintf(
    240423                                'Failed asserting that the parent id of the autosave is the same as %s.',
    241                                 self::$template_post->ID
    242                         )
    243                 );
    244         }
    245 
    246         /**
     424                                $parent_post->ID
     425                        )
     426                );
     427        }
     428
     429        /**
     430         * Data provider for test_get_item_with_data_provider.
     431         *
     432         * @return array
     433         */
     434        public function data_get_item_with_data_provider() {
     435                return array(
     436                        'templates'      => array( 'template_post', 'templates', self::TEST_THEME . '//' . self::TEMPLATE_NAME ),
     437                        'template parts' => array( 'template_part_post', 'template-parts', self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME ),
     438                );
     439        }
     440
     441        /**
     442         * @coversNothing
     443         * @ticket 56922
     444         */
     445        public function test_prepare_item() {
     446                // A proper data provider cannot be used because this method's signature must match the parent method.
     447                // Therefore, actual tests are performed in the test_prepare_item_with_data_provider method.
     448                $this->assertTrue( true );
     449        }
     450
     451        /**
     452         * @dataProvider data_prepare_item_with_data_provider
    247453         * @covers WP_REST_Template_Autosaves_Controller::prepare_item_for_response
    248454         * @ticket 56922
    249          */
    250         public function test_prepare_item() {
     455         *
     456         * @param string $parent_post_property_name A class property name that contains the parent post object.
     457         * @param string $rest_base                 Base part of the REST API endpoint to test.
     458         * @param string $template_id               Template ID to use in the test.
     459         */
     460        public function test_prepare_item_with_data_provider( $parent_post_property_name, $rest_base, $template_id ) {
    251461                wp_set_current_user( self::$admin_id );
     462                $parent_post      = self::$$parent_post_property_name;
    252463                $autosave_post_id = wp_create_post_autosave(
    253464                        array(
    254465                                'post_content' => 'Autosave content.',
    255                                 'post_ID'      => self::$template_post->ID,
    256                                 'post_type'    => self::PARENT_POST_TYPE,
     466                                'post_ID'      => $parent_post->ID,
     467                                'post_type'    => $parent_post->post_type,
    257468                        )
    258469                );
    259470                $autosave_db_post = get_post( $autosave_post_id );
    260                 $template_id      = self::TEST_THEME . '//' . self::TEMPLATE_NAME;
    261                 $request          = new WP_REST_Request( 'GET', '/wp/v2/templates/' . $template_id . '/autosaves/' . $autosave_db_post->ID );
    262                 $controller       = new WP_REST_Template_Autosaves_Controller( self::PARENT_POST_TYPE );
     471                $request          = new WP_REST_Request( 'GET', '/wp/v2/' . $rest_base . '/' . $template_id . '/autosaves/' . $autosave_db_post->ID );
     472                $controller       = new WP_REST_Template_Autosaves_Controller( $parent_post->post_type );
    263473                $response         = $controller->prepare_item_for_response( $autosave_db_post, $request );
    264474                $this->assertInstanceOf(
     
    276486                );
    277487                $this->assertSame(
    278                         self::$template_post->ID,
     488                        $parent_post->ID,
    279489                        $autosave['parent'],
    280490                        sprintf(
    281491                                'Failed asserting that the parent id of the autosave is the same as %s.',
    282                                 self::$template_post->ID
     492                                $parent_post->ID
    283493                        )
    284494                );
     
    301511
    302512        /**
     513         * Data provider for test_prepare_item_with_data_provider.
     514         *
     515         * @return array
     516         */
     517        public function data_prepare_item_with_data_provider() {
     518                return array(
     519                        'templates'      => array( 'template_post', 'templates', self::TEST_THEME . '//' . self::TEMPLATE_NAME ),
     520                        'template parts' => array( 'template_part_post', 'template-parts', self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME ),
     521                );
     522        }
     523
     524        /**
     525         * @coversNothing
     526         * @ticket 56922
     527         */
     528        public function test_get_item_schema() {
     529                // A proper data provider cannot be used because this method's signature must match the parent method.
     530                // Therefore, actual tests are performed in the test_prepare_item_with_data_provider method.
     531                $this->assertTrue( true );
     532        }
     533
     534        /**
     535         * @dataProvider data_get_item_schema_with_data_provider
    303536         * @covers WP_REST_Template_Autosaves_Controller::get_item_schema
    304537         * @ticket 56922
    305          */
    306         public function test_get_item_schema() {
    307                 $request  = new WP_REST_Request( 'OPTIONS', '/wp/v2/templates/' . self::TEST_THEME . '/' . self::TEMPLATE_NAME . '/autosaves' );
     538         *
     539         * @param string $rest_base             Base part of the REST API endpoint to test.
     540         * @param string $template_id           Template ID to use in the test.
     541         * @param int    $properties_count      Number of properties to check for in the schema.
     542         * @param array  $additional_properties Additional properties to check for in the schema.
     543         */
     544        public function test_get_item_schema_with_data_provider( $rest_base, $template_id, $properties_count, $additional_properties = array() ) {
     545                $request  = new WP_REST_Request( 'OPTIONS', '/wp/v2/' . $rest_base . '/' . $template_id . '/autosaves' );
    308546                $response = rest_get_server()->dispatch( $request );
    309547                $data     = $response->get_data();
     
    311549                $properties = $data['schema']['properties'];
    312550
    313                 $this->assertCount( 19, $properties );
     551                $this->assertCount( $properties_count, $properties );
    314552                $this->assertArrayHasKey( 'id', $properties, 'ID key should exist in properties.' );
    315553                $this->assertArrayHasKey( 'slug', $properties, 'Slug key should exist in properties.' );
     
    325563                $this->assertArrayHasKey( 'author', $properties, 'author key should exist in properties.' );
    326564                $this->assertArrayHasKey( 'modified', $properties, 'modified key should exist in properties.' );
    327                 $this->assertArrayHasKey( 'is_custom', $properties, 'is_custom key should exist in properties.' );
    328565                $this->assertArrayHasKey( 'parent', $properties, 'Parent key should exist in properties.' );
    329566                $this->assertArrayHasKey( 'author_text', $properties, 'author_text key should exist in properties.' );
    330567                $this->assertArrayHasKey( 'original_source', $properties, 'original_source key should exist in properties.' );
    331                 $this->assertArrayHasKey( 'plugin', $properties, 'plugin key should exist in properties.' );
    332         }
    333 
    334         /**
     568                foreach ( $additional_properties as $additional_property ) {
     569                        $this->assertArrayHasKey( $additional_property, $properties, $additional_property . ' key should exist in properties.' );
     570                }
     571        }
     572
     573        /**
     574         * Data provider for test_get_item_schema_with_data_provider.
     575         *
     576         * @return array
     577         */
     578        public function data_get_item_schema_with_data_provider() {
     579                return array(
     580                        'templates'      => array(
     581                                'templates',
     582                                self::TEST_THEME . '//' . self::TEMPLATE_NAME,
     583                                19,
     584                                array( 'is_custom', 'plugin' ),
     585                        ),
     586                        'template parts' => array(
     587                                'template-parts',
     588                                self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME,
     589                                18,
     590                                array( 'area' ),
     591                        ),
     592                );
     593        }
     594
     595        /**
     596         * @coversNothing
     597         * @ticket 56922
     598         */
     599        public function test_create_item() {
     600                // A proper data provider cannot be used because this method's signature must match the parent method.
     601                // Therefore, actual tests are performed in the test_create_item_with_data_provider method.
     602                $this->assertTrue( true );
     603        }
     604
     605        /**
     606         * @dataProvider data_create_item_with_data_provider
    335607         * @covers WP_REST_Template_Autosaves_Controller::create_item
    336608         * @ticket 56922
    337          */
    338         public function test_create_item() {
     609         *
     610         * @param string $rest_base   Base part of the REST API endpoint to test.
     611         * @param string $template_id Template ID to use in the test.
     612         */
     613        public function test_create_item_with_data_provider( $rest_base, $template_id ) {
    339614                wp_set_current_user( self::$admin_id );
    340615
    341                 $template_id = self::TEST_THEME . '/' . self::TEMPLATE_NAME;
    342                 $request     = new WP_REST_Request( 'POST', '/wp/v2/templates/' . $template_id . '/autosaves' );
     616                $request = new WP_REST_Request( 'POST', '/wp/v2/' . $rest_base . '/' . $template_id . '/autosaves' );
    343617                $request->add_header( 'Content-Type', 'application/x-www-form-urlencoded' );
    344618
     
    354628                $response = rest_get_server()->dispatch( $request );
    355629
    356                 $this->assertNotWPError( $response, 'The response from this request should not return a WP_Error object' );
     630                $this->assertNotWPError( $response, 'The response from this request should not return a WP_Error object.' );
    357631                $response = rest_ensure_response( $response );
    358632                $data     = $response->get_data();
    359633
    360                 $this->assertArrayHasKey( 'content', $data, 'Response should contain a key called content' );
    361                 $this->assertSame( $request_parameters['content'], $data['content']['raw'], 'Response data should match for field content' );
    362 
    363                 $this->assertArrayHasKey( 'title', $data, 'Response should contain a key called title' );
    364                 $this->assertSame( $request_parameters['title'], $data['title']['raw'], 'Response data should match for field title' );
    365         }
    366 
    367         /**
    368          * @covers WP_REST_Template_Autosaves_Controller::delete_item
    369          * @ticket 56922
    370          */
    371         public function test_create_item_incorrect_permission() {
     634                $this->assertArrayHasKey( 'content', $data, 'Response should contain a key called content.' );
     635                $this->assertSame( $request_parameters['content'], $data['content']['raw'], 'Response data should match for field content.' );
     636
     637                $this->assertArrayHasKey( 'title', $data, 'Response should contain a key called title.' );
     638                $this->assertSame( $request_parameters['title'], $data['title']['raw'], 'Response data should match for field title.' );
     639        }
     640
     641        /**
     642         * Data provider for test_create_item_with_data_provider.
     643         *
     644         * @return array
     645         */
     646        public function data_create_item_with_data_provider() {
     647                return array(
     648                        'templates'     => array( 'templates', self::TEST_THEME . '//' . self::TEMPLATE_NAME ),
     649                        'template part' => array( 'template-parts', self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME ),
     650                );
     651        }
     652
     653        /**
     654         * @dataProvider data_create_item_incorrect_permission
     655         * @covers WP_REST_Template_Autosaves_Controller::create_item_permissions_check
     656         * @ticket 56922
     657         *
     658         * @param string $rest_base   Base part of the REST API endpoint to test.
     659         * @param string $template_id Template ID to use in the test.
     660         */
     661        public function test_create_item_incorrect_permission( $rest_base, $template_id ) {
    372662                wp_set_current_user( self::$contributor_id );
    373                 $template_id = self::TEST_THEME . '/' . self::TEMPLATE_NAME;
    374                 $request     = new WP_REST_Request( 'POST', '/wp/v2/templates/' . $template_id . '/autosaves' );
    375                 $response    = rest_get_server()->dispatch( $request );
     663                $request  = new WP_REST_Request( 'POST', '/wp/v2/' . $rest_base . '/' . $template_id . '/autosaves' );
     664                $response = rest_get_server()->dispatch( $request );
    376665                $this->assertErrorResponse( 'rest_cannot_manage_templates', $response, WP_Http::FORBIDDEN );
    377666        }
    378667
    379668        /**
    380          * @covers WP_REST_Template_Autosaves_Controller::delete_item
    381          * @ticket 56922
    382          */
    383         public function test_create_item_no_permission() {
     669         * Data provider for test_create_item_incorrect_permission.
     670         *
     671         * @return array
     672         */
     673        public function data_create_item_incorrect_permission() {
     674                return array(
     675                        'template'      => array( 'templates', self::TEST_THEME . '//' . self::TEMPLATE_NAME ),
     676                        'template part' => array( 'template-parts', self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME ),
     677                );
     678        }
     679
     680        /**
     681         * @dataProvider data_create_item_no_permission
     682         * @covers WP_REST_Template_Autosaves_Controller::create_item_permissions_check
     683         * @ticket 56922
     684         *
     685         * @param string $rest_base   Base part of the REST API endpoint to test.
     686         * @param string $template_id Template ID to use in the test.
     687         */
     688        public function test_create_item_no_permission( $rest_base, $template_id ) {
    384689                wp_set_current_user( 0 );
    385                 $template_id = self::TEST_THEME . '/' . self::TEMPLATE_NAME;
    386                 $request     = new WP_REST_Request( 'POST', '/wp/v2/templates/' . $template_id . '/autosaves' );
    387                 $response    = rest_get_server()->dispatch( $request );
     690                $request  = new WP_REST_Request( 'POST', '/wp/v2/' . $rest_base . '/' . $template_id . '/autosaves' );
     691                $response = rest_get_server()->dispatch( $request );
    388692                $this->assertErrorResponse( 'rest_cannot_manage_templates', $response, WP_Http::UNAUTHORIZED );
     693        }
     694
     695        /**
     696         * Data provider for test_create_item_no_permission.
     697         *
     698         * @return array
     699         */
     700        public function data_create_item_no_permission() {
     701                return array(
     702                        'template'      => array( 'templates', self::TEST_THEME . '//' . self::TEMPLATE_NAME ),
     703                        'template part' => array( 'template-parts', self::TEST_THEME . '//' . self::TEMPLATE_PART_NAME ),
     704                );
    389705        }
    390706
  • 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.