From 2972c40b9bd767a4df413f1f0f93815285dfc8e9 Mon Sep 17 00:00:00 2001 From: appflowy Date: Tue, 9 Nov 2021 15:32:57 +0800 Subject: [PATCH] [rust]: fix bugs to pass backend tests --- backend/src/service/user/auth.rs | 16 +++---- backend/tests/api/workspace.rs | 2 +- rust-lib/flowy-infra/src/kv/kv.rs | 6 +-- rust-lib/flowy-log/flowy_log_test.2021-11-09 | 0 rust-lib/flowy-log/src/lib.rs | 31 ------------- rust-lib/flowy-sdk/src/lib.rs | 8 ++-- rust-lib/flowy-test/src/lib.rs | 2 - rust-lib/flowy-test/src/workspace.rs | 17 +++---- .../src/services/user/user_session.rs | 1 - .../tests/event/user_profile_test.rs | 2 +- .../src/entities/workspace/workspace_query.rs | 7 +-- rust-lib/flowy-workspace/src/lib.rs | 1 + .../src/services/app_controller.rs | 6 +-- .../flowy-workspace/src/services/helper.rs | 9 ---- rust-lib/flowy-workspace/src/services/mod.rs | 4 +- .../flowy-workspace/src/services/trash_can.rs | 4 +- .../src/services/view_controller.rs | 6 +-- .../src/services/workspace_controller.rs | 46 ++++++++++++------- .../src/{services => }/util.rs | 0 .../tests/workspace/workspace_test.rs | 32 ++++++++----- 20 files changed, 84 insertions(+), 116 deletions(-) create mode 100644 rust-lib/flowy-log/flowy_log_test.2021-11-09 delete mode 100644 rust-lib/flowy-workspace/src/services/helper.rs rename rust-lib/flowy-workspace/src/{services => }/util.rs (100%) diff --git a/backend/src/service/user/auth.rs b/backend/src/service/user/auth.rs index ace13a7616..aa5c332198 100644 --- a/backend/src/service/user/auth.rs +++ b/backend/src/service/user/auth.rs @@ -1,7 +1,10 @@ +use crate::{ + entities::{token::Token, user::UserTable}, + service::user::{hash_password, verify_password, LoggedUser}, + sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder}, +}; use anyhow::Context; - -use sqlx::{PgPool, Postgres}; - +use chrono::Utc; use flowy_net::{ errors::{invalid_params, ErrorCode, ServerError}, response::FlowyResponse, @@ -10,12 +13,7 @@ use flowy_user_infra::{ parser::{UserEmail, UserName, UserPassword}, protobuf::{SignInParams, SignInResponse, SignUpParams, SignUpResponse, UpdateUserParams, UserProfile}, }; - -use crate::{ - entities::{token::Token, user::UserTable}, - service::user::{hash_password, verify_password, LoggedUser}, - sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder}, -}; +use sqlx::{PgPool, Postgres}; use super::AUTHORIZED_USERS; use crate::service::user::user_default::create_default_workspace; diff --git a/backend/tests/api/workspace.rs b/backend/tests/api/workspace.rs index 3355c87106..1f46a065c6 100644 --- a/backend/tests/api/workspace.rs +++ b/backend/tests/api/workspace.rs @@ -210,7 +210,7 @@ async fn workspace_list_read() { let _ = server.create_workspace(params).await; } - let read_params = WorkspaceIdentifier::new(); + let read_params = WorkspaceIdentifier::new(None); let workspaces = server.read_workspaces(read_params).await; assert_eq!(workspaces.len(), 4); } diff --git a/rust-lib/flowy-infra/src/kv/kv.rs b/rust-lib/flowy-infra/src/kv/kv.rs index 4a6813ac51..8ef1c7ccca 100644 --- a/rust-lib/flowy-infra/src/kv/kv.rs +++ b/rust-lib/flowy-infra/src/kv/kv.rs @@ -4,11 +4,7 @@ use diesel::{Connection, SqliteConnection}; use flowy_derive::ProtoBuf; use flowy_sqlite::{DBConnection, Database, PoolConfig}; use lazy_static::lazy_static; -use std::{ - collections::HashMap, - path::Path, - sync::{PoisonError, RwLock, RwLockWriteGuard}, -}; +use std::{collections::HashMap, path::Path, sync::RwLock}; const DB_NAME: &str = "kv.db"; lazy_static! { diff --git a/rust-lib/flowy-log/flowy_log_test.2021-11-09 b/rust-lib/flowy-log/flowy_log_test.2021-11-09 new file mode 100644 index 0000000000..e69de29bb2 diff --git a/rust-lib/flowy-log/src/lib.rs b/rust-lib/flowy-log/src/lib.rs index b2ed12fd00..86b45520f1 100644 --- a/rust-lib/flowy-log/src/lib.rs +++ b/rust-lib/flowy-log/src/lib.rs @@ -102,37 +102,6 @@ mod tests { say("hello world"); } - #[test] - fn test_log2() { - let env_filter = EnvFilter::new("Debug"); - let file_appender = tracing_appender::rolling::daily(".", "flowy_log_test"); - let (non_blocking, _guard) = tracing_appender::non_blocking(file_appender); - - let subscriber = tracing_subscriber::fmt() - .with_target(false) - .with_max_level(tracing::Level::TRACE) - .with_writer(std::io::stderr) - .with_thread_ids(true) - .with_writer(non_blocking) - .json() - .compact() - .finish() - .with(env_filter); - - let formatting_layer = FlowyFormattingLayer::new(std::io::stdout); - let _ = set_global_default(subscriber.with(JsonStorageLayer).with(formatting_layer)) - .map_err(|e| format!("{:?}", e)) - .unwrap(); - - let _ = LogTracer::builder() - .with_max_level(LevelFilter::Trace) - .init() - .map_err(|e| format!("{:?}", e)) - .unwrap(); - - tracing::info!("😁"); - } - #[tracing::instrument(name = "say")] fn say(s: &str) { tracing::info!("{}", s); diff --git a/rust-lib/flowy-sdk/src/lib.rs b/rust-lib/flowy-sdk/src/lib.rs index 50bf75da47..70c5c1f47d 100644 --- a/rust-lib/flowy-sdk/src/lib.rs +++ b/rust-lib/flowy-sdk/src/lib.rs @@ -110,8 +110,8 @@ async fn _listen_user_status( Ok(status) => { let result = || async { match status { - UserStatus::Login { .. } => { - let _ = workspace_controller.user_did_login()?; + UserStatus::Login { token } => { + let _ = workspace_controller.user_did_sign_in(&token)?; }, UserStatus::Logout { .. } => { workspace_controller.user_did_logout(); @@ -119,8 +119,8 @@ async fn _listen_user_status( UserStatus::Expired { .. } => { workspace_controller.user_session_expired(); }, - UserStatus::SignUp { .. } => { - let _ = workspace_controller.user_did_sign_up().await?; + UserStatus::SignUp { profile } => { + let _ = workspace_controller.user_did_sign_up(&profile.token).await?; }, } Ok::<(), WorkspaceError>(()) diff --git a/rust-lib/flowy-test/src/lib.rs b/rust-lib/flowy-test/src/lib.rs index c5b70bceaf..883880349b 100644 --- a/rust-lib/flowy-test/src/lib.rs +++ b/rust-lib/flowy-test/src/lib.rs @@ -40,8 +40,6 @@ impl FlowyTest { pub fn setup_with(server_config: ServerConfig) -> Self { let config = FlowySDKConfig::new(&root_dir(), server_config).log_filter("debug"); let sdk = FlowySDK::new(config); - let _ = sdk.workspace.init().unwrap(); - Self { sdk } } diff --git a/rust-lib/flowy-test/src/workspace.rs b/rust-lib/flowy-test/src/workspace.rs index ff628703a2..85a196d7b9 100644 --- a/rust-lib/flowy-test/src/workspace.rs +++ b/rust-lib/flowy-test/src/workspace.rs @@ -7,6 +7,7 @@ use flowy_workspace::{ view::*, workspace::*, }, + errors::ErrorCode, event::WorkspaceEvent::*, }; @@ -98,11 +99,11 @@ impl ViewTest { } } -pub fn invalid_workspace_name_test_case() -> Vec { - vec!["", "1234".repeat(100).as_str()] - .iter() - .map(|s| s.to_string()) - .collect::>() +pub fn invalid_workspace_name_test_case() -> Vec<(String, ErrorCode)> { + vec![ + ("".to_owned(), ErrorCode::WorkspaceNameInvalid), + ("1234".repeat(100), ErrorCode::WorkspaceNameTooLong), + ] } pub async fn create_workspace(sdk: &FlowyTestSDK, name: &str, desc: &str) -> Workspace { @@ -131,7 +132,7 @@ async fn open_workspace(sdk: &FlowyTestSDK, workspace_id: &str) { .await; } -pub async fn read_workspace(sdk: &FlowyTestSDK, request: QueryWorkspaceRequest) -> Option { +pub async fn read_workspace(sdk: &FlowyTestSDK, request: QueryWorkspaceRequest) -> Vec { let mut repeated_workspace = FlowyWorkspaceTest::new(sdk.clone()) .event(ReadWorkspaces) .request(request.clone()) @@ -139,7 +140,7 @@ pub async fn read_workspace(sdk: &FlowyTestSDK, request: QueryWorkspaceRequest) .await .parse::(); - let mut workspaces; + let workspaces; if let Some(workspace_id) = &request.workspace_id { workspaces = repeated_workspace .into_inner() @@ -151,7 +152,7 @@ pub async fn read_workspace(sdk: &FlowyTestSDK, request: QueryWorkspaceRequest) workspaces = repeated_workspace.items; } - workspaces.drain(..1).collect::>().pop() + workspaces } pub async fn create_app(sdk: &FlowyTestSDK, name: &str, desc: &str, workspace_id: &str) -> App { diff --git a/rust-lib/flowy-user/src/services/user/user_session.rs b/rust-lib/flowy-user/src/services/user/user_session.rs index d6ed352f8a..28d25f6b8c 100644 --- a/rust-lib/flowy-user/src/services/user/user_session.rs +++ b/rust-lib/flowy-user/src/services/user/user_session.rs @@ -75,7 +75,6 @@ impl UserSession { } pub fn init(&self) { - log::debug!("😁😁😁 user did login"); match self.get_session() { Ok(session) => { let _ = self.status_notifier.send(UserStatus::Login { token: session.token }); diff --git a/rust-lib/flowy-user/tests/event/user_profile_test.rs b/rust-lib/flowy-user/tests/event/user_profile_test.rs index b306a2ea4a..3b7bdef947 100644 --- a/rust-lib/flowy-user/tests/event/user_profile_test.rs +++ b/rust-lib/flowy-user/tests/event/user_profile_test.rs @@ -50,7 +50,7 @@ async fn user_update_with_name() { async fn user_update_with_email() { let test = FlowyTest::setup(); let user = test.init_user().await; - let new_email = format!("{}@gmai.com", uuid()); + let new_email = format!("{}@gmail.com", uuid()); let request = UpdateUserRequest::new(&user.id).email(&new_email); let _ = UserTest::new(test.sdk()).event(UpdateUser).request(request).sync_send(); let user_profile = UserTest::new(test.sdk()) diff --git a/rust-lib/flowy-workspace-infra/src/entities/workspace/workspace_query.rs b/rust-lib/flowy-workspace-infra/src/entities/workspace/workspace_query.rs index 5f721265eb..b57072adbe 100644 --- a/rust-lib/flowy-workspace-infra/src/entities/workspace/workspace_query.rs +++ b/rust-lib/flowy-workspace-infra/src/entities/workspace/workspace_query.rs @@ -10,12 +10,7 @@ pub struct QueryWorkspaceRequest { } impl QueryWorkspaceRequest { - pub fn new() -> Self { Self { workspace_id: None } } - - pub fn workspace_id(mut self, workspace_id: &str) -> Self { - self.workspace_id = Some(workspace_id.to_owned()); - self - } + pub fn new(workspace_id: Option) -> Self { Self { workspace_id } } } // Read all workspaces if the workspace_id is None diff --git a/rust-lib/flowy-workspace/src/lib.rs b/rust-lib/flowy-workspace/src/lib.rs index 720096e474..e3441b8d9c 100644 --- a/rust-lib/flowy-workspace/src/lib.rs +++ b/rust-lib/flowy-workspace/src/lib.rs @@ -15,6 +15,7 @@ pub mod handlers; mod notify; pub mod protobuf; mod sql_tables; +mod util; pub mod prelude { pub use flowy_workspace_infra::entities::{app::*, trash::*, view::*, workspace::*}; diff --git a/rust-lib/flowy-workspace/src/services/app_controller.rs b/rust-lib/flowy-workspace/src/services/app_controller.rs index 7da693cbd5..354f94d973 100644 --- a/rust-lib/flowy-workspace/src/services/app_controller.rs +++ b/rust-lib/flowy-workspace/src/services/app_controller.rs @@ -12,7 +12,7 @@ use crate::{ errors::*, module::{WorkspaceDatabase, WorkspaceUser}, notify::*, - services::{helper::spawn, server::Server, TrashCan, TrashEvent}, + services::{server::Server, TrashCan, TrashEvent}, sql_tables::app::{AppTable, AppTableChangeset, AppTableSql}, }; @@ -122,7 +122,7 @@ impl AppController { fn update_app_on_server(&self, params: UpdateAppParams) -> Result<(), WorkspaceError> { let token = self.user.token()?; let server = self.server.clone(); - spawn(async move { + tokio::spawn(async move { match server.update_app(&token, params).await { Ok(_) => {}, Err(e) => { @@ -139,7 +139,7 @@ impl AppController { let token = self.user.token()?; let server = self.server.clone(); let pool = self.database.db_pool()?; - spawn(async move { + tokio::spawn(async move { // Opti: retry? match server.read_app(&token, params).await { Ok(Some(app)) => match pool.get() { diff --git a/rust-lib/flowy-workspace/src/services/helper.rs b/rust-lib/flowy-workspace/src/services/helper.rs deleted file mode 100644 index 73ae8328fa..0000000000 --- a/rust-lib/flowy-workspace/src/services/helper.rs +++ /dev/null @@ -1,9 +0,0 @@ -use tokio::task::JoinHandle; - -pub fn spawn(f: F) -> JoinHandle -where - F: std::future::Future + Send + 'static, - F::Output: Send + 'static, -{ - tokio::spawn(f) -} diff --git a/rust-lib/flowy-workspace/src/services/mod.rs b/rust-lib/flowy-workspace/src/services/mod.rs index 328cf047ab..5678526952 100644 --- a/rust-lib/flowy-workspace/src/services/mod.rs +++ b/rust-lib/flowy-workspace/src/services/mod.rs @@ -5,9 +5,7 @@ pub use workspace_controller::*; mod app_controller; mod database; -mod helper; -pub mod server; +pub(crate) mod server; mod trash_can; -mod util; mod view_controller; mod workspace_controller; diff --git a/rust-lib/flowy-workspace/src/services/trash_can.rs b/rust-lib/flowy-workspace/src/services/trash_can.rs index 290308e2c1..6cbe53aef5 100644 --- a/rust-lib/flowy-workspace/src/services/trash_can.rs +++ b/rust-lib/flowy-workspace/src/services/trash_can.rs @@ -10,7 +10,7 @@ use crate::{ errors::{WorkspaceError, WorkspaceResult}, module::{WorkspaceDatabase, WorkspaceUser}, notify::{send_anonymous_dart_notification, WorkspaceNotification}, - services::{helper::spawn, server::Server}, + services::server::Server, sql_tables::trash::TrashTableSql, }; @@ -232,7 +232,7 @@ impl TrashCan { let server = self.server.clone(); let pool = self.database.db_pool()?; - spawn(async move { + tokio::spawn(async move { match server.read_trash(&token).await { Ok(repeated_trash) => { tracing::debug!("Remote trash count: {}", repeated_trash.items.len()); diff --git a/rust-lib/flowy-workspace/src/services/view_controller.rs b/rust-lib/flowy-workspace/src/services/view_controller.rs index 28a9944060..fc8acddd92 100644 --- a/rust-lib/flowy-workspace/src/services/view_controller.rs +++ b/rust-lib/flowy-workspace/src/services/view_controller.rs @@ -16,7 +16,7 @@ use crate::{ errors::{internal_error, WorkspaceError, WorkspaceResult}, module::{WorkspaceDatabase, WorkspaceUser}, notify::{send_dart_notification, WorkspaceNotification}, - services::{helper::spawn, server::Server, TrashCan, TrashEvent}, + services::{server::Server, TrashCan, TrashEvent}, sql_tables::view::{ViewTable, ViewTableChangeset, ViewTableSql}, }; @@ -187,7 +187,7 @@ impl ViewController { fn update_view_on_server(&self, params: UpdateViewParams) -> Result<(), WorkspaceError> { let token = self.user.token()?; let server = self.server.clone(); - spawn(async move { + tokio::spawn(async move { match server.update_view(&token, params).await { Ok(_) => {}, Err(e) => { @@ -205,7 +205,7 @@ impl ViewController { let server = self.server.clone(); let pool = self.database.db_pool()?; // Opti: retry? - spawn(async move { + tokio::spawn(async move { match server.read_view(&token, params).await { Ok(Some(view)) => match pool.get() { Ok(conn) => { diff --git a/rust-lib/flowy-workspace/src/services/workspace_controller.rs b/rust-lib/flowy-workspace/src/services/workspace_controller.rs index d487b35c5d..ceed90edc6 100644 --- a/rust-lib/flowy-workspace/src/services/workspace_controller.rs +++ b/rust-lib/flowy-workspace/src/services/workspace_controller.rs @@ -2,7 +2,7 @@ use crate::{ errors::*, module::{WorkspaceDatabase, WorkspaceUser}, notify::*, - services::{helper::spawn, read_local_workspace_apps, server::Server, AppController, TrashCan, ViewController}, + services::{read_local_workspace_apps, server::Server, AppController, TrashCan, ViewController}, sql_tables::workspace::{WorkspaceTable, WorkspaceTableChangeset, WorkspaceTableSql}, }; use chrono::Utc; @@ -12,12 +12,19 @@ use flowy_workspace_infra::{ entities::{app::RepeatedApp, workspace::*}, user_default, }; -use std::sync::{ - atomic::{AtomicBool, Ordering}, - Arc, +use lazy_static::lazy_static; +use parking_lot::RwLock; +use std::{ + collections::HashMap, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, }; -static INIT_WORKSPACE: AtomicBool = AtomicBool::new(false); +lazy_static! { + static ref INIT_WORKSPACE: RwLock> = RwLock::new(HashMap::new()); +} pub struct WorkspaceController { pub user: Arc, @@ -50,13 +57,14 @@ impl WorkspaceController { } } - fn init(&self) -> Result<(), WorkspaceError> { - if INIT_WORKSPACE.load(Ordering::SeqCst) { - return Ok(()); + fn init(&self, token: &str) -> Result<(), WorkspaceError> { + if let Some(is_init) = INIT_WORKSPACE.read().get(token) { + if *is_init { + return Ok(()); + } } + INIT_WORKSPACE.write().insert(token.to_owned(), true); - log::debug!("workspace initialize"); - INIT_WORKSPACE.store(true, Ordering::SeqCst); let _ = self.server.init(); let _ = self.trash_can.init()?; let _ = self.view_controller.init()?; @@ -65,9 +73,11 @@ impl WorkspaceController { Ok(()) } - pub fn user_did_login(&self) -> WorkspaceResult<()> { + pub fn user_did_sign_in(&self, token: &str) -> WorkspaceResult<()> { // TODO: (nathan) do something here - let _ = self.init()?; + + log::debug!("workspace initialize after sign in"); + let _ = self.init(token)?; Ok(()) } @@ -79,7 +89,7 @@ impl WorkspaceController { // TODO: (nathan) do something here } - pub async fn user_did_sign_up(&self) -> WorkspaceResult<()> { + pub async fn user_did_sign_up(&self, _token: &str) -> WorkspaceResult<()> { log::debug!("Create user default workspace"); let time = Utc::now(); let mut workspace = user_default::create_default_workspace(time); @@ -103,7 +113,9 @@ impl WorkspaceController { send_dart_notification(&token, WorkspaceNotification::UserCreateWorkspace) .payload(repeated_workspace) .send(); - let _ = self.init()?; + + log::debug!("workspace initialize after sign up"); + let _ = self.init(&token)?; Ok(()) } @@ -290,7 +302,7 @@ impl WorkspaceController { #[tracing::instrument(level = "debug", skip(self), err)] fn update_workspace_on_server(&self, params: UpdateWorkspaceParams) -> Result<(), WorkspaceError> { let (token, server) = self.token_with_server()?; - spawn(async move { + tokio::spawn(async move { match server.update_workspace(&token, params).await { Ok(_) => {}, Err(e) => { @@ -308,7 +320,7 @@ impl WorkspaceController { workspace_id: workspace_id.to_string(), }; let (token, server) = self.token_with_server()?; - spawn(async move { + tokio::spawn(async move { match server.delete_workspace(&token, params).await { Ok(_) => {}, Err(e) => { @@ -327,7 +339,7 @@ impl WorkspaceController { let app_ctrl = self.app_controller.clone(); let view_ctrl = self.view_controller.clone(); let conn = self.database.db_connection()?; - spawn(async move { + tokio::spawn(async move { // Opti: handle the error and retry? let workspaces = server.read_workspace(&token, params).await?; let _ = (&*conn).immediate_transaction::<_, WorkspaceError, _>(|| { diff --git a/rust-lib/flowy-workspace/src/services/util.rs b/rust-lib/flowy-workspace/src/util.rs similarity index 100% rename from rust-lib/flowy-workspace/src/services/util.rs rename to rust-lib/flowy-workspace/src/util.rs diff --git a/rust-lib/flowy-workspace/tests/workspace/workspace_test.rs b/rust-lib/flowy-workspace/tests/workspace/workspace_test.rs index 0bc08519c2..a0e9afc6c5 100644 --- a/rust-lib/flowy-workspace/tests/workspace/workspace_test.rs +++ b/rust-lib/flowy-workspace/tests/workspace/workspace_test.rs @@ -8,30 +8,40 @@ use flowy_workspace::{ #[tokio::test] async fn workspace_read_all() { let test = WorkspaceTest::new().await; - let workspace = read_workspace(&test.sdk, QueryWorkspaceRequest::new()).await.unwrap(); - assert_eq!(test.workspace, workspace); + let workspace = read_workspace(&test.sdk, QueryWorkspaceRequest::new(None)).await; + assert_eq!(workspace.len(), 2); } #[tokio::test] async fn workspace_read() { let test = WorkspaceTest::new().await; - let request = QueryWorkspaceRequest::new().workspace_id(&test.workspace.id); - let workspace = read_workspace(&test.sdk, request).await.unwrap(); - assert_eq!(test.workspace, workspace); + let request = QueryWorkspaceRequest::new(Some(test.workspace.id.clone())); + let workspace_from_db = read_workspace(&test.sdk, request) + .await + .drain(..1) + .collect::>() + .pop() + .unwrap(); + assert_eq!(test.workspace, workspace_from_db); } #[tokio::test] async fn workspace_create_with_apps() { let test = WorkspaceTest::new().await; let app = create_app(&test.sdk, "App A", "AppFlowy Github Project", &test.workspace.id).await; - let request = QueryWorkspaceRequest::new().workspace_id(&test.workspace.id); - let workspace_from_db = read_workspace(&test.sdk, request).await.unwrap(); + let request = QueryWorkspaceRequest::new(Some(test.workspace.id.clone())); + let workspace_from_db = read_workspace(&test.sdk, request) + .await + .drain(..1) + .collect::>() + .pop() + .unwrap(); assert_eq!(&app, workspace_from_db.apps.first_or_crash()); } #[tokio::test] async fn workspace_create_with_invalid_name() { - for name in invalid_workspace_name_test_case() { + for (name, code) in invalid_workspace_name_test_case() { let sdk = FlowyTest::setup().sdk; let request = CreateWorkspaceRequest { name, @@ -45,7 +55,7 @@ async fn workspace_create_with_invalid_name() { .await .error() .code, - ErrorCode::WorkspaceNameInvalid.value() + code.value() ) } } @@ -53,7 +63,7 @@ async fn workspace_create_with_invalid_name() { #[tokio::test] async fn workspace_update_with_invalid_name() { let sdk = FlowyTest::setup().sdk; - for name in invalid_workspace_name_test_case() { + for (name, code) in invalid_workspace_name_test_case() { let request = CreateWorkspaceRequest { name, desc: "".to_owned(), @@ -66,7 +76,7 @@ async fn workspace_update_with_invalid_name() { .await .error() .code, - ErrorCode::WorkspaceNameInvalid.value() + code.value() ) } }