diff --git a/frontend/.vscode/launch.json b/frontend/.vscode/launch.json index 380e99d386..0f11de76bd 100644 --- a/frontend/.vscode/launch.json +++ b/frontend/.vscode/launch.json @@ -13,6 +13,7 @@ "type": "dart", "env": { "RUST_LOG": "debug", + "RUST_BACKTRACE": "1" }, // uncomment the following line to testing performance. // "flutterMode": "profile", diff --git a/frontend/rust-lib/event-integration/src/user_event.rs b/frontend/rust-lib/event-integration/src/user_event.rs index 66757dd534..0c8dfb0003 100644 --- a/frontend/rust-lib/event-integration/src/user_event.rs +++ b/frontend/rust-lib/event-integration/src/user_event.rs @@ -12,6 +12,8 @@ use uuid::Uuid; use flowy_notification::entities::SubscribeObject; use flowy_notification::NotificationSender; use flowy_server::supabase::define::{USER_DEVICE_ID, USER_EMAIL, USER_SIGN_IN_URL, USER_UUID}; +use flowy_server_config::af_cloud_config::AFCloudConfiguration; +use flowy_server_config::AuthenticatorType; use flowy_user::entities::{ AuthTypePB, CloudSettingPB, OauthSignInPB, SignInUrlPB, SignInUrlPayloadPB, SignUpPayloadPB, UpdateCloudConfigPB, UpdateUserProfilePayloadPB, UserProfilePB, @@ -297,3 +299,15 @@ pub struct SignUpContext { pub user_profile: UserProfilePB, pub password: String, } + +pub async fn user_localhost_af_cloud() { + AuthenticatorType::AppFlowyCloud.write_env(); + AFCloudConfiguration { + base_url: "http://localhost:8000".to_string(), + ws_base_url: "ws://localhost:8000/ws".to_string(), + gotrue_url: "http://localhost:9998".to_string(), + } + .write_env(); + std::env::set_var("GOTRUE_ADMIN_EMAIL", "admin@example.com"); + std::env::set_var("GOTRUE_ADMIN_PASSWORD", "password"); +} diff --git a/frontend/rust-lib/event-integration/tests/asset/039_local.zip b/frontend/rust-lib/event-integration/tests/asset/039_local.zip new file mode 100644 index 0000000000..7ef72daa02 Binary files /dev/null and b/frontend/rust-lib/event-integration/tests/asset/039_local.zip differ diff --git a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/anon_user_test.rs b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/anon_user_test.rs new file mode 100644 index 0000000000..975292da61 --- /dev/null +++ b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/anon_user_test.rs @@ -0,0 +1,105 @@ +use event_integration::user_event::user_localhost_af_cloud; +use event_integration::EventIntegrationTest; +use flowy_core::DEFAULT_NAME; +use flowy_user::entities::AuthTypePB; + +use crate::util::{get_af_cloud_config, unzip_history_user_db}; + +#[tokio::test] +async fn reading_039_anon_user_data_test() { + let (cleaner, user_db_path) = unzip_history_user_db("./tests/asset", "039_local").unwrap(); + let test = + EventIntegrationTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string()).await; + let first_level_views = test.get_all_workspace_views().await; + // In the 039_local, the structure is: + // workspace: + // view: Document1 + // view: Document2 + // view: Grid1 + // view: Grid2 + assert_eq!(first_level_views.len(), 1); + assert_eq!( + first_level_views[0].id, + "50a150e0-2aa9-4131-a259-8ef989315540".to_string() + ); + assert_eq!(first_level_views[0].name, "Document1".to_string()); + + let second_level_views = test.get_views(&first_level_views[0].id).await.child_views; + assert_eq!(second_level_views.len(), 1); + assert_eq!(second_level_views[0].name, "Document2".to_string()); + + // In the 039_local, there is only one view of the workspaces child + let third_level_views = test.get_views(&second_level_views[0].id).await.child_views; + assert_eq!(third_level_views.len(), 2); + assert_eq!(third_level_views[0].name, "Grid1".to_string()); + assert_eq!(third_level_views[1].name, "Grid2".to_string()); + + drop(cleaner); +} +#[tokio::test] +async fn anon_user_to_af_cloud_test() { + if get_af_cloud_config().is_none() { + return; + } + let (cleaner, user_db_path) = unzip_history_user_db("./tests/asset", "039_local").unwrap(); + user_localhost_af_cloud().await; + let test = + EventIntegrationTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string()).await; + let anon_first_level_views = test.get_all_workspace_views().await; + let _anon_second_level_views = test + .get_views(&anon_first_level_views[0].id) + .await + .child_views; + + let user = test.af_cloud_sign_up().await; + assert_eq!(user.auth_type, AuthTypePB::AFCloud); + // let mut sync_state = test + // .folder_manager + // .get_mutex_folder() + // .lock() + // .as_ref() + // .unwrap() + // .subscribe_sync_state(); + // + // // TODO(nathan): will be removed when supporting merge FolderData + // // wait until the state is SyncFinished with 10 secs timeout + // loop { + // select! { + // _ = tokio::time::sleep(Duration::from_secs(10)) => { + // panic!("Timeout waiting for sync finished"); + // } + // state = sync_state.next() => { + // if let Some(state) = &state { + // if state == &SyncState::SyncFinished { + // break; + // } + // } + // } + // } + // } + // + // let user_first_level_views = test.get_all_workspace_views().await; + // let user_second_level_views = test + // .get_views(&user_first_level_views[1].id) + // .await + // .child_views; + // + // // first + // assert_eq!(anon_first_level_views.len(), 1); + // assert_eq!(user_first_level_views.len(), 2); + // assert_eq!( + // anon_first_level_views[0].name, + // // The first one is the get started document + // user_first_level_views[1].name + // ); + // assert_ne!(anon_first_level_views[0].id, user_first_level_views[1].id); + // + // // second + // assert_eq!(anon_second_level_views.len(), user_second_level_views.len()); + // assert_eq!( + // anon_second_level_views[0].name, + // user_second_level_views[0].name + // ); + // assert_ne!(anon_second_level_views[0].id, user_second_level_views[0].id); + drop(cleaner); +} diff --git a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/mod.rs b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/mod.rs index 47a617ef52..112d18ad20 100644 --- a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/mod.rs +++ b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/mod.rs @@ -1,3 +1,3 @@ +mod anon_user_test; mod auth_test; mod member_test; -mod sync_anon_data_test; diff --git a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/sync_anon_data_test.rs b/frontend/rust-lib/event-integration/tests/user/af_cloud_test/sync_anon_data_test.rs deleted file mode 100644 index 8b13789179..0000000000 --- a/frontend/rust-lib/event-integration/tests/user/af_cloud_test/sync_anon_data_test.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/frontend/rust-lib/flowy-user/src/anon_user_upgrade/anon_user_data.rs b/frontend/rust-lib/flowy-user/src/anon_user_upgrade/migrate_anon_user_collab.rs similarity index 100% rename from frontend/rust-lib/flowy-user/src/anon_user_upgrade/anon_user_data.rs rename to frontend/rust-lib/flowy-user/src/anon_user_upgrade/migrate_anon_user_collab.rs diff --git a/frontend/rust-lib/flowy-user/src/anon_user_upgrade/mod.rs b/frontend/rust-lib/flowy-user/src/anon_user_upgrade/mod.rs index b4078b6d56..8928821430 100644 --- a/frontend/rust-lib/flowy-user/src/anon_user_upgrade/mod.rs +++ b/frontend/rust-lib/flowy-user/src/anon_user_upgrade/mod.rs @@ -1,7 +1,7 @@ -pub use anon_user_data::*; -pub use sync_af_cloud_new_user::*; -pub use sync_supabase_new_user::*; +pub use migrate_anon_user_collab::*; +pub use sync_af_user_collab::*; +pub use sync_supabase_user_collab::*; -mod anon_user_data; -mod sync_af_cloud_new_user; -mod sync_supabase_new_user; +mod migrate_anon_user_collab; +mod sync_af_user_collab; +mod sync_supabase_user_collab; diff --git a/frontend/rust-lib/flowy-user/src/anon_user_upgrade/sync_af_cloud_new_user.rs b/frontend/rust-lib/flowy-user/src/anon_user_upgrade/sync_af_user_collab.rs similarity index 100% rename from frontend/rust-lib/flowy-user/src/anon_user_upgrade/sync_af_cloud_new_user.rs rename to frontend/rust-lib/flowy-user/src/anon_user_upgrade/sync_af_user_collab.rs diff --git a/frontend/rust-lib/flowy-user/src/anon_user_upgrade/sync_supabase_new_user.rs b/frontend/rust-lib/flowy-user/src/anon_user_upgrade/sync_supabase_user_collab.rs similarity index 100% rename from frontend/rust-lib/flowy-user/src/anon_user_upgrade/sync_supabase_new_user.rs rename to frontend/rust-lib/flowy-user/src/anon_user_upgrade/sync_supabase_user_collab.rs diff --git a/frontend/rust-lib/flowy-user/src/manager.rs b/frontend/rust-lib/flowy-user/src/manager.rs index 874b48b7e6..7f7f1ab025 100644 --- a/frontend/rust-lib/flowy-user/src/manager.rs +++ b/frontend/rust-lib/flowy-user/src/manager.rs @@ -105,13 +105,7 @@ impl UserManager { let user_status_callback: RwLock> = RwLock::new(Arc::new(DefaultUserStatusCallback)); let current_session = Arc::new(parking_lot::RwLock::new(None)); - let current_authenticator = current_authenticator(); - migrate_session_with_user_uuid( - ¤t_authenticator, - &user_config, - ¤t_session, - &store_preferences, - ); + migrate_session_with_user_uuid(&user_config, ¤t_session, &store_preferences); let refresh_user_profile_since = AtomicI64::new(0); let user_manager = Arc::new(Self { diff --git a/frontend/rust-lib/flowy-user/src/migrations/session_migration.rs b/frontend/rust-lib/flowy-user/src/migrations/session_migration.rs index 7f72606628..c5fae7bbb4 100644 --- a/frontend/rust-lib/flowy-user/src/migrations/session_migration.rs +++ b/frontend/rust-lib/flowy-user/src/migrations/session_migration.rs @@ -1,28 +1,37 @@ -use crate::manager::UserConfig; -use crate::services::entities::Session; -use flowy_sqlite::kv::StorePreferences; -use flowy_user_deps::entities::Authenticator; -use serde_json::{json, Value}; use std::sync::Arc; + +use serde_json::{json, Value}; use uuid::Uuid; +use flowy_sqlite::kv::StorePreferences; + +use crate::manager::UserConfig; +use crate::services::entities::Session; + +const MIGRATION_USER_NO_USER_UUID: &str = "migration_user_no_user_uuid"; + pub fn migrate_session_with_user_uuid( - authenticator: &Authenticator, user_config: &UserConfig, session: &Arc>>, store_preferences: &Arc, ) { - if matches!(authenticator, Authenticator::Local) { - if let Some(mut value) = store_preferences.get_object::(&user_config.session_cache_key) { - if value.get("user_uuid").is_none() { - value.as_object_mut().map(|map| { - map.insert("user_uuid".to_string(), json!(Uuid::new_v4())); - }); - } + if !store_preferences.get_bool(MIGRATION_USER_NO_USER_UUID) { + if store_preferences + .set_bool(MIGRATION_USER_NO_USER_UUID, true) + .is_ok() + { + if let Some(mut value) = store_preferences.get_object::(&user_config.session_cache_key) + { + if value.get("user_uuid").is_none() { + value.as_object_mut().map(|map| { + map.insert("user_uuid".to_string(), json!(Uuid::new_v4())); + }); + } - if let Ok(new_session) = serde_json::from_value::(value) { - *session.write() = Some(new_session.clone()); - let _ = store_preferences.set_object(&user_config.session_cache_key, &new_session); + if let Ok(new_session) = serde_json::from_value::(value) { + *session.write() = Some(new_session.clone()); + let _ = store_preferences.set_object(&user_config.session_cache_key, &new_session); + } } } }