script.rs 7.6 KB

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