mirror of
				https://github.com/AppFlowy-IO/AppFlowy.git
				synced 2025-10-31 18:15:09 +00:00 
			
		
		
		
	 fd5299a13d
			
		
	
	
		fd5299a13d
		
			
		
	
	
	
	
		
			
			* chore: move to latest appflowy collab version * chore: filter mapping * chore: remove mutex folder * chore: cleanup borrow checker issues * chore: fixed flowy user crate compilation errors * chore: removed parking lot crate * chore: adjusting non locking approach * chore: remove with folder method * chore: fix folder manager * chore: fixed workspace database compilation errors * chore: initialize database plugins * chore: fix locks in flowy core * chore: remove supabase * chore: async traits * chore: add mutexes in dart ffi * chore: post rebase fixes * chore: remove supabase dart code * chore: fix deadlock * chore: fix page_id is empty * chore: use data source to init collab * chore: fix user awareness test * chore: fix database deadlock * fix: initialize user awareness * chore: fix open workspace test * chore: fix import csv * chore: fix update row meta deadlock * chore: fix document size test * fix: timestamp set/get type convert * fix: calculation * chore: revert Arc to Rc * chore: attach plugin to database and database row * chore: async get row * chore: clippy * chore: fix tauri build * chore: clippy * fix: duplicate view deadlock * chore: fmt * chore: tauri build --------- Co-authored-by: nathan <nathan@appflowy.io>
		
			
				
	
	
		
			410 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			410 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| use collab_folder::ViewLayout;
 | |
| 
 | |
| use event_integration_test::event_builder::EventBuilder;
 | |
| use event_integration_test::EventIntegrationTest;
 | |
| use flowy_folder::entities::icon::{UpdateViewIconPayloadPB, ViewIconPB};
 | |
| use flowy_folder::entities::*;
 | |
| use flowy_folder::event_map::FolderEvent::*;
 | |
| 
 | |
| pub enum FolderScript {
 | |
|   #[allow(dead_code)]
 | |
|   CreateWorkspace {
 | |
|     name: String,
 | |
|     desc: String,
 | |
|   },
 | |
|   #[allow(dead_code)]
 | |
|   AssertWorkspace(WorkspacePB),
 | |
|   #[allow(dead_code)]
 | |
|   ReadWorkspace(String),
 | |
|   CreateParentView {
 | |
|     name: String,
 | |
|     desc: String,
 | |
|   },
 | |
|   AssertParentView(ViewPB),
 | |
|   ReloadParentView(String),
 | |
|   UpdateParentView {
 | |
|     name: Option<String>,
 | |
|     desc: Option<String>,
 | |
|     is_favorite: Option<bool>,
 | |
|   },
 | |
|   DeleteParentView,
 | |
| 
 | |
|   // View
 | |
|   CreateView {
 | |
|     name: String,
 | |
|     desc: String,
 | |
|     layout: ViewLayout,
 | |
|   },
 | |
|   AssertView(ViewPB),
 | |
|   ReadView(String),
 | |
|   UpdateView {
 | |
|     name: Option<String>,
 | |
|     desc: Option<String>,
 | |
|     is_favorite: Option<bool>,
 | |
|   },
 | |
|   UpdateViewIcon {
 | |
|     icon: Option<ViewIconPB>,
 | |
|   },
 | |
|   DeleteView,
 | |
|   DeleteViews(Vec<String>),
 | |
|   MoveView {
 | |
|     view_id: String,
 | |
|     new_parent_id: String,
 | |
|     prev_view_id: Option<String>,
 | |
|   },
 | |
| 
 | |
|   // Trash
 | |
|   RestoreAppFromTrash,
 | |
|   RestoreViewFromTrash,
 | |
|   ReadTrash,
 | |
|   DeleteAllTrash,
 | |
|   ToggleFavorite,
 | |
|   ReadFavorites,
 | |
| }
 | |
| 
 | |
| pub struct FolderTest {
 | |
|   pub sdk: EventIntegrationTest,
 | |
|   pub workspace: WorkspacePB,
 | |
|   pub parent_view: ViewPB,
 | |
|   pub child_view: ViewPB,
 | |
|   pub trash: Vec<TrashPB>,
 | |
|   pub favorites: Vec<ViewPB>,
 | |
| }
 | |
| 
 | |
| impl FolderTest {
 | |
|   pub async fn new() -> Self {
 | |
|     let sdk = EventIntegrationTest::new().await;
 | |
|     let _ = sdk.init_anon_user().await;
 | |
|     let workspace = sdk.folder_manager.get_current_workspace().await.unwrap();
 | |
|     let parent_view = create_view(
 | |
|       &sdk,
 | |
|       &workspace.id,
 | |
|       "first level view",
 | |
|       "",
 | |
|       ViewLayout::Document,
 | |
|     )
 | |
|     .await;
 | |
|     let view = create_view(
 | |
|       &sdk,
 | |
|       &parent_view.id,
 | |
|       "second level view",
 | |
|       "",
 | |
|       ViewLayout::Document,
 | |
|     )
 | |
|     .await;
 | |
|     Self {
 | |
|       sdk,
 | |
|       workspace,
 | |
|       parent_view,
 | |
|       child_view: view,
 | |
|       trash: vec![],
 | |
|       favorites: vec![],
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   pub async fn run_scripts(&mut self, scripts: Vec<FolderScript>) {
 | |
|     for script in scripts {
 | |
|       self.run_script(script).await;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   pub async fn run_script(&mut self, script: FolderScript) {
 | |
|     let sdk = &self.sdk;
 | |
|     match script {
 | |
|       FolderScript::CreateWorkspace { name, desc } => {
 | |
|         let workspace = create_workspace(sdk, &name, &desc).await;
 | |
|         self.workspace = workspace;
 | |
|       },
 | |
|       FolderScript::AssertWorkspace(workspace) => {
 | |
|         assert_eq!(self.workspace, workspace, "Workspace not equal");
 | |
|       },
 | |
|       FolderScript::ReadWorkspace(workspace_id) => {
 | |
|         let workspace = read_workspace(sdk, workspace_id).await;
 | |
|         self.workspace = workspace;
 | |
|       },
 | |
|       FolderScript::CreateParentView { name, desc } => {
 | |
|         let app = create_view(sdk, &self.workspace.id, &name, &desc, ViewLayout::Document).await;
 | |
|         self.parent_view = app;
 | |
|       },
 | |
|       FolderScript::AssertParentView(view) => {
 | |
|         assert_eq!(self.parent_view.id, view.id, "view id not equal");
 | |
|         assert_eq!(self.parent_view.name, view.name, "view name not equal");
 | |
|         assert_eq!(
 | |
|           self.parent_view.is_favorite, view.is_favorite,
 | |
|           "view name not equal"
 | |
|         );
 | |
|       },
 | |
|       FolderScript::ReloadParentView(parent_view_id) => {
 | |
|         let parent_view = read_view(sdk, &parent_view_id).await;
 | |
|         self.parent_view = parent_view;
 | |
|       },
 | |
|       FolderScript::UpdateParentView {
 | |
|         name,
 | |
|         desc,
 | |
|         is_favorite,
 | |
|       } => {
 | |
|         update_view(sdk, &self.parent_view.id, name, desc, is_favorite).await;
 | |
|       },
 | |
|       FolderScript::DeleteParentView => {
 | |
|         delete_view(sdk, vec![self.parent_view.id.clone()]).await;
 | |
|       },
 | |
|       FolderScript::CreateView { name, desc, layout } => {
 | |
|         let view = create_view(sdk, &self.parent_view.id, &name, &desc, layout).await;
 | |
|         self.child_view = view;
 | |
|       },
 | |
|       FolderScript::MoveView {
 | |
|         view_id,
 | |
|         new_parent_id,
 | |
|         prev_view_id,
 | |
|       } => {
 | |
|         move_view(sdk, view_id, new_parent_id, prev_view_id).await;
 | |
|       },
 | |
|       FolderScript::AssertView(view) => {
 | |
|         assert_eq!(self.child_view, view, "View not equal");
 | |
|       },
 | |
|       FolderScript::ReadView(view_id) => {
 | |
|         let mut view = read_view(sdk, &view_id).await;
 | |
|         // Ignore the last edited time
 | |
|         view.last_edited = 0;
 | |
|         self.child_view = view;
 | |
|       },
 | |
|       FolderScript::UpdateView {
 | |
|         name,
 | |
|         desc,
 | |
|         is_favorite,
 | |
|       } => {
 | |
|         update_view(sdk, &self.child_view.id, name, desc, is_favorite).await;
 | |
|       },
 | |
|       FolderScript::UpdateViewIcon { icon } => {
 | |
|         update_view_icon(sdk, &self.child_view.id, icon).await;
 | |
|       },
 | |
|       FolderScript::DeleteView => {
 | |
|         delete_view(sdk, vec![self.child_view.id.clone()]).await;
 | |
|       },
 | |
|       FolderScript::DeleteViews(view_ids) => {
 | |
|         delete_view(sdk, view_ids).await;
 | |
|       },
 | |
|       FolderScript::RestoreAppFromTrash => {
 | |
|         restore_app_from_trash(sdk, &self.parent_view.id).await;
 | |
|       },
 | |
|       FolderScript::RestoreViewFromTrash => {
 | |
|         restore_view_from_trash(sdk, &self.child_view.id).await;
 | |
|       },
 | |
|       FolderScript::ReadTrash => {
 | |
|         let trash = read_trash(sdk).await;
 | |
|         self.trash = trash.items;
 | |
|       },
 | |
|       FolderScript::DeleteAllTrash => {
 | |
|         delete_all_trash(sdk).await;
 | |
|         self.trash = vec![];
 | |
|       },
 | |
|       FolderScript::ToggleFavorite => {
 | |
|         toggle_favorites(sdk, vec![self.child_view.id.clone()]).await;
 | |
|       },
 | |
|       FolderScript::ReadFavorites => {
 | |
|         let favorites = read_favorites(sdk).await;
 | |
|         self.favorites = favorites.items.iter().map(|x| x.item.clone()).collect();
 | |
|       },
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   //   pub async fn duplicate_view(&self, view_id: &str) {
 | |
|   //     let payload = DuplicateViewPayloadPB {
 | |
|   //       view_id: view_id.to_string(),
 | |
|   //       open_after_duplicate: false,
 | |
|   //       include_children: false,
 | |
|   //       parent_view_id: None,
 | |
|   //       suffix: None,
 | |
|   //       sync_after_create: false,
 | |
|   //     };
 | |
|   //     EventBuilder::new(self.sdk.clone())
 | |
|   //       .event(DuplicateView)
 | |
|   //       .payload(payload)
 | |
|   //       .async_send()
 | |
|   //       .await;
 | |
|   //   }
 | |
| }
 | |
| pub async fn create_workspace(sdk: &EventIntegrationTest, name: &str, desc: &str) -> WorkspacePB {
 | |
|   let request = CreateWorkspacePayloadPB {
 | |
|     name: name.to_owned(),
 | |
|     desc: desc.to_owned(),
 | |
|   };
 | |
| 
 | |
|   EventBuilder::new(sdk.clone())
 | |
|     .event(CreateFolderWorkspace)
 | |
|     .payload(request)
 | |
|     .async_send()
 | |
|     .await
 | |
|     .parse::<WorkspacePB>()
 | |
| }
 | |
| 
 | |
| pub async fn read_workspace(sdk: &EventIntegrationTest, workspace_id: String) -> WorkspacePB {
 | |
|   let request = WorkspaceIdPB {
 | |
|     value: workspace_id,
 | |
|   };
 | |
|   EventBuilder::new(sdk.clone())
 | |
|     .event(ReadCurrentWorkspace)
 | |
|     .payload(request.clone())
 | |
|     .async_send()
 | |
|     .await
 | |
|     .parse::<WorkspacePB>()
 | |
| }
 | |
| 
 | |
| pub async fn create_view(
 | |
|   sdk: &EventIntegrationTest,
 | |
|   parent_view_id: &str,
 | |
|   name: &str,
 | |
|   desc: &str,
 | |
|   layout: ViewLayout,
 | |
| ) -> ViewPB {
 | |
|   let request = CreateViewPayloadPB {
 | |
|     parent_view_id: parent_view_id.to_string(),
 | |
|     name: name.to_string(),
 | |
|     desc: desc.to_string(),
 | |
|     thumbnail: None,
 | |
|     layout: layout.into(),
 | |
|     initial_data: vec![],
 | |
|     meta: Default::default(),
 | |
|     set_as_current: true,
 | |
|     index: None,
 | |
|     section: None,
 | |
|     view_id: None,
 | |
|     extra: None,
 | |
|   };
 | |
|   EventBuilder::new(sdk.clone())
 | |
|     .event(CreateView)
 | |
|     .payload(request)
 | |
|     .async_send()
 | |
|     .await
 | |
|     .parse::<ViewPB>()
 | |
| }
 | |
| 
 | |
| pub async fn read_view(sdk: &EventIntegrationTest, view_id: &str) -> ViewPB {
 | |
|   let view_id = ViewIdPB::from(view_id);
 | |
|   EventBuilder::new(sdk.clone())
 | |
|     .event(GetView)
 | |
|     .payload(view_id)
 | |
|     .async_send()
 | |
|     .await
 | |
|     .parse::<ViewPB>()
 | |
| }
 | |
| 
 | |
| pub async fn move_view(
 | |
|   sdk: &EventIntegrationTest,
 | |
|   view_id: String,
 | |
|   parent_id: String,
 | |
|   prev_view_id: Option<String>,
 | |
| ) {
 | |
|   let payload = MoveNestedViewPayloadPB {
 | |
|     view_id,
 | |
|     new_parent_id: parent_id,
 | |
|     prev_view_id,
 | |
|     from_section: None,
 | |
|     to_section: None,
 | |
|   };
 | |
|   let error = EventBuilder::new(sdk.clone())
 | |
|     .event(MoveNestedView)
 | |
|     .payload(payload)
 | |
|     .async_send()
 | |
|     .await
 | |
|     .error();
 | |
| 
 | |
|   assert!(error.is_none());
 | |
| }
 | |
| pub async fn update_view(
 | |
|   sdk: &EventIntegrationTest,
 | |
|   view_id: &str,
 | |
|   name: Option<String>,
 | |
|   desc: Option<String>,
 | |
|   is_favorite: Option<bool>,
 | |
| ) {
 | |
|   println!("Toggling update view {:?}", is_favorite);
 | |
|   let request = UpdateViewPayloadPB {
 | |
|     view_id: view_id.to_string(),
 | |
|     name,
 | |
|     desc,
 | |
|     is_favorite,
 | |
|     ..Default::default()
 | |
|   };
 | |
|   EventBuilder::new(sdk.clone())
 | |
|     .event(UpdateView)
 | |
|     .payload(request)
 | |
|     .async_send()
 | |
|     .await;
 | |
| }
 | |
| 
 | |
| pub async fn update_view_icon(sdk: &EventIntegrationTest, view_id: &str, icon: Option<ViewIconPB>) {
 | |
|   let request = UpdateViewIconPayloadPB {
 | |
|     view_id: view_id.to_string(),
 | |
|     icon,
 | |
|   };
 | |
|   EventBuilder::new(sdk.clone())
 | |
|     .event(UpdateViewIcon)
 | |
|     .payload(request)
 | |
|     .async_send()
 | |
|     .await;
 | |
| }
 | |
| 
 | |
| pub async fn delete_view(sdk: &EventIntegrationTest, view_ids: Vec<String>) {
 | |
|   let request = RepeatedViewIdPB { items: view_ids };
 | |
|   EventBuilder::new(sdk.clone())
 | |
|     .event(DeleteView)
 | |
|     .payload(request)
 | |
|     .async_send()
 | |
|     .await;
 | |
| }
 | |
| 
 | |
| pub async fn read_trash(sdk: &EventIntegrationTest) -> RepeatedTrashPB {
 | |
|   EventBuilder::new(sdk.clone())
 | |
|     .event(ListTrashItems)
 | |
|     .async_send()
 | |
|     .await
 | |
|     .parse::<RepeatedTrashPB>()
 | |
| }
 | |
| 
 | |
| pub async fn restore_app_from_trash(sdk: &EventIntegrationTest, app_id: &str) {
 | |
|   let id = TrashIdPB {
 | |
|     id: app_id.to_owned(),
 | |
|   };
 | |
|   EventBuilder::new(sdk.clone())
 | |
|     .event(RestoreTrashItem)
 | |
|     .payload(id)
 | |
|     .async_send()
 | |
|     .await;
 | |
| }
 | |
| 
 | |
| pub async fn restore_view_from_trash(sdk: &EventIntegrationTest, view_id: &str) {
 | |
|   let id = TrashIdPB {
 | |
|     id: view_id.to_owned(),
 | |
|   };
 | |
|   EventBuilder::new(sdk.clone())
 | |
|     .event(RestoreTrashItem)
 | |
|     .payload(id)
 | |
|     .async_send()
 | |
|     .await;
 | |
| }
 | |
| 
 | |
| pub async fn delete_all_trash(sdk: &EventIntegrationTest) {
 | |
|   EventBuilder::new(sdk.clone())
 | |
|     .event(PermanentlyDeleteAllTrashItem)
 | |
|     .async_send()
 | |
|     .await;
 | |
| }
 | |
| 
 | |
| pub async fn toggle_favorites(sdk: &EventIntegrationTest, view_id: Vec<String>) {
 | |
|   let request = RepeatedViewIdPB { items: view_id };
 | |
|   EventBuilder::new(sdk.clone())
 | |
|     .event(ToggleFavorite)
 | |
|     .payload(request)
 | |
|     .async_send()
 | |
|     .await;
 | |
| }
 | |
| 
 | |
| pub async fn read_favorites(sdk: &EventIntegrationTest) -> RepeatedFavoriteViewPB {
 | |
|   EventBuilder::new(sdk.clone())
 | |
|     .event(ReadFavorites)
 | |
|     .async_send()
 | |
|     .await
 | |
|     .parse::<RepeatedFavoriteViewPB>()
 | |
| }
 |