Make WordPress Core

Changeset 59605


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