lib.rs 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. use std::env::temp_dir;
  2. use std::sync::Arc;
  3. use nanoid::nanoid;
  4. use parking_lot::RwLock;
  5. use flowy_core::{AppFlowyCore, AppFlowyCoreConfig};
  6. use flowy_database2::entities::*;
  7. use flowy_folder2::entities::*;
  8. use flowy_user::entities::{AuthTypePB, UserProfilePB};
  9. use flowy_user::errors::FlowyError;
  10. use crate::event_builder::EventBuilder;
  11. use crate::user_event::{async_sign_up, init_user_setting, SignUpContext};
  12. pub mod event_builder;
  13. pub mod folder_event;
  14. pub mod user_event;
  15. #[derive(Clone)]
  16. pub struct FlowyCoreTest {
  17. auth_type: Arc<RwLock<AuthTypePB>>,
  18. inner: AppFlowyCore,
  19. }
  20. impl Default for FlowyCoreTest {
  21. fn default() -> Self {
  22. let temp_dir = temp_dir();
  23. let config =
  24. AppFlowyCoreConfig::new(temp_dir.to_str().unwrap(), nanoid!(6)).log_filter("info", vec![]);
  25. let inner = std::thread::spawn(|| AppFlowyCore::new(config))
  26. .join()
  27. .unwrap();
  28. let auth_type = Arc::new(RwLock::new(AuthTypePB::Local));
  29. std::mem::forget(inner.dispatcher());
  30. Self { inner, auth_type }
  31. }
  32. }
  33. impl FlowyCoreTest {
  34. pub fn new() -> Self {
  35. Self::default()
  36. }
  37. pub async fn new_with_user() -> Self {
  38. let test = Self::default();
  39. test.sign_up().await;
  40. test
  41. }
  42. pub async fn sign_up(&self) -> SignUpContext {
  43. let auth_type = self.auth_type.read().clone();
  44. async_sign_up(self.inner.dispatcher(), auth_type).await
  45. }
  46. pub fn set_auth_type(&self, auth_type: AuthTypePB) {
  47. *self.auth_type.write() = auth_type;
  48. }
  49. pub async fn init_user(&self) -> UserProfilePB {
  50. let auth_type = self.auth_type.read().clone();
  51. let context = async_sign_up(self.inner.dispatcher(), auth_type).await;
  52. init_user_setting(self.inner.dispatcher()).await;
  53. context.user_profile
  54. }
  55. pub async fn get_current_workspace(&self) -> WorkspaceSettingPB {
  56. EventBuilder::new(self.clone())
  57. .event(flowy_folder2::event_map::FolderEvent::GetCurrentWorkspace)
  58. .async_send()
  59. .await
  60. .parse::<flowy_folder2::entities::WorkspaceSettingPB>()
  61. }
  62. pub async fn get_all_workspace_views(&self) -> Vec<ViewPB> {
  63. EventBuilder::new(self.clone())
  64. .event(flowy_folder2::event_map::FolderEvent::ReadWorkspaceViews)
  65. .async_send()
  66. .await
  67. .parse::<flowy_folder2::entities::RepeatedViewPB>()
  68. .items
  69. }
  70. pub async fn delete_view(&self, view_id: &str) {
  71. let payload = RepeatedViewIdPB {
  72. items: vec![view_id.to_string()],
  73. };
  74. // delete the view. the view will be moved to trash
  75. EventBuilder::new(self.clone())
  76. .event(flowy_folder2::event_map::FolderEvent::DeleteView)
  77. .payload(payload)
  78. .async_send()
  79. .await;
  80. }
  81. pub async fn create_view(&self, parent_id: &str, name: String) -> ViewPB {
  82. let payload = CreateViewPayloadPB {
  83. parent_view_id: parent_id.to_string(),
  84. name,
  85. desc: "".to_string(),
  86. thumbnail: None,
  87. layout: Default::default(),
  88. initial_data: vec![],
  89. meta: Default::default(),
  90. set_as_current: false,
  91. };
  92. EventBuilder::new(self.clone())
  93. .event(flowy_folder2::event_map::FolderEvent::CreateView)
  94. .payload(payload)
  95. .async_send()
  96. .await
  97. .parse::<flowy_folder2::entities::ViewPB>()
  98. }
  99. pub async fn create_grid(&self, parent_id: &str, name: String, initial_data: Vec<u8>) -> ViewPB {
  100. let payload = CreateViewPayloadPB {
  101. parent_view_id: parent_id.to_string(),
  102. name,
  103. desc: "".to_string(),
  104. thumbnail: None,
  105. layout: ViewLayoutPB::Grid,
  106. initial_data,
  107. meta: Default::default(),
  108. set_as_current: true,
  109. };
  110. EventBuilder::new(self.clone())
  111. .event(flowy_folder2::event_map::FolderEvent::CreateView)
  112. .payload(payload)
  113. .async_send()
  114. .await
  115. .parse::<flowy_folder2::entities::ViewPB>()
  116. }
  117. pub async fn get_database(&self, view_id: &str) -> DatabasePB {
  118. EventBuilder::new(self.clone())
  119. .event(flowy_database2::event_map::DatabaseEvent::GetDatabase)
  120. .payload(DatabaseViewIdPB {
  121. value: view_id.to_string(),
  122. })
  123. .async_send()
  124. .await
  125. .parse::<flowy_database2::entities::DatabasePB>()
  126. }
  127. pub async fn get_all_database_fields(&self, view_id: &str) -> RepeatedFieldPB {
  128. EventBuilder::new(self.clone())
  129. .event(flowy_database2::event_map::DatabaseEvent::GetFields)
  130. .payload(GetFieldPayloadPB {
  131. view_id: view_id.to_string(),
  132. field_ids: None,
  133. })
  134. .async_send()
  135. .await
  136. .parse::<RepeatedFieldPB>()
  137. }
  138. pub async fn create_field(&self, view_id: &str, field_type: FieldType) -> FieldPB {
  139. EventBuilder::new(self.clone())
  140. .event(flowy_database2::event_map::DatabaseEvent::CreateTypeOption)
  141. .payload(CreateFieldPayloadPB {
  142. view_id: view_id.to_string(),
  143. field_type,
  144. type_option_data: None,
  145. })
  146. .async_send()
  147. .await
  148. .parse::<TypeOptionPB>()
  149. .field
  150. }
  151. pub async fn update_field(&self, changeset: FieldChangesetPB) {
  152. EventBuilder::new(self.clone())
  153. .event(flowy_database2::event_map::DatabaseEvent::UpdateField)
  154. .payload(changeset)
  155. .async_send()
  156. .await;
  157. }
  158. pub async fn delete_field(&self, view_id: &str, field_id: &str) -> Option<FlowyError> {
  159. EventBuilder::new(self.clone())
  160. .event(flowy_database2::event_map::DatabaseEvent::DeleteField)
  161. .payload(DeleteFieldPayloadPB {
  162. view_id: view_id.to_string(),
  163. field_id: field_id.to_string(),
  164. })
  165. .async_send()
  166. .await
  167. .error()
  168. }
  169. pub async fn update_field_type(
  170. &self,
  171. view_id: &str,
  172. field_id: &str,
  173. field_type: FieldType,
  174. ) -> Option<FlowyError> {
  175. EventBuilder::new(self.clone())
  176. .event(flowy_database2::event_map::DatabaseEvent::UpdateFieldType)
  177. .payload(UpdateFieldTypePayloadPB {
  178. view_id: view_id.to_string(),
  179. field_id: field_id.to_string(),
  180. field_type,
  181. })
  182. .async_send()
  183. .await
  184. .error()
  185. }
  186. pub async fn duplicate_field(&self, view_id: &str, field_id: &str) -> Option<FlowyError> {
  187. EventBuilder::new(self.clone())
  188. .event(flowy_database2::event_map::DatabaseEvent::DuplicateField)
  189. .payload(DuplicateFieldPayloadPB {
  190. view_id: view_id.to_string(),
  191. field_id: field_id.to_string(),
  192. })
  193. .async_send()
  194. .await
  195. .error()
  196. }
  197. pub async fn create_row(
  198. &self,
  199. view_id: &str,
  200. start_row_id: Option<String>,
  201. data: Option<RowDataPB>,
  202. ) -> RowPB {
  203. EventBuilder::new(self.clone())
  204. .event(flowy_database2::event_map::DatabaseEvent::CreateRow)
  205. .payload(CreateRowPayloadPB {
  206. view_id: view_id.to_string(),
  207. start_row_id,
  208. group_id: None,
  209. data,
  210. })
  211. .async_send()
  212. .await
  213. .parse::<RowPB>()
  214. }
  215. pub async fn get_row(&self, view_id: &str, row_id: &str) -> RowPB {
  216. EventBuilder::new(self.clone())
  217. .event(flowy_database2::event_map::DatabaseEvent::GetRow)
  218. .payload(RowIdPB {
  219. view_id: view_id.to_string(),
  220. row_id: row_id.to_string(),
  221. group_id: None,
  222. })
  223. .async_send()
  224. .await
  225. .parse::<RowPB>()
  226. }
  227. pub async fn duplicate_row(&self, view_id: &str, row_id: &str) -> Option<FlowyError> {
  228. EventBuilder::new(self.clone())
  229. .event(flowy_database2::event_map::DatabaseEvent::DuplicateRow)
  230. .payload(RowIdPB {
  231. view_id: view_id.to_string(),
  232. row_id: row_id.to_string(),
  233. group_id: None,
  234. })
  235. .async_send()
  236. .await
  237. .error()
  238. }
  239. pub async fn update_cell(&self, changeset: CellChangesetPB) -> Option<FlowyError> {
  240. EventBuilder::new(self.clone())
  241. .event(flowy_database2::event_map::DatabaseEvent::UpdateCell)
  242. .payload(changeset)
  243. .async_send()
  244. .await
  245. .error()
  246. }
  247. pub async fn get_cell(&self, view_id: &str, row_id: &str, field_id: &str) -> CellPB {
  248. EventBuilder::new(self.clone())
  249. .event(flowy_database2::event_map::DatabaseEvent::GetCell)
  250. .payload(CellIdPB {
  251. view_id: view_id.to_string(),
  252. row_id: row_id.to_string(),
  253. field_id: field_id.to_string(),
  254. })
  255. .async_send()
  256. .await
  257. .parse::<CellPB>()
  258. }
  259. pub async fn insert_option(
  260. &self,
  261. view_id: &str,
  262. field_id: &str,
  263. row_id: &str,
  264. name: &str,
  265. ) -> Option<FlowyError> {
  266. let option = EventBuilder::new(self.clone())
  267. .event(flowy_database2::event_map::DatabaseEvent::CreateSelectOption)
  268. .payload(CreateSelectOptionPayloadPB {
  269. field_id: field_id.to_string(),
  270. view_id: view_id.to_string(),
  271. option_name: name.to_string(),
  272. })
  273. .async_send()
  274. .await
  275. .parse::<SelectOptionPB>();
  276. EventBuilder::new(self.clone())
  277. .event(flowy_database2::event_map::DatabaseEvent::InsertOrUpdateSelectOption)
  278. .payload(RepeatedSelectOptionPayload {
  279. view_id: view_id.to_string(),
  280. field_id: field_id.to_string(),
  281. row_id: row_id.to_string(),
  282. items: vec![option],
  283. })
  284. .async_send()
  285. .await
  286. .error()
  287. }
  288. pub async fn get_view(&self, view_id: &str) -> ViewPB {
  289. EventBuilder::new(self.clone())
  290. .event(flowy_folder2::event_map::FolderEvent::ReadView)
  291. .payload(ViewIdPB {
  292. value: view_id.to_string(),
  293. })
  294. .async_send()
  295. .await
  296. .parse::<flowy_folder2::entities::ViewPB>()
  297. }
  298. }
  299. impl std::ops::Deref for FlowyCoreTest {
  300. type Target = AppFlowyCore;
  301. fn deref(&self) -> &Self::Target {
  302. &self.inner
  303. }
  304. }
  305. // pub struct TestNotificationSender {
  306. // pub(crate) sender: tokio::sync::mpsc::Sender<()>,
  307. // }
  308. //
  309. // impl NotificationSender for TestNotificationSender {
  310. // fn send_subject(&self, subject: SubscribeObject) -> Result<(), String> {
  311. // todo!()
  312. // }
  313. // }