grid_test.rs 15 KB

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