grid_test.rs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. use crate::grid::script::EditorScript::*;
  2. use crate::grid::script::*;
  3. use chrono::NaiveDateTime;
  4. use flowy_grid::services::field::{
  5. MultiSelectTypeOption, SelectOption, SingleSelectTypeOption, SELECTION_IDS_SEPARATOR,
  6. };
  7. use flowy_grid::services::row::{deserialize_cell_data, serialize_cell_data, CellDataSerde, CreateRowMetaBuilder};
  8. use flowy_grid_data_model::entities::{
  9. CellMetaChangeset, FieldChangeset, FieldType, GridBlockMeta, GridBlockMetaChangeset, RowMetaChangeset,
  10. };
  11. #[tokio::test]
  12. async fn grid_create_field() {
  13. let mut test = GridEditorTest::new().await;
  14. let (text_field_params, text_field_meta) = create_text_field(&test.grid_id);
  15. let (single_select_params, single_select_field) = create_single_select_field(&test.grid_id);
  16. let scripts = vec![
  17. CreateField {
  18. params: text_field_params,
  19. },
  20. AssertFieldEqual {
  21. field_index: test.field_count,
  22. field_meta: text_field_meta,
  23. },
  24. ];
  25. test.run_scripts(scripts).await;
  26. let scripts = vec![
  27. CreateField {
  28. params: single_select_params,
  29. },
  30. AssertFieldEqual {
  31. field_index: test.field_count,
  32. field_meta: single_select_field,
  33. },
  34. ];
  35. test.run_scripts(scripts).await;
  36. }
  37. #[tokio::test]
  38. async fn grid_create_duplicate_field() {
  39. let mut test = GridEditorTest::new().await;
  40. let (params, _) = create_text_field(&test.grid_id);
  41. let field_count = test.field_count;
  42. let expected_field_count = field_count + 1;
  43. let scripts = vec![
  44. CreateField { params: params.clone() },
  45. CreateField { params },
  46. AssertFieldCount(expected_field_count),
  47. ];
  48. test.run_scripts(scripts).await;
  49. }
  50. #[tokio::test]
  51. async fn grid_update_field_with_empty_change() {
  52. let mut test = GridEditorTest::new().await;
  53. let (params, field_meta) = create_single_select_field(&test.grid_id);
  54. let changeset = FieldChangeset {
  55. field_id: field_meta.id.clone(),
  56. grid_id: test.grid_id.clone(),
  57. name: None,
  58. desc: None,
  59. field_type: None,
  60. frozen: None,
  61. visibility: None,
  62. width: None,
  63. type_options: None,
  64. };
  65. let scripts = vec![
  66. CreateField { params },
  67. UpdateField { changeset },
  68. AssertFieldEqual {
  69. field_index: test.field_count,
  70. field_meta,
  71. },
  72. ];
  73. test.run_scripts(scripts).await;
  74. }
  75. #[tokio::test]
  76. async fn grid_update_field() {
  77. let mut test = GridEditorTest::new().await;
  78. let (single_select_params, single_select_field) = create_single_select_field(&test.grid_id);
  79. let mut cloned_field = single_select_field.clone();
  80. let mut single_select_type_options = SingleSelectTypeOption::from(&single_select_field);
  81. single_select_type_options.options.push(SelectOption::new("Unknown"));
  82. let changeset = FieldChangeset {
  83. field_id: single_select_field.id.clone(),
  84. grid_id: test.grid_id.clone(),
  85. name: None,
  86. desc: None,
  87. field_type: None,
  88. frozen: Some(true),
  89. visibility: None,
  90. width: Some(1000),
  91. type_options: Some(single_select_type_options.clone().into()),
  92. };
  93. cloned_field.frozen = true;
  94. cloned_field.width = 1000;
  95. cloned_field.type_option_json = single_select_type_options.into();
  96. let scripts = vec![
  97. CreateField {
  98. params: single_select_params,
  99. },
  100. UpdateField { changeset },
  101. AssertFieldEqual {
  102. field_index: test.field_count,
  103. field_meta: cloned_field,
  104. },
  105. ];
  106. test.run_scripts(scripts).await;
  107. }
  108. #[tokio::test]
  109. async fn grid_delete_field() {
  110. let mut test = GridEditorTest::new().await;
  111. let expected_field_count = test.field_count;
  112. let (text_params, text_field) = create_text_field(&test.grid_id);
  113. let scripts = vec![
  114. CreateField { params: text_params },
  115. DeleteField { field_meta: text_field },
  116. AssertFieldCount(expected_field_count),
  117. ];
  118. test.run_scripts(scripts).await;
  119. }
  120. #[tokio::test]
  121. async fn grid_create_block() {
  122. let grid_block = GridBlockMeta::new();
  123. let scripts = vec![
  124. AssertBlockCount(1),
  125. CreateBlock { block: grid_block },
  126. AssertBlockCount(2),
  127. ];
  128. GridEditorTest::new().await.run_scripts(scripts).await;
  129. }
  130. #[tokio::test]
  131. async fn grid_update_block() {
  132. let grid_block = GridBlockMeta::new();
  133. let mut cloned_grid_block = grid_block.clone();
  134. let changeset = GridBlockMetaChangeset {
  135. block_id: grid_block.block_id.clone(),
  136. start_row_index: Some(2),
  137. row_count: Some(10),
  138. };
  139. cloned_grid_block.start_row_index = 2;
  140. cloned_grid_block.row_count = 10;
  141. let scripts = vec![
  142. AssertBlockCount(1),
  143. CreateBlock { block: grid_block },
  144. UpdateBlock { changeset },
  145. AssertBlockCount(2),
  146. AssertBlockEqual {
  147. block_index: 1,
  148. block: cloned_grid_block,
  149. },
  150. ];
  151. GridEditorTest::new().await.run_scripts(scripts).await;
  152. }
  153. #[tokio::test]
  154. async fn grid_create_row() {
  155. let scripts = vec![AssertRowCount(3), CreateEmptyRow, CreateEmptyRow, AssertRowCount(5)];
  156. GridEditorTest::new().await.run_scripts(scripts).await;
  157. }
  158. #[tokio::test]
  159. async fn grid_create_row2() {
  160. let mut test = GridEditorTest::new().await;
  161. let create_row_context = CreateRowMetaBuilder::new(&test.field_metas).build();
  162. let scripts = vec![
  163. AssertRowCount(3),
  164. CreateRow {
  165. context: create_row_context,
  166. },
  167. AssertRowCount(4),
  168. ];
  169. test.run_scripts(scripts).await;
  170. }
  171. #[tokio::test]
  172. async fn grid_update_row() {
  173. let mut test = GridEditorTest::new().await;
  174. let context = CreateRowMetaBuilder::new(&test.field_metas).build();
  175. let changeset = RowMetaChangeset {
  176. row_id: context.row_id.clone(),
  177. height: None,
  178. visibility: None,
  179. cell_by_field_id: Default::default(),
  180. };
  181. let scripts = vec![
  182. AssertRowCount(3),
  183. CreateRow { context },
  184. UpdateRow {
  185. changeset: changeset.clone(),
  186. },
  187. AssertRow { changeset },
  188. AssertRowCount(4),
  189. ];
  190. test.run_scripts(scripts).await;
  191. }
  192. #[tokio::test]
  193. async fn grid_delete_row() {
  194. let mut test = GridEditorTest::new().await;
  195. let context_1 = CreateRowMetaBuilder::new(&test.field_metas).build();
  196. let context_2 = CreateRowMetaBuilder::new(&test.field_metas).build();
  197. let row_ids = vec![context_1.row_id.clone(), context_2.row_id.clone()];
  198. let scripts = vec![
  199. AssertRowCount(3),
  200. CreateRow { context: context_1 },
  201. CreateRow { context: context_2 },
  202. AssertBlockCount(1),
  203. AssertBlock {
  204. block_index: 0,
  205. row_count: 5,
  206. start_row_index: 0,
  207. },
  208. DeleteRow { row_ids },
  209. AssertBlock {
  210. block_index: 0,
  211. row_count: 3,
  212. start_row_index: 0,
  213. },
  214. ];
  215. test.run_scripts(scripts).await;
  216. }
  217. #[tokio::test]
  218. async fn grid_row_add_cells_test() {
  219. let mut test = GridEditorTest::new().await;
  220. let mut builder = CreateRowMetaBuilder::new(&test.field_metas);
  221. for field in &test.field_metas {
  222. match field.field_type {
  223. FieldType::RichText => {
  224. let data = serialize_cell_data("hello world", field).unwrap();
  225. builder.add_cell(&field.id, data).unwrap();
  226. }
  227. FieldType::Number => {
  228. let data = serialize_cell_data("¥18,443", field).unwrap();
  229. builder.add_cell(&field.id, data).unwrap();
  230. }
  231. FieldType::DateTime => {
  232. let data = serialize_cell_data("1647251762", field).unwrap();
  233. builder.add_cell(&field.id, data).unwrap();
  234. }
  235. FieldType::SingleSelect => {
  236. let type_option = SingleSelectTypeOption::from(field);
  237. let options = description.options.first().unwrap();
  238. let data = description.serialize_cell_data(&options.id).unwrap();
  239. builder.add_cell(&field.id, data).unwrap();
  240. }
  241. FieldType::MultiSelect => {
  242. let type_option = MultiSelectTypeOption::from(field);
  243. let options = description
  244. .options
  245. .iter()
  246. .map(|option| option.id.clone())
  247. .collect::<Vec<_>>()
  248. .join(SELECTION_IDS_SEPARATOR);
  249. let data = description.serialize_cell_data(&options).unwrap();
  250. builder.add_cell(&field.id, data).unwrap();
  251. }
  252. FieldType::Checkbox => {
  253. let data = serialize_cell_data("false", field).unwrap();
  254. builder.add_cell(&field.id, data).unwrap();
  255. }
  256. }
  257. }
  258. let context = builder.build();
  259. let scripts = vec![CreateRow { context }, AssertGridMetaPad];
  260. test.run_scripts(scripts).await;
  261. }
  262. #[tokio::test]
  263. async fn grid_row_add_selection_cell_test() {
  264. let mut test = GridEditorTest::new().await;
  265. let mut builder = CreateRowMetaBuilder::new(&test.field_metas);
  266. let uuid = uuid::Uuid::new_v4().to_string();
  267. let mut single_select_field_id = "".to_string();
  268. let mut multi_select_field_id = "".to_string();
  269. for field in &test.field_metas {
  270. match field.field_type {
  271. FieldType::SingleSelect => {
  272. single_select_field_id = field.id.clone();
  273. // The element must be parsed as uuid
  274. assert!(builder.add_cell(&field.id, "data".to_owned()).is_err());
  275. // // The data should not be empty
  276. assert!(builder.add_cell(&field.id, "".to_owned()).is_err());
  277. // The element must be parsed as uuid
  278. assert!(builder.add_cell(&field.id, "1,2,3".to_owned()).is_err(),);
  279. // The separator must be comma
  280. assert!(builder.add_cell(&field.id, format!("{}. {}", &uuid, &uuid),).is_err());
  281. //
  282. assert!(builder.add_cell(&field.id, uuid.clone()).is_ok());
  283. assert!(builder.add_cell(&field.id, format!("{}, {}", &uuid, &uuid)).is_ok());
  284. }
  285. FieldType::MultiSelect => {
  286. multi_select_field_id = field.id.clone();
  287. assert!(builder.add_cell(&field.id, format!("{}, {}", &uuid, &uuid)).is_ok());
  288. }
  289. _ => {}
  290. }
  291. }
  292. let context = builder.build();
  293. assert_eq!(
  294. &context
  295. .cell_by_field_id
  296. .get(&single_select_field_id)
  297. .as_ref()
  298. .unwrap()
  299. .data,
  300. &uuid
  301. );
  302. assert_eq!(
  303. context
  304. .cell_by_field_id
  305. .get(&multi_select_field_id)
  306. .as_ref()
  307. .unwrap()
  308. .data,
  309. format!("{},{}", &uuid, &uuid)
  310. );
  311. let scripts = vec![CreateRow { context }];
  312. test.run_scripts(scripts).await;
  313. }
  314. #[tokio::test]
  315. async fn grid_row_add_date_cell_test() {
  316. let mut test = GridEditorTest::new().await;
  317. let mut builder = CreateRowMetaBuilder::new(&test.field_metas);
  318. let mut date_field = None;
  319. let timestamp = 1647390674;
  320. for field in &test.field_metas {
  321. if field.field_type == FieldType::DateTime {
  322. date_field = Some(field.clone());
  323. NaiveDateTime::from_timestamp(123, 0);
  324. // The data should not be empty
  325. assert!(builder.add_cell(&field.id, "".to_owned()).is_err());
  326. assert!(builder.add_cell(&field.id, "123".to_owned()).is_ok());
  327. assert!(builder.add_cell(&field.id, format!("{}", timestamp)).is_ok());
  328. }
  329. }
  330. let context = builder.build();
  331. let date_field = date_field.unwrap();
  332. let cell_data = context.cell_by_field_id.get(&date_field.id).unwrap().clone();
  333. assert_eq!(
  334. deserialize_cell_data(cell_data.data.clone(), &date_field).unwrap(),
  335. "2022/03/16 08:31",
  336. );
  337. let scripts = vec![CreateRow { context }];
  338. test.run_scripts(scripts).await;
  339. }
  340. #[tokio::test]
  341. async fn grid_cell_update() {
  342. let mut test = GridEditorTest::new().await;
  343. let field_metas = &test.field_metas;
  344. let row_metas = &test.row_metas;
  345. let grid_blocks = &test.grid_blocks;
  346. assert_eq!(row_metas.len(), 3);
  347. assert_eq!(grid_blocks.len(), 1);
  348. let block_id = &grid_blocks.first().unwrap().block_id;
  349. let mut scripts = vec![];
  350. for (index, row_meta) in row_metas.iter().enumerate() {
  351. for field_meta in field_metas {
  352. if index == 0 {
  353. let data = match field_meta.field_type {
  354. FieldType::RichText => "".to_string(),
  355. FieldType::Number => "123".to_string(),
  356. FieldType::DateTime => "123".to_string(),
  357. FieldType::SingleSelect => {
  358. let type_option = SingleSelectTypeOption::from(field_meta);
  359. description.options.first().unwrap().id.clone()
  360. }
  361. FieldType::MultiSelect => {
  362. let type_option = MultiSelectTypeOption::from(field_meta);
  363. description.options.first().unwrap().id.clone()
  364. }
  365. FieldType::Checkbox => "1".to_string(),
  366. };
  367. scripts.push(UpdateCell {
  368. changeset: CellMetaChangeset {
  369. grid_id: block_id.to_string(),
  370. row_id: row_meta.id.clone(),
  371. field_id: field_meta.id.clone(),
  372. data: Some(data),
  373. },
  374. is_err: false,
  375. });
  376. }
  377. if index == 1 {
  378. let (data, is_err) = match field_meta.field_type {
  379. FieldType::RichText => ("1".to_string().repeat(10001), true),
  380. FieldType::Number => ("abc".to_string(), true),
  381. FieldType::DateTime => ("abc".to_string(), true),
  382. FieldType::SingleSelect => ("abc".to_string(), true),
  383. FieldType::MultiSelect => ("abc".to_string(), true),
  384. FieldType::Checkbox => ("2".to_string(), false),
  385. };
  386. scripts.push(UpdateCell {
  387. changeset: CellMetaChangeset {
  388. grid_id: block_id.to_string(),
  389. row_id: row_meta.id.clone(),
  390. field_id: field_meta.id.clone(),
  391. data: Some(data),
  392. },
  393. is_err,
  394. });
  395. }
  396. }
  397. }
  398. test.run_scripts(scripts).await;
  399. }