AppFlowy-Cloud/tests/workspace/member_crud.rs

505 lines
15 KiB
Rust

use app_error::ErrorCode;
use client_api::entity::AFWorkspaceInvitationStatus;
use client_api_test::{api_client_with_email, TestClient};
use database_entity::dto::{AFAccessLevel, AFRole, QueryCollabMembers};
use shared_entity::dto::workspace_dto::WorkspaceMemberInvitation;
#[tokio::test]
async fn get_workspace_owner_after_sign_up_test() {
let c1 = TestClient::new_user_without_ws_conn().await;
let workspace_id = c1.workspace_id().await;
// after the user sign up, the user should be the owner of the workspace
let members = c1
.api_client
.get_workspace_members(&workspace_id)
.await
.unwrap();
assert_eq!(members.len(), 1);
assert_eq!(members[0].email, c1.email().await);
// after user sign up, the user should have full access to the workspace
let collab_members = c1
.api_client
.get_collab_members(QueryCollabMembers {
workspace_id: workspace_id.clone(),
object_id: workspace_id.clone(),
})
.await
.unwrap()
.0;
assert_eq!(collab_members.len(), 1);
assert_eq!(
collab_members[0].permission.access_level,
AFAccessLevel::FullAccess
);
}
#[tokio::test]
async fn workspace_members_through_invite_or_direct_add() {
let owner = TestClient::new_user_without_ws_conn().await;
let member_1 = TestClient::new_user_without_ws_conn().await;
let member_2 = TestClient::new_user_without_ws_conn().await;
let workspace_id = owner.workspace_id().await;
owner
.invite_and_accepted_workspace_member(&workspace_id, &member_1, AFRole::Member)
.await
.unwrap();
// TODO(Zack): fix { code: OAuthError, message: "code: 500, msg:Error sending magic link, error_id: Some(\"3ec69543-e7b9-496d-92d8-f0b73ff09e0f\")" }
owner
.invite_and_accepted_workspace_member(&workspace_id, &member_2, AFRole::Member)
.await
.unwrap();
let members = owner
.api_client
.get_workspace_members(&workspace_id)
.await
.unwrap();
assert_eq!(members.len(), 3);
}
#[tokio::test]
async fn add_workspace_members_not_enough_permission() {
let owner = TestClient::new_user_without_ws_conn().await;
let member_1 = TestClient::new_user_without_ws_conn().await;
let member_2 = TestClient::new_user_without_ws_conn().await;
let workspace_id = owner.workspace_id().await;
// add client 2 to client 1's workspace
owner
.invite_and_accepted_workspace_member(&workspace_id, &member_1, AFRole::Member)
.await
.unwrap();
// client 2 add client 3 to client 1's workspace but permission denied
let error = member_1
.invite_and_accepted_workspace_member(&workspace_id, &member_2, AFRole::Member)
.await
.unwrap_err();
assert_eq!(error.code, ErrorCode::NotEnoughPermissions);
}
#[tokio::test]
async fn add_duplicate_workspace_members() {
let c1 = TestClient::new_user_without_ws_conn().await;
let c2 = TestClient::new_user_without_ws_conn().await;
let workspace_id = c1.workspace_id().await;
c1.invite_and_accepted_workspace_member(&workspace_id, &c2, AFRole::Member)
.await
.unwrap();
// next invite should return error since the user is already in the workspace
let err = c1
.api_client
.invite_workspace_members(
&workspace_id,
vec![WorkspaceMemberInvitation {
email: c2.email().await,
role: AFRole::Member,
}],
)
.await
.unwrap_err();
assert_eq!(err.code, ErrorCode::InvalidRequest, "{:?}", err);
// should not find any invitation
let invitations = c2
.api_client
.list_workspace_invitations(Some(AFWorkspaceInvitationStatus::Pending))
.await
.unwrap();
let is_none = !invitations
.iter()
.any(|inv| inv.workspace_id.to_string().as_str() == workspace_id);
assert!(is_none);
}
#[tokio::test]
async fn add_not_exist_workspace_members() {
let c1 = TestClient::new_user_without_ws_conn().await;
let workspace_id = c1.workspace_id().await;
let email = format!("{}@appflowy.io", uuid::Uuid::new_v4());
c1.api_client
.invite_workspace_members(
&workspace_id,
vec![WorkspaceMemberInvitation {
email: email.clone(),
role: AFRole::Member,
}],
)
.await
.unwrap();
let invited_client = api_client_with_email(&email).await;
let invite_id = invited_client
.list_workspace_invitations(None)
.await
.unwrap()
.first()
.unwrap()
.invite_id;
invited_client
.accept_workspace_invitation(invite_id.to_string().as_str())
.await
.unwrap();
let workspaces = invited_client.get_workspaces().await.unwrap();
assert_eq!(workspaces.len(), 2);
}
#[tokio::test]
async fn update_workspace_member_role_not_enough_permission() {
let c1 = TestClient::new_user_without_ws_conn().await;
let c2 = TestClient::new_user_without_ws_conn().await;
let workspace_id = c1.workspace_id().await;
// add client 2 to client 1's workspace
c1.invite_and_accepted_workspace_member(&workspace_id, &c2, AFRole::Member)
.await
.unwrap();
// client 2 want to update client 2's role to owner
let error = c2
.try_update_workspace_member(&workspace_id, &c2, AFRole::Owner)
.await
.unwrap_err();
assert_eq!(error.code, ErrorCode::NotEnoughPermissions);
}
#[tokio::test]
async fn update_workspace_member_role_from_guest_to_member() {
let owner = TestClient::new_user_without_ws_conn().await;
let guest = TestClient::new_user_without_ws_conn().await;
let workspace_id = owner.workspace_id().await;
// add client 2 to client 1's workspace
owner
.invite_and_accepted_workspace_member(&workspace_id, &guest, AFRole::Guest)
.await
.unwrap();
let members = owner
.api_client
.get_workspace_members(&workspace_id)
.await
.unwrap();
assert_eq!(members[0].email, owner.email().await);
assert_eq!(members[0].role, AFRole::Owner);
assert_eq!(members[1].email, guest.email().await);
assert_eq!(members[1].role, AFRole::Guest);
owner
.try_update_workspace_member(&workspace_id, &guest, AFRole::Member)
.await
.unwrap();
let members = owner
.api_client
.get_workspace_members(&workspace_id)
.await
.unwrap();
assert_eq!(members[0].email, owner.email().await);
assert_eq!(members[0].role, AFRole::Owner);
assert_eq!(members[1].email, guest.email().await);
assert_eq!(members[1].role, AFRole::Member);
}
#[tokio::test]
async fn workspace_add_member() {
let owner = TestClient::new_user_without_ws_conn().await;
let other_owner = TestClient::new_user_without_ws_conn().await;
let member = TestClient::new_user_without_ws_conn().await;
let guest = TestClient::new_user_without_ws_conn().await;
let workspace_id = owner.workspace_id().await;
// add client 2 to client 1's workspace
owner
.invite_and_accepted_workspace_member(&workspace_id, &other_owner, AFRole::Owner)
.await
.unwrap();
// add client 3 to client 1's workspace
other_owner
.invite_and_accepted_workspace_member(&workspace_id, &member, AFRole::Member)
.await
.unwrap();
other_owner
.invite_and_accepted_workspace_member(&workspace_id, &guest, AFRole::Guest)
.await
.unwrap();
let members = owner
.api_client
.get_workspace_members(&workspace_id)
.await
.unwrap();
assert_eq!(members.len(), 4);
assert_eq!(members[0].email, owner.email().await);
assert_eq!(members[0].role, AFRole::Owner);
assert_eq!(members[1].email, other_owner.email().await);
assert_eq!(members[1].role, AFRole::Owner);
assert_eq!(members[2].email, member.email().await);
assert_eq!(members[2].role, AFRole::Member);
assert_eq!(members[3].email, guest.email().await);
assert_eq!(members[3].role, AFRole::Guest);
// after adding the members to the workspace, we should be able to get the collab members
// of the workspace.
let collab_members = owner
.api_client
.get_collab_members(QueryCollabMembers {
workspace_id: workspace_id.clone(),
object_id: workspace_id.clone(),
})
.await
.unwrap()
.0;
assert_eq!(collab_members.len(), 4);
// owner
assert_eq!(collab_members[0].uid, owner.uid().await);
assert_eq!(
collab_members[0].permission.access_level,
AFAccessLevel::FullAccess
);
// other owner
assert_eq!(collab_members[1].uid, other_owner.uid().await);
assert_eq!(
collab_members[1].permission.access_level,
AFAccessLevel::FullAccess
);
// member
assert_eq!(collab_members[2].uid, member.uid().await);
assert_eq!(
collab_members[2].permission.access_level,
AFAccessLevel::ReadAndWrite
);
// guest
assert_eq!(collab_members[3].uid, guest.uid().await);
assert_eq!(
collab_members[3].permission.access_level,
AFAccessLevel::ReadOnly
);
}
#[tokio::test]
async fn add_workspace_member_and_owner_then_delete_all() {
let owner = TestClient::new_user_without_ws_conn().await;
let member = TestClient::new_user_without_ws_conn().await;
let second_owner = TestClient::new_user_without_ws_conn().await;
let workspace_id = owner.workspace_id().await;
// add client 2 to client 1's workspace
owner
.invite_and_accepted_workspace_member(&workspace_id, &member, AFRole::Member)
.await
.unwrap();
owner
.invite_and_accepted_workspace_member(&workspace_id, &second_owner, AFRole::Owner)
.await
.unwrap();
let members = owner
.api_client
.get_workspace_members(&workspace_id)
.await
.unwrap();
assert_eq!(members[0].email, owner.email().await);
assert_eq!(members[1].email, member.email().await);
assert_eq!(members[2].email, second_owner.email().await);
// delete the members
owner
.try_remove_workspace_member(&workspace_id, &member)
.await
.unwrap();
owner
.try_remove_workspace_member(&workspace_id, &second_owner)
.await
.unwrap();
let members = owner
.api_client
.get_workspace_members(&workspace_id)
.await
.unwrap();
assert_eq!(members.len(), 1);
assert_eq!(members[0].email, owner.email().await);
}
#[tokio::test]
async fn workspace_owner_remove_self_from_workspace() {
let c1 = TestClient::new_user_without_ws_conn().await;
let workspace_id = c1.workspace_id().await;
// the workspace owner can not remove 'self' from the workspace
let error = c1
.try_remove_workspace_member(&workspace_id, &c1)
.await
.unwrap_err();
assert_eq!(error.code, ErrorCode::NotEnoughPermissions);
let members = c1.get_workspace_members(&workspace_id).await;
assert_eq!(members.len(), 1);
assert_eq!(members[0].email, c1.email().await);
}
#[tokio::test]
async fn workspace_second_owner_can_not_delete_origin_owner() {
let c1 = TestClient::new_user_without_ws_conn().await;
let c2 = TestClient::new_user_without_ws_conn().await;
let workspace_id = c1.workspace_id().await;
c1.invite_and_accepted_workspace_member(&workspace_id, &c2, AFRole::Owner)
.await
.unwrap();
let error = c2
.try_remove_workspace_member(&workspace_id, &c1)
.await
.unwrap_err();
assert_eq!(error.code, ErrorCode::NotEnoughPermissions);
}
#[tokio::test]
async fn user_workspace_info() {
let c1 = TestClient::new_user_without_ws_conn().await;
let workspace_id = c1.workspace_id().await;
let info = c1.get_user_workspace_info().await;
assert_eq!(info.workspaces.len(), 1);
assert_eq!(
info.visiting_workspace.workspace_id.to_string(),
workspace_id
);
let c2 = TestClient::new_user_without_ws_conn().await;
c1.invite_and_accepted_workspace_member(&workspace_id, &c2, AFRole::Owner)
.await
.unwrap();
// c2 should have 2 workspaces
let info = c2.get_user_workspace_info().await;
assert_eq!(info.workspaces.len(), 2);
}
#[tokio::test]
async fn get_user_workspace_info_after_open_workspace() {
let c1 = TestClient::new_user_without_ws_conn().await;
let workspace_id_c1 = c1.workspace_id().await;
let c2 = TestClient::new_user_without_ws_conn().await;
c1.invite_and_accepted_workspace_member(&workspace_id_c1, &c2, AFRole::Owner)
.await
.unwrap();
let info = c2.get_user_workspace_info().await;
let workspace_id_c2 = c1.workspace_id().await;
assert_eq!(
info.visiting_workspace.workspace_id.to_string(),
workspace_id_c2
);
// After open workspace, the visiting workspace should be the workspace that user just opened
c2.open_workspace(&workspace_id_c1).await;
let info = c2.get_user_workspace_info().await;
assert_eq!(
info.visiting_workspace.workspace_id.to_string(),
workspace_id_c1
);
}
#[tokio::test]
async fn member_leave_workspace_test() {
let c1 = TestClient::new_user().await;
let workspace_id_c1 = c1.workspace_id().await;
let c2 = TestClient::new_user().await;
c1.invite_and_accepted_workspace_member(&workspace_id_c1, &c2, AFRole::Member)
.await
.unwrap();
c2.api_client
.leave_workspace(&workspace_id_c1)
.await
.unwrap();
let members = c1.get_workspace_members(&workspace_id_c1).await;
assert_eq!(members.len(), 1);
}
#[tokio::test]
async fn owner_leave_workspace_test() {
let c1 = TestClient::new_user().await;
let workspace_id_c1 = c1.workspace_id().await;
let err = c1
.api_client
.leave_workspace(&workspace_id_c1)
.await
.unwrap_err();
// owner of workspace cannot leave the workspace
assert_eq!(err.code, ErrorCode::NotEnoughPermissions);
}
#[tokio::test]
async fn add_workspace_member_and_then_member_get_member_list() {
let owner = TestClient::new_user_without_ws_conn().await;
let member = TestClient::new_user_without_ws_conn().await;
let guest = TestClient::new_user_without_ws_conn().await;
let workspace_id = owner.workspace_id().await;
owner
.invite_and_accepted_workspace_member(&workspace_id, &member, AFRole::Member)
.await
.unwrap();
owner
.invite_and_accepted_workspace_member(&workspace_id, &guest, AFRole::Guest)
.await
.unwrap();
// member should be able to get the member list of the workspace
let members = member.get_workspace_members(&workspace_id).await;
assert_eq!(members.len(), 3);
// guest should not be able to get the member list of the workspace
let error = guest
.try_get_workspace_members(&workspace_id)
.await
.unwrap_err();
assert_eq!(error.code, ErrorCode::NotEnoughPermissions);
}
#[tokio::test]
async fn workspace_member_through_user_id() {
let owner = TestClient::new_user_without_ws_conn().await;
let member_1 = TestClient::new_user_without_ws_conn().await;
let workspace_id = owner.workspace_id().await;
let owner_member = owner
.get_workspace_member(&workspace_id, owner.uid().await)
.await;
assert_eq!(owner_member.role, AFRole::Owner);
owner
.invite_and_accepted_workspace_member(&workspace_id, &member_1, AFRole::Member)
.await
.unwrap();
let member_1_member = member_1
.get_workspace_member(&workspace_id, member_1.uid().await)
.await;
assert_eq!(member_1_member.role, AFRole::Member);
assert_ne!(owner_member.role, member_1_member.role);
}