diff --git a/includes/bp-groups/classes/class-bp-rest-group-membership-endpoint.php b/includes/bp-groups/classes/class-bp-rest-group-membership-endpoint.php index 9092b28c..ecd2e86e 100644 --- a/includes/bp-groups/classes/class-bp-rest-group-membership-endpoint.php +++ b/includes/bp-groups/classes/class-bp-rest-group-membership-endpoint.php @@ -58,12 +58,6 @@ public function register_routes() { $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)/members', array( - 'args' => array( - 'group_id' => array( - 'description' => __( 'A unique numeric ID for the Group.', 'buddypress' ), - 'type' => 'integer', - ), - ), array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), @@ -84,16 +78,6 @@ public function register_routes() { $this->namespace, '/' . $this->rest_base . '/(?P[\d]+)/members/(?P[\d]+)', array( - 'args' => array( - 'group_id' => array( - 'description' => __( 'A unique numeric ID for the Group.', 'buddypress' ), - 'type' => 'integer', - ), - 'user_id' => array( - 'description' => __( 'A unique numeric ID for the Group Member.', 'buddypress' ), - 'type' => 'integer', - ), - ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), @@ -320,18 +304,14 @@ public function create_item_permissions_check( $request ) { $retval = new WP_Error( 'bp_rest_authorization_required', __( 'Sorry, you are not allowed to perform this action.', 'buddypress' ), - array( - 'status' => rest_authorization_required_code(), - ) + array( 'status' => rest_authorization_required_code() ) ); if ( ! is_user_logged_in() ) { $retval = new WP_Error( 'bp_rest_authorization_required', __( 'Sorry, you need to be logged in to join a group.', 'buddypress' ), - array( - 'status' => rest_authorization_required_code(), - ) + array( 'status' => rest_authorization_required_code() ) ); } else { $user = bp_rest_get_user( $request->get_param( 'user_id' ) ); @@ -341,9 +321,7 @@ public function create_item_permissions_check( $request ) { $retval = new WP_Error( 'bp_rest_group_member_invalid_id', __( 'Invalid group member ID.', 'buddypress' ), - array( - 'status' => 404, - ) + array( 'status' => 404 ) ); } else { $group = $this->groups_endpoint->get_group_object( $request->get_param( 'group_id' ) ); @@ -352,9 +330,7 @@ public function create_item_permissions_check( $request ) { $retval = new WP_Error( 'bp_rest_group_invalid_id', __( 'Invalid group ID.', 'buddypress' ), - array( - 'status' => 404, - ) + array( 'status' => 404 ) ); } elseif ( bp_current_user_can( 'bp_moderate' ) || ( bp_current_user_can( 'groups_join_group', array( 'group_id' => $group->id ) ) && $loggedin_user_id === $user->ID ) ) { $retval = true; @@ -362,9 +338,7 @@ public function create_item_permissions_check( $request ) { $retval = new WP_Error( 'bp_rest_group_member_failed_to_join', __( 'Could not join the group.', 'buddypress' ), - array( - 'status' => 500, - ) + array( 'status' => 500 ) ); } } @@ -396,28 +370,35 @@ public function update_item( $request ) { $role = $request->get_param( 'role' ); $group_id = $group->id; + $bp_loggedin_user_id = bp_loggedin_user_id(); + + // Check if the user is a member of the group. + if ( 'unban' !== $action && ! groups_is_user_member( $user->ID, $group_id ) ) { + return new WP_Error( + 'bp_rest_group_member_not_member', + __( 'Sorry, you are not allowed to perform this action.', 'buddypress' ), + array( 'status' => 500 ) + ); + } + if ( 'promote' === $action ) { - if ( ! groups_promote_member( $user->ID, $group_id, $role, bp_loggedin_user_id() ) ) { + if ( ! groups_promote_member( $user->ID, $group_id, $role, $bp_loggedin_user_id ) ) { return new WP_Error( 'bp_rest_group_member_failed_to_promote', __( 'Could not promote member.', 'buddypress' ), - array( - 'status' => 500, - ) + array( 'status' => 500 ) ); } } elseif ( 'demote' === $action && 'member' !== $role ) { - if ( ! groups_promote_member( $user->ID, $group_id, $role, bp_loggedin_user_id() ) ) { + if ( ! groups_promote_member( $user->ID, $group_id, $role, $bp_loggedin_user_id ) ) { return new WP_Error( 'bp_rest_group_member_failed_to_demote', __( 'Could not demote member.', 'buddypress' ), - array( - 'status' => 500, - ) + array( 'status' => 500 ) ); } } elseif ( in_array( $action, array( 'demote', 'ban', 'unban' ), true ) ) { - if ( ! call_user_func( 'groups_' . $action . '_member', $user->ID, $group_id, bp_loggedin_user_id() ) ) { + if ( ! call_user_func( 'groups_' . $action . '_member', $user->ID, $group_id, $bp_loggedin_user_id ) ) { $messages = array( 'demote' => __( 'Could not demote member from the group.', 'buddypress' ), 'ban' => __( 'Could not ban member from the group.', 'buddypress' ), @@ -427,9 +408,7 @@ public function update_item( $request ) { return new WP_Error( 'bp_rest_group_member_failed_to_' . $action, $messages[ $action ], - array( - 'status' => 500, - ) + array( 'status' => 500 ) ); } } @@ -437,9 +416,6 @@ public function update_item( $request ) { // Get updated group member. $group_member = new BP_Groups_Member( $user->ID, $group_id ); - // Setting context. - $request->set_param( 'context', 'edit' ); - $retval = array( $this->prepare_response_for_collection( $this->prepare_item_for_response( $group_member, $request ) @@ -449,7 +425,7 @@ public function update_item( $request ) { $response = rest_ensure_response( $retval ); /** - * Fires after a group member is updated via the REST API. + * Fires after a group member status is updated via the REST API. * * @since 0.1.0 * @@ -473,23 +449,23 @@ public function update_item( $request ) { * @return true|WP_Error */ public function update_item_permissions_check( $request ) { - $error = new WP_Error( + $error = new WP_Error( 'bp_rest_authorization_required', __( 'Sorry, you are not allowed to perform this action.', 'buddypress' ), - array( - 'status' => rest_authorization_required_code(), - ) + array( 'status' => rest_authorization_required_code() ) ); + + $admin_error = new WP_Error( + 'bp_rest_authorization_required', + __( 'Group needs 1 admin at least. Please promote a user before trying to remove this group admin.', 'buddypress' ), + array( 'status' => rest_authorization_required_code() ) + ); + $retval = $error; + $action = $request->get_param( 'action' ); if ( ! is_user_logged_in() ) { - $retval = new WP_Error( - 'bp_rest_authorization_required', - __( 'Sorry, you need to be logged in to make an update.', 'buddypress' ), - array( - 'status' => rest_authorization_required_code(), - ) - ); + $retval = $error; } else { $user = bp_rest_get_user( $request->get_param( 'user_id' ) ); $loggedin_user_id = bp_loggedin_user_id(); @@ -498,9 +474,7 @@ public function update_item_permissions_check( $request ) { $retval = new WP_Error( 'bp_rest_group_member_invalid_id', __( 'Invalid group member ID.', 'buddypress' ), - array( - 'status' => 404, - ) + array( 'status' => 404 ) ); } else { $group = $this->groups_endpoint->get_group_object( $request->get_param( 'group_id' ) ); @@ -509,41 +483,35 @@ public function update_item_permissions_check( $request ) { $retval = new WP_Error( 'bp_rest_group_invalid_id', __( 'Invalid group ID.', 'buddypress' ), - array( - 'status' => 404, - ) + array( 'status' => 404 ) ); - } elseif ( bp_current_user_can( 'bp_moderate' ) ) { - $retval = true; - } elseif ( in_array( $request->get_param( 'action' ), array( 'ban', 'unban', 'promote', 'demote' ), true ) ) { - if ( groups_is_user_admin( $loggedin_user_id, $group->id ) ) { - if ( $loggedin_user_id !== $user->ID ) { + } elseif ( bp_current_user_can( 'bp_moderate' ) && $loggedin_user_id !== $user->ID ) { + if ( 'demote' === $action && groups_is_user_admin( $user->ID, $group->id ) ) { + $group_admins = groups_get_group_admins( $group->id ); + + if ( 1 !== count( $group_admins ) ) { $retval = true; } else { - $group_admins = groups_get_group_admins( $group->id ); - - if ( 1 !== count( $group_admins ) ) { - $retval = true; - } else { - $retval = $error; - } + $retval = $admin_error; } } else { - $messages = array( - 'ban' => __( 'Sorry, you are not allowed to ban this group member.', 'buddypress' ), - 'unban' => __( 'Sorry, you are not allowed to unban this group member.', 'buddypress' ), - 'promote' => __( 'Sorry, you are not allowed to promote this group member.', 'buddypress' ), - 'demote' => __( 'Sorry, you are not allowed to demote this group member.', 'buddypress' ), - ); - - $retval = new WP_Error( - 'bp_rest_group_member_cannot_' . $request->get_param( 'action' ), - $messages[ $request->get_param( 'action' ) ], - array( - 'status' => rest_authorization_required_code(), - ) - ); + $retval = true; } + } elseif ( groups_is_user_admin( $loggedin_user_id, $group->id ) && $loggedin_user_id !== $user->ID ) { + $retval = true; + } else { + $messages = array( + 'ban' => __( 'Sorry, you are not allowed to ban this group member.', 'buddypress' ), + 'unban' => __( 'Sorry, you are not allowed to unban this group member.', 'buddypress' ), + 'promote' => __( 'Sorry, you are not allowed to promote this group member.', 'buddypress' ), + 'demote' => __( 'Sorry, you are not allowed to demote this group member.', 'buddypress' ), + ); + + $retval = new WP_Error( + 'bp_rest_group_member_cannot_' . $action, + $messages[ $action ], + array( 'status' => rest_authorization_required_code() ) + ); } } } @@ -568,34 +536,33 @@ public function update_item_permissions_check( $request ) { * @return WP_REST_Response|WP_Error */ public function delete_item( $request ) { - // Setting context. - $request->set_param( 'context', 'edit' ); + $group_id = $request->get_param( 'group_id' ); + $user_id = $request->get_param( 'user_id' ); // Get the Group member before it's removed. - $member = new BP_Groups_Member( $request->get_param( 'user_id' ), $request->get_param( 'group_id' ) ); - $previous = $this->prepare_item_for_response( $member, $request ); + $member = new BP_Groups_Member( $user_id, $group_id ); if ( ! $member->remove() ) { return new WP_Error( 'bp_rest_group_member_failed_to_remove', __( 'Could not remove member from this group.', 'buddypress' ), - array( - 'status' => 500, - ) + array( 'status' => 500 ) ); } + $previous_member = $this->prepare_item_for_response( $member, $request ); + // Build the response. $response = new WP_REST_Response(); $response->set_data( array( 'removed' => true, - 'previous' => $previous->get_data(), + 'previous' => $previous_member->get_data(), ) ); - $user = bp_rest_get_user( $request->get_param( 'user_id' ) ); - $group = $this->groups_endpoint->get_group_object( $request->get_param( 'group_id' ) ); + $user = bp_rest_get_user( $user_id ); + $group = $this->groups_endpoint->get_group_object( $group_id ); /** * Fires after a group member is deleted via the REST API. @@ -622,22 +589,27 @@ public function delete_item( $request ) { * @return true|WP_Error */ public function delete_item_permissions_check( $request ) { - $error = new WP_Error( + $authorization_code = rest_authorization_required_code(); + + $error = new WP_Error( 'bp_rest_authorization_required', __( 'Sorry, you are not allowed to perform this action.', 'buddypress' ), - array( - 'status' => rest_authorization_required_code(), - ) + array( 'status' => $authorization_code ) + ); + + $admin_error = new WP_Error( + 'bp_rest_authorization_required', + __( 'Group needs 1 admin at least. Please promote a user before trying to remove this group admin.', 'buddypress' ), + array( 'status' => $authorization_code ) ); + $retval = $error; if ( ! is_user_logged_in() ) { $retval = new WP_Error( 'bp_rest_authorization_required', __( 'Sorry, you need to be logged in to view a group membership.', 'buddypress' ), - array( - 'status' => rest_authorization_required_code(), - ) + array( 'status' => $authorization_code ) ); } else { $user = bp_rest_get_user( $request->get_param( 'user_id' ) ); @@ -647,9 +619,7 @@ public function delete_item_permissions_check( $request ) { return new WP_Error( 'bp_rest_group_member_invalid_id', __( 'Invalid group member ID.', 'buddypress' ), - array( - 'status' => 404, - ) + array( 'status' => 404 ) ); } else { $group = $this->groups_endpoint->get_group_object( $request->get_param( 'group_id' ) ); @@ -658,21 +628,28 @@ public function delete_item_permissions_check( $request ) { $retval = new WP_Error( 'bp_rest_group_invalid_id', __( 'Invalid group ID.', 'buddypress' ), - array( - 'status' => 404, - ) + array( 'status' => 404 ) ); - } elseif ( bp_current_user_can( 'bp_moderate' ) || ( $user->ID !== $loggedin_user_id && groups_is_user_admin( $loggedin_user_id, $group->id ) ) ) { - $retval = true; + } elseif ( bp_current_user_can( 'bp_moderate' ) || ( groups_is_user_admin( $loggedin_user_id, $group->id ) && $loggedin_user_id !== $user->ID ) ) { + if ( groups_is_user_admin( $user->ID, $group->id ) ) { + $group_admins = groups_get_group_admins( $group->id ); + + if ( 1 !== count( $group_admins ) ) { + $retval = true; + } else { + $retval = $admin_error; + } + } else { + $retval = true; + } } elseif ( $user->ID === $loggedin_user_id && ! groups_is_user_banned( $user->ID, $group->id ) ) { - $group_admins = groups_get_group_admins( $group->id ); + if ( groups_is_user_admin( $loggedin_user_id, $group->id ) ) { + $group_admins = groups_get_group_admins( $group->id ); - // Special case for self-removal: don't allow if it'd leave a group with no admins. - if ( in_array( $loggedin_user_id, wp_list_pluck( $group_admins, 'user_id' ), true ) ) { if ( 1 !== count( $group_admins ) ) { $retval = true; } else { - $retval = $error; + $retval = $admin_error; } } else { $retval = true; diff --git a/tests/testcases/membership/test-group-membership-controller.php b/tests/testcases/membership/test-group-membership-controller.php index a80fe172..42d2f73c 100644 --- a/tests/testcases/membership/test-group-membership-controller.php +++ b/tests/testcases/membership/test-group-membership-controller.php @@ -68,29 +68,24 @@ public function test_get_items() { $this->bp::set_current_user( $u1 ); - $request = new WP_REST_Request( 'GET', $this->endpoint_url . $g1 . '/members' ); - - $request->set_param( 'context', 'view' ); + $request = new WP_REST_Request( 'GET', $this->endpoint_url . $g1 . '/members' ); $response = $this->server->dispatch( $request ); $this->assertEquals( 200, $response->get_status() ); + $headers = $response->get_headers(); + $this->assertEquals( 2, $headers['X-WP-Total'] ); + $this->assertEquals( 1, $headers['X-WP-TotalPages'] ); + $all_data = $response->get_data(); $this->assertNotEmpty( $all_data ); $u_ids = wp_list_pluck( $all_data, 'id' ); // Check results. + $this->assertCount( 2, $u_ids ); $this->assertEqualSets( [ $u1, $u2 ], $u_ids ); $this->assertNotContains( $u3, $u_ids ); - - // Verify user information. - foreach ( $all_data as $data ) { - $user = bp_rest_get_user( $data['id'] ); - $member_object = new BP_Groups_Member( $user->ID, $g1 ); - - $this->check_user_data( $user, $data, $member_object ); - } } /** @@ -111,7 +106,8 @@ public function test_get_items_by_specific_group_role() { // Promote $u2 to a moderator add_filter( 'bp_is_item_admin', '__return_true' ); - groups_promote_member( $u2, $g1, 'mod' ); + $member_object = new BP_Groups_Member( $u2, $g1 ); + $member_object->promote( 'mod' ); remove_filter( 'bp_is_item_admin', '__return_true' ); @@ -120,7 +116,6 @@ public function test_get_items_by_specific_group_role() { 'roles' => array( 'mod' ), ) ); - $request->set_param( 'context', 'view' ); $response = $this->server->dispatch( $request ); $this->assertEquals( 200, $response->get_status() ); @@ -131,16 +126,9 @@ public function test_get_items_by_specific_group_role() { $u_ids = wp_list_pluck( $all_data, 'id' ); // Check results. + $this->assertCount( 1, $u_ids ); $this->assertEqualSets( [ $u2 ], $u_ids ); $this->assertNotContains( $u1, $u_ids ); - - // Verify user information. - foreach ( $all_data as $data ) { - $user = bp_rest_get_user( $data['id'] ); - $member_object = new BP_Groups_Member( $user->ID, $g1 ); - - $this->check_user_data( $user, $data, $member_object ); - } } /** @@ -159,7 +147,6 @@ public function test_get_items_with_support_for_the_community_visibility() { $this->populate_group_with_members( [ $u1, $u2 ], $g1 ); $request = new WP_REST_Request( 'GET', $this->endpoint_url . $g1 . '/members' ); - $request->set_param( 'context', 'view' ); $response = $this->server->dispatch( $request ); $this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() ); @@ -189,8 +176,6 @@ public function test_get_paginated_items() { 'page' => 2, 'per_page' => 3, ) ); - - $request->set_param( 'context', 'view' ); $response = $this->server->dispatch( $request ); $this->assertEquals( 200, $response->get_status() ); @@ -202,13 +187,11 @@ public function test_get_paginated_items() { $all_data = $response->get_data(); $this->assertNotEmpty( $all_data ); - // Verify user information. - foreach ( $all_data as $data ) { - $user = bp_rest_get_user( $data['id'] ); - $member_object = new BP_Groups_Member( $user->ID, $g1 ); + $u_ids = wp_list_pluck( $all_data, 'id' ); - $this->check_user_data( $user, $data, $member_object ); - } + // Check results. + $this->assertCount( 3, $u_ids ); + $this->assertEqualSets( [ $u4, $u5, $u6 ], $u_ids ); } /** @@ -217,13 +200,12 @@ public function test_get_paginated_items() { public function test_get_items_no_search_terms() { $u1 = static::factory()->user->create(); $u2 = static::factory()->user->create(); - - $g1 = $this->bp::factory()->group->create( array( - 'status' => 'public', - ) ); + $g1 = $this->bp::factory()->group->create(); $this->populate_group_with_members( [ $u1, $u2 ], $g1 ); - groups_promote_member( $u1, $g1, 'admin' ); + + $member_object = new BP_Groups_Member( $u1, $g1 ); + $member_object->promote( 'admin' ); $this->bp::set_current_user( $u1 ); @@ -231,8 +213,7 @@ public function test_get_items_no_search_terms() { $request = new WP_REST_Request( 'GET', $this->endpoint_url . $g1 . '/members' ); - $request->set_param( 'context', 'view' ); - $response = $this->server->dispatch( $request ); + $this->server->dispatch( $request ); remove_filter( 'bp_rest_group_members_get_items_query_args', array( $this, 'group_members_query_args' ) ); @@ -251,20 +232,18 @@ public function test_get_items_has_search_terms() { 'user_nicename' => 'foo bar', ) ); - $g1 = $this->bp::factory()->group->create( array( - 'status' => 'public', - ) ); + $g1 = $this->bp::factory()->group->create(); $this->populate_group_with_members( [ $u1, $u2 ], $g1 ); - groups_promote_member( $u1, $g1, 'admin' ); + + $member_object = new BP_Groups_Member( $u1, $g1 ); + $member_object->promote( 'admin' ); $this->bp::set_current_user( $u1 ); add_filter( 'bp_rest_group_members_get_items_query_args', array( $this, 'group_members_query_args' ) ); $request = new WP_REST_Request( 'GET', $this->endpoint_url . $g1 . '/members' ); - - $request->set_param( 'context', 'view' ); $request->set_param( 'search', 'bar' ); $response = $this->server->dispatch( $request ); @@ -275,7 +254,7 @@ public function test_get_items_has_search_terms() { $all_data = $response->get_data(); $results = wp_list_pluck( $all_data, 'id' ); - $this->assertTrue( 1 === count( $results ) ); + $this->assertCount( 1, $results ); $this->assertSame( $u2, $results[0] ); } @@ -292,23 +271,20 @@ public function group_members_query_args( $args ) { * @group get_item */ public function test_get_item() { - $this->markTestSkipped(); + $this->markTestSkipped( 'This endpoint does not have a get_item meethod.' ); } /** * @group create_item */ public function test_create_item() { - $u = static::factory()->user->create( array( 'role' => 'subscriber' ) ); + $u = static::factory()->user->create(); $g = $this->bp::factory()->group->create(); $this->bp::set_current_user( $u ); $request = new WP_REST_Request( 'POST', $this->endpoint_url . $g . '/members' ); - $request->set_param( 'context', 'view' ); - $request->set_query_params( array( - 'user_id' => $u, - ) ); + $request->set_query_params( array( 'user_id' => $u ) ); $response = $this->server->dispatch( $request ); $this->assertEquals( 200, $response->get_status() ); @@ -337,32 +313,28 @@ public function test_create_item_as_admin() { $this->assertEquals( 200, $response->get_status() ); $all_data = $response->get_data(); - $this->assertNotEmpty( $all_data ); + $data = reset( $all_data ); - foreach ( $all_data as $data ) { - $user = bp_rest_get_user( $data['id'] ); - $member_object = new BP_Groups_Member( $user->ID, $this->group_id ); + $user = bp_rest_get_user( $data['id'] ); + $member_object = new BP_Groups_Member( $user->ID, $this->group_id ); - $this->check_user_data( $user, $data, $member_object, 'edit' ); - } + $this->check_user_data( $user, $data, $member_object, 'edit' ); } /** * @group create_item */ public function test_member_can_add_himself_to_public_group() { - $u = static::factory()->user->create( array( 'role' => 'subscriber' ) ); + $u = static::factory()->user->create(); $this->bp::set_current_user( $u ); $request = new WP_REST_Request( 'POST', $this->endpoint_url . $this->group_id . '/members' ); // This usually would be 'edit', but we are testing a public group. - $request->set_param( 'context', 'view' ); - $request->set_query_params( array( - 'user_id' => $u, - ) ); + $request->set_query_params( array( 'user_id' => $u ) ); + $response = $this->server->dispatch( $request ); $this->assertEquals( 200, $response->get_status() ); @@ -382,7 +354,7 @@ public function test_member_can_add_himself_to_public_group() { * @group create_item */ public function test_member_can_not_add_himself_to_private_group() { - $u = static::factory()->user->create( array( 'role' => 'subscriber' ) ); + $u = static::factory()->user->create(); $g1 = $this->bp::factory()->group->create( array( 'status' => 'private', @@ -391,10 +363,7 @@ public function test_member_can_not_add_himself_to_private_group() { $this->bp::set_current_user( $u ); $request = new WP_REST_Request( 'POST', $this->endpoint_url . $g1 . '/members' ); - $request->set_param( 'context', 'view' ); - $request->set_query_params( array( - 'user_id' => $u, - ) ); + $request->set_query_params( array( 'user_id' => $u ) ); $response = $this->server->dispatch( $request ); $this->assertErrorResponse( 'bp_rest_group_member_failed_to_join', $response, 500 ); @@ -404,7 +373,7 @@ public function test_member_can_not_add_himself_to_private_group() { * @group create_item */ public function test_member_can_not_add_himself_to_hidden_group() { - $u = static::factory()->user->create( array( 'role' => 'subscriber' ) ); + $u = static::factory()->user->create(); $g1 = $this->bp::factory()->group->create( array( 'status' => 'hidden', @@ -426,13 +395,12 @@ public function test_member_can_not_add_himself_to_hidden_group() { * @group create_item */ public function test_member_cannot_add_others_to_public_group() { - $u1 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); - $u2 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); $this->bp::set_current_user( $u1 ); $request = new WP_REST_Request( 'POST', $this->endpoint_url . $this->group_id . '/members' ); - $request->set_param( 'context', 'view' ); $request->set_query_params( array( 'user_id' => $u2, ) ); @@ -442,361 +410,761 @@ public function test_member_cannot_add_others_to_public_group() { } /** + * Site admin can ban member. + * * @group update_item + * @group ban_member */ public function test_update_item() { - $u = static::factory()->user->create( array( 'role' => 'subscriber' ) ); + $u = static::factory()->user->create(); $this->populate_group_with_members( [ $u ], $this->group_id ); $this->bp::set_current_user( $this->user ); $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $this->group_id . '/members/' . $u ); - $request->set_query_params( array( - 'action' => 'ban', - ) ); - - $request->set_param( 'context', 'view' ); + $request->set_query_params( array( 'action' => 'ban' ) ); $response = $this->server->dispatch( $request ); $this->assertEquals( 200, $response->get_status() ); $all_data = $response->get_data(); - $this->assertNotEmpty( $all_data ); + $data = reset( $all_data ); - foreach ( $all_data as $data ) { - $user = bp_rest_get_user( $data['id'] ); - $member_object = new BP_Groups_Member( $user->ID, $this->group_id ); + $user = bp_rest_get_user( $data['id'] ); + $member_object = new BP_Groups_Member( $u, $this->group_id ); - $this->check_user_data( $user, $data, $member_object, 'edit' ); - } + $this->assertTrue( $u === $user->ID ); + $this->assertTrue( (bool) $member_object->is_banned ); } /** * @group update_item + * @group ban_member */ - public function test_administrator_can_ban_member() { - $u = static::factory()->user->create( array( 'role' => 'subscriber' ) ); - - $this->populate_group_with_members( [ $u ], $this->group_id ); - - $this->bp::set_current_user( $this->user ); + public function test_group_mod_can_not_ban_member() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); - $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $this->group_id . '/members/' . $u ); - $request->set_query_params( array( - 'action' => 'ban', - ) ); + $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) ); - $request->set_param( 'context', 'edit' ); - $response = $this->server->dispatch( $request ); + $this->populate_group_with_members( [ $u1, $u3 ], $g1 ); - $this->assertEquals( 200, $response->get_status() ); + // Promote $u2 to a group mod. + $member_object = new BP_Groups_Member( $u1, $g1 ); + $member_object->promote( 'mod' ); - $all_data = $response->get_data(); - $this->assertNotEmpty( $all_data ); + $this->bp::set_current_user( $u1 ); - foreach ( $all_data as $data ) { - $user = bp_rest_get_user( $data['id'] ); - $member_object = new BP_Groups_Member( $user->ID, $this->group_id ); + $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u3 ); + $request->set_query_params( array( 'action' => 'ban' ) ); + $response = $this->server->dispatch( $request ); - $this->assertTrue( (bool) $member_object->is_banned ); - $this->check_user_data( $user, $data, $member_object, 'edit' ); - } + $this->assertErrorResponse( 'bp_rest_group_member_cannot_ban', $response, rest_authorization_required_code() ); } /** * @group update_item + * @group ban_member */ - public function test_group_admin_can_ban_member() { - $u1 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); - $u2 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); + public function test_group_mod_can_not_ban_random_member() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); + $u4 = static::factory()->user->create(); - $g1 = $this->bp::factory()->group->create( array( - 'creator_id' => $u2, - ) ); + $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) ); - $this->populate_group_with_members( [ $u1 ], $g1 ); + $this->populate_group_with_members( [ $u1, $u3 ], $g1 ); - $this->bp::set_current_user( $u2 ); + // Promote $u2 to a group mod. + $member_object = new BP_Groups_Member( $u1, $g1 ); + $member_object->promote( 'mod' ); - $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 ); - $request->set_query_params( array( - 'action' => 'ban', - ) ); + $this->bp::set_current_user( $u1 ); - $request->set_param( 'context', 'edit' ); + $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u4 ); + $request->set_query_params( array( 'action' => 'ban' ) ); $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - - $all_data = $response->get_data(); - $this->assertNotEmpty( $all_data ); - - foreach ( $all_data as $data ) { - $user = bp_rest_get_user( $data['id'] ); - $member_object = new BP_Groups_Member( $user->ID, $this->group_id ); - - $this->assertTrue( $u1 === $user->ID ); - $this->assertTrue( empty( $member_object->is_banned ) ); - } + $this->assertErrorResponse( 'bp_rest_group_member_cannot_ban', $response, rest_authorization_required_code() ); } /** * @group update_item + * @group ban_member */ - public function test_administrator_can_promote_member() { - $u = static::factory()->user->create( array( 'role' => 'subscriber' ) ); + public function test_group_admin_can_ban_member() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); - $this->populate_group_with_members( [ $u ], $this->group_id ); + $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) ); - $this->bp::set_current_user( $this->user ); + $this->populate_group_with_members( [ $u1, $u3 ], $g1 ); - $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $this->group_id . '/members/' . $u ); - $request->set_query_params( array( - 'action' => 'promote', - 'role' => 'mod', - ) ); + // Promote $u2 to a group admin. + $member_object = new BP_Groups_Member( $u2, $g1 ); + $member_object->promote( 'admin' ); - $request->set_param( 'context', 'edit' ); + $this->bp::set_current_user( $u2 ); + + $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 ); + $request->set_query_params( array( 'action' => 'ban' ) ); $response = $this->server->dispatch( $request ); $this->assertEquals( 200, $response->get_status() ); $all_data = $response->get_data(); - $this->assertNotEmpty( $all_data ); + $data = reset( $all_data ); - foreach ( $all_data as $data ) { - $user = bp_rest_get_user( $data['id'] ); - $member_object = new BP_Groups_Member( $user->ID, $this->group_id ); + $user = bp_rest_get_user( $data['id'] ); + $member_object = new BP_Groups_Member( $user->ID, $g1 ); - $this->check_user_data( $user, $data, $member_object, 'edit' ); - } + $this->assertTrue( $u1 === $user->ID ); + $this->assertTrue( (bool) $member_object->is_banned ); } /** * @group update_item + * @group ban_member */ - public function test_group_admin_can_promote_member() { + public function test_group_admin_can_not_ban_random_member() { $u1 = static::factory()->user->create(); $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); + $u4 = static::factory()->user->create(); - $g1 = $this->bp::factory()->group->create( array( - 'creator_id' => $u2, - ) ); + $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) ); - $this->populate_group_with_members( [ $u1 ], $this->group_id ); + $this->populate_group_with_members( [ $u1, $u3 ], $g1 ); $this->bp::set_current_user( $u2 ); - $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 ); - $request->set_query_params( array( - 'action' => 'promote', - 'role' => 'mod', - ) ); - - $request->set_param( 'context', 'edit' ); + $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u4 ); + $request->set_query_params( array( 'action' => 'ban' ) ); $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); - - $all_data = $response->get_data(); - $this->assertNotEmpty( $all_data ); - - foreach ( $all_data as $data ) { - $user = bp_rest_get_user( $data['id'] ); - $member_object = new BP_Groups_Member( $user->ID, $g1 ); - - $this->check_user_data( $user, $data, $member_object, 'edit' ); - } + $this->assertErrorResponse( 'bp_rest_group_member_not_member', $response, 500 ); } /** * @group update_item */ - public function test_member_can_not_promote_other_member() { - $u1 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); - $u2 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); - $u3 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); + public function test_site_admin_can_unban_member_from_group() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); - $g1 = $this->bp::factory()->group->create( array( - 'creator_id' => $u2, - ) ); + $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) ); $this->populate_group_with_members( [ $u1, $u3 ], $g1 ); - $this->bp::set_current_user( $u3 ); - - $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 ); - $request->set_query_params( array( - 'action' => 'promote', - 'role' => 'mod', - ) ); - - $request->set_param( 'context', 'edit' ); - $response = $this->server->dispatch( $request ); + // Ban $u1. + $member_object = new BP_Groups_Member( $u1, $g1 ); + $member_object->ban(); - $this->assertErrorResponse( 'bp_rest_group_member_cannot_promote', $response, 403 ); - } + $this->assertTrue( (bool) $member_object->is_banned ); - /** - * @group update_item - */ - public function test_group_mods_can_not_promote_members() { - $u1 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); - $u2 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); + $this->bp::set_current_user( $this->user ); - $g1 = $this->bp::factory()->group->create( array( - 'creator_id' => $u1, - ) ); + $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 ); + $request->set_query_params( array( 'action' => 'unban' ) ); + $response = $this->server->dispatch( $request ); - $this->bp::add_user_to_group( $u2, $g1, array( - 'is_mod' => true, - ) ); + $this->assertEquals( 200, $response->get_status() ); - $this->bp::set_current_user( $u2 ); + $all_data = $response->get_data(); + $data = reset( $all_data ); - $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 ); - $request->set_query_params( array( - 'action' => 'promote', - 'role' => 'mod', - ) ); - $response = $this->server->dispatch( $request ); + $user = bp_rest_get_user( $data['id'] ); + $member_object = new BP_Groups_Member( $user->ID, $g1 ); - $this->assertErrorResponse( 'bp_rest_group_member_cannot_promote', $response, 403 ); + $this->assertTrue( $u1 === $user->ID ); + $this->assertFalse( (bool) $member_object->is_banned ); } /** * @group update_item */ - public function test_admin_can_demote_group_admin_to_member() { - $u1 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); - $u2 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); - $u3 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); + public function test_site_admin_can_not_unban_random_member() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); + $u4 = static::factory()->user->create(); - $g1 = $this->bp::factory()->group->create( array( - 'creator_id' => $u2, - ) ); + $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) ); $this->populate_group_with_members( [ $u1, $u3 ], $g1 ); $this->bp::set_current_user( $this->user ); - $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u2 ); - $request->set_query_params( array( - 'action' => 'demote', - ) ); + $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u4 ); + $request->set_query_params( array( 'action' => 'unban' ) ); $response = $this->server->dispatch( $request ); $this->assertEquals( 200, $response->get_status() ); $all_data = $response->get_data(); - $this->assertNotEmpty( $all_data ); + $data = reset( $all_data ); - $data = $all_data[0]; $user = bp_rest_get_user( $data['id'] ); $member_object = new BP_Groups_Member( $user->ID, $g1 ); - $this->assertTrue( $u2 === $user->ID ); - $this->assertFalse( (bool) $member_object->is_mod ); - $this->assertFalse( (bool) $member_object->is_admin ); - $this->assertTrue( (bool) $member_object::check_is_member( $u2, $g1 ) ); - $this->check_user_data( $user, $data, $member_object, 'edit' ); + $this->assertFalse( groups_is_user_member( $user->ID, $g1 ) ); + $this->assertTrue( $u4 === $user->ID ); + $this->assertFalse( (bool) $member_object->is_banned ); } /** * @group update_item */ - public function test_group_admin_can_demote_another_group_admin_to_mod() { - $u1 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); - $u2 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); - $u3 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); + public function test_group_admin_can_unban_member() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); - $g1 = $this->bp::factory()->group->create( array( - 'creator_id' => $u3, - ) ); + $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) ); - $this->populate_group_with_members( [ $u1, $u2 ], $g1 ); + $this->populate_group_with_members( [ $u1, $u3 ], $g1 ); - $group_member_1 = new BP_Groups_Member( $u1, $g1 ); - $group_member_1->promote( 'admin' ); + // Promote $u2 to a group admin. + $member_object = new BP_Groups_Member( $u2, $g1 ); + $member_object->promote( 'admin' ); - $group_member_2 = new BP_Groups_Member( $u2, $g1 ); - $group_member_2->promote( 'admin' ); + // Ban $u1. + $member_object = new BP_Groups_Member( $u1, $g1 ); + $member_object->ban(); - $this->bp::set_current_user( $u1 ); + $this->assertTrue( (bool) $member_object->is_banned ); - $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u2 ); - $request->set_query_params( array( - 'action' => 'demote', - 'role' => 'mod', - ) ); + $this->bp::set_current_user( $u2 ); - $request->set_param( 'context', 'edit' ); + $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 ); + $request->set_query_params( array( 'action' => 'unban' ) ); $response = $this->server->dispatch( $request ); $this->assertEquals( 200, $response->get_status() ); $all_data = $response->get_data(); - $this->assertNotEmpty( $all_data ); + $data = reset( $all_data ); - foreach ( $all_data as $data ) { - $user = bp_rest_get_user( $data['id'] ); - $member_object = new BP_Groups_Member( $user->ID, $g1 ); + $user = bp_rest_get_user( $data['id'] ); + $member_object = new BP_Groups_Member( $user->ID, $g1 ); - $this->assertTrue( $u2 === $user->ID ); - $this->assertTrue( (bool) $member_object->is_mod ); - $this->check_user_data( $user, $data, $member_object, 'edit' ); - } + $this->assertTrue( $u1 === $user->ID ); + $this->assertFalse( (bool) $member_object->is_banned ); } /** * @group update_item */ - public function test_member_can_not_demote_other_member() { - $u1 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); - $u2 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); - $u3 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); + public function test_group_mod_can_not_unban_member() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); - $g1 = $this->bp::factory()->group->create( array( - 'creator_id' => $u2, - ) ); + $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) ); $this->populate_group_with_members( [ $u1, $u3 ], $g1 ); - $this->bp::set_current_user( $u3 ); + // Promote $u2 to a group mod. + $member_object = new BP_Groups_Member( $u2, $g1 ); + $member_object->promote( 'mod' ); - $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u2 ); - $request->set_query_params( array( - 'action' => 'demote', - ) ); + // Ban $u1. + $member_object = new BP_Groups_Member( $u1, $g1 ); + $member_object->ban(); - $request->set_param( 'context', 'edit' ); + $this->assertTrue( (bool) $member_object->is_banned ); + + $this->bp::set_current_user( $u2 ); + + $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 ); + $request->set_query_params( array( 'action' => 'unban' ) ); $response = $this->server->dispatch( $request ); - $this->assertErrorResponse( 'bp_rest_group_member_cannot_demote', $response, 403 ); + $this->assertErrorResponse( 'bp_rest_group_member_cannot_unban', $response, rest_authorization_required_code() ); } /** * @group update_item + * @group promote_member */ - public function test_update_item_invalid_group_id() { - $u = static::factory()->user->create( array( 'role' => 'subscriber' ) ); + public function test_site_admin_can_promote_member_to_mod() { + $u = static::factory()->user->create(); + + $this->populate_group_with_members( [ $u ], $this->group_id ); $this->bp::set_current_user( $this->user ); - $request = new WP_REST_Request( 'PUT', $this->endpoint_url . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER . '/members/' . $u ); + $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $this->group_id . '/members/' . $u ); $request->set_query_params( array( 'action' => 'promote', 'role' => 'mod', ) ); - - $request->set_param( 'context', 'edit' ); $response = $this->server->dispatch( $request ); - $this->assertErrorResponse( 'bp_rest_group_invalid_id', $response, 404 ); - } + $this->assertEquals( 200, $response->get_status() ); - /** + $all_data = $response->get_data(); + $data = reset( $all_data ); + + $user = bp_rest_get_user( $data['id'] ); + $member_object = new BP_Groups_Member( $user->ID, $this->group_id ); + + $this->assertTrue( $u === $user->ID ); + $this->assertTrue( (bool) $member_object->is_mod ); + } + + /** + * @group update_item + * @group promote_member + */ + public function test_group_admin_can_promote_member() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + + $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) ); + + $this->populate_group_with_members( [ $u1 ], $g1 ); + + $this->bp::set_current_user( $u2 ); + + $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 ); + $request->set_query_params( array( + 'action' => 'promote', + 'role' => 'mod', + ) ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 200, $response->get_status() ); + + $all_data = $response->get_data(); + $data = reset( $all_data ); + + $user = bp_rest_get_user( $data['id'] ); + $member_object = new BP_Groups_Member( $user->ID, $g1 ); + + $this->assertTrue( $u1 === $user->ID ); + $this->assertTrue( (bool) $member_object->is_mod ); + } + + /** + * @group update_item + * @group promote_member + */ + public function test_member_can_not_promote_other_member() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); + + $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) ); + + $this->populate_group_with_members( [ $u1, $u3 ], $g1 ); + + $this->bp::set_current_user( $u3 ); + + $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 ); + $request->set_query_params( array( + 'action' => 'promote', + 'role' => 'mod', + ) ); + $response = $this->server->dispatch( $request ); + + $this->assertErrorResponse( 'bp_rest_group_member_cannot_promote', $response, rest_authorization_required_code() ); + } + + /** + * @group update_item + * @group promote_member + */ + public function test_group_mods_can_not_promote_members() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + + $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u1 ) ); + + // Promote $u2 to a mod. + $this->bp::add_user_to_group( $u2, $g1, array( 'is_mod' => true ) ); + + $this->bp::set_current_user( $u2 ); + + $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 ); + $request->set_query_params( array( + 'action' => 'promote', + 'role' => 'mod', + ) ); + $response = $this->server->dispatch( $request ); + + $this->assertErrorResponse( 'bp_rest_group_member_cannot_promote', $response, rest_authorization_required_code() ); + } + + /** + * @group update_item + * @group promote_member + */ + public function test_group_mod_can_not_promote_himself() { + $u1 = static::factory()->user->create(); + $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u1 ) ); + + // Promote $u1 to a mod. + $this->bp::add_user_to_group( $u1, $g1, array( 'is_mod' => true ) ); + + $this->bp::set_current_user( $u1 ); + + $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 ); + $request->set_query_params( array( + 'action' => 'promote', + 'role' => 'admin', + ) ); + $response = $this->server->dispatch( $request ); + + $this->assertErrorResponse( 'bp_rest_group_member_cannot_promote', $response, rest_authorization_required_code() ); + } + + /** + * @group update_item + * @group demote_member + */ + public function test_site_admin_can_demote_group_admin_to_member() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); + + $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) ); + + $this->populate_group_with_members( [ $u1, $u3 ], $g1 ); + + // Promote $u3 to an admin. + $member_object = new BP_Groups_Member( $u3, $g1 ); + $member_object->promote( 'admin' ); + + $this->assertTrue( (bool) $member_object->is_admin ); + + // Site admin. + $this->bp::set_current_user( $this->user ); + + $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u2 ); + $request->set_query_params( array( 'action' => 'demote' ) ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 200, $response->get_status() ); + + $all_data = $response->get_data(); + $data = $all_data[0]; + $user = bp_rest_get_user( $data['id'] ); + $member_object = new BP_Groups_Member( $user->ID, $g1 ); + + $this->assertTrue( $u2 === $user->ID ); + $this->assertFalse( (bool) $member_object->is_mod ); + $this->assertFalse( (bool) $member_object->is_admin ); + $this->assertTrue( (bool) groups_is_user_member( $u2, $g1 ) ); + } + + /** + * @group update_item + * @group demote_member + */ + public function test_site_admin_can_not_demote_the_only_group_admin() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); + + $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) ); + + $this->populate_group_with_members( [ $u1, $u3 ], $g1 ); + + // Site admin. + $this->bp::set_current_user( $this->user ); + + $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u2 ); + $request->set_query_params( array( 'action' => 'demote' ) ); + $response = $this->server->dispatch( $request ); + + $this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() ); + } + + /** + * @group update_item + * @group demote_member + */ + public function test_site_admin_can_not_demote_himself() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); + + $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) ); + + $this->populate_group_with_members( [ $u1, $u3 ], $g1 ); + + // Site admin. + $this->bp::set_current_user( $this->user ); + + $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $this->user ); + $request->set_query_params( array( 'action' => 'demote' ) ); + $response = $this->server->dispatch( $request ); + + $this->assertErrorResponse( 'bp_rest_group_member_cannot_demote', $response, rest_authorization_required_code() ); + } + + /** + * @group update_item + * @group demote_member + */ + public function test_site_admin_can_demote_group_admins() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); + + $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) ); + + $this->populate_group_with_members( [ $u1, $u3 ], $g1 ); + + // Promote $u2 to an admin. + $member_object = new BP_Groups_Member( $u2, $g1 ); + $member_object->promote( 'admin' ); + + // Promote $u3 to an admin. + $member_object = new BP_Groups_Member( $u3, $g1 ); + $member_object->promote( 'admin' ); + + $this->assertTrue( (bool) $member_object->is_admin ); + + // Site admin. + $this->bp::set_current_user( $this->user ); + + $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u2 ); + $request->set_query_params( array( 'action' => 'demote' ) ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 200, $response->get_status() ); + + $data = $response->get_data(); + $user = bp_rest_get_user( $data[0]['id'] ); + + $member_object = new BP_Groups_Member( $user->ID, $g1 ); + + $this->assertTrue( $u2 === $user->ID ); + $this->assertFalse( (bool) $member_object->is_mod ); + $this->assertFalse( (bool) $member_object->is_admin ); + $this->assertTrue( (bool) groups_is_user_member( $u2, $g1 ) ); + } + + /** + * @group update_item + * @group demote_member + */ + public function test_site_admin_can_demote_group_mods() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); + + $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u3 ) ); + + $this->populate_group_with_members( [ $u1, $u2, $u3 ], $g1 ); + + // Promote $u2 to an admin. + $member_object = new BP_Groups_Member( $u2, $g1 ); + $member_object->promote( 'mod' ); + + $this->assertTrue( (bool) $member_object->is_mod ); + + // Site admin. + $this->bp::set_current_user( $this->user ); + + $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u2 ); + $request->set_query_params( array( 'action' => 'demote' ) ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 200, $response->get_status() ); + + $data = $response->get_data(); + $user = bp_rest_get_user( $data[0]['id'] ); + + $member_object = new BP_Groups_Member( $user->ID, $g1 ); + + $this->assertTrue( $u2 === $user->ID ); + $this->assertFalse( (bool) $member_object->is_mod ); + $this->assertFalse( (bool) $member_object->is_admin ); + $this->assertTrue( (bool) groups_is_user_member( $u2, $g1 ) ); + } + + /** + * @group update_item + * @group demote_member + */ + public function test_site_admin_can_not_demote_already_group_members() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); + + $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u3 ) ); + + $this->populate_group_with_members( [ $u1, $u2, $u3 ], $g1 ); + + // Promote $u2 to an admin. + $member_object = new BP_Groups_Member( $u2, $g1 ); + $member_object->promote( 'mod' ); + + $this->assertTrue( (bool) $member_object->is_mod ); + + // Site admin. + $this->bp::set_current_user( $this->user ); + + $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 ); + $request->set_query_params( array( 'action' => 'demote' ) ); + $response = $this->server->dispatch( $request ); + + $this->assertErrorResponse( 'bp_rest_group_member_failed_to_demote', $response, 500 ); + } + + /** + * @group update_item + * @group demote_member + */ + public function test_group_admin_can_demote_another_group_admin_to_mod() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); + + $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u3 ) ); + + $this->populate_group_with_members( [ $u1, $u2 ], $g1 ); + + $group_member = new BP_Groups_Member( $u2, $g1 ); + $group_member->promote( 'admin' ); + + $this->bp::set_current_user( $u3 ); + + $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u2 ); + $request->set_query_params( array( + 'action' => 'demote', + 'role' => 'mod', + ) ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 200, $response->get_status() ); + + $data = $response->get_data(); + $user = bp_rest_get_user( $data[0]['id'] ); + + $member_object = new BP_Groups_Member( $user->ID, $g1 ); + + $this->assertTrue( $u2 === $user->ID ); + $this->assertTrue( (bool) $member_object->is_mod ); + $this->assertFalse( (bool) $member_object->is_admin ); + } + + /** + * @group update_item + * @group demote_member + */ + public function test_group_admin_can_not_demote_himself() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); + + $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) ); + + $this->populate_group_with_members( [ $u1, $u3 ], $g1 ); + + $this->bp::set_current_user( $u2 ); + + $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u2 ); + $request->set_query_params( array( 'action' => 'demote' ) ); + $response = $this->server->dispatch( $request ); + + $this->assertErrorResponse( 'bp_rest_group_member_cannot_demote', $response, rest_authorization_required_code() ); + } + + /** + * @group update_item + * @group demote_member + */ + public function test_group_admin_can_not_demote_already_group_members() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); + + $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) ); + + $this->populate_group_with_members( [ $u1, $u3 ], $g1 ); + + $this->bp::set_current_user( $u2 ); + + $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 ); + $request->set_query_params( array( 'action' => 'demote' ) ); + $response = $this->server->dispatch( $request ); + + $this->assertErrorResponse( 'bp_rest_group_member_failed_to_demote', $response, 500 ); + } + + /** + * @group update_item + * @group demote_member + */ + public function test_member_can_not_demote_another_member() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); + + $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) ); + + $this->populate_group_with_members( [ $u1, $u3 ], $g1 ); + + $this->bp::set_current_user( $u3 ); + + $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u1 ); + $request->set_query_params( array( 'action' => 'demote' ) ); + $response = $this->server->dispatch( $request ); + + $this->assertErrorResponse( 'bp_rest_group_member_cannot_demote', $response, rest_authorization_required_code() ); + } + + /** + * @group update_item + * @group demote_member + */ + public function test_member_can_not_demote_himself() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); + + $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u2 ) ); + + $this->populate_group_with_members( [ $u1, $u3 ], $g1 ); + + $this->bp::set_current_user( $u3 ); + + $request = new WP_REST_Request( 'PUT', $this->endpoint_url . $g1 . '/members/' . $u3 ); + $request->set_query_params( array( 'action' => 'demote' ) ); + $response = $this->server->dispatch( $request ); + + $this->assertErrorResponse( 'bp_rest_group_member_cannot_demote', $response, rest_authorization_required_code() ); + } + + /** + * @group update_item + * @group promote_member + */ + public function test_update_item_invalid_group_id() { + $u = static::factory()->user->create(); + + $this->bp::set_current_user( $this->user ); + + $request = new WP_REST_Request( 'PUT', $this->endpoint_url . REST_TESTS_IMPOSSIBLY_HIGH_NUMBER . '/members/' . $u ); + $request->set_query_params( array( + 'action' => 'promote', + 'role' => 'mod', + ) ); + $response = $this->server->dispatch( $request ); + + $this->assertErrorResponse( 'bp_rest_group_invalid_id', $response, 404 ); + } + + /** * @group update_item */ public function test_update_item_user_not_logged_in() { @@ -810,9 +1178,9 @@ public function test_update_item_user_not_logged_in() { * @group delete_item */ public function test_delete_item() { - $u1 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); - $u2 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); - $u3 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u3, @@ -824,7 +1192,6 @@ public function test_delete_item() { $request = new WP_REST_Request( 'DELETE', $this->endpoint_url . $g1 . '/members/' . $u1 ); - $request->set_param( 'context', 'view' ); $response = $this->server->dispatch( $request ); $this->assertEquals( 200, $response->get_status() ); @@ -834,15 +1201,16 @@ public function test_delete_item() { $user = bp_rest_get_user( $all_data['previous']['id'] ); $this->assertFalse( groups_is_user_member( $user->ID, $g1 ) ); + $this->assertSame( $u1, $user->ID ); } /** * @group delete_item */ public function test_member_can_remove_himself_from_group() { - $u1 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); - $u2 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); - $u3 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u3, @@ -854,7 +1222,6 @@ public function test_member_can_remove_himself_from_group() { $request = new WP_REST_Request( 'DELETE', $this->endpoint_url . $g1 . '/members/' . $u1 ); - $request->set_param( 'context', 'view' ); $response = $this->server->dispatch( $request ); $this->assertEquals( 200, $response->get_status() ); @@ -869,10 +1236,10 @@ public function test_member_can_remove_himself_from_group() { /** * @group delete_item */ - public function test_member_can_not_remove_others_from_group() { - $u1 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); - $u2 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); - $u3 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); + public function test_banned_member_can_not_remove_himself_from_group() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); $g1 = $this->bp::factory()->group->create( array( 'creator_id' => $u3, @@ -880,11 +1247,34 @@ public function test_member_can_not_remove_others_from_group() { $this->populate_group_with_members( [ $u1, $u2 ], $g1 ); + $group_member = new BP_Groups_Member( $u1, $g1 ); + $group_member->ban(); + $this->bp::set_current_user( $u1 ); - $request = new WP_REST_Request( 'DELETE', $this->endpoint_url . $g1 . '/members/' . $u2 ); + $request = new WP_REST_Request( 'DELETE', $this->endpoint_url . $g1 . '/members/' . $u1 ); + $response = $this->server->dispatch( $request ); + + $this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() ); + } + + /** + * @group delete_item + */ + public function test_member_can_not_remove_others_from_group() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); + + $g1 = $this->bp::factory()->group->create( array( + 'creator_id' => $u3, + ) ); + + $this->populate_group_with_members( [ $u1, $u2 ], $g1 ); + + $this->bp::set_current_user( $u1 ); - $request->set_param( 'context', 'view' ); + $request = new WP_REST_Request( 'DELETE', $this->endpoint_url . $g1 . '/members/' . $u2 ); $response = $this->server->dispatch( $request ); $this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() ); @@ -894,12 +1284,12 @@ public function test_member_can_not_remove_others_from_group() { * @group delete_item */ public function test_group_admin_can_remove_member_from_group() { - $u1 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); - $u2 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); - $u3 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); $g1 = $this->bp::factory()->group->create( array( - 'creator_id' => $u3, + 'creator_id' => $u3, // <- group admin. ) ); $this->populate_group_with_members( [ $u1, $u2 ], $g1 ); @@ -907,37 +1297,170 @@ public function test_group_admin_can_remove_member_from_group() { $this->bp::set_current_user( $u3 ); $request = new WP_REST_Request( 'DELETE', $this->endpoint_url . $g1 . '/members/' . $u1 ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 200, $response->get_status() ); + + $all_data = $response->get_data(); + + $user = bp_rest_get_user( $all_data['previous']['id'] ); + $this->assertFalse( groups_is_user_member( $user->ID, $g1 ) ); + $this->assertSame( $u1, $user->ID ); + } + + /** + * @group delete_item + */ + public function test_group_admin_can_remove_himself_from_group() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); + + $g1 = $this->bp::factory()->group->create( array( + 'creator_id' => $u2, // <- group admin. + ) ); - $request->set_param( 'context', 'view' ); + $this->populate_group_with_members( [ $u1, $u3 ], $g1 ); + + // Another group admin. + $group_member = new BP_Groups_Member( $u3, $g1 ); + $group_member->promote( 'admin' ); + + $this->bp::set_current_user( $u2 ); + + $request = new WP_REST_Request( 'DELETE', $this->endpoint_url . $g1 . '/members/' . $u2 ); $response = $this->server->dispatch( $request ); $this->assertEquals( 200, $response->get_status() ); $all_data = $response->get_data(); - $this->assertNotEmpty( $all_data ); $user = bp_rest_get_user( $all_data['previous']['id'] ); $this->assertFalse( groups_is_user_member( $user->ID, $g1 ) ); + $this->assertSame( $u2, $user->ID ); } /** * @group delete_item */ - public function test_group_admin_can_not_remove_himself_from_group() { - $u1 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); - $u2 = static::factory()->user->create( array( 'role' => 'subscriber' ) ); + public function test_last_group_admin_can_not_remove_himself_from_group() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); $g1 = $this->bp::factory()->group->create( array( - 'creator_id' => $u2, + 'creator_id' => $u2, // <- group admin. ) ); $this->populate_group_with_members( [ $u1 ], $g1 ); $this->bp::set_current_user( $u2 ); - $request = new WP_REST_Request( 'DELETE', $this->endpoint_url . $g1 . '/members/' . $u2 ); + $request = new WP_REST_Request( 'DELETE', $this->endpoint_url . $g1 . '/members/' . $u2 ); + $response = $this->server->dispatch( $request ); + + $this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() ); + } + + /** + * @group delete_item + */ + public function test_group_admin_can_remove_another_group_admin() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); + + $g1 = $this->bp::factory()->group->create( array( + 'creator_id' => $u1, // <- group admin. + ) ); + + $this->populate_group_with_members( [ $u2, $u3 ], $g1 ); + + $group_member = new BP_Groups_Member( $u3, $g1 ); + $group_member->promote( 'admin' ); + + $this->bp::set_current_user( $u3 ); + + $request = new WP_REST_Request( 'DELETE', $this->endpoint_url . $g1 . '/members/' . $u1 ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 200, $response->get_status() ); + + $all_data = $response->get_data(); + + $user = bp_rest_get_user( $all_data['previous']['id'] ); + $this->assertFalse( groups_is_user_member( $user->ID, $g1 ) ); + $this->assertSame( $u1, $user->ID ); + } + + /** + * @group delete_item + */ + public function test_site_admin_can_not_remove_himself_group_admin() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); + + $g1 = $this->bp::factory()->group->create( array( + 'creator_id' => $u1, // <- group admin. + ) ); + + $this->populate_group_with_members( [ $u2, $u3 ], $g1 ); + + $this->bp::set_current_user( $this->user ); + + $request = new WP_REST_Request( 'DELETE', $this->endpoint_url . $g1 . '/members/' . $this->user ); + $response = $this->server->dispatch( $request ); + + $this->assertErrorResponse( 'bp_rest_group_member_failed_to_remove', $response, 500 ); + } + + /** + * @group delete_item + */ + public function test_site_admin_can_remove_group_admin() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + $u3 = static::factory()->user->create(); + + $g1 = $this->bp::factory()->group->create( array( + 'creator_id' => $u1, // <- group admin. + ) ); + + $this->populate_group_with_members( [ $u2, $u3 ], $g1 ); + + $group_member = new BP_Groups_Member( $u3, $g1 ); + $group_member->promote( 'admin' ); + + $this->bp::set_current_user( $this->user ); + + $request = new WP_REST_Request( 'DELETE', $this->endpoint_url . $g1 . '/members/' . $u1 ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 200, $response->get_status() ); + + $all_data = $response->get_data(); + + $user = bp_rest_get_user( $all_data['previous']['id'] ); + $this->assertFalse( groups_is_user_member( $user->ID, $g1 ) ); + $this->assertSame( $u1, $user->ID ); + } + + /** + * @group delete_item + */ + public function test_site_admin_can_not_remove_last_group_admin() { + $u1 = static::factory()->user->create(); + $u2 = static::factory()->user->create(); + + $g1 = $this->bp::factory()->group->create( array( + 'creator_id' => $u1, // <- group admin. + ) ); + + $this->populate_group_with_members( [ $u1, $u2 ], $g1 ); + + $this->bp::set_current_user( $this->user ); - $request->set_param( 'context', 'view' ); + $request = new WP_REST_Request( 'DELETE', $this->endpoint_url . $g1 . '/members/' . $u1 ); $response = $this->server->dispatch( $request ); $this->assertErrorResponse( 'bp_rest_authorization_required', $response, rest_authorization_required_code() );