Skip to content

Commit eac878d

Browse files
authored
fix: import document from database row (#4295)
* fix: import document from database row * chore: update test * chore: fix test * chore: fix test * chore: fix test * chore: fix local user on appflowy cloud error * chore: clippy * chore: bump pubspec version
1 parent de08c01 commit eac878d

File tree

19 files changed

+228
-186
lines changed

19 files changed

+228
-186
lines changed

frontend/.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"program": "./lib/main.dart",
1313
"type": "dart",
1414
"env": {
15-
"RUST_LOG": "debug",
15+
"RUST_LOG": "trace",
1616
"RUST_BACKTRACE": "1"
1717
},
1818
// uncomment the following line to testing performance.

frontend/appflowy_flutter/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
1515
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
1616
# Read more about iOS versioning at
1717
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
18-
version: 0.4.0
18+
version: 0.4.1
1919

2020
environment:
2121
flutter: ">=3.18.0-0.2.pre"

frontend/rust-lib/event-integration/src/lib.rs

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,8 @@ impl EventIntegrationTest {
5353
let path = path_buf.to_str().unwrap().to_string();
5454
let device_id = uuid::Uuid::new_v4().to_string();
5555

56-
let level = "trace";
57-
std::env::set_var("RUST_LOG", level);
5856
let config = AppFlowyCoreConfig::new(path.clone(), path, device_id, name).log_filter(
59-
level,
57+
"trace",
6058
vec![
6159
"flowy_test".to_string(),
6260
"tokio".to_string(),
@@ -79,27 +77,16 @@ impl EventIntegrationTest {
7977
}
8078
}
8179

82-
pub fn get_appflowy_cloud_server(&self) -> Arc<dyn AppFlowyServer> {
83-
self
84-
.appflowy_core
85-
.server_provider
86-
.get_appflowy_cloud_server()
87-
.unwrap()
80+
pub fn get_server(&self) -> Arc<dyn AppFlowyServer> {
81+
self.appflowy_core.server_provider.get_server().unwrap()
8882
}
8983

9084
pub async fn wait_ws_connected(&self) {
91-
if self
92-
.get_appflowy_cloud_server()
93-
.get_ws_state()
94-
.is_connected()
95-
{
85+
if self.get_server().get_ws_state().is_connected() {
9686
return;
9787
}
9888

99-
let mut ws_state = self
100-
.get_appflowy_cloud_server()
101-
.subscribe_ws_state()
102-
.unwrap();
89+
let mut ws_state = self.get_server().subscribe_ws_state().unwrap();
10390
loop {
10491
select! {
10592
_ = sleep(Duration::from_secs(20)) => {
@@ -121,7 +108,7 @@ impl EventIntegrationTest {
121108
oid: &str,
122109
collay_type: CollabType,
123110
) -> Result<CollabDocState, FlowyError> {
124-
let server = self.server_provider.get_appflowy_cloud_server().unwrap();
111+
let server = self.server_provider.get_server().unwrap();
125112
let workspace_id = self.get_current_workspace().await.id;
126113
let uid = self.get_user_profile().await?.id;
127114
let doc_state = server
82.9 KB
Binary file not shown.

frontend/rust-lib/event-integration/tests/user/af_cloud_test/import_af_data_folder_test.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::util::unzip_history_user_db;
22
use assert_json_diff::assert_json_include;
3+
use collab_database::rows::database_row_document_id_from_row_id;
34
use collab_entity::CollabType;
45
use event_integration::user_event::user_localhost_af_cloud;
56
use event_integration::{document_data_from_document_doc_state, EventIntegrationTest};
@@ -45,6 +46,9 @@ async fn import_appflowy_data_folder_into_new_view_test() {
4546
assert_eq!(views.len(), 2);
4647
assert_eq!(views[1].name, import_container_name);
4748

49+
// the 040_local should be an empty document, so try to get the document data
50+
let _ = test.get_document_data(&views[1].id).await;
51+
4852
let local_child_views = test.get_view(&views[1].id).await.child_views;
4953
assert_eq!(local_child_views.len(), 1);
5054
assert_eq!(local_child_views[0].name, "Document1");
@@ -61,6 +65,14 @@ async fn import_appflowy_data_folder_into_new_view_test() {
6165
assert_eq!(document2_child_views[0].name, "Grid1");
6266
assert_eq!(document2_child_views[1].name, "Grid2");
6367

68+
let rows = test.get_database(&document2_child_views[1].id).await.rows;
69+
assert_eq!(rows.len(), 3);
70+
71+
// In the 040_local, only the first row has a document with content
72+
let row_document_id = database_row_document_id_from_row_id(&rows[0].id);
73+
let row_document_data = test.get_document_data(&row_document_id).await;
74+
assert_json_include!(actual: json!(row_document_data), expected: expected_row_doc_json());
75+
6476
drop(cleaner);
6577
}
6678

@@ -370,3 +382,46 @@ fn expected_doc_2_json() -> Value {
370382
"page_id": "ZVogdaK9yO"
371383
})
372384
}
385+
386+
fn expected_row_doc_json() -> Value {
387+
json!( {
388+
"blocks": {
389+
"eSBQHZ28e0": {
390+
"children": "RbLAaE9UDJ",
391+
"data": {},
392+
"external_id": null,
393+
"external_type": null,
394+
"id": "eSBQHZ28e0",
395+
"parent": "",
396+
"ty": "page"
397+
},
398+
"eUIL6qjgj3": {
399+
"children": "fUnGRcvPEA",
400+
"data": {
401+
"delta": [
402+
{
403+
"insert": "document in database row"
404+
}
405+
]
406+
},
407+
"external_id": "-DliEUjHr2",
408+
"external_type": "text",
409+
"id": "eUIL6qjgj3",
410+
"parent": "eSBQHZ28e0",
411+
"ty": "paragraph"
412+
}
413+
},
414+
"meta": {
415+
"children_map": {
416+
"RbLAaE9UDJ": [
417+
"eUIL6qjgj3"
418+
],
419+
"fUnGRcvPEA": []
420+
},
421+
"text_map": {
422+
"-DliEUjHr2": "[{\"insert\":\"document in database row\"}]"
423+
}
424+
},
425+
"page_id": "eSBQHZ28e0"
426+
})
427+
}

frontend/rust-lib/event-integration/tests/user/migration_test/version_test.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use event_integration::EventIntegrationTest;
22
use flowy_core::DEFAULT_NAME;
33
use flowy_folder::entities::ViewLayoutPB;
4+
use std::time::Duration;
45

56
use crate::util::unzip_history_user_db;
67

@@ -140,10 +141,7 @@ async fn collab_db_backup_test() {
140141
assert_eq!(backups.len(), 1);
141142
assert_eq!(
142143
backups[0],
143-
format!(
144-
"collab_db_{}",
145-
chrono::Local::now().format("%Y%m%d").to_string()
146-
)
144+
format!("collab_db_{}", chrono::Local::now().format("%Y%m%d"))
147145
);
148146
drop(cleaner);
149147
}
@@ -157,7 +155,15 @@ async fn delete_outdated_collab_db_backup_test() {
157155
EventIntegrationTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string()).await;
158156

159157
let uid = test.get_user_profile().await.unwrap().id;
158+
// saving the backup is a background task, so we need to wait for it to finish
159+
// 2 seconds should be enough for the background task to finish
160+
tokio::time::sleep(Duration::from_secs(2)).await;
160161
let backups = test.user_manager.get_collab_backup_list(uid);
162+
163+
if backups.len() != 10 {
164+
dbg!("backups: {:?}", backups.clone());
165+
}
166+
161167
assert_eq!(backups.len(), 10);
162168
assert_eq!(backups[0], "collab_db_0.4.0_20231202");
163169
assert_eq!(backups[1], "collab_db_0.4.0_20231203");
@@ -170,10 +176,7 @@ async fn delete_outdated_collab_db_backup_test() {
170176
assert_eq!(backups[8], "collab_db_0.4.0_20231210");
171177
assert_eq!(
172178
backups[9],
173-
format!(
174-
"collab_db_{}",
175-
chrono::Local::now().format("%Y%m%d").to_string()
176-
)
179+
format!("collab_db_{}", chrono::Local::now().format("%Y%m%d"))
177180
);
178181
drop(cleaner);
179182
}

frontend/rust-lib/event-integration/tests/util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use flowy_user::entities::{AuthenticatorPB, UpdateUserProfilePayloadPB};
2727
use flowy_user::errors::FlowyError;
2828

2929
use flowy_user::event_map::UserEvent::*;
30-
use flowy_user_deps::cloud::{UserCloudService, UserCloudServiceProvider};
30+
use flowy_user_deps::cloud::UserCloudService;
3131
use flowy_user_deps::entities::Authenticator;
3232

3333
pub fn get_supabase_config() -> Option<SupabaseConfiguration> {

frontend/rust-lib/flowy-core/src/integrate/log.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ pub(crate) fn create_log_filter(level: String, with_crates: Vec<String>) -> Stri
1919
.map(|crate_name| format!("{}={}", crate_name, level))
2020
.collect::<Vec<String>>();
2121
filters.push(format!("flowy_core={}", level));
22-
filters.push(format!("flowy_folder2={}", level));
22+
filters.push(format!("flowy_folder={}", level));
2323
filters.push(format!("collab_sync={}", level));
2424
filters.push(format!("collab_folder={}", level));
2525
filters.push(format!("collab_persistence={}", level));
@@ -28,7 +28,7 @@ pub(crate) fn create_log_filter(level: String, with_crates: Vec<String>) -> Stri
2828
filters.push(format!("collab_integrate={}", level));
2929
filters.push(format!("collab={}", level));
3030
filters.push(format!("flowy_user={}", level));
31-
filters.push(format!("flowy_document2={}", level));
31+
filters.push(format!("flowy_document={}", level));
3232
filters.push(format!("flowy_database2={}", level));
3333
filters.push(format!("flowy_server={}", level));
3434
filters.push(format!("flowy_notification={}", "info"));

frontend/rust-lib/flowy-core/src/integrate/server.rs

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ pub enum Server {
3333
Supabase = 2,
3434
}
3535

36+
impl Server {
37+
pub fn is_local(&self) -> bool {
38+
matches!(self, Server::Local)
39+
}
40+
}
41+
3642
impl Display for Server {
3743
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
3844
match self {
@@ -49,15 +55,14 @@ impl Display for Server {
4955
/// Each server implements the [AppFlowyServer] trait, which provides the [UserCloudService], etc.
5056
pub struct ServerProvider {
5157
config: AppFlowyCoreConfig,
52-
server: RwLock<Server>,
5358
providers: RwLock<HashMap<Server, Arc<dyn AppFlowyServer>>>,
5459
pub(crate) encryption: RwLock<Arc<dyn AppFlowyEncryption>>,
5560
#[allow(dead_code)]
5661
pub(crate) store_preferences: Weak<StorePreferences>,
5762
pub(crate) user_enable_sync: RwLock<bool>,
5863

5964
/// The authenticator type of the user.
60-
pub(crate) user_authenticator: RwLock<Authenticator>,
65+
authenticator: RwLock<Authenticator>,
6166
pub(crate) uid: Arc<RwLock<Option<i64>>>,
6267
}
6368

@@ -70,41 +75,42 @@ impl ServerProvider {
7075
let encryption = EncryptionImpl::new(None);
7176
Self {
7277
config,
73-
server: RwLock::new(server),
7478
providers: RwLock::new(HashMap::new()),
7579
user_enable_sync: RwLock::new(true),
76-
user_authenticator: RwLock::new(Authenticator::Local),
80+
authenticator: RwLock::new(Authenticator::from(server)),
7781
encryption: RwLock::new(Arc::new(encryption)),
7882
store_preferences,
7983
uid: Default::default(),
8084
}
8185
}
8286

8387
pub fn get_server_type(&self) -> Server {
84-
self.server.read().clone()
88+
match &*self.authenticator.read() {
89+
Authenticator::Local => Server::Local,
90+
Authenticator::AppFlowyCloud => Server::AppFlowyCloud,
91+
Authenticator::Supabase => Server::Supabase,
92+
}
8593
}
8694

87-
pub fn set_server_type(&self, server_type: Server) {
88-
let old_server_type = self.server.read().clone();
89-
if server_type != old_server_type {
95+
pub fn set_authenticator(&self, authenticator: Authenticator) {
96+
let old_server_type = self.get_server_type();
97+
*self.authenticator.write() = authenticator;
98+
let new_server_type = self.get_server_type();
99+
100+
if old_server_type != new_server_type {
90101
self.providers.write().remove(&old_server_type);
91102
}
92-
93-
*self.server.write() = server_type;
94-
}
95-
96-
pub fn get_user_authenticator(&self) -> Authenticator {
97-
self.user_authenticator.read().clone()
98103
}
99104

100-
pub fn get_appflowy_cloud_server(&self) -> FlowyResult<Arc<dyn AppFlowyServer>> {
101-
let server = self.get_server(&Server::AppFlowyCloud)?;
102-
Ok(server)
105+
pub fn get_authenticator(&self) -> Authenticator {
106+
self.authenticator.read().clone()
103107
}
104108

105109
/// Returns a [AppFlowyServer] trait implementation base on the provider_type.
106-
pub fn get_server(&self, server_type: &Server) -> FlowyResult<Arc<dyn AppFlowyServer>> {
107-
if let Some(provider) = self.providers.read().get(server_type) {
110+
pub fn get_server(&self) -> FlowyResult<Arc<dyn AppFlowyServer>> {
111+
let server_type = self.get_server_type();
112+
113+
if let Some(provider) = self.providers.read().get(&server_type) {
108114
return Ok(provider.clone());
109115
}
110116

0 commit comments

Comments
 (0)