script.rs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. use crate::helper::*;
  2. use flowy_collaboration::entities::{document_info::DocumentInfo, revision::RevisionState};
  3. use flowy_core::{errors::ErrorCode, services::folder_editor::FolderEditor};
  4. use flowy_core_data_model::entities::{
  5. app::{App, RepeatedApp},
  6. trash::Trash,
  7. view::{RepeatedView, View, ViewType},
  8. workspace::Workspace,
  9. };
  10. use flowy_sync::REVISION_WRITE_INTERVAL_IN_MILLIS;
  11. use flowy_test::FlowySDKTest;
  12. use std::{sync::Arc, time::Duration};
  13. use tokio::time::sleep;
  14. pub enum FolderScript {
  15. // Workspace
  16. ReadAllWorkspaces,
  17. CreateWorkspace { name: String, desc: String },
  18. AssertWorkspaceJson(String),
  19. AssertWorkspace(Workspace),
  20. ReadWorkspace(Option<String>),
  21. // App
  22. CreateApp { name: String, desc: String },
  23. AssertAppJson(String),
  24. AssertApp(App),
  25. ReadApp(String),
  26. UpdateApp { name: Option<String>, desc: Option<String> },
  27. DeleteApp,
  28. // View
  29. CreateView { name: String, desc: String },
  30. AssertView(View),
  31. ReadView(String),
  32. UpdateView { name: Option<String>, desc: Option<String> },
  33. DeleteView,
  34. DeleteViews(Vec<String>),
  35. // Trash
  36. RestoreAppFromTrash,
  37. RestoreViewFromTrash,
  38. ReadTrash,
  39. DeleteAllTrash,
  40. // Document
  41. OpenDocument,
  42. // Sync
  43. AssertCurrentRevId(i64),
  44. AssertNextSyncRevId(Option<i64>),
  45. AssertRevisionState { rev_id: i64, state: RevisionState },
  46. }
  47. pub struct FolderTest {
  48. pub sdk: FlowySDKTest,
  49. pub all_workspace: Vec<Workspace>,
  50. pub workspace: Workspace,
  51. pub app: App,
  52. pub view: View,
  53. pub trash: Vec<Trash>,
  54. pub document_info: Option<DocumentInfo>,
  55. // pub folder_editor:
  56. }
  57. impl FolderTest {
  58. pub async fn new() -> Self {
  59. let sdk = FlowySDKTest::default();
  60. let _ = sdk.init_user().await;
  61. let mut workspace = create_workspace(&sdk, "FolderWorkspace", "Folder test workspace").await;
  62. let mut app = create_app(&sdk, &workspace.id, "Folder App", "Folder test app").await;
  63. let view = create_view(&sdk, &app.id, "Folder View", "Folder test view", ViewType::Doc).await;
  64. app.belongings = RepeatedView {
  65. items: vec![view.clone()],
  66. };
  67. workspace.apps = RepeatedApp {
  68. items: vec![app.clone()],
  69. };
  70. Self {
  71. sdk,
  72. all_workspace: vec![],
  73. workspace,
  74. app,
  75. view,
  76. trash: vec![],
  77. document_info: None,
  78. }
  79. }
  80. pub async fn run_scripts(&mut self, scripts: Vec<FolderScript>) {
  81. for script in scripts {
  82. self.run_script(script).await;
  83. }
  84. }
  85. pub async fn run_script(&mut self, script: FolderScript) {
  86. let sdk = &self.sdk;
  87. let folder_editor: Arc<FolderEditor> = sdk.folder_manager.folder_editor().await;
  88. let rev_manager = folder_editor.rev_manager();
  89. let cache = rev_manager.revision_cache().await;
  90. match script {
  91. FolderScript::ReadAllWorkspaces => {
  92. let all_workspace = read_workspace(sdk, None).await;
  93. self.all_workspace = all_workspace;
  94. }
  95. FolderScript::CreateWorkspace { name, desc } => {
  96. let workspace = create_workspace(sdk, &name, &desc).await;
  97. self.workspace = workspace;
  98. }
  99. FolderScript::AssertWorkspaceJson(expected_json) => {
  100. let workspace = read_workspace(sdk, Some(self.workspace.id.clone()))
  101. .await
  102. .pop()
  103. .unwrap();
  104. let json = serde_json::to_string(&workspace).unwrap();
  105. assert_eq!(json, expected_json);
  106. }
  107. FolderScript::AssertWorkspace(workspace) => {
  108. assert_eq!(self.workspace, workspace);
  109. }
  110. FolderScript::ReadWorkspace(workspace_id) => {
  111. let workspace = read_workspace(sdk, workspace_id).await.pop().unwrap();
  112. self.workspace = workspace;
  113. }
  114. FolderScript::CreateApp { name, desc } => {
  115. let app = create_app(sdk, &self.workspace.id, &name, &desc).await;
  116. self.app = app;
  117. }
  118. FolderScript::AssertAppJson(expected_json) => {
  119. let json = serde_json::to_string(&self.app).unwrap();
  120. assert_eq!(json, expected_json);
  121. }
  122. FolderScript::AssertApp(app) => {
  123. assert_eq!(self.app, app);
  124. }
  125. FolderScript::ReadApp(app_id) => {
  126. let app = read_app(sdk, &app_id).await;
  127. self.app = app;
  128. }
  129. FolderScript::UpdateApp { name, desc } => {
  130. update_app(sdk, &self.app.id, name, desc).await;
  131. }
  132. FolderScript::DeleteApp => {
  133. delete_app(sdk, &self.app.id).await;
  134. }
  135. FolderScript::CreateView { name, desc } => {
  136. let view = create_view(sdk, &self.app.id, &name, &desc, ViewType::Doc).await;
  137. self.view = view;
  138. }
  139. FolderScript::AssertView(view) => {
  140. assert_eq!(self.view, view);
  141. }
  142. FolderScript::ReadView(view_id) => {
  143. let view = read_view(sdk, vec![view_id]).await;
  144. self.view = view;
  145. }
  146. FolderScript::UpdateView { name, desc } => {
  147. update_view(sdk, &self.view.id, name, desc).await;
  148. }
  149. FolderScript::DeleteView => {
  150. delete_view(sdk, vec![self.view.id.clone()]).await;
  151. }
  152. FolderScript::DeleteViews(view_ids) => {
  153. delete_view(sdk, view_ids).await;
  154. }
  155. FolderScript::RestoreAppFromTrash => {
  156. restore_app_from_trash(sdk, &self.app.id).await;
  157. }
  158. FolderScript::RestoreViewFromTrash => {
  159. restore_view_from_trash(sdk, &self.view.id).await;
  160. }
  161. FolderScript::ReadTrash => {
  162. let trash = read_trash(sdk).await;
  163. self.trash = trash.into_inner();
  164. }
  165. FolderScript::DeleteAllTrash => {
  166. delete_all_trash(sdk).await;
  167. self.trash = vec![];
  168. }
  169. FolderScript::OpenDocument => {
  170. let document_info = open_document(sdk, &self.view.id).await;
  171. self.document_info = Some(document_info);
  172. }
  173. FolderScript::AssertRevisionState { rev_id, state } => {
  174. let record = cache.get(rev_id).await.unwrap();
  175. assert_eq!(record.state, state);
  176. if let RevisionState::Ack = state {
  177. // There is a defer action that writes the revisions to disk, so we wait here.
  178. // Make sure everything is written.
  179. sleep(Duration::from_millis(2 * REVISION_WRITE_INTERVAL_IN_MILLIS)).await;
  180. }
  181. }
  182. FolderScript::AssertCurrentRevId(rev_id) => {
  183. assert_eq!(rev_manager.rev_id(), rev_id, "Current rev_id is not match");
  184. }
  185. FolderScript::AssertNextSyncRevId(rev_id) => {
  186. let next_revision = rev_manager.next_sync_revision().await.unwrap();
  187. if rev_id.is_none() {
  188. assert!(next_revision.is_none(), "Next revision should be None");
  189. return;
  190. }
  191. let next_revision = next_revision
  192. .unwrap_or_else(|| panic!("Expected Next revision is {}, but receive None", rev_id.unwrap()));
  193. let mut receiver = rev_manager.revision_ack_receiver();
  194. let _ = receiver.recv().await;
  195. assert_eq!(next_revision.rev_id, rev_id.unwrap());
  196. }
  197. }
  198. }
  199. }
  200. pub fn invalid_workspace_name_test_case() -> Vec<(String, ErrorCode)> {
  201. vec![
  202. ("".to_owned(), ErrorCode::WorkspaceNameInvalid),
  203. ("1234".repeat(100), ErrorCode::WorkspaceNameTooLong),
  204. ]
  205. }