Browse Source

test: add subscription test (#3126)

Nathan.fooo 1 year ago
parent
commit
63a12a1d2b

+ 22 - 2
frontend/rust-lib/flowy-test/src/lib.rs

@@ -162,6 +162,17 @@ impl FlowyCoreTest {
       .items
   }
 
+  pub async fn get_views(&self, parent_view_id: &str) -> ViewPB {
+    EventBuilder::new(self.clone())
+      .event(FolderEvent::ReadView)
+      .payload(ViewIdPB {
+        value: parent_view_id.to_string(),
+      })
+      .async_send()
+      .await
+      .parse::<flowy_folder2::entities::ViewPB>()
+  }
+
   pub async fn delete_view(&self, view_id: &str) {
     let payload = RepeatedViewIdPB {
       items: vec![view_id.to_string()],
@@ -758,8 +769,17 @@ impl TestNotificationSender {
       while let Ok(value) = receiver.recv().await {
         if value.id == id && value.ty == ty {
           if let Some(payload) = value.payload {
-            if let Ok(object) = T::try_from(Bytes::from(payload)) {
-              let _ = tx.send(object).await;
+            match T::try_from(Bytes::from(payload)) {
+              Ok(object) => {
+                let _ = tx.send(object).await;
+              },
+              Err(e) => {
+                panic!(
+                  "Failed to parse notification payload to type: {:?} with error: {}",
+                  std::any::type_name::<T>(),
+                  e
+                );
+              },
             }
           }
         }

+ 1 - 0
frontend/rust-lib/flowy-test/tests/folder/local_test/mod.rs

@@ -1 +1,2 @@
+mod subscription_test;
 mod test;

+ 127 - 0
frontend/rust-lib/flowy-test/tests/folder/local_test/subscription_test.rs

@@ -0,0 +1,127 @@
+use std::time::Duration;
+
+use flowy_folder2::entities::{ChildViewUpdatePB, RepeatedViewPB, UpdateViewPayloadPB};
+use flowy_folder2::notification::FolderNotification;
+use flowy_test::FlowyCoreTest;
+
+use crate::util::receive_with_timeout;
+
+#[tokio::test]
+/// The primary purpose of this test is to validate that the notification subscription mechanism
+/// correctly notifies the subscriber of updates to workspace views.
+/// 1. Initialize the `FlowyCoreTest` with a guest user.
+/// 2. Retrieve the current workspace for the test user.
+/// 3. Subscribe to workspace view updates using the `RepeatedViewPB` notification.
+/// 4. Spawn a new asynchronous task to create a new view named "test_view" within the workspace.
+/// 5. Await the notification for workspace view updates with a timeout of 30 seconds.
+/// 6. Ensure that the received views contain the newly created "test_view".
+async fn create_child_view_in_workspace_subscription_test() {
+  let test = FlowyCoreTest::new_with_guest_user().await;
+  let workspace = test.get_current_workspace().await.workspace;
+  let mut rx = test
+    .notification_sender
+    .subscribe::<RepeatedViewPB>(&workspace.id, FolderNotification::DidUpdateWorkspaceViews);
+
+  let cloned_test = test.clone();
+  let cloned_workspace_id = workspace.id.clone();
+  tokio::spawn(async move {
+    cloned_test
+      .create_view(&cloned_workspace_id, "workspace child view".to_string())
+      .await;
+  });
+
+  let views = receive_with_timeout(&mut rx, Duration::from_secs(30))
+    .await
+    .unwrap()
+    .items;
+  assert_eq!(views.len(), 2);
+  assert_eq!(views[1].name, "workspace child view".to_string());
+}
+
+#[tokio::test]
+async fn create_child_view_in_view_subscription_test() {
+  let test = FlowyCoreTest::new_with_guest_user().await;
+  let mut workspace = test.get_current_workspace().await.workspace;
+  let workspace_child_view = workspace.views.pop().unwrap();
+  let mut rx = test.notification_sender.subscribe::<ChildViewUpdatePB>(
+    &workspace_child_view.id,
+    FolderNotification::DidUpdateChildViews,
+  );
+
+  let cloned_test = test.clone();
+  let child_view_id = workspace_child_view.id.clone();
+  tokio::spawn(async move {
+    cloned_test
+      .create_view(
+        &child_view_id,
+        "workspace child view's child view".to_string(),
+      )
+      .await;
+  });
+
+  let update = receive_with_timeout(&mut rx, Duration::from_secs(30))
+    .await
+    .unwrap();
+
+  assert_eq!(update.create_child_views.len(), 1);
+  assert_eq!(
+    update.create_child_views[0].name,
+    "workspace child view's child view".to_string()
+  );
+}
+
+#[tokio::test]
+async fn delete_view_subscription_test() {
+  let test = FlowyCoreTest::new_with_guest_user().await;
+  let workspace = test.get_current_workspace().await.workspace;
+  let mut rx = test
+    .notification_sender
+    .subscribe::<ChildViewUpdatePB>(&workspace.id, FolderNotification::DidUpdateChildViews);
+
+  let cloned_test = test.clone();
+  let delete_view_id = workspace.views.first().unwrap().id.clone();
+  let cloned_delete_view_id = delete_view_id.clone();
+  tokio::spawn(async move {
+    cloned_test.delete_view(&cloned_delete_view_id).await;
+  });
+
+  let update = receive_with_timeout(&mut rx, Duration::from_secs(30))
+    .await
+    .unwrap();
+  assert_eq!(update.delete_child_views.len(), 1);
+  assert_eq!(update.delete_child_views[0], delete_view_id);
+}
+
+#[tokio::test]
+async fn update_view_subscription_test() {
+  let test = FlowyCoreTest::new_with_guest_user().await;
+  let mut workspace = test.get_current_workspace().await.workspace;
+  let mut rx = test
+    .notification_sender
+    .subscribe::<ChildViewUpdatePB>(&workspace.id, FolderNotification::DidUpdateChildViews);
+
+  let cloned_test = test.clone();
+  let view = workspace.views.pop().unwrap();
+  assert_eq!(view.is_favorite, false);
+
+  let update_view_id = view.id.clone();
+  tokio::spawn(async move {
+    cloned_test
+      .update_view(UpdateViewPayloadPB {
+        view_id: update_view_id,
+        name: Some("hello world".to_string()),
+        is_favorite: Some(true),
+        ..Default::default()
+      })
+      .await;
+  });
+
+  let update = receive_with_timeout(&mut rx, Duration::from_secs(30))
+    .await
+    .unwrap();
+  assert_eq!(update.update_child_views.len(), 1);
+  let expected_view = update.update_child_views.first().unwrap();
+  assert_eq!(expected_view.id, view.id);
+  assert_eq!(expected_view.name, "hello world".to_string());
+  assert_eq!(expected_view.is_favorite, true);
+}

+ 4 - 2
frontend/rust-lib/flowy-test/tests/user/migration_test/document_test.rs

@@ -13,8 +13,10 @@ async fn migrate_historical_empty_document_test() {
   assert_eq!(views.len(), 3);
   for view in views {
     assert_eq!(view.layout, ViewLayoutPB::Document);
-    let doc = test.open_document(view.id).await;
-    println!("doc: {:?}", doc.data);
+    let data = test.open_document(view.id).await.data;
+    assert!(!data.page_id.is_empty());
+    assert_eq!(data.blocks.len(), 2);
+    assert!(!data.meta.children_map.is_empty());
   }
 
   drop(cleaner);

BIN
frontend/rust-lib/flowy-test/tests/user/migration_test/history_user_db/020_historical_user_data.zip


+ 1 - 0
frontend/rust-lib/flowy-test/tests/user/migration_test/mod.rs

@@ -1,2 +1,3 @@
 mod document_test;
 mod util;
+mod version_test;

+ 35 - 0
frontend/rust-lib/flowy-test/tests/user/migration_test/version_test.rs

@@ -0,0 +1,35 @@
+use flowy_core::DEFAULT_NAME;
+use flowy_folder2::entities::ViewLayoutPB;
+use flowy_test::FlowyCoreTest;
+
+use crate::user::migration_test::util::unzip_history_user_db;
+
+#[tokio::test]
+async fn migrate_020_historical_empty_document_test() {
+  let (cleaner, user_db_path) = unzip_history_user_db("020_historical_user_data").unwrap();
+  let test = FlowyCoreTest::new_with_user_data_path(user_db_path, DEFAULT_NAME.to_string());
+
+  let mut views = test.get_all_workspace_views().await;
+  assert_eq!(views.len(), 1);
+
+  // Check the parent view
+  let parent_view = views.pop().unwrap();
+  assert_eq!(parent_view.layout, ViewLayoutPB::Document);
+  let data = test.open_document(parent_view.id.clone()).await.data;
+  assert!(!data.page_id.is_empty());
+  assert_eq!(data.blocks.len(), 2);
+  assert!(!data.meta.children_map.is_empty());
+
+  // Check the child views of the parent view
+  let child_views = test.get_views(&parent_view.id).await.child_views;
+  assert_eq!(child_views.len(), 4);
+  assert_eq!(child_views[0].layout, ViewLayoutPB::Document);
+  assert_eq!(child_views[1].layout, ViewLayoutPB::Grid);
+  assert_eq!(child_views[2].layout, ViewLayoutPB::Calendar);
+  assert_eq!(child_views[3].layout, ViewLayoutPB::Board);
+
+  let database = test.get_database(&child_views[1].id).await;
+  assert_eq!(database.fields.len(), 8);
+  assert_eq!(database.rows.len(), 3);
+  drop(cleaner);
+}