diff --git a/tests/phpunit/includes/testcase.php b/tests/phpunit/includes/testcase.php index 0528cfffa7..b06fffe2c1 100644 --- a/tests/phpunit/includes/testcase.php +++ b/tests/phpunit/includes/testcase.php @@ -184,8 +184,10 @@ class WP_UnitTestCase extends PHPUnit_Framework_TestCase { * it has a chance to do so. */ protected function reset_post_types() { - foreach ( get_post_types() as $pt ) { - _unregister_post_type( $pt ); + foreach ( get_post_types( array(), 'objects' ) as $pt ) { + if ( empty( $pt->tests_no_auto_unregister ) ) { + _unregister_post_type( $pt->name ); + } } create_initial_post_types(); } diff --git a/tests/phpunit/tests/rest-api/rest-comments-controller.php b/tests/phpunit/tests/rest-api/rest-comments-controller.php index 9de7d88308..99de8bd110 100644 --- a/tests/phpunit/tests/rest-api/rest-comments-controller.php +++ b/tests/phpunit/tests/rest-api/rest-comments-controller.php @@ -76,7 +76,9 @@ class WP_Test_REST_Comments_Controller extends WP_Test_REST_Controller_Testcase } public static function wpTearDownAfterClass() { + self::delete_user( self::$superadmin_id ); self::delete_user( self::$admin_id ); + self::delete_user( self::$editor_id ); self::delete_user( self::$subscriber_id ); self::delete_user( self::$author_id ); diff --git a/tests/phpunit/tests/rest-api/rest-posts-controller.php b/tests/phpunit/tests/rest-api/rest-posts-controller.php index 67d4b0eea5..a026b8c2f1 100644 --- a/tests/phpunit/tests/rest-api/rest-posts-controller.php +++ b/tests/phpunit/tests/rest-api/rest-posts-controller.php @@ -57,6 +57,7 @@ class WP_Test_REST_Posts_Controller extends WP_Test_REST_Post_Type_Controller_Te wp_delete_post( self::$post_id, true ); + self::delete_user( self::$superadmin_id ); self::delete_user( self::$editor_id ); self::delete_user( self::$author_id ); self::delete_user( self::$contributor_id ); diff --git a/tests/phpunit/tests/rest-api/rest-tags-controller.php b/tests/phpunit/tests/rest-api/rest-tags-controller.php index bdca9cb852..cb81b17159 100644 --- a/tests/phpunit/tests/rest-api/rest-tags-controller.php +++ b/tests/phpunit/tests/rest-api/rest-tags-controller.php @@ -35,7 +35,9 @@ class WP_Test_REST_Tags_Controller extends WP_Test_REST_Controller_Testcase { } public static function wpTearDownAfterClass() { + self::delete_user( self::$superadmin ); self::delete_user( self::$administrator ); + self::delete_user( self::$editor ); self::delete_user( self::$subscriber ); } diff --git a/tests/phpunit/tests/rest-api/rest-users-controller.php b/tests/phpunit/tests/rest-api/rest-users-controller.php index 2f17495157..0d592814e5 100644 --- a/tests/phpunit/tests/rest-api/rest-users-controller.php +++ b/tests/phpunit/tests/rest-api/rest-users-controller.php @@ -13,9 +13,9 @@ class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { protected static $superadmin; protected static $user; protected static $editor; - protected static $editor2; - protected static $secret_editor; - protected static $secret_editor2; + protected static $draft_editor; + protected static $authors = array(); + protected static $posts = array(); protected static $site; public static function wpSetUpBeforeClass( $factory ) { @@ -30,17 +30,38 @@ class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { 'role' => 'editor', 'user_email' => 'editor@example.com', ) ); - self::$editor2 = $factory->user->create( array( + self::$draft_editor = $factory->user->create( array( 'role' => 'editor', - 'user_email' => 'editor2@example.com', + 'user_email' => 'draft-editor@example.com', ) ); - self::$secret_editor = $factory->user->create( array( - 'role' => 'editor', - 'user_email' => 'secret_editor@example.com', + + foreach ( array( true, false ) as $show_in_rest ) { + foreach ( array( true, false ) as $public ) { + $post_type_name = 'r_' . json_encode( $show_in_rest ) . '_p_' . json_encode( $public ); + register_post_type( $post_type_name, array( + 'public' => $public, + 'show_in_rest' => $show_in_rest, + 'tests_no_auto_unregister' => true, + ) ); + self::$authors[ $post_type_name ] = $factory->user->create( array( + 'role' => 'editor', + 'user_email' => 'author_' . $post_type_name . '@example.com', + ) ); + self::$posts[ $post_type_name ] = $factory->post->create( array( + 'post_type' => $post_type_name, + 'post_author' => self::$authors[ $post_type_name ], + ) ); + } + } + + self::$posts['post'] = $factory->post->create( array( + 'post_type' => 'post', + 'post_author' => self::$editor, ) ); - self::$secret_editor2 = $factory->user->create( array( - 'role' => 'editor', - 'user_email' => 'secret_editor2@example.com', + self::$posts['r_true_p_true_DRAFT'] = $factory->post->create( array( + 'post_type' => 'r_true_p_true', + 'post_author' => self::$draft_editor, + 'post_status' => 'draft', ) ); if ( is_multisite() ) { @@ -52,9 +73,18 @@ class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { public static function wpTearDownAfterClass() { self::delete_user( self::$user ); self::delete_user( self::$editor ); - self::delete_user( self::$editor2 ); - self::delete_user( self::$secret_editor ); - self::delete_user( self::$secret_editor2 ); + self::delete_user( self::$draft_editor ); + + foreach ( self::$posts as $post ) { + wp_delete_post( $post, true ); + } + foreach ( self::$authors as $author ) { + self::delete_user( $author ); + } + _unregister_post_type( 'r_true_p_true' ); + _unregister_post_type( 'r_true_p_false' ); + _unregister_post_type( 'r_false_p_true' ); + _unregister_post_type( 'r_false_p_false' ); if ( is_multisite() ) { wpmu_delete_blog( self::$site, true ); @@ -66,12 +96,6 @@ class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { */ public function setUp() { parent::setUp(); - - register_post_type( 'rest_public', array( 'public' => true, 'show_in_rest' => true ) ); - register_post_type( 'secret_public', array( 'public' => true, 'show_in_rest' => false ) ); - register_post_type( 'secret_hidden', array( 'public' => false, 'show_in_rest' => false ) ); - register_post_type( 'rest_hidden', array( 'public' => false, 'show_in_rest' => true ) ); - $this->endpoint = new WP_REST_Users_Controller(); } @@ -169,36 +193,14 @@ class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { } public function test_get_items_unauthenticated_includes_authors_of_post_types_shown_in_rest() { - $created_posts = array(); - $created_posts[] = $this->factory->post->create( array( - 'post_author' => self::$user, - 'post_status' => 'publish', - ) ); - // Expose authors if show_in_rest is true, even if the post_type is not public. - $created_posts[] = $this->factory->post->create( array( - 'post_type' => 'rest_hidden', - 'post_author' => self::$editor, - 'post_status' => 'publish', - ) ); - $created_posts[] = $this->factory->post->create( array( - 'post_type' => 'rest_public', - 'post_author' => self::$editor2, - 'post_status' => 'publish', - ) ); - $created_posts[] = $this->factory->post->create( array( - 'post_type' => 'rest_public', - 'post_author' => self::$secret_editor, - 'post_status' => 'draft', - ) ); - $request = new WP_REST_Request( 'GET', '/wp/v2/users' ); $response = $this->server->dispatch( $request ); $users = $response->get_data(); - $public_post_types = array_values( get_post_types( array( 'show_in_rest' => true ), 'names' ) ); + $rest_post_types = array_values( get_post_types( array( 'show_in_rest' => true ), 'names' ) ); foreach ( $users as $user ) { - $this->assertTrue( count_user_posts( $user['id'], $public_post_types ) > 0 ); + $this->assertTrue( count_user_posts( $user['id'], $rest_post_types ) > 0 ); // Ensure we don't expose non-public data. $this->assertArrayNotHasKey( 'capabilities', $user ); @@ -213,55 +215,45 @@ class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { $this->assertArrayNotHasKey( 'locale', $user ); } - $this->assertTrue( in_array( self::$user, wp_list_pluck( $users, 'id' ), true ) ); - $this->assertTrue( in_array( self::$editor, wp_list_pluck( $users, 'id' ), true ) ); - $this->assertTrue( in_array( self::$editor2, wp_list_pluck( $users, 'id' ), true ) ); + $user_ids = wp_list_pluck( $users, 'id' ); - // Do not include authors of unpublished posts. - $this->assertFalse( in_array( self::$secret_editor, wp_list_pluck( $users, 'id' ), true ) ); - - foreach ( $created_posts as $post_id ) { - wp_delete_post( $post_id, true ); - } + $this->assertTrue( in_array( self::$editor , $user_ids, true ) ); + $this->assertTrue( in_array( self::$authors['r_true_p_true'] , $user_ids, true ) ); + $this->assertTrue( in_array( self::$authors['r_true_p_false'], $user_ids, true ) ); + $this->assertCount( 3, $user_ids ); } public function test_get_items_unauthenticated_does_not_include_authors_of_post_types_not_shown_in_rest() { - $created_posts = array(); - $created_posts[] = $this->factory->post->create( array( - 'post_type' => 'secret_hidden', - 'post_author' => self::$secret_editor, - 'post_status' => 'publish', - ) ); - $created_posts[] = $this->factory->post->create( array( - 'post_type' => 'secret_public', - 'post_author' => self::$secret_editor2, - 'post_status' => 'publish', - ) ); - $request = new WP_REST_Request( 'GET', '/wp/v2/users' ); $response = $this->server->dispatch( $request ); - $data = $response->get_data(); + $users = $response->get_data(); + $user_ids = wp_list_pluck( $users, 'id' ); - $this->assertFalse( in_array( self::$secret_editor, wp_list_pluck( $data, 'id' ), true ) ); - $this->assertFalse( in_array( self::$secret_editor2, wp_list_pluck( $data, 'id' ), true ) ); + $this->assertFalse( in_array( self::$authors['r_false_p_true'] , $user_ids, true ) ); + $this->assertFalse( in_array( self::$authors['r_false_p_false'], $user_ids, true ) ); + } - foreach ( $created_posts as $post_id ) { - wp_delete_post( $post_id, true ); - } + public function test_get_items_unauthenticated_does_not_include_users_without_published_posts() { + $request = new WP_REST_Request( 'GET', '/wp/v2/users' ); + $response = $this->server->dispatch( $request ); + $users = $response->get_data(); + $user_ids = wp_list_pluck( $users, 'id' ); + + $this->assertFalse( in_array( self::$draft_editor, $user_ids, true ) ); + $this->assertFalse( in_array( self::$user , $user_ids, true ) ); } public function test_get_items_pagination_headers() { wp_set_current_user( self::$user ); - // Start of the index, including the six existing users. for ( $i = 0; $i < 44; $i++ ) { $this->factory->user->create( array( - 'name' => "User {$i}", - ) ); + 'name' => "User {$i}", + ) ); } $request = new WP_REST_Request( 'GET', '/wp/v2/users' ); $response = $this->server->dispatch( $request ); $headers = $response->get_headers(); - $this->assertEquals( 51, $headers['X-WP-Total'] ); + $this->assertEquals( 53, $headers['X-WP-Total'] ); $this->assertEquals( 6, $headers['X-WP-TotalPages'] ); $next_link = add_query_arg( array( 'page' => 2, @@ -276,7 +268,7 @@ class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { $request->set_param( 'page', 3 ); $response = $this->server->dispatch( $request ); $headers = $response->get_headers(); - $this->assertEquals( 52, $headers['X-WP-Total'] ); + $this->assertEquals( 54, $headers['X-WP-Total'] ); $this->assertEquals( 6, $headers['X-WP-TotalPages'] ); $prev_link = add_query_arg( array( 'page' => 2, @@ -291,7 +283,7 @@ class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { $request->set_param( 'page', 6 ); $response = $this->server->dispatch( $request ); $headers = $response->get_headers(); - $this->assertEquals( 52, $headers['X-WP-Total'] ); + $this->assertEquals( 54, $headers['X-WP-Total'] ); $this->assertEquals( 6, $headers['X-WP-TotalPages'] ); $prev_link = add_query_arg( array( 'page' => 5, @@ -303,7 +295,7 @@ class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { $request->set_param( 'page', 8 ); $response = $this->server->dispatch( $request ); $headers = $response->get_headers(); - $this->assertEquals( 52, $headers['X-WP-Total'] ); + $this->assertEquals( 54, $headers['X-WP-Total'] ); $this->assertEquals( 6, $headers['X-WP-TotalPages'] ); $prev_link = add_query_arg( array( 'page' => 6, @@ -474,12 +466,12 @@ class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { public function test_get_items_offset() { wp_set_current_user( self::$user ); - // 5 users created in __construct(), plus default user. + // 7 users created in wpSetUpBeforeClass(), plus default user. $this->factory->user->create(); $request = new WP_REST_Request( 'GET', '/wp/v2/users' ); $request->set_param( 'offset', 1 ); $response = $this->server->dispatch( $request ); - $this->assertCount( 7, $response->get_data() ); + $this->assertCount( 9, $response->get_data() ); // 'offset' works with 'per_page' $request->set_param( 'per_page', 2 ); $response = $this->server->dispatch( $request ); @@ -530,6 +522,7 @@ class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { $id1 = $this->factory->user->create(); $id2 = $this->factory->user->create(); $request = new WP_REST_Request( 'GET', '/wp/v2/users' ); + $request->set_param( 'per_page', 20 ); // there are >10 users at this point $response = $this->server->dispatch( $request ); $data = $response->get_data(); $this->assertTrue( in_array( $id1, wp_list_pluck( $data, 'id' ), true ) ); @@ -688,15 +681,63 @@ class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { $this->assertEquals( $data['extra_capabilities'], new stdClass() ); } - public function test_get_item_without_permission() { + public function test_cannot_get_item_without_permission() { wp_set_current_user( self::$editor ); - $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d', self::$user ) ); $response = $this->server->dispatch( $request ); - $this->assertErrorResponse( 'rest_user_cannot_view', $response, 403 ); } + public function test_can_get_item_author_of_rest_true_public_true_unauthenticated() { + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d', self::$authors['r_true_p_true'] ) ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + } + + public function test_can_get_item_author_of_rest_true_public_true_authenticated() { + wp_set_current_user( self::$editor ); + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d', self::$authors['r_true_p_true'] ) ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + } + + public function test_can_get_item_author_of_rest_true_public_false() { + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d', self::$authors['r_true_p_false'] ) ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + } + + public function test_cannot_get_item_author_of_rest_false_public_true_unauthenticated() { + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d', self::$authors['r_false_p_true'] ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_user_cannot_view', $response, 401 ); + } + + public function test_cannot_get_item_author_of_rest_false_public_true_without_permission() { + wp_set_current_user( self::$editor ); + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d', self::$authors['r_false_p_true'] ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_user_cannot_view', $response, 403 ); + } + + public function test_cannot_get_item_author_of_rest_false_public_false() { + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d', self::$authors['r_false_p_false'] ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_user_cannot_view', $response, 401 ); + } + + public function test_can_get_item_author_of_post() { + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d', self::$editor ) ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + } + + public function test_cannot_get_item_author_of_draft() { + $request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d', self::$draft_editor ) ); + $response = $this->server->dispatch( $request ); + $this->assertErrorResponse( 'rest_user_cannot_view', $response, 401 ); + } + public function test_get_item_published_author_post() { $this->author_id = $this->factory->user->create( array( 'role' => 'author', @@ -2166,11 +2207,6 @@ class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase { } public function tearDown() { - _unregister_post_type( 'rest_public' ); - _unregister_post_type( 'secret_public' ); - _unregister_post_type( 'secret_hidden' ); - _unregister_post_type( 'rest_hidden' ); - parent::tearDown(); }