grid_test.rs 12 KB

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