Make WordPress Core


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

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

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

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

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

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

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