fix: view id

This commit is contained in:
Zack Fu Zi Xiang 2024-09-17 14:58:36 +08:00
parent 09892c9897
commit 62980a780e
No known key found for this signature in database
5 changed files with 415 additions and 180 deletions

1
Cargo.lock generated
View File

@ -2027,6 +2027,7 @@ dependencies = [
"dotenvy",
"futures",
"gotrue",
"hex",
"image",
"lazy_static",
"mime",

View File

@ -37,6 +37,7 @@ client-websocket.workspace = true
futures = "0.3.30"
anyhow = "1.0.80"
serde = { version = "1.0.199", features = ["derive"] }
hex = "0.4.3"
[target.'cfg(target_arch = "wasm32")'.dependencies]
web-sys = { version = "0.3", features = ["console"] }

View File

@ -20,6 +20,7 @@ use collab_user::core::UserAwareness;
use mime::Mime;
use serde::Deserialize;
use serde_json::{json, Value};
use shared_entity::dto::publish_dto::PublishViewMetaData;
use tokio::time::{sleep, timeout, Duration};
use tokio_stream::StreamExt;
use tracing::trace;
@ -28,7 +29,7 @@ use uuid::Uuid;
#[cfg(feature = "collab-sync")]
use client_api::collab_sync::{SinkConfig, SyncObject, SyncPlugin};
use client_api::entity::id::user_awareness_object_id;
use client_api::entity::QueryWorkspaceMember;
use client_api::entity::{PublishCollabItem, PublishCollabMetadata, QueryWorkspaceMember};
use client_api::ws::{WSClient, WSClientConfig};
use database_entity::dto::{
AFAccessLevel, AFRole, AFSnapshotMeta, AFSnapshotMetas, AFUserProfile, AFUserWorkspaceInfo,
@ -830,6 +831,31 @@ impl TestClient {
let collab = (*lock).borrow();
collab.to_json_value()
}
/// data: [(view_id, meta_json, blob_hex)]
pub async fn publish_collabs(&self, workspace_id: &str, data: Vec<(Uuid, &str, &str)>) {
let pub_items = data
.into_iter()
.map(|(view_id, meta_json, blob_hex)| {
let meta: PublishViewMetaData = serde_json::from_str(meta_json).unwrap();
let blob = hex::decode(blob_hex).unwrap();
PublishCollabItem {
meta: PublishCollabMetadata {
view_id,
publish_name: uuid::Uuid::new_v4().to_string(),
metadata: meta,
},
data: blob,
}
})
.collect();
self
.api_client
.publish_collabs(&workspace_id, pub_items)
.await
.unwrap();
}
}
pub async fn assert_server_snapshot(

View File

@ -682,57 +682,34 @@ async fn duplicate_to_workspace_references() {
let client_1 = TestClient::new_user().await;
let workspace_id = client_1.workspace_id().await;
// doc2 contains a reference to doc1
let doc_2_view_id = uuid::Uuid::new_v4();
let doc_2_metadata: PublishViewMetaData =
serde_json::from_str(published_data::DOC_2_META).unwrap();
let doc_2_doc_state = hex::decode(published_data::DOC_2_DOC_STATE_HEX).unwrap();
// doc_1_view_id needs to be fixed because doc_2 references it
let doc_1_view_id: uuid::Uuid = "e8c4f99a-50ea-4758-bca0-afa7df5c2434".parse().unwrap();
let doc_1_metadata: PublishViewMetaData =
serde_json::from_str(published_data::DOC_1_META).unwrap();
let doc_1_doc_state = hex::decode(published_data::DOC_1_DOC_STATE_HEX).unwrap();
// doc1 contains @reference database to grid1 (not inline)
let grid_1_view_id: uuid::Uuid = "8e062f61-d7ae-4f4b-869c-f44c43149399".parse().unwrap();
let grid_1_metadata: PublishViewMetaData =
serde_json::from_str(published_data::GRID_1_META).unwrap();
let grid_1_db_data = hex::decode(published_data::GRID_1_DB_DATA).unwrap();
client_1
.api_client
.publish_collabs(
&workspace_id,
vec![
PublishCollabItem {
meta: PublishCollabMetadata {
view_id: doc_1_view_id,
publish_name: doc_1_metadata.view.name.clone(),
metadata: doc_1_metadata.clone(),
},
data: doc_1_doc_state,
},
PublishCollabItem {
meta: PublishCollabMetadata {
view_id: doc_2_view_id,
publish_name: doc_2_metadata.view.name.clone(),
metadata: doc_2_metadata.clone(),
},
data: doc_2_doc_state,
},
PublishCollabItem {
meta: PublishCollabMetadata {
view_id: grid_1_view_id,
publish_name: grid_1_metadata.view.name.clone(),
metadata: grid_1_metadata.clone(),
},
data: grid_1_db_data,
},
(
// doc2 contains a reference to doc1
doc_2_view_id,
published_data::DOC_2_META,
published_data::DOC_2_DOC_STATE_HEX,
),
(
// doc_1_view_id needs to be fixed because doc_2 references it
doc_1_view_id,
published_data::DOC_1_META,
published_data::DOC_1_DOC_STATE_HEX,
),
(
// doc1 contains @reference database to grid1 (not inline)
grid_1_view_id,
published_data::GRID_1_META,
published_data::GRID_1_DB_DATA,
),
],
)
.await
.unwrap();
.await;
{
let client_2 = TestClient::new_user().await;
@ -768,24 +745,20 @@ async fn duplicate_to_workspace_references() {
.await
.unwrap();
let doc_2_fv = fv
.children
.into_iter()
.find(|v| v.name == doc_2_metadata.view.name)
.unwrap();
let doc_2_fv = fv.children.into_iter().find(|v| v.name == "doc2").unwrap();
assert_ne!(doc_2_fv.view_id, doc_1_view_id.to_string());
let doc_1_fv = doc_2_fv
.children
.into_iter()
.find(|v| v.name == doc_1_metadata.view.name)
.find(|v| v.name == "doc1")
.unwrap();
assert_ne!(doc_1_fv.view_id, doc_1_view_id.to_string());
let grid_1_fv = doc_1_fv
.children
.into_iter()
.find(|v| v.name == grid_1_metadata.view.name)
.find(|v| v.name == "grid1")
.unwrap();
assert_ne!(grid_1_fv.view_id, grid_1_view_id.to_string());
}
@ -798,42 +771,29 @@ async fn duplicate_to_workspace_doc_inline_database() {
// doc3 contains inline database to a view in grid1 (view of grid1)
let doc_3_view_id = uuid::Uuid::new_v4();
let doc_3_metadata: PublishViewMetaData =
serde_json::from_str(published_data::DOC_3_META).unwrap();
let doc_3_doc_state = hex::decode(published_data::DOC_3_DOC_STATE_HEX).unwrap();
// view of grid1
let view_of_grid_1_view_id: uuid::Uuid = "d8589e98-88fc-42e4-888c-b03338bf22bb".parse().unwrap();
let view_of_grid_1_metadata: PublishViewMetaData =
serde_json::from_str(published_data::VIEW_OF_GRID1_META).unwrap();
let view_of_grid_1_db_data = hex::decode(published_data::VIEW_OF_GRID_1_DB_DATA).unwrap();
let (pub_db_id, pub_row_ids) = get_database_id_and_row_ids(&view_of_grid_1_db_data);
client_1
.api_client
.publish_collabs(
&workspace_id,
vec![
PublishCollabItem {
meta: PublishCollabMetadata {
view_id: doc_3_view_id,
publish_name: doc_3_metadata.view.name.clone(),
metadata: doc_3_metadata.clone(),
},
data: doc_3_doc_state,
},
PublishCollabItem {
meta: PublishCollabMetadata {
view_id: view_of_grid_1_view_id,
publish_name: view_of_grid_1_metadata.view.name.replace(' ', "-"),
metadata: view_of_grid_1_metadata.clone(),
},
data: view_of_grid_1_db_data,
},
(
doc_3_view_id,
published_data::DOC_3_META,
published_data::DOC_3_DOC_STATE_HEX,
),
(
view_of_grid_1_view_id,
published_data::VIEW_OF_GRID_1_META,
published_data::VIEW_OF_GRID_1_DB_DATA,
),
],
)
.await
.unwrap();
.await;
{
let mut client_2 = TestClient::new_user().await;
@ -875,11 +835,7 @@ async fn duplicate_to_workspace_doc_inline_database() {
.get_workspace_folder(&workspace_id_2, Some(5), None)
.await
.unwrap();
let doc_3_fv = fv
.children
.into_iter()
.find(|v| v.name == doc_3_metadata.view.name)
.unwrap();
let doc_3_fv = fv.children.into_iter().find(|v| v.name == "doc3").unwrap();
let grid1_fv = doc_3_fv
.children
.into_iter()
@ -915,7 +871,7 @@ async fn duplicate_to_workspace_doc_inline_database() {
let doc_3_fv = folder_view
.children
.into_iter()
.find(|v| v.name == doc_3_metadata.view.name)
.find(|v| v.name == "doc3")
.unwrap();
assert_ne!(doc_3_fv.view_id, doc_3_view_id.to_string());
@ -982,42 +938,26 @@ async fn duplicate_to_workspace_db_embedded_in_doc() {
// embedded doc with db
// database is created in the doc, not linked from a separate view
let doc_with_embedded_db_view_id: uuid::Uuid = uuid::Uuid::new_v4();
let doc_with_embedded_db_metadata: PublishViewMetaData =
serde_json::from_str(published_data::DOC_WITH_EMBEDDED_DB_META).unwrap();
let doc_with_embedded_db_blob = hex::decode(published_data::DOC_WITH_EMBEDDED_DB_HEX).unwrap();
// user will also need to publish the database (even though it is embedded)
// uuid must be fixed because it is referenced in the doc
let embedded_db_view_id: uuid::Uuid = "bb221175-14da-4a05-a09d-595e42d2350f".parse().unwrap();
let embedded_db_metadata: PublishViewMetaData =
serde_json::from_str(published_data::EMBEDDED_DB_META).unwrap();
let embedded_db_blob = hex::decode(published_data::EMBEDDED_DB_HEX).unwrap();
client_1
.api_client
.publish_collabs(
&workspace_id,
vec![
PublishCollabItem {
meta: PublishCollabMetadata {
view_id: doc_with_embedded_db_view_id,
publish_name: "doc-with-embedded-db".to_string(),
metadata: doc_with_embedded_db_metadata.clone(),
},
data: doc_with_embedded_db_blob,
},
PublishCollabItem {
meta: PublishCollabMetadata {
view_id: embedded_db_view_id,
publish_name: "embedded-db".to_string(),
metadata: embedded_db_metadata.clone(),
},
data: embedded_db_blob,
},
(
doc_with_embedded_db_view_id,
published_data::DOC_WITH_EMBEDDED_DB_META,
published_data::DOC_WITH_EMBEDDED_DB_HEX,
),
(
// user will also need to publish the database (even though it is embedded)
// uuid must be fixed because it is referenced in the doc
"bb221175-14da-4a05-a09d-595e42d2350f".parse().unwrap(),
published_data::EMBEDDED_DB_META,
published_data::EMBEDDED_DB_HEX,
),
],
)
.await
.unwrap();
.await;
{
let mut client_2 = TestClient::new_user().await;
@ -1093,42 +1033,38 @@ async fn duplicate_to_workspace_db_with_relation() {
// database with relation column to another database
let db_with_rel_col_view_id: uuid::Uuid = uuid::Uuid::new_v4();
let db_with_rel_col_metadata: PublishViewMetaData =
serde_json::from_str(published_data::DB_WITH_REL_COL_META).unwrap();
let db_with_rel_col_blob = hex::decode(published_data::DB_WITH_REL_COL_HEX).unwrap();
// related database
// uuid must be fixed because it is related to the db_with_rel_col
let related_db_view_id: uuid::Uuid = "5fc669fa-8867-4f6d-98f1-ce387597eabd".parse().unwrap();
let related_db_metadata: PublishViewMetaData =
serde_json::from_str(published_data::RELATED_DB_META).unwrap();
let related_db_blob = hex::decode(published_data::RELATED_DB_HEX).unwrap();
client_1
.api_client
.publish_collabs(
&workspace_id,
vec![
PublishCollabItem {
meta: PublishCollabMetadata {
view_id: db_with_rel_col_view_id,
publish_name: "db-with-rel-col".to_string(),
metadata: db_with_rel_col_metadata.clone(),
},
data: db_with_rel_col_blob,
},
PublishCollabItem {
meta: PublishCollabMetadata {
view_id: related_db_view_id,
publish_name: "related-db".to_string(),
metadata: related_db_metadata.clone(),
},
data: related_db_blob,
},
(
db_with_rel_col_view_id,
published_data::DB_WITH_REL_COL_META,
published_data::DB_WITH_REL_COL_HEX,
),
(
// related database
// uuid must be fixed because it is related to the db_with_rel_col
"5fc669fa-8867-4f6d-98f1-ce387597eabd".parse().unwrap(),
published_data::RELATED_DB_META,
published_data::RELATED_DB_HEX,
),
],
)
.await
.unwrap();
.await;
let db_with_row_doc_view_id: uuid::Uuid = uuid::Uuid::new_v4();
client_1
.publish_collabs(
&workspace_id,
vec![(
db_with_row_doc_view_id,
published_data::DB_ROW_WITH_DOC_META,
published_data::DB_ROW_WITH_DOC_HEX,
)],
)
.await;
{
let mut client_2 = TestClient::new_user().await;
@ -1210,27 +1146,17 @@ async fn duplicate_to_workspace_db_row_with_doc() {
let client_1 = TestClient::new_user().await;
let workspace_id = client_1.workspace_id().await;
// database with a row having doc data
let db_with_row_doc_view_id: uuid::Uuid = uuid::Uuid::new_v4();
let db_with_row_doc_metadata: PublishViewMetaData =
serde_json::from_str(published_data::DB_ROW_WITH_DOC_META).unwrap();
let db_with_row_doc_blob = hex::decode(published_data::DB_ROW_WITH_DOC_HEX).unwrap();
client_1
.api_client
.publish_collabs(
&workspace_id,
vec![PublishCollabItem {
meta: PublishCollabMetadata {
view_id: db_with_row_doc_view_id,
publish_name: "db-with-rel-col".to_string(),
metadata: db_with_row_doc_metadata.clone(),
},
data: db_with_row_doc_blob,
}],
vec![(
db_with_row_doc_view_id,
published_data::DB_ROW_WITH_DOC_META,
published_data::DB_ROW_WITH_DOC_HEX,
)],
)
.await
.unwrap();
.await;
{
let mut client_2 = TestClient::new_user().await;
@ -1309,28 +1235,17 @@ async fn duplicate_to_workspace_db_rel_self() {
let client_1 = TestClient::new_user().await;
let workspace_id = client_1.workspace_id().await;
// database with a row referencing itself
// uuid must be fixed because the collab contains row data which reference itself
let db_rel_self_view_id: uuid::Uuid = "18d72589-80d7-4041-9342-5d572facb7c9".parse().unwrap();
let db_rel_self_metadata: PublishViewMetaData =
serde_json::from_str(published_data::DB_REL_SELF_META).unwrap();
let db_rel_self_blob = hex::decode(published_data::DB_REL_SELF_HEX).unwrap();
client_1
.api_client
.publish_collabs(
&workspace_id,
vec![PublishCollabItem {
meta: PublishCollabMetadata {
view_id: db_rel_self_view_id,
publish_name: "db-rel-self".to_string(),
metadata: db_rel_self_metadata.clone(),
},
data: db_rel_self_blob,
}],
vec![(
db_rel_self_view_id,
published_data::DB_REL_SELF_META,
published_data::DB_REL_SELF_HEX,
)],
)
.await
.unwrap();
.await;
{
let mut client_2 = TestClient::new_user().await;
@ -1386,6 +1301,85 @@ async fn duplicate_to_workspace_db_rel_self() {
}
}
#[tokio::test]
async fn duplicate_to_workspace_inline_db_doc_with_relation() {
// scenario:
// client_1 publish doc4
// doc4 has inline database grid3
// grid3 has relation to grid2
// grid2 has relation to grid3
// .
// ├── grid2
// └┬─ doc4
// └── grid3
let client_1 = TestClient::new_user().await;
let workspace_id = client_1.workspace_id().await;
// database with a row referencing itself
// uuid must be fixed because the collab contains row data which reference itself
let doc_4_view_id: uuid::Uuid = uuid::Uuid::new_v4();
client_1
.publish_collabs(
&workspace_id,
vec![
(
doc_4_view_id,
published_data::DOC_4_META,
published_data::DOC_4_DOC_STATE_HEX,
),
(
"5ecf6aa1-d4d6-47e4-af0f-3a7a9fd8299d".parse().unwrap(),
published_data::GRID_3_META,
published_data::GRID_3_HEX,
),
(
"cfdd03b2-b539-4f1d-84c3-3c0424bbd345".parse().unwrap(),
published_data::GRID_2_META,
published_data::GRID_2_HEX,
),
],
)
.await;
{
let client_2 = TestClient::new_user().await;
let workspace_id_2 = client_2.workspace_id().await;
let fv = client_2
.api_client
.get_workspace_folder(&workspace_id_2, Some(5), None)
.await
.unwrap();
client_2
.api_client
.duplicate_published_to_workspace(
&workspace_id_2,
&PublishedDuplicate {
published_view_id: doc_4_view_id.to_string(),
dest_view_id: fv.view_id, // use the root view
},
)
.await
.unwrap();
let fv = client_2
.api_client
.get_workspace_folder(&workspace_id_2, Some(5), None)
.await
.unwrap();
println!("{:#?}", fv);
let doc_4_fv = fv.children.iter().find(|v| v.name == "doc4").unwrap();
let _ = doc_4_fv
.children
.iter()
.find(|v| v.name == "grid3")
.unwrap();
let _ = fv.children.iter().find(|v| v.name == "grid2").unwrap();
}
}
fn get_database_id_and_row_ids(published_db_blob: &[u8]) -> (String, HashSet<String>) {
let pub_db_data = serde_json::from_slice::<PublishDatabaseData>(published_db_blob).unwrap();
let db_collab = collab_from_doc_state(pub_db_data.database_collab, "").unwrap();

File diff suppressed because one or more lines are too long