test.rs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. use flowy_folder2::entities::*;
  2. use flowy_test::event_builder::EventBuilder;
  3. use flowy_test::FlowyCoreTest;
  4. use flowy_user::errors::ErrorCode;
  5. #[tokio::test]
  6. async fn create_workspace_event_test() {
  7. let test = FlowyCoreTest::new_with_user().await;
  8. let request = CreateWorkspacePayloadPB {
  9. name: "my second workspace".to_owned(),
  10. desc: "".to_owned(),
  11. };
  12. let resp = EventBuilder::new(test)
  13. .event(flowy_folder2::event_map::FolderEvent::CreateWorkspace)
  14. .payload(request)
  15. .async_send()
  16. .await
  17. .parse::<flowy_folder2::entities::WorkspacePB>();
  18. assert_eq!(resp.name, "my second workspace");
  19. }
  20. #[tokio::test]
  21. async fn open_workspace_event_test() {
  22. let test = FlowyCoreTest::new_with_user().await;
  23. let payload = CreateWorkspacePayloadPB {
  24. name: "my second workspace".to_owned(),
  25. desc: "".to_owned(),
  26. };
  27. // create a workspace
  28. let resp_1 = EventBuilder::new(test.clone())
  29. .event(flowy_folder2::event_map::FolderEvent::CreateWorkspace)
  30. .payload(payload)
  31. .async_send()
  32. .await
  33. .parse::<flowy_folder2::entities::WorkspacePB>();
  34. // open the workspace
  35. let payload = WorkspaceIdPB {
  36. value: Some(resp_1.id.clone()),
  37. };
  38. let resp_2 = EventBuilder::new(test)
  39. .event(flowy_folder2::event_map::FolderEvent::OpenWorkspace)
  40. .payload(payload)
  41. .async_send()
  42. .await
  43. .parse::<flowy_folder2::entities::WorkspacePB>();
  44. assert_eq!(resp_1.id, resp_2.id);
  45. assert_eq!(resp_1.name, resp_2.name);
  46. }
  47. #[tokio::test]
  48. async fn create_view_event_test() {
  49. let test = FlowyCoreTest::new_with_user().await;
  50. let current_workspace = test.get_current_workspace().await.workspace;
  51. let view = test
  52. .create_view(&current_workspace.id, "My first view".to_string())
  53. .await;
  54. assert_eq!(view.parent_view_id, current_workspace.id);
  55. assert_eq!(view.name, "My first view");
  56. assert_eq!(view.layout, ViewLayoutPB::Document);
  57. }
  58. #[tokio::test]
  59. async fn delete_view_event_test() {
  60. let test = FlowyCoreTest::new_with_user().await;
  61. let current_workspace = test.get_current_workspace().await.workspace;
  62. let view = test
  63. .create_view(&current_workspace.id, "My first view".to_string())
  64. .await;
  65. test.delete_view(&view.id).await;
  66. // Try the read the view
  67. let payload = ViewIdPB {
  68. value: view.id.clone(),
  69. };
  70. let error = EventBuilder::new(test.clone())
  71. .event(flowy_folder2::event_map::FolderEvent::ReadView)
  72. .payload(payload)
  73. .async_send()
  74. .await
  75. .error()
  76. .unwrap();
  77. assert_eq!(error.code, ErrorCode::RecordNotFound.value());
  78. }
  79. #[tokio::test]
  80. async fn put_back_trash_event_test() {
  81. let test = FlowyCoreTest::new_with_user().await;
  82. let current_workspace = test.get_current_workspace().await.workspace;
  83. let view = test
  84. .create_view(&current_workspace.id, "My first view".to_string())
  85. .await;
  86. test.delete_view(&view.id).await;
  87. // After delete view, the view will be moved to trash
  88. let payload = ViewIdPB {
  89. value: view.id.clone(),
  90. };
  91. let error = EventBuilder::new(test.clone())
  92. .event(flowy_folder2::event_map::FolderEvent::ReadView)
  93. .payload(payload)
  94. .async_send()
  95. .await
  96. .error()
  97. .unwrap();
  98. assert_eq!(error.code, ErrorCode::RecordNotFound.value());
  99. let payload = TrashIdPB {
  100. id: view.id.clone(),
  101. };
  102. EventBuilder::new(test.clone())
  103. .event(flowy_folder2::event_map::FolderEvent::PutbackTrash)
  104. .payload(payload)
  105. .async_send()
  106. .await;
  107. let payload = ViewIdPB {
  108. value: view.id.clone(),
  109. };
  110. let error = EventBuilder::new(test.clone())
  111. .event(flowy_folder2::event_map::FolderEvent::ReadView)
  112. .payload(payload)
  113. .async_send()
  114. .await
  115. .error();
  116. assert!(error.is_none());
  117. }
  118. #[tokio::test]
  119. async fn delete_view_permanently_event_test() {
  120. let test = FlowyCoreTest::new_with_user().await;
  121. let current_workspace = test.get_current_workspace().await.workspace;
  122. let view = test
  123. .create_view(&current_workspace.id, "My first view".to_string())
  124. .await;
  125. let payload = RepeatedViewIdPB {
  126. items: vec![view.id.clone()],
  127. };
  128. // delete the view. the view will be moved to trash
  129. EventBuilder::new(test.clone())
  130. .event(flowy_folder2::event_map::FolderEvent::DeleteView)
  131. .payload(payload)
  132. .async_send()
  133. .await;
  134. let trash = EventBuilder::new(test.clone())
  135. .event(flowy_folder2::event_map::FolderEvent::ReadTrash)
  136. .async_send()
  137. .await
  138. .parse::<flowy_folder2::entities::RepeatedTrashPB>()
  139. .items;
  140. assert_eq!(trash.len(), 1);
  141. assert_eq!(trash[0].id, view.id);
  142. // delete the view from trash
  143. let payload = RepeatedTrashIdPB {
  144. items: vec![TrashIdPB {
  145. id: view.id.clone(),
  146. }],
  147. };
  148. EventBuilder::new(test.clone())
  149. .event(flowy_folder2::event_map::FolderEvent::DeleteTrash)
  150. .payload(payload)
  151. .async_send()
  152. .await;
  153. // After delete the last view, the trash should be empty
  154. let trash = EventBuilder::new(test.clone())
  155. .event(flowy_folder2::event_map::FolderEvent::ReadTrash)
  156. .async_send()
  157. .await
  158. .parse::<flowy_folder2::entities::RepeatedTrashPB>()
  159. .items;
  160. assert!(trash.is_empty());
  161. }
  162. #[tokio::test]
  163. async fn delete_all_trash_test() {
  164. let test = FlowyCoreTest::new_with_user().await;
  165. let current_workspace = test.get_current_workspace().await.workspace;
  166. for i in 0..3 {
  167. let view = test
  168. .create_view(&current_workspace.id, format!("My {} view", i))
  169. .await;
  170. let payload = RepeatedViewIdPB {
  171. items: vec![view.id.clone()],
  172. };
  173. // delete the view. the view will be moved to trash
  174. EventBuilder::new(test.clone())
  175. .event(flowy_folder2::event_map::FolderEvent::DeleteView)
  176. .payload(payload)
  177. .async_send()
  178. .await;
  179. }
  180. let trash = EventBuilder::new(test.clone())
  181. .event(flowy_folder2::event_map::FolderEvent::ReadTrash)
  182. .async_send()
  183. .await
  184. .parse::<flowy_folder2::entities::RepeatedTrashPB>()
  185. .items;
  186. assert_eq!(trash.len(), 3);
  187. // Delete all the trash
  188. EventBuilder::new(test.clone())
  189. .event(flowy_folder2::event_map::FolderEvent::DeleteAllTrash)
  190. .async_send()
  191. .await;
  192. // After delete the last view, the trash should be empty
  193. let trash = EventBuilder::new(test.clone())
  194. .event(flowy_folder2::event_map::FolderEvent::ReadTrash)
  195. .async_send()
  196. .await
  197. .parse::<flowy_folder2::entities::RepeatedTrashPB>()
  198. .items;
  199. assert!(trash.is_empty());
  200. }
  201. #[tokio::test]
  202. async fn multiple_hierarchy_view_test() {
  203. let test = FlowyCoreTest::new_with_user().await;
  204. let current_workspace = test.get_current_workspace().await.workspace;
  205. for i in 1..4 {
  206. let parent = test
  207. .create_view(&current_workspace.id, format!("My {} view", i))
  208. .await;
  209. for j in 1..3 {
  210. let child = test
  211. .create_view(&parent.id, format!("My {}-{} view", i, j))
  212. .await;
  213. for k in 1..2 {
  214. let _sub_child = test
  215. .create_view(&child.id, format!("My {}-{}-{} view", i, j, k))
  216. .await;
  217. }
  218. }
  219. }
  220. let mut views = EventBuilder::new(test.clone())
  221. .event(flowy_folder2::event_map::FolderEvent::ReadWorkspaceViews)
  222. .async_send()
  223. .await
  224. .parse::<flowy_folder2::entities::RepeatedViewPB>()
  225. .items;
  226. // There will be one default view when AppFlowy is initialized. So there will be 4 views in total
  227. assert_eq!(views.len(), 4);
  228. views.remove(0);
  229. // workspace
  230. // - view1
  231. // - view1-1
  232. // - view1-1-1
  233. // - view1-2
  234. // - view1-2-1
  235. // - view2
  236. // - view2-1
  237. // - view2-1-1
  238. // - view2-2
  239. // - view2-2-1
  240. // - view3
  241. // - view3-1
  242. // - view3-1-1
  243. // - view3-2
  244. // - view3-2-1
  245. assert_eq!(views[0].name, "My 1 view");
  246. assert_eq!(views[1].name, "My 2 view");
  247. assert_eq!(views[2].name, "My 3 view");
  248. assert_eq!(views[0].child_views.len(), 2);
  249. // By default only the first level of child views will be loaded
  250. assert!(views[0].child_views[0].child_views.is_empty());
  251. for (i, view) in views.into_iter().enumerate() {
  252. for (j, child_view) in view.child_views.into_iter().enumerate() {
  253. let payload = ViewIdPB {
  254. value: child_view.id.clone(),
  255. };
  256. let child = EventBuilder::new(test.clone())
  257. .event(flowy_folder2::event_map::FolderEvent::ReadView)
  258. .payload(payload)
  259. .async_send()
  260. .await
  261. .parse::<flowy_folder2::entities::ViewPB>();
  262. assert_eq!(child.name, format!("My {}-{} view", i + 1, j + 1));
  263. assert_eq!(child.child_views.len(), 1);
  264. // By default only the first level of child views will be loaded
  265. assert!(child.child_views[0].child_views.is_empty());
  266. for (k, _child_view) in child_view.child_views.into_iter().enumerate() {
  267. // Get the last level view
  268. let sub_child = EventBuilder::new(test.clone())
  269. .event(flowy_folder2::event_map::FolderEvent::ReadView)
  270. .payload(ViewIdPB {
  271. value: child.id.clone(),
  272. })
  273. .async_send()
  274. .await
  275. .parse::<flowy_folder2::entities::ViewPB>();
  276. assert_eq!(child.name, format!("My {}-{}-{} view", i + 1, j + 1, k + 1));
  277. assert!(sub_child.child_views.is_empty());
  278. }
  279. }
  280. }
  281. }
  282. #[tokio::test]
  283. async fn move_view_event_test() {
  284. let test = FlowyCoreTest::new_with_user().await;
  285. let current_workspace = test.get_current_workspace().await.workspace;
  286. for i in 1..4 {
  287. let parent = test
  288. .create_view(&current_workspace.id, format!("My {} view", i))
  289. .await;
  290. for j in 1..3 {
  291. let _ = test
  292. .create_view(&parent.id, format!("My {}-{} view", i, j))
  293. .await;
  294. }
  295. }
  296. let views = EventBuilder::new(test.clone())
  297. .event(flowy_folder2::event_map::FolderEvent::ReadWorkspaceViews)
  298. .async_send()
  299. .await
  300. .parse::<flowy_folder2::entities::RepeatedViewPB>()
  301. .items;
  302. // There will be one default view when AppFlowy is initialized. So there will be 4 views in total
  303. assert_eq!(views.len(), 4);
  304. assert_eq!(views[1].name, "My 1 view");
  305. assert_eq!(views[2].name, "My 2 view");
  306. assert_eq!(views[3].name, "My 3 view");
  307. let payload = MoveViewPayloadPB {
  308. view_id: views[1].id.clone(),
  309. from: 1,
  310. to: 2,
  311. };
  312. let _ = EventBuilder::new(test.clone())
  313. .event(flowy_folder2::event_map::FolderEvent::MoveView)
  314. .payload(payload)
  315. .async_send()
  316. .await;
  317. let views = EventBuilder::new(test.clone())
  318. .event(flowy_folder2::event_map::FolderEvent::ReadWorkspaceViews)
  319. .async_send()
  320. .await
  321. .parse::<flowy_folder2::entities::RepeatedViewPB>()
  322. .items;
  323. assert_eq!(views[1].name, "My 2 view");
  324. assert_eq!(views[2].name, "My 1 view");
  325. assert_eq!(views[3].name, "My 3 view");
  326. }
  327. #[tokio::test]
  328. async fn create_parent_view_with_invalid_name() {
  329. for (name, code) in invalid_workspace_name_test_case() {
  330. let sdk = FlowyCoreTest::new();
  331. let request = CreateWorkspacePayloadPB {
  332. name,
  333. desc: "".to_owned(),
  334. };
  335. assert_eq!(
  336. EventBuilder::new(sdk)
  337. .event(flowy_folder2::event_map::FolderEvent::CreateWorkspace)
  338. .payload(request)
  339. .async_send()
  340. .await
  341. .error()
  342. .unwrap()
  343. .code,
  344. code.value()
  345. )
  346. }
  347. }
  348. fn invalid_workspace_name_test_case() -> Vec<(String, ErrorCode)> {
  349. vec![
  350. ("".to_owned(), ErrorCode::WorkspaceNameInvalid),
  351. ("1234".repeat(100), ErrorCode::WorkspaceNameTooLong),
  352. ]
  353. }