Selaa lähdekoodia

[rust]: fix bugs to pass backend tests

appflowy 3 vuotta sitten
vanhempi
commit
2972c40b9b

+ 7 - 9
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;

+ 1 - 1
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);
 }

+ 1 - 5
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! {

+ 0 - 0
rust-lib/flowy-log/flowy_log_test.2021-11-09


+ 0 - 31
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);

+ 4 - 4
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>(())

+ 0 - 2
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 }
     }
 

+ 9 - 8
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<String> {
-    vec!["", "1234".repeat(100).as_str()]
-        .iter()
-        .map(|s| s.to_string())
-        .collect::<Vec<_>>()
+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<Workspace> {
+pub async fn read_workspace(sdk: &FlowyTestSDK, request: QueryWorkspaceRequest) -> Vec<Workspace> {
     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::<RepeatedWorkspace>();
 
-    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::<Vec<Workspace>>().pop()
+    workspaces
 }
 
 pub async fn create_app(sdk: &FlowyTestSDK, name: &str, desc: &str, workspace_id: &str) -> App {

+ 0 - 1
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 });

+ 1 - 1
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())

+ 1 - 6
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<String>) -> Self { Self { workspace_id } }
 }
 
 // Read all workspaces if the workspace_id is None

+ 1 - 0
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::*};

+ 3 - 3
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() {

+ 0 - 9
rust-lib/flowy-workspace/src/services/helper.rs

@@ -1,9 +0,0 @@
-use tokio::task::JoinHandle;
-
-pub fn spawn<F>(f: F) -> JoinHandle<F::Output>
-where
-    F: std::future::Future + Send + 'static,
-    F::Output: Send + 'static,
-{
-    tokio::spawn(f)
-}

+ 1 - 3
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;

+ 2 - 2
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());

+ 3 - 3
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) => {

+ 29 - 17
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<HashMap<String, bool>> = RwLock::new(HashMap::new());
+}
 
 pub struct WorkspaceController {
     pub user: Arc<dyn WorkspaceUser>,
@@ -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, _>(|| {

+ 0 - 0
rust-lib/flowy-workspace/src/services/util.rs → rust-lib/flowy-workspace/src/util.rs


+ 21 - 11
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::<Vec<Workspace>>()
+        .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::<Vec<Workspace>>()
+        .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()
         )
     }
 }