feat: add workspace invitation test

This commit is contained in:
Zack Fu Zi Xiang 2024-03-10 20:15:10 +08:00
parent 91e8793010
commit 3effd53241
No known key found for this signature in database
13 changed files with 124 additions and 56 deletions

View File

@ -62,14 +62,12 @@ impl EventBuilder {
let response = self.get_response();
match response.clone().parse::<R, FlowyError>() {
Ok(Ok(data)) => data,
Ok(Err(e)) => {
panic!(
"Parser {:?} failed: {:?}, response {:?}",
std::any::type_name::<R>(),
e,
response
)
},
Ok(Err(e)) => panic!(
"Parser {:?} failed: {:?}, response {:?}",
std::any::type_name::<R>(),
e,
response
),
Err(e) => panic!(
"Dispatch {:?} failed: {:?}, response {:?}",
std::any::type_name::<R>(),

View File

@ -3,11 +3,13 @@ use flowy_folder::entities::*;
use flowy_folder::event_map::FolderEvent;
use flowy_folder::event_map::FolderEvent::*;
use flowy_user::entities::{
AddWorkspaceMemberPB, QueryWorkspacePB, RemoveWorkspaceMemberPB, RepeatedWorkspaceMemberPB,
AcceptWorkspaceInvitationPB, AddWorkspaceMemberPB, QueryWorkspacePB, RemoveWorkspaceMemberPB,
RepeatedWorkspaceInvitationPB, RepeatedWorkspaceMemberPB, WorkspaceMemberInvitationPB,
WorkspaceMemberPB,
};
use flowy_user::errors::FlowyError;
use flowy_user::event_map::UserEvent;
use flowy_user_pub::entities::WorkspaceRole;
use crate::event_builder::EventBuilder;
use crate::EventIntegrationTest;
@ -24,6 +26,41 @@ impl EventIntegrationTest {
.await;
}
pub async fn invite_workspace_member(
&self,
workspace_id: &str,
email: &str,
role: WorkspaceRole,
) {
EventBuilder::new(self.clone())
.event(UserEvent::InviteWorkspaceMember)
.payload(WorkspaceMemberInvitationPB {
workspace_id: workspace_id.to_string(),
invitee_email: email.to_string(),
role: role.into(),
})
.async_send()
.await;
}
pub async fn list_workspace_invitations(&self) -> RepeatedWorkspaceInvitationPB {
EventBuilder::new(self.clone())
.event(UserEvent::ListWorkspaceInvitations)
.async_send()
.await
.parse()
}
pub async fn accept_workspace_invitation(&self, invitation_id: &str) {
EventBuilder::new(self.clone())
.event(UserEvent::AcceptWorkspaceInvitation)
.payload(AcceptWorkspaceInvitationPB {
invite_id: invitation_id.to_string(),
})
.async_send()
.await;
}
pub async fn delete_workspace_member(&self, workspace_id: &str, email: &str) {
EventBuilder::new(self.clone())
.event(UserEvent::RemoveWorkspaceMember)

View File

@ -1,5 +1,36 @@
use event_integration::user_event::user_localhost_af_cloud;
use event_integration::EventIntegrationTest;
use flowy_user_pub::entities::WorkspaceRole;
use crate::user::af_cloud_test::workspace_test::get_synced_workspaces;
#[tokio::test]
async fn af_cloud_invite_workspace_member() {
user_localhost_af_cloud().await;
let test_1 = EventIntegrationTest::new().await;
let user_1 = test_1.af_cloud_sign_up().await;
let test_2 = EventIntegrationTest::new().await;
let user_2 = test_2.af_cloud_sign_up().await;
test_1
.invite_workspace_member(&user_1.workspace_id, &user_2.email, WorkspaceRole::Member)
.await;
let invitations = test_2.list_workspace_invitations().await;
let target_invi = invitations
.items
.into_iter()
.find(|i| i.inviter_name == user_1.name && i.workspace_id == user_1.workspace_id)
.unwrap();
test_2
.accept_workspace_invitation(&target_invi.invite_id)
.await;
let workspaces = get_synced_workspaces(&test_2, user_2.id).await;
assert_eq!(workspaces.len(), 2);
}
#[tokio::test]
async fn af_cloud_add_workspace_member_test() {

View File

@ -99,7 +99,10 @@ async fn af_cloud_open_workspace_test() {
assert_eq!(views[2].name, "my second document".to_string());
}
async fn get_synced_workspaces(test: &EventIntegrationTest, user_id: i64) -> Vec<UserWorkspacePB> {
pub async fn get_synced_workspaces(
test: &EventIntegrationTest,
user_id: i64,
) -> Vec<UserWorkspacePB> {
let _workspaces = test.get_all_workspaces().await.items;
let sub_id = user_id.to_string();
let rx = test

View File

@ -69,7 +69,7 @@ impl CalculationsService {
}
}
fn median(array: &Vec<f64>) -> f64 {
fn median(array: &[f64]) -> f64 {
if (array.len() % 2) == 0 {
let left = array.len() / 2 - 1;
let right = array.len() / 2;

View File

@ -17,8 +17,8 @@ use parking_lot::RwLock;
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
use flowy_user_pub::cloud::{UserCloudService, UserCollabParams, UserUpdate, UserUpdateReceiver};
use flowy_user_pub::entities::{
AFCloudOAuthParams, AuthResponse, Role, UpdateUserProfileParams, UserCredentials, UserProfile,
UserWorkspace, WorkspaceInvitation, WorkspaceInvitationStatus, WorkspaceMember,
AFCloudOAuthParams, AuthResponse, UpdateUserProfileParams, UserCredentials, UserProfile,
UserWorkspace, WorkspaceInvitation, WorkspaceInvitationStatus, WorkspaceMember, WorkspaceRole,
};
use lib_infra::box_any::BoxAny;
use lib_infra::future::FutureResult;
@ -206,7 +206,7 @@ where
&self,
invitee_email: String,
workspace_id: String,
role: Role,
role: WorkspaceRole,
) -> FutureResult<(), Error> {
let try_get_client = self.server.try_get_client();
FutureResult::new(async move {
@ -269,7 +269,7 @@ where
&self,
user_email: String,
workspace_id: String,
role: Role,
role: WorkspaceRole,
) -> FutureResult<(), Error> {
let try_get_client = self.server.try_get_client();
FutureResult::new(async move {

View File

@ -3,9 +3,8 @@ use client_api::entity::auth_dto::{UpdateUserParams, UserMetaData};
use client_api::entity::{AFRole, AFUserProfile, AFWorkspaceInvitationStatus, AFWorkspaceMember};
use flowy_user_pub::entities::{
Authenticator, Role, UpdateUserProfileParams, UserProfile, WorkspaceInvitationStatus,
WorkspaceMember, USER_METADATA_ICON_URL, USER_METADATA_OPEN_AI_KEY,
USER_METADATA_STABILITY_AI_KEY,
Authenticator, UpdateUserProfileParams, UserProfile, WorkspaceInvitationStatus, WorkspaceMember,
WorkspaceRole, USER_METADATA_ICON_URL, USER_METADATA_OPEN_AI_KEY, USER_METADATA_STABILITY_AI_KEY,
};
use crate::af_cloud::impls::user::util::encryption_type_from_profile;
@ -68,19 +67,19 @@ pub fn user_profile_from_af_profile(
})
}
pub fn to_af_role(role: Role) -> AFRole {
pub fn to_af_role(role: WorkspaceRole) -> AFRole {
match role {
Role::Owner => AFRole::Owner,
Role::Member => AFRole::Member,
Role::Guest => AFRole::Guest,
WorkspaceRole::Owner => AFRole::Owner,
WorkspaceRole::Member => AFRole::Member,
WorkspaceRole::Guest => AFRole::Guest,
}
}
pub fn from_af_role(role: AFRole) -> Role {
pub fn from_af_role(role: AFRole) -> WorkspaceRole {
match role {
AFRole::Owner => Role::Owner,
AFRole::Member => Role::Member,
AFRole::Guest => Role::Guest,
AFRole::Owner => WorkspaceRole::Owner,
AFRole::Member => WorkspaceRole::Member,
AFRole::Guest => WorkspaceRole::Guest,
}
}

View File

@ -15,8 +15,9 @@ use tokio_stream::wrappers::WatchStream;
use uuid::Uuid;
use crate::entities::{
AuthResponse, Authenticator, Role, UpdateUserProfileParams, UserCredentials, UserProfile,
AuthResponse, Authenticator, UpdateUserProfileParams, UserCredentials, UserProfile,
UserTokenState, UserWorkspace, WorkspaceInvitation, WorkspaceInvitationStatus, WorkspaceMember,
WorkspaceRole,
};
#[derive(Debug, Clone, Serialize, Deserialize)]
@ -195,7 +196,7 @@ pub trait UserCloudService: Send + Sync + 'static {
&self,
invitee_email: String,
workspace_id: String,
role: Role,
role: WorkspaceRole,
) -> FutureResult<(), Error> {
FutureResult::new(async { Ok(()) })
}
@ -223,7 +224,7 @@ pub trait UserCloudService: Send + Sync + 'static {
&self,
user_email: String,
workspace_id: String,
role: Role,
role: WorkspaceRole,
) -> FutureResult<(), Error> {
FutureResult::new(async { Ok(()) })
}

View File

@ -381,7 +381,7 @@ pub enum UserTokenState {
}
#[derive(Clone, Debug)]
pub enum Role {
pub enum WorkspaceRole {
Owner,
Member,
Guest,
@ -389,7 +389,7 @@ pub enum Role {
pub struct WorkspaceMember {
pub email: String,
pub role: Role,
pub role: WorkspaceRole,
pub name: String,
}

View File

@ -1,7 +1,7 @@
use validator::Validate;
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_user_pub::entities::{Role, WorkspaceInvitation, WorkspaceMember};
use flowy_user_pub::entities::{WorkspaceInvitation, WorkspaceMember, WorkspaceRole};
use lib_infra::validator_fn::required_not_empty_str;
#[derive(ProtoBuf, Default, Clone)]
@ -13,7 +13,7 @@ pub struct WorkspaceMemberPB {
pub name: String,
#[pb(index = 3)]
pub role: AFRolePB,
pub role: WorkspaceRolePB,
}
impl From<WorkspaceMember> for WorkspaceMemberPB {
@ -43,16 +43,16 @@ pub struct WorkspaceMemberInvitationPB {
pub invitee_email: String,
#[pb(index = 3)]
pub role: AFRolePB,
pub role: WorkspaceRolePB,
}
#[derive(ProtoBuf, Default, Clone)]
#[derive(Debug, ProtoBuf, Default, Clone)]
pub struct RepeatedWorkspaceInvitationPB {
#[pb(index = 1)]
pub items: Vec<WorkspaceInvitationPB>,
}
#[derive(ProtoBuf, Default, Clone)]
#[derive(Debug, ProtoBuf, Default, Clone)]
pub struct WorkspaceInvitationPB {
#[pb(index = 1)]
pub invite_id: String,
@ -131,33 +131,33 @@ pub struct UpdateWorkspaceMemberPB {
pub email: String,
#[pb(index = 3)]
pub role: AFRolePB,
pub role: WorkspaceRolePB,
}
#[derive(ProtoBuf_Enum, Clone, Default)]
pub enum AFRolePB {
pub enum WorkspaceRolePB {
Owner = 0,
Member = 1,
#[default]
Guest = 2,
}
impl From<AFRolePB> for Role {
fn from(value: AFRolePB) -> Self {
impl From<WorkspaceRolePB> for WorkspaceRole {
fn from(value: WorkspaceRolePB) -> Self {
match value {
AFRolePB::Owner => Role::Owner,
AFRolePB::Member => Role::Member,
AFRolePB::Guest => Role::Guest,
WorkspaceRolePB::Owner => WorkspaceRole::Owner,
WorkspaceRolePB::Member => WorkspaceRole::Member,
WorkspaceRolePB::Guest => WorkspaceRole::Guest,
}
}
}
impl From<Role> for AFRolePB {
fn from(value: Role) -> Self {
impl From<WorkspaceRole> for WorkspaceRolePB {
fn from(value: WorkspaceRole) -> Self {
match value {
Role::Owner => AFRolePB::Owner,
Role::Member => AFRolePB::Member,
Role::Guest => AFRolePB::Guest,
WorkspaceRole::Owner => WorkspaceRolePB::Owner,
WorkspaceRole::Member => WorkspaceRolePB::Member,
WorkspaceRole::Guest => WorkspaceRolePB::Guest,
}
}
}

View File

@ -711,7 +711,7 @@ pub async fn change_workspace_icon_handler(
}
#[tracing::instrument(level = "debug", skip_all, err)]
pub async fn invite_members_to_workspace_handler(
pub async fn invite_workspace_member_handler(
param: AFPluginData<WorkspaceMemberInvitationPB>,
manager: AFPluginState<Weak<UserManager>>,
) -> Result<(), FlowyError> {
@ -720,8 +720,7 @@ pub async fn invite_members_to_workspace_handler(
manager
.invite_member_to_workspace(param.workspace_id, param.invitee_email, param.role.into())
.await?;
todo!()
Ok(())
}
#[tracing::instrument(level = "debug", skip_all, err)]

View File

@ -67,7 +67,7 @@ pub fn init(user_manager: Weak<UserManager>) -> AFPlugin {
.event(UserEvent::RenameWorkspace, rename_workspace_handler)
.event(UserEvent::ChangeWorkspaceIcon, change_workspace_icon_handler)
.event(UserEvent::InviteMembersToWorkspace, invite_members_to_workspace_handler)
.event(UserEvent::InviteWorkspaceMember, invite_workspace_member_handler)
.event(UserEvent::ListWorkspaceInvitations, list_workspace_invitations_handler)
.event(UserEvent::AcceptWorkspaceInvitation, accept_workspace_invitations_handler)
}
@ -216,7 +216,7 @@ pub enum UserEvent {
ChangeWorkspaceIcon = 45,
#[event(input = "WorkspaceMemberInvitationPB")]
InviteMembersToWorkspace = 46,
InviteWorkspaceMember = 46,
#[event(output = "RepeatedWorkspaceInvitationPB")]
ListWorkspaceInvitations = 47,

View File

@ -10,7 +10,7 @@ use flowy_folder_pub::entities::{AppFlowyData, ImportData};
use flowy_sqlite::schema::user_workspace_table;
use flowy_sqlite::{query_dsl::*, DBConnection, ExpressionMethods};
use flowy_user_pub::entities::{
Role, UserWorkspace, WorkspaceInvitation, WorkspaceInvitationStatus, WorkspaceMember,
UserWorkspace, WorkspaceInvitation, WorkspaceInvitationStatus, WorkspaceMember, WorkspaceRole,
};
use lib_dispatch::prelude::af_spawn;
@ -200,7 +200,7 @@ impl UserManager {
&self,
workspace_id: String,
invitee_email: String,
role: Role,
role: WorkspaceRole,
) -> FlowyResult<()> {
self
.cloud_services
@ -272,7 +272,7 @@ impl UserManager {
&self,
user_email: String,
workspace_id: String,
role: Role,
role: WorkspaceRole,
) -> FlowyResult<()> {
self
.cloud_services