feat: added tests for inviting member which has not signed up yet

This commit is contained in:
Zack Fu Zi Xiang 2024-03-06 14:01:57 +08:00
parent dca443affc
commit c293929b11
No known key found for this signature in database
7 changed files with 89 additions and 17 deletions

View File

@ -76,6 +76,30 @@ pub async fn generate_sign_in_action_link(email: &str) -> String {
.unwrap()
}
// same as generate_unique_registered_user_client
// but with specific email
pub async fn api_client_with_email(user_email: &str) -> client_api::Client {
let new_user_sign_in_link = {
let admin_client = admin_user_client().await;
admin_client
.generate_sign_in_action_link(user_email)
.await
.unwrap()
};
let client = localhost_client();
let appflowy_sign_in_url = client
.extract_sign_in_url(&new_user_sign_in_link)
.await
.unwrap();
client
.sign_in_with_url(&appflowy_sign_in_url)
.await
.unwrap();
client
}
pub fn localhost_gotrue_client() -> gotrue::api::Client {
let reqwest_client = reqwest::Client::new();
gotrue::api::Client::new(reqwest_client, &LOCALHOST_GOTRUE)

View File

@ -36,7 +36,7 @@ pub struct CreateWorkspaceMember {
pub role: AFRole,
}
#[derive(Deserialize, Serialize)]
#[derive(Debug, Deserialize, Serialize)]
pub struct WorkspaceMemberInvitation {
pub email: String,
pub role: AFRole,

View File

@ -246,6 +246,8 @@ async fn post_workspace_invite_handler(
let invited_members = payload.into_inner();
workspace::ops::invite_workspace_members(
&state.pg_pool,
&state.gotrue_admin,
&state.gotrue_client,
&user_uuid,
&workspace_id,
invited_members,

View File

@ -255,10 +255,7 @@ async fn setup_admin_account(
) -> Result<GoTrueAdmin, Error> {
let admin_email = gotrue_setting.admin_email.as_str();
let password = gotrue_setting.admin_password.as_str();
let gotrue_admin = GoTrueAdmin {
admin_email: admin_email.to_owned(),
password: admin_email.to_owned().into(),
};
let gotrue_admin = GoTrueAdmin::new(admin_email.to_owned(), password.to_owned());
let res_resp = gotrue_client.sign_up(admin_email, password, None).await;
match res_resp {

View File

@ -1,4 +1,5 @@
use crate::biz::workspace::access_control::WorkspaceAccessControl;
use crate::state::GoTrueAdmin;
use anyhow::Context;
use app_error::AppError;
use database::collab::upsert_collab_member_with_txn;
@ -17,6 +18,8 @@ use database::workspace::{
use database_entity::dto::{
AFAccessLevel, AFRole, AFWorkspace, AFWorkspaceInvitation, AFWorkspaceInvitationStatus,
};
use gotrue::params::InviteUserParams;
use shared_entity::dto::workspace_dto::{
CreateWorkspaceMember, WorkspaceMemberChangeset, WorkspaceMemberInvitation,
};
@ -26,7 +29,7 @@ use sqlx::{types::uuid, PgPool};
use std::collections::HashMap;
use std::ops::DerefMut;
use std::sync::Arc;
use tracing::instrument;
use tracing::{info, instrument};
use uuid::Uuid;
use workspace_template::document::get_started::GetStartedDocumentTemplate;
@ -159,6 +162,8 @@ pub async fn accept_workspace_invite(
#[instrument(level = "debug", skip_all, err)]
pub async fn invite_workspace_members(
pg_pool: &PgPool,
gotrue_admin: &GoTrueAdmin,
gotrue_client: &gotrue::api::Client,
inviter: &Uuid,
workspace_id: &Uuid,
invitations: Vec<WorkspaceMemberInvitation>,
@ -168,7 +173,37 @@ pub async fn invite_workspace_members(
.await
.context("Begin transaction to invite workspace members")?;
let admin_token = gotrue_admin.token(gotrue_client).await?;
for invitation in invitations {
match gotrue_client
.admin_invite_user(
&admin_token,
&InviteUserParams {
email: invitation.email.clone(),
..Default::default()
},
)
.await
{
Ok(new_user) => {
info!(
"Invited new user: {:?} to workspace: {:?}",
new_user, workspace_id
);
},
Err(err) => match err {
app_error::gotrue::GoTrueError::Internal(ref err_serde) => {
match (err_serde.code, err_serde.msg.as_str()) {
(422, "A user with this email address has already been registered") => {
info!("User already exists, skipping invite");
},
_ => return Err(AppError::Internal(err.into())),
}
},
_ => return Err(err.into()),
},
}
insert_workspace_invitation(
&mut txn,
workspace_id,

View File

@ -19,7 +19,7 @@ async fn main() -> anyhow::Result<()> {
filters.push(format!("gotrue={}", level));
let conf =
get_configuration().map_err(|e| anyhow::anyhow!("Failed to read configuration: {}", e))?;
init_subscriber(&conf.app_env, filters);
// init_subscriber(&conf.app_env, filters);
// If current build is debug and the feature "custom_env" is not enabled, load from .env
// otherwise, load from .env.without_nginx.

View File

@ -1,7 +1,7 @@
use app_error::ErrorCode;
use client_api_test_util::TestClient;
use client_api_test_util::{api_client_with_email, TestClient};
use database_entity::dto::{AFAccessLevel, AFRole, QueryCollabMembers};
use shared_entity::dto::workspace_dto::CreateWorkspaceMember;
use shared_entity::dto::workspace_dto::WorkspaceMemberInvitation;
#[tokio::test]
async fn get_workspace_owner_after_sign_up_test() {
@ -73,20 +73,34 @@ 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());
let err = c1
.api_client
.add_workspace_members(
workspace_id,
vec![CreateWorkspaceMember {
email,
c1.api_client
.invite_workspace_members(
&workspace_id,
vec![WorkspaceMemberInvitation {
email: email.clone(),
role: AFRole::Member,
}],
)
.await
.unwrap_err();
.unwrap();
assert_eq!(err.code, ErrorCode::RecordNotFound);
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.0.len(), 2);
}
#[tokio::test]
async fn update_workspace_member_role_not_enough_permission() {
let c1 = TestClient::new_user_without_ws_conn().await;