Merge pull request #7816 from AppFlowy-IO/disable_migrate_anono

chore: disable migrate anon user
This commit is contained in:
Nathan.fooo 2025-04-24 09:59:58 +08:00 committed by GitHub
commit 276e6503f7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 4 additions and 411 deletions

View file

@ -1,5 +1,3 @@
import 'anon_user_data_migration_test.dart' as anon_user_test;
void main() async {
anon_user_test.main();
// anon_user_test.main();
}

View file

@ -1,12 +1,8 @@
use crate::util::{receive_with_timeout, unzip};
use collab_document::blocks::DocumentData;
use collab_folder::SpaceInfo;
use crate::util::receive_with_timeout;
use event_integration_test::document_event::assert_document_data_equal;
use event_integration_test::user_event::use_localhost_af_cloud;
use event_integration_test::EventIntegrationTest;
use flowy_core::DEFAULT_NAME;
use flowy_document::entities::{DocumentSyncState, DocumentSyncStatePB};
use serde_json::json;
use std::time::Duration;
#[tokio::test]
@ -39,223 +35,3 @@ async fn af_cloud_edit_document_test() {
assert!(!doc_state.is_empty());
assert_document_data_equal(&doc_state, &document_id, document_data);
}
#[tokio::test]
async fn af_cloud_sync_anon_user_document_test() {
let user_db_path = unzip("./tests/asset", "040_sync_local_document").unwrap();
use_localhost_af_cloud().await;
let test =
EventIntegrationTest::new_with_user_data_path(user_db_path.clone(), DEFAULT_NAME.to_string())
.await;
test.af_cloud_sign_up().await;
test.wait_ws_connected().await;
// In the 040_sync_local_document, the structure is:
// workspace:
// view: SyncDocument
let views = test.get_all_workspace_views().await;
assert_eq!(views.len(), 3);
for view in views.iter() {
let space_info = serde_json::from_str::<SpaceInfo>(view.extra.as_ref().unwrap()).unwrap();
assert!(space_info.is_space);
}
let document_id = views[2].id.clone();
test.open_document(document_id.clone()).await;
// wait all update are send to the remote
let rx = test
.notification_sender
.subscribe_with_condition::<DocumentSyncStatePB, _>(&document_id, |pb| {
pb.value != DocumentSyncState::Syncing
});
let _ = receive_with_timeout(rx, Duration::from_secs(30)).await;
let doc_state = test.get_document_doc_state(&document_id).await;
assert_document_data_equal(
&doc_state,
&document_id,
expected_040_sync_local_document_data(),
);
}
fn expected_040_sync_local_document_data() -> DocumentData {
serde_json::from_value(json!( {
"blocks": {
"2hYJqg": {
"children": "AdDT7G",
"data": {
"delta": [
{
"insert": "bullet list format"
}
]
},
"external_id": null,
"external_type": null,
"id": "2hYJqg",
"parent": "beEtQt9xw6",
"ty": "bulleted_list"
},
"9GWi-3": {
"children": "osttqJ",
"data": {
"delta": [
{
"insert": "quote format"
}
]
},
"external_id": null,
"external_type": null,
"id": "9GWi-3",
"parent": "beEtQt9xw6",
"ty": "quote"
},
"RB-9fj": {
"children": "GNv1Bx",
"data": {
"delta": [
{
"insert": "number list format"
}
]
},
"external_id": null,
"external_type": null,
"id": "RB-9fj",
"parent": "beEtQt9xw6",
"ty": "numbered_list"
},
"TtoXrhXQKK": {
"children": "xVai4jK835",
"data": {
"delta": [
{
"insert": "Syncing the document content between server and the local."
}
]
},
"external_id": "-qBAb5hSHZ",
"external_type": "text",
"id": "TtoXrhXQKK",
"parent": "beEtQt9xw6",
"ty": "paragraph"
},
"beEtQt9xw6": {
"children": "e8O8NqDFSa",
"data": {},
"external_id": null,
"external_type": null,
"id": "beEtQt9xw6",
"parent": "",
"ty": "page"
},
"m59P6g": {
"children": "x2Nypz",
"data": {
"delta": [
{
"insert": "Header one format"
}
],
"level": 1
},
"external_id": null,
"external_type": null,
"id": "m59P6g",
"parent": "beEtQt9xw6",
"ty": "heading"
},
"mvGqkR": {
"children": "k7Pozf",
"data": {
"delta": [
{
"insert": "Header two format"
}
],
"level": 2
},
"external_id": null,
"external_type": null,
"id": "mvGqkR",
"parent": "beEtQt9xw6",
"ty": "heading"
},
"otbxLc": {
"children": "QJGGOs",
"data": {
"checked": false,
"delta": [
{
"insert": "checkbox format"
}
]
},
"external_id": null,
"external_type": null,
"id": "otbxLc",
"parent": "beEtQt9xw6",
"ty": "todo_list"
},
"qOb8PS": {
"children": "fbEQ-2",
"data": {
"delta": [
{
"insert": "It contains lots of formats."
}
]
},
"external_id": null,
"external_type": null,
"id": "qOb8PS",
"parent": "beEtQt9xw6",
"ty": "paragraph"
}
},
"meta": {
"children_map": {
"AdDT7G": [],
"GNv1Bx": [],
"QJGGOs": [],
"e8O8NqDFSa": [
"TtoXrhXQKK",
"qOb8PS",
"m59P6g",
"mvGqkR",
"RB-9fj",
"2hYJqg",
"otbxLc",
"9GWi-3"
],
"fbEQ-2": [],
"k7Pozf": [],
"osttqJ": [],
"x2Nypz": [],
"xVai4jK835": []
},
"text_map": {
"-qBAb5hSHZ": "[{\"insert\":\"Syncing the document content between server and the local.\"}]",
"0qTSZK": "[]",
"1aO3pe": "[]",
"5PVbjJ": "[{\"insert\":\"It contains lots of formats.\"}]",
"6Up-3y": "[]",
"GkpKE6": "[{\"insert\":\"number list format\"}]",
"Mhpd_J": "[{\"insert\":\"Header one format\"}]",
"OvsPP4": "[]",
"Ozaw6E": "[]",
"Q2lcja": "[]",
"YrAL0L": "[{\"insert\":\"Header two format\"}]",
"cQHJvj": "[]",
"eiHaS2": "[]",
"hHGl05": "[{\"insert\":\"quote format\"}]",
"ht7dE4": "[{\"insert\":\"bullet list format\"}]",
"iWrg77": "[{\"insert\":\"checkbox format\"}]",
"xSTRAY": "[]"
}
},
"page_id": "beEtQt9xw6"
})).unwrap()
}

View file

@ -1,114 +0,0 @@
use event_integration_test::user_event::use_localhost_af_cloud;
use event_integration_test::EventIntegrationTest;
use flowy_core::DEFAULT_NAME;
use flowy_user::entities::AuthTypePB;
use crate::util::unzip;
#[tokio::test]
async fn reading_039_anon_user_data_test() {
let user_db_path = unzip("./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_view(&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_view(&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());
let trash_items = test.get_trash().await.items;
assert_eq!(trash_items.len(), 1);
}
#[tokio::test]
async fn migrate_anon_user_data_to_af_cloud_test() {
let user_db_path = unzip("./tests/asset", "040_local").unwrap();
// In the 040_local, the structure is:
// workspace:
// view: Document1
// view: Document2
// view: Grid1
// view: Grid2
use_localhost_af_cloud().await;
let test =
EventIntegrationTest::new_with_user_data_path(user_db_path.clone(), DEFAULT_NAME.to_string())
.await;
let anon_trash = test.get_trash().await;
assert_eq!(anon_trash.items.len(), 1);
assert_eq!(
anon_trash.items[0].name,
"Local Getting started".to_string()
);
let anon_first_level_views = test.get_all_workspace_views().await;
let anon_second_level_views = test
.get_view(&anon_first_level_views[0].id)
.await
.child_views;
let anon_third_level_views = test
.get_view(&anon_second_level_views[0].id)
.await
.child_views;
// The anon user data will be migrated to the AppFlowy cloud after sign up
let user = test.af_cloud_sign_up().await;
let workspace = test.get_current_workspace().await;
println!("user workspace: {:?}", workspace.id);
assert_eq!(user.user_auth_type, AuthTypePB::Server);
let user_first_level_views = test.get_all_workspace_views().await;
assert_eq!(user_first_level_views.len(), 3);
println!("user first level views: {:?}", user_first_level_views);
let user_second_level_views = test
.get_view(&user_first_level_views[2].id)
.await
.child_views;
println!("user second level views: {:?}", user_second_level_views);
let user_third_level_views = test
.get_view(&user_second_level_views[0].id)
.await
.child_views;
println!("user third level views: {:?}", user_third_level_views);
// check first level
assert_eq!(anon_first_level_views.len(), 1);
// the first view of user_first_level_views is the default get started view
assert_eq!(user_first_level_views.len(), 3);
assert_ne!(anon_first_level_views[0].id, user_first_level_views[1].id);
assert_eq!(
anon_first_level_views[0].name,
user_first_level_views[2].name
);
// check second level
assert_ne!(anon_second_level_views[0].id, user_second_level_views[0].id);
assert_eq!(
anon_second_level_views[0].name,
user_second_level_views[0].name
);
// check third level
assert_eq!(anon_third_level_views.len(), 2);
assert_eq!(user_third_level_views[0].name, "Grid1".to_string());
assert_eq!(user_third_level_views[1].name, "Grid2".to_string());
}

View file

@ -1,4 +1,3 @@
mod anon_user_test;
mod auth_test;
mod import_af_data_folder_test;
mod member_test;

View file

@ -57,7 +57,6 @@ pub(crate) struct ImportedFolder {
#[derive(Clone)]
pub(crate) enum ImportedSource {
ExternalFolder,
AnonUser,
}
impl ImportedFolder {
@ -189,7 +188,6 @@ pub(crate) fn generate_import_data(
None => workspace_id.to_string(),
Some(_) => gen_view_id().to_string(),
},
ImportedSource::AnonUser => workspace_id.to_string(),
};
let (views, orphan_views) = user_collab_db.with_write_txn(|current_collab_db_write_txn| {
@ -359,7 +357,6 @@ pub(crate) fn generate_import_data(
Ok((child_views, orphan_views))
},
},
ImportedSource::AnonUser => Ok((child_views, orphan_views)),
}?;
if !invalid_orphan_views.is_empty() {
@ -400,7 +397,6 @@ pub(crate) fn generate_import_data(
let source = match imported_folder.source {
ImportedSource::ExternalFolder => ImportFrom::AppFlowyDataFolder,
ImportedSource::AnonUser => ImportFrom::AnonUser,
};
Ok(ImportedAppFlowyData {

View file

@ -32,7 +32,6 @@ use crate::migrations::migration::{
};
use crate::migrations::workspace_and_favorite_v1::FavoriteV1AndWorkspaceArrayMigration;
use crate::migrations::workspace_trash_v1::WorkspaceTrashMapToSectionMigration;
use crate::migrations::AnonUser;
use crate::services::authenticate_user::AuthenticateUser;
use crate::services::cloud_config::get_cloud_config;
use crate::services::collab_interact::{DefaultCollabInteract, UserReminder};
@ -408,13 +407,11 @@ impl UserManager {
let cloud_service = self.cloud_service()?;
cloud_service.set_server_auth_type(&auth_type, None)?;
// sign out the current user if there is one
let migration_user = self.get_migration_user(&auth_type).await;
let auth_service = cloud_service.get_user_service()?;
let response: AuthResponse = auth_service.sign_up(params).await?;
let new_user_profile = UserProfile::from((&response, &auth_type));
self
.continue_sign_up(&new_user_profile, migration_user, response, &auth_type)
.continue_sign_up(&new_user_profile, response, &auth_type)
.await?;
Ok(new_user_profile)
}
@ -423,7 +420,6 @@ impl UserManager {
async fn continue_sign_up(
&self,
new_user_profile: &UserProfile,
migration_user: Option<AnonUser>,
response: AuthResponse,
auth_type: &AuthType,
) -> FlowyResult<()> {
@ -466,23 +462,6 @@ impl UserManager {
} else {
error!("Failed to get pool for user {}", new_session.user_id);
}
if let Some(old_user) = migration_user {
event!(
tracing::Level::INFO,
"Migrate anon user data from {:?} to {:?}",
old_user.session.user_id,
new_user_profile.uid
);
self
.migrate_anon_user_data_to_cloud(&old_user, &new_session, auth_type)
.await?;
self.remove_anon_user();
let _ = self
.authenticate_user
.database
.close(old_user.session.user_id);
}
}
send_auth_state_notification(AuthStateChangedPB {
@ -808,28 +787,6 @@ impl UserManager {
Ok(())
}
async fn migrate_anon_user_data_to_cloud(
&self,
old_user: &AnonUser,
_new_user_session: &Session,
auth_type: &AuthType,
) -> Result<(), FlowyError> {
let old_collab_db = self
.authenticate_user
.database
.get_collab_db(old_user.session.user_id)?
.upgrade()
.ok_or_else(FlowyError::ref_drop)?;
if auth_type == &AuthType::AppFlowyCloud {
self
.migration_anon_user_on_appflowy_cloud_sign_up(old_user, &old_collab_db)
.await?;
}
Ok(())
}
}
pub fn upsert_user_profile_change(

View file

@ -9,15 +9,13 @@ use crate::entities::{
RepeatedUserWorkspacePB, SubscribeWorkspacePB, SuccessWorkspaceSubscriptionPB,
UpdateUserWorkspaceSettingPB, UserWorkspacePB, WorkspaceSettingsPB, WorkspaceSubscriptionInfoPB,
};
use crate::migrations::AnonUser;
use crate::notification::{send_notification, UserNotification};
use crate::services::billing_check::PeriodicallyCheckBillingState;
use crate::services::data_import::{
generate_import_data, upload_collab_objects_data, ImportedFolder, ImportedSource,
generate_import_data, upload_collab_objects_data, ImportedFolder,
};
use crate::user_manager::UserManager;
use collab_integrate::CollabKVDB;
use flowy_error::{ErrorCode, FlowyError, FlowyResult};
use flowy_folder_pub::entities::{ImportFrom, ImportedCollabData, ImportedFolderData};
use flowy_sqlite::ConnectionPool;
@ -138,23 +136,6 @@ impl UserManager {
Ok(())
}
pub async fn migration_anon_user_on_appflowy_cloud_sign_up(
&self,
old_user: &AnonUser,
old_collab_db: &Arc<CollabKVDB>,
) -> FlowyResult<()> {
let import_context = ImportedFolder {
imported_session: old_user.session.as_ref().clone(),
imported_collab_db: old_collab_db.clone(),
container_name: None,
parent_view_id: None,
source: ImportedSource::AnonUser,
workspace_database_id: "".to_string(),
};
self.perform_import(import_context).await?;
Ok(())
}
#[instrument(skip(self), err)]
pub async fn open_workspace(
&self,