From 46a3006f4d6bcf99079776f67204bf2cb1ba7aa4 Mon Sep 17 00:00:00 2001 From: "Nathan.fooo" <86001920+appflowy@users.noreply.github.com> Date: Tue, 15 Oct 2024 09:32:06 +0800 Subject: [PATCH] refactor: database test (#6544) * chore: remove script * chore: remove script * chore: refactor test * chore: clippy * chore: fix test * chore: fix test * chore: fmt --- frontend/appflowy_flutter/pubspec.lock | 12 +- .../database/local_test/calculate_test.rs | 1 + .../local_test/{test.rs => event_test.rs} | 0 .../tests/database/local_test/mod.rs | 3 +- .../tests/database/block_test/row_test.rs | 33 +- .../tests/database/block_test/script.rs | 50 +- .../calculations_test/calculation_test.rs | 124 ++-- .../database/calculations_test/script.rs | 44 +- .../tests/database/cell_test/script.rs | 61 +- .../tests/database/cell_test/test.rs | 61 +- .../tests/database/database_editor.rs | 1 + .../database/field_settings_test/script.rs | 119 ++-- .../database/field_settings_test/test.rs | 305 ++++++--- .../tests/database/field_test/script.rs | 178 +++--- .../tests/database/field_test/test.rs | 343 ++++------ .../filter_test/advanced_filter_test.rs | 409 ++++++------ .../filter_test/checkbox_filter_test.rs | 46 +- .../filter_test/checklist_filter_test.rs | 67 +- .../database/filter_test/date_filter_test.rs | 119 ++-- .../filter_test/number_filter_test.rs | 142 +++-- .../tests/database/filter_test/script.rs | 379 +++++------ .../filter_test/select_option_filter_test.rs | 237 +++---- .../database/filter_test/text_filter_test.rs | 371 ++++++----- .../database/filter_test/time_filter_test.rs | 118 ++-- .../database/group_test/date_group_test.rs | 187 ++---- .../tests/database/group_test/script.rs | 415 +++++------- .../tests/database/group_test/test.rs | 553 ++++------------ .../database/group_test/url_group_test.rs | 186 ++---- .../tests/database/layout_test/script.rs | 190 +++--- .../tests/database/layout_test/test.rs | 59 +- .../pre_fill_row_according_to_filter_test.rs | 564 +++++++---------- .../pre_fill_row_with_payload_test.rs | 493 ++++++--------- .../database/pre_fill_cell_test/script.rs | 179 +++--- .../database/sort_test/multi_sort_test.rs | 187 +++--- .../tests/database/sort_test/script.rs | 305 ++++----- .../database/sort_test/single_sort_test.rs | 595 ++++++------------ 36 files changed, 3090 insertions(+), 4046 deletions(-) create mode 100644 frontend/rust-lib/event-integration-test/tests/database/local_test/calculate_test.rs rename frontend/rust-lib/event-integration-test/tests/database/local_test/{test.rs => event_test.rs} (100%) diff --git a/frontend/appflowy_flutter/pubspec.lock b/frontend/appflowy_flutter/pubspec.lock index 2805904da879..e090c4eb0526 100644 --- a/frontend/appflowy_flutter/pubspec.lock +++ b/frontend/appflowy_flutter/pubspec.lock @@ -1535,10 +1535,10 @@ packages: dependency: transitive description: name: platform - sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" + sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" url: "https://pub.dev" source: hosted - version: "3.1.5" + version: "3.1.4" plugin_platform_interface: dependency: "direct dev" description: @@ -1933,10 +1933,10 @@ packages: dependency: transitive description: name: string_scanner - sha256: "688af5ed3402a4bde5b3a6c15fd768dbf2621a614950b17f04626c431ab3c4c3" + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.2.0" string_validator: dependency: "direct main" description: @@ -2238,10 +2238,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" url: "https://pub.dev" source: hosted - version: "14.2.5" + version: "14.2.1" watcher: dependency: transitive description: diff --git a/frontend/rust-lib/event-integration-test/tests/database/local_test/calculate_test.rs b/frontend/rust-lib/event-integration-test/tests/database/local_test/calculate_test.rs new file mode 100644 index 000000000000..8b137891791f --- /dev/null +++ b/frontend/rust-lib/event-integration-test/tests/database/local_test/calculate_test.rs @@ -0,0 +1 @@ + diff --git a/frontend/rust-lib/event-integration-test/tests/database/local_test/test.rs b/frontend/rust-lib/event-integration-test/tests/database/local_test/event_test.rs similarity index 100% rename from frontend/rust-lib/event-integration-test/tests/database/local_test/test.rs rename to frontend/rust-lib/event-integration-test/tests/database/local_test/event_test.rs diff --git a/frontend/rust-lib/event-integration-test/tests/database/local_test/mod.rs b/frontend/rust-lib/event-integration-test/tests/database/local_test/mod.rs index 8b91f8511371..f1c1b64a540b 100644 --- a/frontend/rust-lib/event-integration-test/tests/database/local_test/mod.rs +++ b/frontend/rust-lib/event-integration-test/tests/database/local_test/mod.rs @@ -1,2 +1,3 @@ +mod calculate_test; +mod event_test; mod group_test; -mod test; diff --git a/frontend/rust-lib/flowy-database2/tests/database/block_test/row_test.rs b/frontend/rust-lib/flowy-database2/tests/database/block_test/row_test.rs index 07e1287a86cc..08ce2e954e14 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/block_test/row_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/block_test/row_test.rs @@ -4,23 +4,24 @@ use lib_infra::util::timestamp; use std::time::Duration; use crate::database::block_test::script::DatabaseRowTest; -use crate::database::block_test::script::RowScript::*; -// Create a new row at the end of the grid and check the create time is valid. #[tokio::test] async fn created_at_field_test() { let mut test = DatabaseRowTest::new().await; + + // Get initial row count let row_count = test.rows.len(); - test - .run_scripts(vec![CreateEmptyRow, AssertRowCount(row_count + 1)]) - .await; + + // Create a new row and assert the row count has increased by 1 + test.create_empty_row().await; + test.assert_row_count(row_count + 1).await; // Get created time of the new row. let row = test.get_rows().await.last().cloned().unwrap(); - let updated_at_field = test.get_first_field(FieldType::CreatedTime).await; + let created_at_field = test.get_first_field(FieldType::CreatedTime).await; let cell = test .editor - .get_cell(&updated_at_field.id, &row.id) + .get_cell(&created_at_field.id, &row.id) .await .unwrap(); let created_at_timestamp = DateCellData::from(&cell).timestamp.unwrap(); @@ -29,10 +30,11 @@ async fn created_at_field_test() { assert!(created_at_timestamp <= timestamp()); } -// Update row and check the update time is valid. #[tokio::test] async fn update_at_field_test() { let mut test = DatabaseRowTest::new().await; + + // Get the first row and the current LastEditedTime field let row = test.get_rows().await.remove(0); let last_edit_field = test.get_first_field(FieldType::LastEditedTime).await; let cell = test @@ -42,15 +44,13 @@ async fn update_at_field_test() { .unwrap(); let old_updated_at = DateCellData::from(&cell).timestamp.unwrap(); + // Wait for 1 second before updating the row tokio::time::sleep(Duration::from_millis(1000)).await; - test - .run_script(UpdateTextCell { - row_id: row.id.clone(), - content: "test".to_string(), - }) - .await; - - // Get the updated time of the row. + + // Update the text cell of the first row + test.update_text_cell(row.id.clone(), "test").await; + + // Get the updated time of the row let row = test.get_rows().await.remove(0); let last_edit_field = test.get_first_field(FieldType::LastEditedTime).await; let cell = test @@ -59,5 +59,6 @@ async fn update_at_field_test() { .await .unwrap(); let new_updated_at = DateCellData::from(&cell).timestamp.unwrap(); + assert!(old_updated_at < new_updated_at); } diff --git a/frontend/rust-lib/flowy-database2/tests/database/block_test/script.rs b/frontend/rust-lib/flowy-database2/tests/database/block_test/script.rs index 80a2c9977522..b8035767ef02 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/block_test/script.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/block_test/script.rs @@ -1,15 +1,7 @@ +use crate::database::database_editor::DatabaseEditorTest; use collab_database::rows::RowId; - use flowy_database2::entities::CreateRowPayloadPB; -use crate::database::database_editor::DatabaseEditorTest; - -pub enum RowScript { - CreateEmptyRow, - UpdateTextCell { row_id: RowId, content: String }, - AssertRowCount(usize), -} - pub struct DatabaseRowTest { inner: DatabaseEditorTest, } @@ -20,32 +12,24 @@ impl DatabaseRowTest { Self { inner: editor_test } } - pub async fn run_scripts(&mut self, scripts: Vec) { - for script in scripts { - self.run_script(script).await; - } + pub async fn create_empty_row(&mut self) { + let params = CreateRowPayloadPB { + view_id: self.view_id.clone(), + ..Default::default() + }; + let row_detail = self.editor.create_row(params).await.unwrap().unwrap(); + self + .row_by_row_id + .insert(row_detail.row.id.to_string(), row_detail.into()); + self.rows = self.get_rows().await; + } + + pub async fn update_text_cell(&mut self, row_id: RowId, content: &str) { + self.inner.update_text_cell(row_id, content).await.unwrap(); } - pub async fn run_script(&mut self, script: RowScript) { - match script { - RowScript::CreateEmptyRow => { - let params = CreateRowPayloadPB { - view_id: self.view_id.clone(), - ..Default::default() - }; - let row_detail = self.editor.create_row(params).await.unwrap().unwrap(); - self - .row_by_row_id - .insert(row_detail.row.id.to_string(), row_detail.into()); - self.rows = self.get_rows().await; - }, - RowScript::UpdateTextCell { row_id, content } => { - self.update_text_cell(row_id, &content).await.unwrap(); - }, - RowScript::AssertRowCount(expected_row_count) => { - assert_eq!(expected_row_count, self.rows.len()); - }, - } + pub async fn assert_row_count(&self, expected_row_count: usize) { + assert_eq!(expected_row_count, self.rows.len()); } } diff --git a/frontend/rust-lib/flowy-database2/tests/database/calculations_test/calculation_test.rs b/frontend/rust-lib/flowy-database2/tests/database/calculations_test/calculation_test.rs index 2800596900b0..99b8d015941f 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/calculations_test/calculation_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/calculations_test/calculation_test.rs @@ -1,7 +1,6 @@ use std::sync::Arc; -use crate::database::calculations_test::script::{CalculationScript::*, DatabaseCalculationTest}; - +use crate::database::calculations_test::script::DatabaseCalculationTest; use collab_database::fields::Field; use flowy_database2::entities::{CalculationType, FieldType, UpdateCalculationChangesetPB}; @@ -15,7 +14,7 @@ async fn calculations_test() { let expected_max = 14.00000; let expected_median = 3.00000; - let view_id = &test.view_id; + let view_id = &test.view_id(); let number_fields = test .fields .clone() @@ -25,63 +24,64 @@ async fn calculations_test() { let field_id = &number_fields.first().unwrap().id; let calculation_id = "calc_id".to_owned(); - let scripts = vec![ - // Insert Sum calculation first time - InsertCalculation { - payload: UpdateCalculationChangesetPB { - view_id: view_id.to_owned(), - field_id: field_id.to_owned(), - calculation_id: Some(calculation_id.clone()), - calculation_type: CalculationType::Sum, - }, - }, - AssertCalculationValue { - expected: expected_sum, - }, - InsertCalculation { - payload: UpdateCalculationChangesetPB { - view_id: view_id.to_owned(), - field_id: field_id.to_owned(), - calculation_id: Some(calculation_id.clone()), - calculation_type: CalculationType::Min, - }, - }, - AssertCalculationValue { - expected: expected_min, - }, - InsertCalculation { - payload: UpdateCalculationChangesetPB { - view_id: view_id.to_owned(), - field_id: field_id.to_owned(), - calculation_id: Some(calculation_id.clone()), - calculation_type: CalculationType::Average, - }, - }, - AssertCalculationValue { - expected: expected_average, - }, - InsertCalculation { - payload: UpdateCalculationChangesetPB { - view_id: view_id.to_owned(), - field_id: field_id.to_owned(), - calculation_id: Some(calculation_id.clone()), - calculation_type: CalculationType::Max, - }, - }, - AssertCalculationValue { - expected: expected_max, - }, - InsertCalculation { - payload: UpdateCalculationChangesetPB { - view_id: view_id.to_owned(), - field_id: field_id.to_owned(), - calculation_id: Some(calculation_id), - calculation_type: CalculationType::Median, - }, - }, - AssertCalculationValue { - expected: expected_median, - }, - ]; - test.run_scripts(scripts).await; + + // Insert Sum calculation and assert its value + test + .insert_calculation(UpdateCalculationChangesetPB { + view_id: view_id.to_owned(), + field_id: field_id.to_owned(), + calculation_id: Some(calculation_id.clone()), + calculation_type: CalculationType::Sum, + }) + .await; + + test.assert_calculation_value(expected_sum).await; + + // Insert Min calculation and assert its value + test + .insert_calculation(UpdateCalculationChangesetPB { + view_id: view_id.to_owned(), + field_id: field_id.to_owned(), + calculation_id: Some(calculation_id.clone()), + calculation_type: CalculationType::Min, + }) + .await; + + test.assert_calculation_value(expected_min).await; + + // Insert Average calculation and assert its value + test + .insert_calculation(UpdateCalculationChangesetPB { + view_id: view_id.to_owned(), + field_id: field_id.to_owned(), + calculation_id: Some(calculation_id.clone()), + calculation_type: CalculationType::Average, + }) + .await; + + test.assert_calculation_value(expected_average).await; + + // Insert Max calculation and assert its value + test + .insert_calculation(UpdateCalculationChangesetPB { + view_id: view_id.to_owned(), + field_id: field_id.to_owned(), + calculation_id: Some(calculation_id.clone()), + calculation_type: CalculationType::Max, + }) + .await; + + test.assert_calculation_value(expected_max).await; + + // Insert Median calculation and assert its value + test + .insert_calculation(UpdateCalculationChangesetPB { + view_id: view_id.to_owned(), + field_id: field_id.to_owned(), + calculation_id: Some(calculation_id.clone()), + calculation_type: CalculationType::Median, + }) + .await; + + test.assert_calculation_value(expected_median).await; } diff --git a/frontend/rust-lib/flowy-database2/tests/database/calculations_test/script.rs b/frontend/rust-lib/flowy-database2/tests/database/calculations_test/script.rs index 978acd84633f..a3d37d2cc512 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/calculations_test/script.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/calculations_test/script.rs @@ -5,15 +5,6 @@ use flowy_database2::services::database_view::DatabaseViewChanged; use crate::database::database_editor::DatabaseEditorTest; -pub enum CalculationScript { - InsertCalculation { - payload: UpdateCalculationChangesetPB, - }, - AssertCalculationValue { - expected: f64, - }, -} - pub struct DatabaseCalculationTest { inner: DatabaseEditorTest, recv: Option>, @@ -32,30 +23,21 @@ impl DatabaseCalculationTest { self.view_id.clone() } - pub async fn run_scripts(&mut self, scripts: Vec) { - for script in scripts { - self.run_script(script).await; - } + pub async fn insert_calculation(&mut self, payload: UpdateCalculationChangesetPB) { + self.recv = Some( + self + .editor + .subscribe_view_changed(&self.view_id()) + .await + .unwrap(), + ); + self.editor.update_calculation(payload).await.unwrap(); } - pub async fn run_script(&mut self, script: CalculationScript) { - match script { - CalculationScript::InsertCalculation { payload } => { - self.recv = Some( - self - .editor - .subscribe_view_changed(&self.view_id()) - .await - .unwrap(), - ); - self.editor.update_calculation(payload).await.unwrap(); - }, - CalculationScript::AssertCalculationValue { expected } => { - let calculations = self.editor.get_all_calculations(&self.view_id()).await; - let calculation = calculations.items.first().unwrap(); - assert_eq!(calculation.value, format!("{:.5}", expected)); - }, - } + pub async fn assert_calculation_value(&mut self, expected: f64) { + let calculations = self.editor.get_all_calculations(&self.view_id()).await; + let calculation = calculations.items.first().unwrap(); + assert_eq!(calculation.value, format!("{:.5}", expected)); } } diff --git a/frontend/rust-lib/flowy-database2/tests/database/cell_test/script.rs b/frontend/rust-lib/flowy-database2/tests/database/cell_test/script.rs index 833ce832b509..68b3ebe8ca26 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/cell_test/script.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/cell_test/script.rs @@ -1,19 +1,7 @@ +use crate::database::database_editor::DatabaseEditorTest; use collab_database::rows::RowId; - use lib_infra::box_any::BoxAny; -use crate::database::database_editor::DatabaseEditorTest; - -pub enum CellScript { - UpdateCell { - view_id: String, - field_id: String, - row_id: RowId, - changeset: BoxAny, - is_err: bool, - }, -} - pub struct DatabaseCellTest { inner: DatabaseEditorTest, } @@ -24,41 +12,18 @@ impl DatabaseCellTest { Self { inner } } - pub async fn run_scripts(&mut self, scripts: Vec) { - for script in scripts { - self.run_script(script).await; - } - } - - pub async fn run_script(&mut self, script: CellScript) { - // let grid_manager = self.sdk.grid_manager.clone(); - // let pool = self.sdk.user_session.db_pool().unwrap(); - // let rev_manager = self.editor.rev_manager(); - // let _cache = rev_manager.revision_cache().await; - - match script { - CellScript::UpdateCell { - view_id, - field_id, - row_id, - changeset, - is_err: _, - } => { - self - .editor - .update_cell_with_changeset(&view_id, &row_id, &field_id, changeset) - .await - .unwrap(); - }, - // CellScript::AssertGridRevisionPad => { - // sleep(Duration::from_millis(2 * REVISION_WRITE_INTERVAL_IN_MILLIS)).await; - // let mut grid_rev_manager = grid_manager - // .make_grid_rev_manager(&self.grid_id, pool.clone()) - // .unwrap(); - // let grid_pad = grid_rev_manager.load::(None).await.unwrap(); - // println!("{}", grid_pad.delta_str()); - // }, - } + pub async fn update_cell( + &self, + view_id: &str, + field_id: &str, + row_id: &RowId, + changeset: BoxAny, + ) { + self + .editor + .update_cell_with_changeset(view_id, row_id, field_id, changeset) + .await + .unwrap(); } } diff --git a/frontend/rust-lib/flowy-database2/tests/database/cell_test/test.rs b/frontend/rust-lib/flowy-database2/tests/database/cell_test/test.rs index 7cd6053f3a2e..e02b8c9d2c39 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/cell_test/test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/cell_test/test.rs @@ -1,4 +1,3 @@ -use crate::database::cell_test::script::CellScript::UpdateCell; use crate::database::cell_test::script::DatabaseCellTest; use collab_database::fields::date_type_option::DateCellData; use collab_database::fields::media_type_option::{MediaFile, MediaFileType, MediaUploadType}; @@ -14,11 +13,10 @@ use std::time::Duration; #[tokio::test] async fn grid_cell_update() { - let mut test = DatabaseCellTest::new().await; + let test = DatabaseCellTest::new().await; let fields = test.get_fields().await; let rows = &test.rows; - let mut scripts = vec![]; for row in rows.iter() { for field in &fields { let field_type = FieldType::from(field.field_type); @@ -74,17 +72,12 @@ async fn grid_cell_update() { _ => BoxAny::new("".to_string()), }; - scripts.push(UpdateCell { - view_id: test.view_id.clone(), - field_id: field.id.clone(), - row_id: row.id.clone(), - changeset: cell_changeset, - is_err: false, - }); + // Call the new `update_cell` function directly + test + .update_cell(&test.view_id, &field.id, &row.id, cell_changeset) + .await; } } - - test.run_scripts(scripts).await; } #[tokio::test] @@ -135,7 +128,7 @@ async fn url_cell_data_test() { #[tokio::test] async fn update_updated_at_field_on_other_cell_update() { - let mut test = DatabaseCellTest::new().await; + let test = DatabaseCellTest::new().await; let updated_at_field = test.get_first_field(FieldType::LastEditedTime).await; let text_field = test @@ -145,14 +138,15 @@ async fn update_updated_at_field_on_other_cell_update() { .unwrap(); let before_update_timestamp = chrono::offset::Utc::now().timestamp(); + + // Directly call the `update_cell` function test - .run_script(UpdateCell { - view_id: test.view_id.clone(), - row_id: test.rows[0].id.clone(), - field_id: text_field.id.clone(), - changeset: BoxAny::new("change".to_string()), - is_err: false, - }) + .update_cell( + &test.view_id, + &text_field.id, + &test.rows[0].id, + BoxAny::new("change".to_string()), + ) .await; let cells = test @@ -180,37 +174,12 @@ async fn update_updated_at_field_on_other_cell_update() { timestamp, after_update_timestamp ), - 1 => assert!( + _ => assert!( timestamp <= before_update_timestamp, "{} <= {}", timestamp, before_update_timestamp ), - 2 => assert!( - timestamp <= before_update_timestamp, - "{} <= {}", - timestamp, - before_update_timestamp - ), - 3 => assert!( - timestamp <= before_update_timestamp, - "{} <= {}", - timestamp, - before_update_timestamp - ), - 4 => assert!( - timestamp <= before_update_timestamp, - "{} <= {}", - timestamp, - before_update_timestamp - ), - 5 => assert!( - timestamp <= before_update_timestamp, - "{} <= {}", - timestamp, - before_update_timestamp - ), - _ => {}, } } } diff --git a/frontend/rust-lib/flowy-database2/tests/database/database_editor.rs b/frontend/rust-lib/flowy-database2/tests/database/database_editor.rs index 22c9c7a536de..86035191f833 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/database_editor.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/database_editor.rs @@ -111,6 +111,7 @@ impl DatabaseEditorTest { self.editor.open_database_view(view_id, None).await.unwrap() } + #[allow(dead_code)] pub async fn database_filters(&self) -> Vec { self.editor.get_all_filters(&self.view_id).await.items } diff --git a/frontend/rust-lib/flowy-database2/tests/database/field_settings_test/script.rs b/frontend/rust-lib/flowy-database2/tests/database/field_settings_test/script.rs index b87684163b95..c6755ef009bd 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/field_settings_test/script.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/field_settings_test/script.rs @@ -1,79 +1,102 @@ -use flowy_database2::entities::{FieldSettingsChangesetPB, FieldVisibility}; - use crate::database::database_editor::DatabaseEditorTest; +use collab_database::fields::{Field, TypeOptionData}; +use flowy_database2::entities::{CreateFieldParams, FieldChangesetPB, FieldType}; +use flowy_database2::services::cell::stringify_cell; -pub struct FieldSettingsTest { +pub struct DatabaseFieldTest { inner: DatabaseEditorTest, } -impl FieldSettingsTest { - pub async fn new_grid() -> Self { - let inner = DatabaseEditorTest::new_grid().await; - Self { inner } +impl DatabaseFieldTest { + pub async fn new() -> Self { + let editor_test = DatabaseEditorTest::new_grid().await; + Self { inner: editor_test } + } + + pub fn view_id(&self) -> String { + self.view_id.clone() } - pub async fn new_board() -> Self { - let inner = DatabaseEditorTest::new_board().await; - Self { inner } + pub fn field_count(&self) -> usize { + self.field_count } - pub async fn new_calendar() -> Self { - let inner = DatabaseEditorTest::new_calendar().await; - Self { inner } + pub async fn create_field(&mut self, params: CreateFieldParams) { + self.field_count += 1; + let _ = self.editor.create_field_with_type_option(params).await; + let fields = self.editor.get_fields(&self.view_id, None).await; + assert_eq!(self.field_count, fields.len()); } - pub async fn assert_field_settings( + pub async fn update_field(&mut self, changeset: FieldChangesetPB) { + self.editor.update_field(changeset).await.unwrap(); + } + + pub async fn delete_field(&mut self, field: Field) { + if self.editor.get_field(&field.id).await.is_some() { + self.field_count -= 1; + } + + self.editor.delete_field(&field.id).await.unwrap(); + let fields = self.editor.get_fields(&self.view_id, None).await; + assert_eq!(self.field_count, fields.len()); + } + + pub async fn switch_to_field( &mut self, - field_ids: Vec, - visibility: FieldVisibility, - width: i32, + view_id: String, + field_id: String, + new_field_type: FieldType, ) { - let field_settings = self + self .editor - .get_field_settings(&self.view_id, field_ids) + .switch_to_field_type(&view_id, &field_id, new_field_type, None) .await .unwrap(); - - for field_setting in field_settings { - assert_eq!(field_setting.width, width); - assert_eq!(field_setting.visibility, visibility); - } } - pub async fn assert_all_field_settings(&mut self, visibility: FieldVisibility, width: i32) { - let field_settings = self + pub async fn update_type_option(&mut self, field_id: String, type_option: TypeOptionData) { + let old_field = self.editor.get_field(&field_id).await.unwrap(); + self .editor - .get_all_field_settings(&self.view_id) + .update_field_type_option(&field_id, type_option, old_field) .await .unwrap(); + } - for field_setting in field_settings { - assert_eq!(field_setting.width, width); - assert_eq!(field_setting.visibility, visibility); - } + pub async fn assert_field_count(&self, count: usize) { + assert_eq!(self.get_fields().await.len(), count); } - pub async fn update_field_settings( - &mut self, + pub async fn assert_field_type_option_equal( + &self, + field_index: usize, + expected_type_option_data: TypeOptionData, + ) { + let fields = self.get_fields().await; + let field = &fields[field_index]; + let type_option_data = field.get_any_type_option(field.field_type).unwrap(); + assert_eq!(type_option_data, expected_type_option_data); + } + + pub async fn assert_cell_content( + &self, field_id: String, - visibility: Option, - width: Option, + row_index: usize, + expected_content: String, ) { - let params = FieldSettingsChangesetPB { - view_id: self.view_id.clone(), - field_id, - visibility, - width, - wrap_cell_content: None, - }; - let _ = self - .editor - .update_field_settings_with_changeset(params) - .await; + let field = self.editor.get_field(&field_id).await.unwrap(); + + let rows = self.editor.get_all_rows(&self.view_id()).await.unwrap(); + let row = rows.get(row_index).unwrap(); + + let cell = row.cells.get(&field_id).unwrap().clone(); + let content = stringify_cell(&cell, &field); + assert_eq!(content, expected_content); } } -impl std::ops::Deref for FieldSettingsTest { +impl std::ops::Deref for DatabaseFieldTest { type Target = DatabaseEditorTest; fn deref(&self) -> &Self::Target { @@ -81,7 +104,7 @@ impl std::ops::Deref for FieldSettingsTest { } } -impl std::ops::DerefMut for FieldSettingsTest { +impl std::ops::DerefMut for DatabaseFieldTest { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.inner } diff --git a/frontend/rust-lib/flowy-database2/tests/database/field_settings_test/test.rs b/frontend/rust-lib/flowy-database2/tests/database/field_settings_test/test.rs index a378f4d90e9e..ec2f188be828 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/field_settings_test/test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/field_settings_test/test.rs @@ -1,122 +1,253 @@ -use flowy_database2::entities::FieldType; -use flowy_database2::entities::FieldVisibility; -use flowy_database2::services::field_settings::DEFAULT_WIDTH; +use crate::database::field_settings_test::script::DatabaseFieldTest; +use crate::database::field_test::util::*; +use collab_database::database::gen_option_id; +use collab_database::fields::select_type_option::SingleSelectTypeOption; +use collab_database::fields::select_type_option::{SelectOption, SelectTypeOption}; +use flowy_database2::entities::{FieldChangesetPB, FieldType}; +use flowy_database2::services::field::{CHECK, UNCHECK}; -use crate::database::field_settings_test::script::FieldSettingsTest; - -/// Check default field settings for grid, kanban and calendar #[tokio::test] -async fn get_default_grid_field_settings() { - // grid - let mut test = FieldSettingsTest::new_grid().await; +async fn grid_create_field() { + let mut test = DatabaseFieldTest::new().await; + + // Create and assert a text field + let (params, field) = create_text_field(&test.view_id()); + test.create_field(params).await; test - .assert_all_field_settings(FieldVisibility::AlwaysShown, DEFAULT_WIDTH) + .assert_field_type_option_equal( + test.field_count() - 1, + field.get_any_type_option(field.field_type).unwrap(), + ) .await; -} -#[tokio::test] -async fn get_default_board_field_settings() { - // board - let mut test = FieldSettingsTest::new_board().await; - let non_primary_field_ids: Vec = test - .get_fields() - .await - .into_iter() - .filter(|field| !field.is_primary) - .map(|field| field.id) - .collect(); - let primary_field_id = test.get_first_field(FieldType::RichText).await.id; - test - .assert_field_settings( - non_primary_field_ids.clone(), - FieldVisibility::HideWhenEmpty, - DEFAULT_WIDTH, + // Create and assert a single select field + let (params, field) = create_single_select_field(&test.view_id()); + test.create_field(params).await; + test + .assert_field_type_option_equal( + test.field_count() - 1, + field.get_any_type_option(field.field_type).unwrap(), + ) + .await; + + // Create and assert a timestamp field + let (params, field) = create_timestamp_field(&test.view_id(), FieldType::CreatedTime); + test.create_field(params).await; + test + .assert_field_type_option_equal( + test.field_count() - 1, + field.get_any_type_option(field.field_type).unwrap(), ) .await; + + // Create and assert a time field + let (params, field) = create_time_field(&test.view_id()); + test.create_field(params).await; test - .assert_field_settings( - vec![primary_field_id.clone()], - FieldVisibility::AlwaysShown, - DEFAULT_WIDTH, + .assert_field_type_option_equal( + test.field_count() - 1, + field.get_any_type_option(field.field_type).unwrap(), ) .await; } #[tokio::test] -async fn get_default_calendar_field_settings() { - // calendar - let mut test = FieldSettingsTest::new_calendar().await; - let non_primary_field_ids: Vec = test - .get_fields() - .await - .into_iter() - .filter(|field| !field.is_primary) - .map(|field| field.id) - .collect(); - let primary_field_id = test.get_first_field(FieldType::RichText).await.id; - test - .assert_field_settings( - non_primary_field_ids.clone(), - FieldVisibility::HideWhenEmpty, - DEFAULT_WIDTH, +async fn grid_create_duplicate_field() { + let mut test = DatabaseFieldTest::new().await; + let (params, _) = create_text_field(&test.view_id()); + let field_count = test.field_count(); + let expected_field_count = field_count + 1; + + test.create_field(params.clone()).await; + test.assert_field_count(expected_field_count).await; +} + +#[tokio::test] +async fn grid_update_field_with_empty_change() { + let mut test = DatabaseFieldTest::new().await; + let (params, _) = create_single_select_field(&test.view_id()); + let create_field_index = test.field_count(); + test.create_field(params).await; + + let field = test.get_fields().await.pop().unwrap().clone(); + let changeset = FieldChangesetPB { + field_id: field.id.clone(), + view_id: test.view_id(), + ..Default::default() + }; + + test.update_field(changeset).await; + test + .assert_field_type_option_equal( + create_field_index, + field.get_any_type_option(field.field_type).unwrap(), ) .await; +} + +#[tokio::test] +async fn grid_delete_field() { + let mut test = DatabaseFieldTest::new().await; + let original_field_count = test.field_count(); + let (params, _) = create_text_field(&test.view_id()); + test.create_field(params).await; + + let field = test.get_fields().await.pop().unwrap(); + test.delete_field(field).await; + test.assert_field_count(original_field_count).await; +} + +#[tokio::test] +async fn grid_switch_from_select_option_to_checkbox_test() { + let mut test = DatabaseFieldTest::new().await; + let field = test.get_first_field(FieldType::SingleSelect).await; + let view_id = test.view_id(); + + // Update the type option data of the single select option + let mut options = test.get_single_select_type_option(&field.id).await; + options.clear(); + options.push(SelectOption { + id: gen_option_id(), + name: CHECK.to_string(), + color: Default::default(), + }); + options.push(SelectOption { + id: gen_option_id(), + name: UNCHECK.to_string(), + color: Default::default(), + }); + test - .assert_field_settings( - vec![primary_field_id.clone()], - FieldVisibility::AlwaysShown, - DEFAULT_WIDTH, + .update_type_option( + field.id.clone(), + SingleSelectTypeOption(SelectTypeOption { + options, + disable_color: false, + }) + .into(), ) .await; + + // Switch to checkbox field + test + .switch_to_field(view_id, field.id.clone(), FieldType::Checkbox) + .await; } -/// Update field settings for a field #[tokio::test] -async fn update_field_settings_test() { - let mut test = FieldSettingsTest::new_board().await; - let non_primary_field_ids: Vec = test - .get_fields() - .await - .into_iter() - .filter(|field| !field.is_primary) - .map(|field| field.id) - .collect(); - let primary_field_id = test.get_first_field(FieldType::RichText).await.id; - - test - .assert_field_settings( - non_primary_field_ids.clone(), - FieldVisibility::HideWhenEmpty, - DEFAULT_WIDTH, +async fn grid_switch_from_checkbox_to_select_option_test() { + let mut test = DatabaseFieldTest::new().await; + let checkbox_field = test.get_first_field(FieldType::Checkbox).await.clone(); + + // Switch to single-select field + test + .switch_to_field( + test.view_id(), + checkbox_field.id.clone(), + FieldType::SingleSelect, ) .await; + + // Assert cell content after switching the field type test - .assert_field_settings( - vec![primary_field_id.clone()], - FieldVisibility::AlwaysShown, - DEFAULT_WIDTH, + .assert_cell_content( + checkbox_field.id.clone(), + 1, // row_index + CHECK.to_string(), // expected content ) .await; + // Check that the options contain both "CHECK" and "UNCHECK" + let options = test.get_single_select_type_option(&checkbox_field.id).await; + assert_eq!(options.len(), 2); + assert!(options.iter().any(|option| option.name == UNCHECK)); + assert!(options.iter().any(|option| option.name == CHECK)); +} + +#[tokio::test] +async fn grid_switch_from_multi_select_to_text_test() { + let mut test = DatabaseFieldTest::new().await; + let field_rev = test.get_first_field(FieldType::MultiSelect).await.clone(); + let multi_select_type_option = test.get_multi_select_type_option(&field_rev.id).await; + test - .update_field_settings( - primary_field_id.clone(), - Some(FieldVisibility::HideWhenEmpty), - None, - ) + .switch_to_field(test.view_id(), field_rev.id.clone(), FieldType::RichText) .await; + test - .assert_field_settings( - non_primary_field_ids.clone(), - FieldVisibility::HideWhenEmpty, - DEFAULT_WIDTH, + .assert_cell_content( + field_rev.id.clone(), + 0, // row_index + format!( + "{},{}", + multi_select_type_option.first().unwrap().name, + multi_select_type_option.get(1).unwrap().name + ), ) .await; +} + +#[tokio::test] +async fn grid_switch_from_checkbox_to_text_test() { + let mut test = DatabaseFieldTest::new().await; + let field_rev = test.get_first_field(FieldType::Checkbox).await; + + test + .switch_to_field(test.view_id(), field_rev.id.clone(), FieldType::RichText) + .await; + test - .assert_field_settings( - vec![primary_field_id.clone()], - FieldVisibility::HideWhenEmpty, - DEFAULT_WIDTH, - ) + .assert_cell_content(field_rev.id.clone(), 1, "Yes".to_string()) + .await; + test + .assert_cell_content(field_rev.id.clone(), 2, "No".to_string()) + .await; +} + +#[tokio::test] +async fn grid_switch_from_date_to_text_test() { + let mut test = DatabaseFieldTest::new().await; + let field = test.get_first_field(FieldType::DateTime).await.clone(); + + test + .switch_to_field(test.view_id(), field.id.clone(), FieldType::RichText) + .await; + + test + .assert_cell_content(field.id.clone(), 2, "2022/03/14".to_string()) + .await; + test + .assert_cell_content(field.id.clone(), 3, "2022/11/17".to_string()) + .await; +} + +#[tokio::test] +async fn grid_switch_from_number_to_text_test() { + let mut test = DatabaseFieldTest::new().await; + let field = test.get_first_field(FieldType::Number).await.clone(); + + test + .switch_to_field(test.view_id(), field.id.clone(), FieldType::RichText) + .await; + + test + .assert_cell_content(field.id.clone(), 0, "$1".to_string()) + .await; + test + .assert_cell_content(field.id.clone(), 4, "".to_string()) + .await; +} + +#[tokio::test] +async fn grid_switch_from_checklist_to_text_test() { + let mut test = DatabaseFieldTest::new().await; + let field_rev = test.get_first_field(FieldType::Checklist).await; + + test + .switch_to_field(test.view_id(), field_rev.id.clone(), FieldType::RichText) + .await; + + test + .assert_cell_content(field_rev.id.clone(), 0, "First thing".to_string()) .await; } diff --git a/frontend/rust-lib/flowy-database2/tests/database/field_test/script.rs b/frontend/rust-lib/flowy-database2/tests/database/field_test/script.rs index c61355fcbb4b..c6755ef009bd 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/field_test/script.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/field_test/script.rs @@ -1,41 +1,8 @@ +use crate::database::database_editor::DatabaseEditorTest; use collab_database::fields::{Field, TypeOptionData}; - use flowy_database2::entities::{CreateFieldParams, FieldChangesetPB, FieldType}; use flowy_database2::services::cell::stringify_cell; -use crate::database::database_editor::DatabaseEditorTest; - -pub enum FieldScript { - CreateField { - params: CreateFieldParams, - }, - UpdateField { - changeset: FieldChangesetPB, - }, - DeleteField { - field: Field, - }, - SwitchToField { - view_id: String, - field_id: String, - new_field_type: FieldType, - }, - UpdateTypeOption { - field_id: String, - type_option: TypeOptionData, - }, - AssertFieldCount(usize), - AssertFieldTypeOptionEqual { - field_index: usize, - expected_type_option_data: TypeOptionData, - }, - AssertCellContent { - field_id: String, - row_index: usize, - expected_content: String, - }, -} - pub struct DatabaseFieldTest { inner: DatabaseEditorTest, } @@ -54,83 +21,78 @@ impl DatabaseFieldTest { self.field_count } - pub async fn run_scripts(&mut self, scripts: Vec) { - for script in scripts { - self.run_script(script).await; - } + pub async fn create_field(&mut self, params: CreateFieldParams) { + self.field_count += 1; + let _ = self.editor.create_field_with_type_option(params).await; + let fields = self.editor.get_fields(&self.view_id, None).await; + assert_eq!(self.field_count, fields.len()); + } + + pub async fn update_field(&mut self, changeset: FieldChangesetPB) { + self.editor.update_field(changeset).await.unwrap(); } - pub async fn run_script(&mut self, script: FieldScript) { - match script { - FieldScript::CreateField { params } => { - self.field_count += 1; - let _ = self.editor.create_field_with_type_option(params).await; - let fields = self.editor.get_fields(&self.view_id, None).await; - assert_eq!(self.field_count, fields.len()); - }, - FieldScript::UpdateField { changeset: change } => { - self.editor.update_field(change).await.unwrap(); - }, - FieldScript::DeleteField { field } => { - if self.editor.get_field(&field.id).await.is_some() { - self.field_count -= 1; - } - - self.editor.delete_field(&field.id).await.unwrap(); - let fields = self.editor.get_fields(&self.view_id, None).await; - assert_eq!(self.field_count, fields.len()); - }, - FieldScript::SwitchToField { - view_id, - field_id, - new_field_type, - } => { - // - self - .editor - .switch_to_field_type(&view_id, &field_id, new_field_type, None) - .await - .unwrap(); - }, - FieldScript::UpdateTypeOption { - field_id, - type_option, - } => { - // - let old_field = self.editor.get_field(&field_id).await.unwrap(); - self - .editor - .update_field_type_option(&field_id, type_option, old_field) - .await - .unwrap(); - }, - FieldScript::AssertFieldCount(count) => { - assert_eq!(self.get_fields().await.len(), count); - }, - FieldScript::AssertFieldTypeOptionEqual { - field_index, - expected_type_option_data, - } => { - let fields = self.get_fields().await; - let field = &fields[field_index]; - let type_option_data = field.get_any_type_option(field.field_type).unwrap(); - assert_eq!(type_option_data, expected_type_option_data); - }, - FieldScript::AssertCellContent { - field_id, - row_index, - expected_content, - } => { - let field = self.editor.get_field(&field_id).await.unwrap(); - - let rows = self.editor.get_all_rows(&self.view_id()).await.unwrap(); - let row = rows.get(row_index).unwrap(); - - let cell = row.cells.get(&field_id).unwrap().clone(); - let content = stringify_cell(&cell, &field); - assert_eq!(content, expected_content); - }, + pub async fn delete_field(&mut self, field: Field) { + if self.editor.get_field(&field.id).await.is_some() { + self.field_count -= 1; } + + self.editor.delete_field(&field.id).await.unwrap(); + let fields = self.editor.get_fields(&self.view_id, None).await; + assert_eq!(self.field_count, fields.len()); + } + + pub async fn switch_to_field( + &mut self, + view_id: String, + field_id: String, + new_field_type: FieldType, + ) { + self + .editor + .switch_to_field_type(&view_id, &field_id, new_field_type, None) + .await + .unwrap(); + } + + pub async fn update_type_option(&mut self, field_id: String, type_option: TypeOptionData) { + let old_field = self.editor.get_field(&field_id).await.unwrap(); + self + .editor + .update_field_type_option(&field_id, type_option, old_field) + .await + .unwrap(); + } + + pub async fn assert_field_count(&self, count: usize) { + assert_eq!(self.get_fields().await.len(), count); + } + + pub async fn assert_field_type_option_equal( + &self, + field_index: usize, + expected_type_option_data: TypeOptionData, + ) { + let fields = self.get_fields().await; + let field = &fields[field_index]; + let type_option_data = field.get_any_type_option(field.field_type).unwrap(); + assert_eq!(type_option_data, expected_type_option_data); + } + + pub async fn assert_cell_content( + &self, + field_id: String, + row_index: usize, + expected_content: String, + ) { + let field = self.editor.get_field(&field_id).await.unwrap(); + + let rows = self.editor.get_all_rows(&self.view_id()).await.unwrap(); + let row = rows.get(row_index).unwrap(); + + let cell = row.cells.get(&field_id).unwrap().clone(); + let content = stringify_cell(&cell, &field); + assert_eq!(content, expected_content); } } diff --git a/frontend/rust-lib/flowy-database2/tests/database/field_test/test.rs b/frontend/rust-lib/flowy-database2/tests/database/field_test/test.rs index 25f8341d77bf..488ae4d57722 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/field_test/test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/field_test/test.rs @@ -4,63 +4,52 @@ use flowy_database2::entities::{FieldChangesetPB, FieldType}; use flowy_database2::services::field::{CHECK, UNCHECK}; use crate::database::field_test::script::DatabaseFieldTest; -use crate::database::field_test::script::FieldScript::*; use crate::database::field_test::util::*; use collab_database::fields::select_type_option::SingleSelectTypeOption; #[tokio::test] async fn grid_create_field() { let mut test = DatabaseFieldTest::new().await; - let (params, field) = create_text_field(&test.view_id()); - - let scripts = vec![ - CreateField { params }, - AssertFieldTypeOptionEqual { - field_index: test.field_count(), - expected_type_option_data: field.get_any_type_option(field.field_type).unwrap(), - }, - ]; - test.run_scripts(scripts).await; + // Create and assert text field + let (params, field) = create_text_field(&test.view_id()); + test.create_field(params).await; + test + .assert_field_type_option_equal( + test.field_count() - 1, + field.get_any_type_option(field.field_type).unwrap(), + ) + .await; + + // Create and assert single select field let (params, field) = create_single_select_field(&test.view_id()); - let scripts = vec![ - CreateField { params }, - AssertFieldTypeOptionEqual { - field_index: test.field_count(), - expected_type_option_data: field.get_any_type_option(field.field_type).unwrap(), - }, - ]; - test.run_scripts(scripts).await; - + test.create_field(params).await; + test + .assert_field_type_option_equal( + test.field_count() - 1, + field.get_any_type_option(field.field_type).unwrap(), + ) + .await; + + // Create and assert timestamp field let (params, field) = create_timestamp_field(&test.view_id(), FieldType::CreatedTime); - let scripts = vec![ - CreateField { params }, - AssertFieldTypeOptionEqual { - field_index: test.field_count(), - expected_type_option_data: field.get_any_type_option(field.field_type).unwrap(), - }, - ]; - test.run_scripts(scripts).await; - + test.create_field(params).await; + test + .assert_field_type_option_equal( + test.field_count() - 1, + field.get_any_type_option(field.field_type).unwrap(), + ) + .await; + + // Create and assert time field let (params, field) = create_time_field(&test.view_id()); - let scripts = vec![ - CreateField { params }, - AssertFieldTypeOptionEqual { - field_index: test.field_count(), - expected_type_option_data: field.get_any_type_option(field.field_type).unwrap(), - }, - ]; - test.run_scripts(scripts).await; - - let (params, field) = create_time_field(&test.view_id()); - let scripts = vec![ - CreateField { params }, - AssertFieldTypeOptionEqual { - field_index: test.field_count(), - expected_type_option_data: field.get_any_type_option(field.field_type).unwrap(), - }, - ]; - test.run_scripts(scripts).await; + test.create_field(params).await; + test + .assert_field_type_option_equal( + test.field_count() - 1, + field.get_any_type_option(field.field_type).unwrap(), + ) + .await; } #[tokio::test] @@ -69,13 +58,9 @@ async fn grid_create_duplicate_field() { let (params, _) = create_text_field(&test.view_id()); let field_count = test.field_count(); let expected_field_count = field_count + 1; - let scripts = vec![ - CreateField { - params: params.clone(), - }, - AssertFieldCount(expected_field_count), - ]; - test.run_scripts(scripts).await; + + test.create_field(params.clone()).await; + test.assert_field_count(expected_field_count).await; } #[tokio::test] @@ -83,8 +68,8 @@ async fn grid_update_field_with_empty_change() { let mut test = DatabaseFieldTest::new().await; let (params, _) = create_single_select_field(&test.view_id()); let create_field_index = test.field_count(); - let scripts = vec![CreateField { params }]; - test.run_scripts(scripts).await; + + test.create_field(params).await; let field = test.get_fields().await.pop().unwrap().clone(); let changeset = FieldChangesetPB { @@ -93,14 +78,13 @@ async fn grid_update_field_with_empty_change() { ..Default::default() }; - let scripts = vec![ - UpdateField { changeset }, - AssertFieldTypeOptionEqual { - field_index: create_field_index, - expected_type_option_data: field.get_any_type_option(field.field_type).unwrap(), - }, - ]; - test.run_scripts(scripts).await; + test.update_field(changeset).await; + test + .assert_field_type_option_equal( + create_field_index, + field.get_any_type_option(field.field_type).unwrap(), + ) + .await; } #[tokio::test] @@ -108,15 +92,12 @@ async fn grid_delete_field() { let mut test = DatabaseFieldTest::new().await; let original_field_count = test.field_count(); let (params, _) = create_text_field(&test.view_id()); - let scripts = vec![CreateField { params }]; - test.run_scripts(scripts).await; + + test.create_field(params).await; let field = test.get_fields().await.pop().unwrap(); - let scripts = vec![ - DeleteField { field }, - AssertFieldCount(original_field_count), - ]; - test.run_scripts(scripts).await; + test.delete_field(field).await; + test.assert_field_count(original_field_count).await; } #[tokio::test] @@ -128,73 +109,64 @@ async fn grid_switch_from_select_option_to_checkbox_test() { // Update the type option data of single select option let mut options = test.get_single_select_type_option(&field.id).await; options.clear(); - // Add a new option with name CHECK options.push(SelectOption { id: gen_option_id(), name: CHECK.to_string(), color: Default::default(), }); - // Add a new option with name UNCHECK options.push(SelectOption { id: gen_option_id(), name: UNCHECK.to_string(), color: Default::default(), }); - let scripts = vec![ - UpdateTypeOption { - field_id: field.id.clone(), - type_option: SingleSelectTypeOption(SelectTypeOption { + test + .update_type_option( + field.id.clone(), + SingleSelectTypeOption(SelectTypeOption { options, disable_color: false, }) .into(), - }, - SwitchToField { - view_id: view_id.clone(), - field_id: field.id.clone(), - new_field_type: FieldType::Checkbox, - }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + // Switch to checkbox field + test + .switch_to_field(view_id, field.id.clone(), FieldType::Checkbox) + .await; } #[tokio::test] async fn grid_switch_from_checkbox_to_select_option_test() { let mut test = DatabaseFieldTest::new().await; let checkbox_field = test.get_first_field(FieldType::Checkbox).await.clone(); - let scripts = vec![ - // switch to single-select field type - SwitchToField { - view_id: test.view_id(), - field_id: checkbox_field.id.clone(), - new_field_type: FieldType::SingleSelect, - }, - // Assert the cell content after switch the field type. The cell content will be changed if - // the FieldType::SingleSelect implement the cell data TypeOptionTransform. Check out the - // TypeOptionTransform trait for more information. - // - // Make sure which cell of the row you want to check. - AssertCellContent { - field_id: checkbox_field.id.clone(), - // the mock data of the checkbox with row_index one is "true" - row_index: 1, - // The content of the checkbox should transform to the corresponding option name. - expected_content: CHECK.to_string(), - }, - ]; - test.run_scripts(scripts).await; + // Switch to single-select field + test + .switch_to_field( + test.view_id(), + checkbox_field.id.clone(), + FieldType::SingleSelect, + ) + .await; + + // Assert cell content after switching the field type + test + .assert_cell_content( + checkbox_field.id.clone(), + 1, // row_index + CHECK.to_string(), // expected content + ) + .await; + + // Check that the options contain both "CHECK" and "UNCHECK" let options = test.get_single_select_type_option(&checkbox_field.id).await; assert_eq!(options.len(), 2); assert!(options.iter().any(|option| option.name == UNCHECK)); assert!(options.iter().any(|option| option.name == CHECK)); } -// Test when switching the current field from Multi-select to Text test -// The build-in test data is located in `make_test_grid` method(flowy-database/tests/grid_editor.rs). -// input: -// option1, option2 -> "option1.name, option2.name" #[tokio::test] async fn grid_switch_from_multi_select_to_text_test() { let mut test = DatabaseFieldTest::new().await; @@ -202,129 +174,84 @@ async fn grid_switch_from_multi_select_to_text_test() { let multi_select_type_option = test.get_multi_select_type_option(&field_rev.id).await; - let script_switch_field = vec![SwitchToField { - view_id: test.view_id(), - field_id: field_rev.id.clone(), - new_field_type: FieldType::RichText, - }]; - - test.run_scripts(script_switch_field).await; - - let script_assert_field = vec![AssertCellContent { - field_id: field_rev.id.clone(), - row_index: 0, - expected_content: format!( - "{},{}", - multi_select_type_option.first().unwrap().name, - multi_select_type_option.get(1).unwrap().name - ), - }]; - - test.run_scripts(script_assert_field).await; + test + .switch_to_field(test.view_id(), field_rev.id.clone(), FieldType::RichText) + .await; + + test + .assert_cell_content( + field_rev.id.clone(), + 0, // row_index + format!( + "{},{}", + multi_select_type_option.first().unwrap().name, + multi_select_type_option.get(1).unwrap().name + ), + ) + .await; } -// Test when switching the current field from Checkbox to Text test -// input: -// check -> "Yes" -// unchecked -> "No" #[tokio::test] async fn grid_switch_from_checkbox_to_text_test() { let mut test = DatabaseFieldTest::new().await; let field_rev = test.get_first_field(FieldType::Checkbox).await; - let scripts = vec![ - SwitchToField { - view_id: test.view_id(), - field_id: field_rev.id.clone(), - new_field_type: FieldType::RichText, - }, - AssertCellContent { - field_id: field_rev.id.clone(), - row_index: 1, - expected_content: "Yes".to_string(), - }, - AssertCellContent { - field_id: field_rev.id.clone(), - row_index: 2, - expected_content: "No".to_string(), - }, - ]; - test.run_scripts(scripts).await; + test + .switch_to_field(test.view_id(), field_rev.id.clone(), FieldType::RichText) + .await; + + test + .assert_cell_content(field_rev.id.clone(), 1, "Yes".to_string()) + .await; + test + .assert_cell_content(field_rev.id.clone(), 2, "No".to_string()) + .await; } -// Test when switching the current field from Date to Text test -// input: -// 1647251762 -> Mar 14,2022 (This string will be different base on current data setting) #[tokio::test] async fn grid_switch_from_date_to_text_test() { let mut test = DatabaseFieldTest::new().await; let field = test.get_first_field(FieldType::DateTime).await.clone(); - let scripts = vec![ - SwitchToField { - view_id: test.view_id(), - field_id: field.id.clone(), - new_field_type: FieldType::RichText, - }, - AssertCellContent { - field_id: field.id.clone(), - row_index: 2, - expected_content: "2022/03/14".to_string(), - }, - AssertCellContent { - field_id: field.id.clone(), - row_index: 3, - expected_content: "2022/11/17".to_string(), - }, - ]; - test.run_scripts(scripts).await; + + test + .switch_to_field(test.view_id(), field.id.clone(), FieldType::RichText) + .await; + + test + .assert_cell_content(field.id.clone(), 2, "2022/03/14".to_string()) + .await; + test + .assert_cell_content(field.id.clone(), 3, "2022/11/17".to_string()) + .await; } -// Test when switching the current field from Number to Text test -// input: -// $1 -> "$1"(This string will be different base on current data setting) #[tokio::test] async fn grid_switch_from_number_to_text_test() { let mut test = DatabaseFieldTest::new().await; let field = test.get_first_field(FieldType::Number).await.clone(); - let scripts = vec![ - SwitchToField { - view_id: test.view_id(), - field_id: field.id.clone(), - new_field_type: FieldType::RichText, - }, - AssertCellContent { - field_id: field.id.clone(), - row_index: 0, - expected_content: "$1".to_string(), - }, - AssertCellContent { - field_id: field.id.clone(), - row_index: 4, - expected_content: "".to_string(), - }, - ]; - - test.run_scripts(scripts).await; + test + .switch_to_field(test.view_id(), field.id.clone(), FieldType::RichText) + .await; + + test + .assert_cell_content(field.id.clone(), 0, "$1".to_string()) + .await; + test + .assert_cell_content(field.id.clone(), 4, "".to_string()) + .await; } -/// Test when switching the current field from Checklist to Text test #[tokio::test] async fn grid_switch_from_checklist_to_text_test() { let mut test = DatabaseFieldTest::new().await; let field_rev = test.get_first_field(FieldType::Checklist).await; - let scripts = vec![ - SwitchToField { - view_id: test.view_id(), - field_id: field_rev.id.clone(), - new_field_type: FieldType::RichText, - }, - AssertCellContent { - field_id: field_rev.id.clone(), - row_index: 0, - expected_content: "First thing".to_string(), - }, - ]; - test.run_scripts(scripts).await; + test + .switch_to_field(test.view_id(), field_rev.id.clone(), FieldType::RichText) + .await; + + test + .assert_cell_content(field_rev.id.clone(), 0, "First thing".to_string()) + .await; } diff --git a/frontend/rust-lib/flowy-database2/tests/database/filter_test/advanced_filter_test.rs b/frontend/rust-lib/flowy-database2/tests/database/filter_test/advanced_filter_test.rs index 6e3db58723f4..d077b4c61f95 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/filter_test/advanced_filter_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/filter_test/advanced_filter_test.rs @@ -1,3 +1,4 @@ +use crate::database::filter_test::script::{DatabaseFilterTest, FilterRowChanged}; use bytes::Bytes; use flowy_database2::entities::{ CheckboxFilterConditionPB, CheckboxFilterPB, DateFilterConditionPB, DateFilterPB, FieldType, @@ -7,8 +8,6 @@ use lib_infra::box_any::BoxAny; use protobuf::ProtobufError; use std::convert::TryInto; -use crate::database::filter_test::script::{DatabaseFilterTest, FilterRowChanged, FilterScript::*}; - /// Create a single advanced filter: /// /// 1. Add an OR filter @@ -40,72 +39,69 @@ async fn create_advanced_filter_test() { } }; - let scripts = vec![ - CreateOrFilter { - parent_filter_id: None, - changed: None, - }, - Wait { millisecond: 100 }, - AssertFilters { - expected: vec![FilterPB { - id: "".to_string(), - filter_type: FilterType::Or, - children: vec![], - data: None, - }], - }, - ]; - test.run_scripts(scripts).await; - // OR + // Create OR Filter + test.create_or_filter(None, None).await; + test.wait(100).await; + + test + .assert_filters(vec![FilterPB { + id: "".to_string(), + filter_type: FilterType::Or, + children: vec![], + data: None, + }]) + .await; let or_filter = test.get_filter(FilterType::Or, None).await.unwrap(); + let checkbox_filter_bytes: Result = create_checkbox_filter().try_into(); let checkbox_filter_bytes = checkbox_filter_bytes.unwrap().to_vec(); - let scripts = vec![ - CreateDataFilter { - parent_filter_id: Some(or_filter.id.clone()), - field_type: FieldType::Checkbox, - data: BoxAny::new(create_checkbox_filter()), - changed: Some(FilterRowChanged { + // Create Checkbox Filter and AND Filter + test + .create_data_filter( + Some(or_filter.id.clone()), + FieldType::Checkbox, + BoxAny::new(create_checkbox_filter()), + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: 4, }), - }, - CreateAndFilter { - parent_filter_id: Some(or_filter.id), - changed: None, - }, - Wait { millisecond: 100 }, - AssertFilters { - expected: vec![FilterPB { - id: "".to_string(), - filter_type: FilterType::Or, - children: vec![ - FilterPB { - id: "".to_string(), - filter_type: FilterType::Data, - children: vec![], - data: Some(FilterDataPB { - field_id: "".to_string(), - field_type: FieldType::Checkbox, - data: checkbox_filter_bytes.clone(), - }), - }, - FilterPB { - id: "".to_string(), - filter_type: FilterType::And, - children: vec![], - data: None, - }, - ], - data: None, - }], - }, - AssertNumberOfVisibleRows { expected: 3 }, - ]; - test.run_scripts(scripts).await; - // IS_CHECK OR AND + ) + .await; + + test + .create_and_filter(Some(or_filter.id.clone()), None) + .await; + test.wait(100).await; + + test + .assert_filters(vec![FilterPB { + id: "".to_string(), + filter_type: FilterType::Or, + children: vec![ + FilterPB { + id: "".to_string(), + filter_type: FilterType::Data, + children: vec![], + data: Some(FilterDataPB { + field_id: "".to_string(), + field_type: FieldType::Checkbox, + data: checkbox_filter_bytes.clone(), + }), + }, + FilterPB { + id: "".to_string(), + filter_type: FilterType::And, + children: vec![], + data: None, + }, + ], + data: None, + }]) + .await; + + test.assert_number_of_visible_rows(3).await; let and_filter = test.get_filter(FilterType::And, None).await.unwrap(); @@ -114,70 +110,75 @@ async fn create_advanced_filter_test() { let number_filter_bytes: Result = create_number_filter().try_into(); let number_filter_bytes = number_filter_bytes.unwrap().to_vec(); - let scripts = vec![ - CreateDataFilter { - parent_filter_id: Some(and_filter.id.clone()), - field_type: FieldType::DateTime, - data: BoxAny::new(create_date_filter()), - changed: None, - }, - CreateDataFilter { - parent_filter_id: Some(and_filter.id), - field_type: FieldType::Number, - data: BoxAny::new(create_number_filter()), - changed: None, - }, - Wait { millisecond: 100 }, - AssertFilters { - expected: vec![FilterPB { - id: "".to_string(), - filter_type: FilterType::Or, - children: vec![ - FilterPB { - id: "".to_string(), - filter_type: FilterType::Data, - children: vec![], - data: Some(FilterDataPB { - field_id: "".to_string(), - field_type: FieldType::Checkbox, - data: checkbox_filter_bytes, - }), - }, - FilterPB { - id: "".to_string(), - filter_type: FilterType::And, - children: vec![ - FilterPB { - id: "".to_string(), - filter_type: FilterType::Data, - children: vec![], - data: Some(FilterDataPB { - field_id: "".to_string(), - field_type: FieldType::DateTime, - data: date_filter_bytes, - }), - }, - FilterPB { - id: "".to_string(), - filter_type: FilterType::Data, - children: vec![], - data: Some(FilterDataPB { - field_id: "".to_string(), - field_type: FieldType::Number, - data: number_filter_bytes, - }), - }, - ], - data: None, - }, - ], - data: None, - }], - }, - AssertNumberOfVisibleRows { expected: 4 }, - ]; - test.run_scripts(scripts).await; - // IS_CHECK OR (DATE > 1651366800 AND NUMBER NOT EMPTY) + // Create Date Filter and Number Filter + test + .create_data_filter( + Some(and_filter.id.clone()), + FieldType::DateTime, + BoxAny::new(create_date_filter()), + None, + ) + .await; + + test + .create_data_filter( + Some(and_filter.id), + FieldType::Number, + BoxAny::new(create_number_filter()), + None, + ) + .await; + + test.wait(100).await; + + test + .assert_filters(vec![FilterPB { + id: "".to_string(), + filter_type: FilterType::Or, + children: vec![ + FilterPB { + id: "".to_string(), + filter_type: FilterType::Data, + children: vec![], + data: Some(FilterDataPB { + field_id: "".to_string(), + field_type: FieldType::Checkbox, + data: checkbox_filter_bytes, + }), + }, + FilterPB { + id: "".to_string(), + filter_type: FilterType::And, + children: vec![ + FilterPB { + id: "".to_string(), + filter_type: FilterType::Data, + children: vec![], + data: Some(FilterDataPB { + field_id: "".to_string(), + field_type: FieldType::DateTime, + data: date_filter_bytes, + }), + }, + FilterPB { + id: "".to_string(), + filter_type: FilterType::Data, + children: vec![], + data: Some(FilterDataPB { + field_id: "".to_string(), + field_type: FieldType::Number, + data: number_filter_bytes, + }), + }, + ], + data: None, + }, + ], + data: None, + }]) + .await; + + test.assert_number_of_visible_rows(4).await; } /// Create the same advanced filter single advanced filter: @@ -211,34 +212,32 @@ async fn create_advanced_filter_with_conversion_test() { } }; - let scripts = vec![CreateOrFilter { - parent_filter_id: None, - changed: None, - }]; - test.run_scripts(scripts).await; - // IS_CHECK OR DATE > 1651366800 + // Create OR Filter + test.create_or_filter(None, None).await; let or_filter = test.get_filter(FilterType::Or, None).await.unwrap(); - let scripts = vec![ - CreateDataFilter { - parent_filter_id: Some(or_filter.id.clone()), - field_type: FieldType::Checkbox, - data: BoxAny::new(create_checkbox_filter()), - changed: Some(FilterRowChanged { + // Create Checkbox Filter and Date Filter + test + .create_data_filter( + Some(or_filter.id.clone()), + FieldType::Checkbox, + BoxAny::new(create_checkbox_filter()), + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: 4, }), - }, - CreateDataFilter { - parent_filter_id: Some(or_filter.id.clone()), - field_type: FieldType::DateTime, - data: BoxAny::new(create_date_filter()), - changed: None, - }, - ]; - test.run_scripts(scripts).await; - // OR + ) + .await; + + test + .create_data_filter( + Some(or_filter.id.clone()), + FieldType::DateTime, + BoxAny::new(create_date_filter()), + None, + ) + .await; let date_filter = test .get_filter(FilterType::Data, Some(FieldType::DateTime)) @@ -252,62 +251,64 @@ async fn create_advanced_filter_with_conversion_test() { let number_filter_bytes: Result = create_number_filter().try_into(); let number_filter_bytes = number_filter_bytes.unwrap().to_vec(); - let scripts = vec![ - CreateDataFilter { - parent_filter_id: Some(date_filter.id), - field_type: FieldType::Number, - data: BoxAny::new(create_number_filter()), - changed: None, - }, - Wait { millisecond: 100 }, - AssertFilters { - expected: vec![FilterPB { - id: "".to_string(), - filter_type: FilterType::Or, - children: vec![ - FilterPB { - id: "".to_string(), - filter_type: FilterType::Data, - children: vec![], - data: Some(FilterDataPB { - field_id: "".to_string(), - field_type: FieldType::Checkbox, - data: checkbox_filter_bytes, - }), - }, - FilterPB { - id: "".to_string(), - filter_type: FilterType::And, - children: vec![ - FilterPB { - id: "".to_string(), - filter_type: FilterType::Data, - children: vec![], - data: Some(FilterDataPB { - field_id: "".to_string(), - field_type: FieldType::DateTime, - data: date_filter_bytes, - }), - }, - FilterPB { - id: "".to_string(), - filter_type: FilterType::Data, - children: vec![], - data: Some(FilterDataPB { - field_id: "".to_string(), - field_type: FieldType::Number, - data: number_filter_bytes, - }), - }, - ], - data: None, - }, - ], - data: None, - }], - }, - AssertNumberOfVisibleRows { expected: 4 }, - ]; - test.run_scripts(scripts).await; - // IS_CHECK OR (DATE > 1651366800 AND NUMBER NOT EMPTY) + // Create Number Filter + test + .create_data_filter( + Some(date_filter.id), + FieldType::Number, + BoxAny::new(create_number_filter()), + None, + ) + .await; + + test.wait(100).await; + + test + .assert_filters(vec![FilterPB { + id: "".to_string(), + filter_type: FilterType::Or, + children: vec![ + FilterPB { + id: "".to_string(), + filter_type: FilterType::Data, + children: vec![], + data: Some(FilterDataPB { + field_id: "".to_string(), + field_type: FieldType::Checkbox, + data: checkbox_filter_bytes, + }), + }, + FilterPB { + id: "".to_string(), + filter_type: FilterType::And, + children: vec![ + FilterPB { + id: "".to_string(), + filter_type: FilterType::Data, + children: vec![], + data: Some(FilterDataPB { + field_id: "".to_string(), + field_type: FieldType::DateTime, + data: date_filter_bytes, + }), + }, + FilterPB { + id: "".to_string(), + filter_type: FilterType::Data, + children: vec![], + data: Some(FilterDataPB { + field_id: "".to_string(), + field_type: FieldType::Number, + data: number_filter_bytes, + }), + }, + ], + data: None, + }, + ], + data: None, + }]) + .await; + + test.assert_number_of_visible_rows(4).await; } diff --git a/frontend/rust-lib/flowy-database2/tests/database/filter_test/checkbox_filter_test.rs b/frontend/rust-lib/flowy-database2/tests/database/filter_test/checkbox_filter_test.rs index f2591906ddd3..26a018d8de65 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/filter_test/checkbox_filter_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/filter_test/checkbox_filter_test.rs @@ -1,31 +1,30 @@ +use crate::database::filter_test::script::{DatabaseFilterTest, FilterRowChanged}; use flowy_database2::entities::{CheckboxFilterConditionPB, CheckboxFilterPB, FieldType}; use lib_infra::box_any::BoxAny; -use crate::database::filter_test::script::FilterScript::*; -use crate::database::filter_test::script::{DatabaseFilterTest, FilterRowChanged}; - #[tokio::test] async fn grid_filter_checkbox_is_check_test() { let mut test = DatabaseFilterTest::new().await; let expected = 3; let row_count = test.rows.len(); + // The initial number of checked is 3 // The initial number of unchecked is 4 - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::Checkbox, - data: BoxAny::new(CheckboxFilterPB { + test + .create_data_filter( + None, + FieldType::Checkbox, + BoxAny::new(CheckboxFilterPB { condition: CheckboxFilterConditionPB::IsChecked, }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, }), - }, - AssertNumberOfVisibleRows { expected }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + test.assert_number_of_visible_rows(expected).await; } #[tokio::test] @@ -33,19 +32,20 @@ async fn grid_filter_checkbox_is_uncheck_test() { let mut test = DatabaseFilterTest::new().await; let expected = 4; let row_count = test.rows.len(); - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::Checkbox, - data: BoxAny::new(CheckboxFilterPB { + + test + .create_data_filter( + None, + FieldType::Checkbox, + BoxAny::new(CheckboxFilterPB { condition: CheckboxFilterConditionPB::IsUnChecked, }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, }), - }, - AssertNumberOfVisibleRows { expected }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + test.assert_number_of_visible_rows(expected).await; } diff --git a/frontend/rust-lib/flowy-database2/tests/database/filter_test/checklist_filter_test.rs b/frontend/rust-lib/flowy-database2/tests/database/filter_test/checklist_filter_test.rs index 3e92391d928e..7be2310ef5e5 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/filter_test/checklist_filter_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/filter_test/checklist_filter_test.rs @@ -1,10 +1,8 @@ +use crate::database::filter_test::script::{DatabaseFilterTest, FilterRowChanged}; use flowy_database2::entities::{ChecklistFilterConditionPB, ChecklistFilterPB, FieldType}; use flowy_database2::services::field::checklist_type_option::ChecklistCellData; use lib_infra::box_any::BoxAny; -use crate::database::filter_test::script::FilterScript::*; -use crate::database::filter_test::script::{DatabaseFilterTest, FilterRowChanged}; - #[tokio::test] async fn grid_filter_checklist_is_incomplete_test() { let mut test = DatabaseFilterTest::new().await; @@ -12,25 +10,28 @@ async fn grid_filter_checklist_is_incomplete_test() { let row_count = test.rows.len(); let option_ids = get_checklist_cell_options(&test).await; - let scripts = vec![ - UpdateChecklistCell { - row_id: test.rows[0].id.clone(), - selected_option_ids: option_ids, - }, - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::Checklist, - data: BoxAny::new(ChecklistFilterPB { + // Update checklist cell with selected option IDs + test + .update_checklist_cell(test.rows[0].id.clone(), option_ids) + .await; + + // Create Checklist "Is Incomplete" filter + test + .create_data_filter( + None, + FieldType::Checklist, + BoxAny::new(ChecklistFilterPB { condition: ChecklistFilterConditionPB::IsIncomplete, }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, }), - }, - AssertNumberOfVisibleRows { expected }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + // Assert the number of visible rows + test.assert_number_of_visible_rows(expected).await; } #[tokio::test] @@ -39,25 +40,29 @@ async fn grid_filter_checklist_is_complete_test() { let expected = 2; let row_count = test.rows.len(); let option_ids = get_checklist_cell_options(&test).await; - let scripts = vec![ - UpdateChecklistCell { - row_id: test.rows[0].id.clone(), - selected_option_ids: option_ids, - }, - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::Checklist, - data: BoxAny::new(ChecklistFilterPB { + + // Update checklist cell with selected option IDs + test + .update_checklist_cell(test.rows[0].id.clone(), option_ids) + .await; + + // Create Checklist "Is Complete" filter + test + .create_data_filter( + None, + FieldType::Checklist, + BoxAny::new(ChecklistFilterPB { condition: ChecklistFilterConditionPB::IsComplete, }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, }), - }, - AssertNumberOfVisibleRows { expected }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + // Assert the number of visible rows + test.assert_number_of_visible_rows(expected).await; } async fn get_checklist_cell_options(test: &DatabaseFilterTest) -> Vec { diff --git a/frontend/rust-lib/flowy-database2/tests/database/filter_test/date_filter_test.rs b/frontend/rust-lib/flowy-database2/tests/database/filter_test/date_filter_test.rs index 7cc5cdf9a743..deff2a588887 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/filter_test/date_filter_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/filter_test/date_filter_test.rs @@ -1,32 +1,33 @@ +use crate::database::filter_test::script::{DatabaseFilterTest, FilterRowChanged}; use flowy_database2::entities::{DateFilterConditionPB, DateFilterPB, FieldType}; use lib_infra::box_any::BoxAny; -use crate::database::filter_test::script::FilterScript::*; -use crate::database::filter_test::script::{DatabaseFilterTest, FilterRowChanged}; - #[tokio::test] async fn grid_filter_date_is_test() { let mut test = DatabaseFilterTest::new().await; let row_count = test.rows.len(); let expected = 3; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::DateTime, - data: BoxAny::new(DateFilterPB { + + // Create "Date Is" filter + test + .create_data_filter( + None, + FieldType::DateTime, + BoxAny::new(DateFilterPB { condition: DateFilterConditionPB::DateStartsOn, start: None, end: None, timestamp: Some(1647251762), }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, }), - }, - AssertNumberOfVisibleRows { expected }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + // Assert the number of visible rows + test.assert_number_of_visible_rows(expected).await; } #[tokio::test] @@ -34,24 +35,27 @@ async fn grid_filter_date_after_test() { let mut test = DatabaseFilterTest::new().await; let row_count = test.rows.len(); let expected = 3; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::DateTime, - data: BoxAny::new(DateFilterPB { + + // Create "Date After" filter + test + .create_data_filter( + None, + FieldType::DateTime, + BoxAny::new(DateFilterPB { condition: DateFilterConditionPB::DateStartsAfter, start: None, end: None, timestamp: Some(1647251762), }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, }), - }, - AssertNumberOfVisibleRows { expected }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + // Assert the number of visible rows + test.assert_number_of_visible_rows(expected).await; } #[tokio::test] @@ -59,24 +63,27 @@ async fn grid_filter_date_on_or_after_test() { let mut test = DatabaseFilterTest::new().await; let row_count = test.rows.len(); let expected = 3; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::DateTime, - data: BoxAny::new(DateFilterPB { + + // Create "Date On Or After" filter + test + .create_data_filter( + None, + FieldType::DateTime, + BoxAny::new(DateFilterPB { condition: DateFilterConditionPB::DateStartsOnOrAfter, start: None, end: None, timestamp: Some(1668359085), }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, }), - }, - AssertNumberOfVisibleRows { expected }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + // Assert the number of visible rows + test.assert_number_of_visible_rows(expected).await; } #[tokio::test] @@ -84,24 +91,27 @@ async fn grid_filter_date_on_or_before_test() { let mut test = DatabaseFilterTest::new().await; let row_count = test.rows.len(); let expected = 4; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::DateTime, - data: BoxAny::new(DateFilterPB { + + // Create "Date On Or Before" filter + test + .create_data_filter( + None, + FieldType::DateTime, + BoxAny::new(DateFilterPB { condition: DateFilterConditionPB::DateStartsOnOrBefore, start: None, end: None, timestamp: Some(1668359085), }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, }), - }, - AssertNumberOfVisibleRows { expected }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + // Assert the number of visible rows + test.assert_number_of_visible_rows(expected).await; } #[tokio::test] @@ -109,22 +119,25 @@ async fn grid_filter_date_within_test() { let mut test = DatabaseFilterTest::new().await; let row_count = test.rows.len(); let expected = 5; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::DateTime, - data: BoxAny::new(DateFilterPB { + + // Create "Date Within Range" filter + test + .create_data_filter( + None, + FieldType::DateTime, + BoxAny::new(DateFilterPB { condition: DateFilterConditionPB::DateStartsBetween, start: Some(1647251762), end: Some(1668704685), timestamp: None, }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, }), - }, - AssertNumberOfVisibleRows { expected }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + // Assert the number of visible rows + test.assert_number_of_visible_rows(expected).await; } diff --git a/frontend/rust-lib/flowy-database2/tests/database/filter_test/number_filter_test.rs b/frontend/rust-lib/flowy-database2/tests/database/filter_test/number_filter_test.rs index 8b2f32499065..509b520361c2 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/filter_test/number_filter_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/filter_test/number_filter_test.rs @@ -1,30 +1,31 @@ +use crate::database::filter_test::script::{DatabaseFilterTest, FilterRowChanged}; use flowy_database2::entities::{FieldType, NumberFilterConditionPB, NumberFilterPB}; use lib_infra::box_any::BoxAny; -use crate::database::filter_test::script::FilterScript::*; -use crate::database::filter_test::script::{DatabaseFilterTest, FilterRowChanged}; - #[tokio::test] async fn grid_filter_number_is_equal_test() { let mut test = DatabaseFilterTest::new().await; let row_count = test.rows.len(); let expected = 1; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::Number, - data: BoxAny::new(NumberFilterPB { + + // Create Number "Equal" filter + test + .create_data_filter( + None, + FieldType::Number, + BoxAny::new(NumberFilterPB { condition: NumberFilterConditionPB::Equal, content: "1".to_string(), }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, }), - }, - AssertNumberOfVisibleRows { expected }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + // Assert the number of visible rows + test.assert_number_of_visible_rows(expected).await; } #[tokio::test] @@ -32,22 +33,25 @@ async fn grid_filter_number_is_less_than_test() { let mut test = DatabaseFilterTest::new().await; let row_count = test.rows.len(); let expected = 2; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::Number, - data: BoxAny::new(NumberFilterPB { + + // Create Number "Less Than" filter + test + .create_data_filter( + None, + FieldType::Number, + BoxAny::new(NumberFilterPB { condition: NumberFilterConditionPB::LessThan, content: "3".to_string(), }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, }), - }, - AssertNumberOfVisibleRows { expected }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + // Assert the number of visible rows + test.assert_number_of_visible_rows(expected).await; } #[tokio::test] @@ -56,22 +60,25 @@ async fn grid_filter_number_is_less_than_test2() { let mut test = DatabaseFilterTest::new().await; let row_count = test.rows.len(); let expected = 2; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::Number, - data: BoxAny::new(NumberFilterPB { + + // Create Number "Less Than" filter with invalid content (should panic) + test + .create_data_filter( + None, + FieldType::Number, + BoxAny::new(NumberFilterPB { condition: NumberFilterConditionPB::LessThan, content: "$3".to_string(), }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, }), - }, - AssertNumberOfVisibleRows { expected }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + // Assert the number of visible rows + test.assert_number_of_visible_rows(expected).await; } #[tokio::test] @@ -79,22 +86,25 @@ async fn grid_filter_number_is_less_than_or_equal_test() { let mut test = DatabaseFilterTest::new().await; let row_count = test.rows.len(); let expected = 3; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::Number, - data: BoxAny::new(NumberFilterPB { + + // Create Number "Less Than Or Equal" filter + test + .create_data_filter( + None, + FieldType::Number, + BoxAny::new(NumberFilterPB { condition: NumberFilterConditionPB::LessThanOrEqualTo, content: "3".to_string(), }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, }), - }, - AssertNumberOfVisibleRows { expected }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + // Assert the number of visible rows + test.assert_number_of_visible_rows(expected).await; } #[tokio::test] @@ -102,22 +112,25 @@ async fn grid_filter_number_is_empty_test() { let mut test = DatabaseFilterTest::new().await; let row_count = test.rows.len(); let expected = 2; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::Number, - data: BoxAny::new(NumberFilterPB { + + // Create Number "Is Empty" filter + test + .create_data_filter( + None, + FieldType::Number, + BoxAny::new(NumberFilterPB { condition: NumberFilterConditionPB::NumberIsEmpty, content: "".to_string(), }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, }), - }, - AssertNumberOfVisibleRows { expected }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + // Assert the number of visible rows + test.assert_number_of_visible_rows(expected).await; } #[tokio::test] @@ -125,20 +138,23 @@ async fn grid_filter_number_is_not_empty_test() { let mut test = DatabaseFilterTest::new().await; let row_count = test.rows.len(); let expected = 5; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::Number, - data: BoxAny::new(NumberFilterPB { + + // Create Number "Is Not Empty" filter + test + .create_data_filter( + None, + FieldType::Number, + BoxAny::new(NumberFilterPB { condition: NumberFilterConditionPB::NumberIsNotEmpty, content: "".to_string(), }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, }), - }, - AssertNumberOfVisibleRows { expected }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + // Assert the number of visible rows + test.assert_number_of_visible_rows(expected).await; } diff --git a/frontend/rust-lib/flowy-database2/tests/database/filter_test/script.rs b/frontend/rust-lib/flowy-database2/tests/database/filter_test/script.rs index 0b1f27af12f5..cd09a45ede1f 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/filter_test/script.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/filter_test/script.rs @@ -20,71 +20,6 @@ pub struct FilterRowChanged { pub(crate) hiding_num_of_rows: usize, } -pub enum FilterScript { - UpdateTextCell { - row_id: RowId, - text: String, - changed: Option, - }, - UpdateChecklistCell { - row_id: RowId, - selected_option_ids: Vec, - }, - UpdateSingleSelectCell { - row_id: RowId, - option_id: String, - changed: Option, - }, - CreateDataFilter { - parent_filter_id: Option, - field_type: FieldType, - data: BoxAny, - changed: Option, - }, - UpdateTextFilter { - filter: FilterPB, - condition: TextFilterConditionPB, - content: String, - changed: Option, - }, - CreateAndFilter { - parent_filter_id: Option, - changed: Option, - }, - CreateOrFilter { - parent_filter_id: Option, - changed: Option, - }, - DeleteFilter { - filter_id: String, - changed: Option, - }, - // CreateSimpleAdvancedFilter, - // CreateComplexAdvancedFilter, - AssertFilterCount { - count: usize, - }, - AssertNumberOfVisibleRows { - expected: usize, - }, - AssertFilters { - /// 1. assert that the filter type is correct - /// 2. if the filter is data, assert that the field_type, condition and content are correct - /// (no field_id) - /// 3. if the filter is and/or, assert that each child is correct as well. - expected: Vec, - }, - // AssertSimpleAdvancedFilter, - // AssertComplexAdvancedFilterResult, - #[allow(dead_code)] - AssertGridSetting { - expected_setting: DatabaseViewSettingPB, - }, - Wait { - millisecond: u64, - }, -} - pub struct DatabaseFilterTest { inner: DatabaseEditorTest, recv: Option>, @@ -147,169 +82,173 @@ impl DatabaseFilterTest { } } - pub async fn run_scripts(&mut self, scripts: Vec) { - for script in scripts { - self.run_script(script).await; - } + pub async fn update_text_cell_with_change( + &mut self, + row_id: RowId, + text: String, + changed: Option, + ) { + self.subscribe_view_changed().await; + self.assert_future_changed(changed).await; + self.update_text_cell(row_id, &text).await.unwrap(); } - pub async fn run_script(&mut self, script: FilterScript) { - match script { - FilterScript::UpdateTextCell { - row_id, - text, - changed, - } => { - self.subscribe_view_changed().await; - self.assert_future_changed(changed).await; - self.update_text_cell(row_id, &text).await.unwrap(); - }, - FilterScript::UpdateChecklistCell { - row_id, - selected_option_ids, - } => { - self - .set_checklist_cell(row_id, selected_option_ids) - .await - .unwrap(); - }, - FilterScript::UpdateSingleSelectCell { - row_id, - option_id, - changed, - } => { - self.subscribe_view_changed().await; - self.assert_future_changed(changed).await; - self - .update_single_select_cell(row_id, &option_id) - .await - .unwrap(); - }, - FilterScript::CreateDataFilter { - parent_filter_id, + pub async fn update_checklist_cell(&mut self, row_id: RowId, selected_option_ids: Vec) { + self + .set_checklist_cell(row_id, selected_option_ids) + .await + .unwrap(); + } + + pub async fn update_single_select_cell_with_change( + &mut self, + row_id: RowId, + option_id: String, + changed: Option, + ) { + self.subscribe_view_changed().await; + self.assert_future_changed(changed).await; + self + .update_single_select_cell(row_id, &option_id) + .await + .unwrap(); + } + + pub async fn create_data_filter( + &mut self, + parent_filter_id: Option, + field_type: FieldType, + data: BoxAny, + changed: Option, + ) { + self.subscribe_view_changed().await; + self.assert_future_changed(changed).await; + let field = self.get_first_field(field_type).await; + let params = FilterChangeset::Insert { + parent_filter_id, + data: FilterInner::Data { + field_id: field.id, field_type, - data, - changed, - } => { - self.subscribe_view_changed().await; - self.assert_future_changed(changed).await; - let field = self.get_first_field(field_type).await; - let params = FilterChangeset::Insert { - parent_filter_id, - data: FilterInner::Data { - field_id: field.id, - field_type, - condition_and_content: data, - }, - }; - self - .editor - .modify_view_filters(&self.view_id, params) - .await - .unwrap(); - }, - FilterScript::UpdateTextFilter { - filter, - condition, - content, - changed, - } => { - self.subscribe_view_changed().await; - - self.assert_future_changed(changed).await; - let current_filter = filter.data.unwrap(); - let params = FilterChangeset::UpdateData { - filter_id: filter.id, - data: FilterInner::Data { - field_id: current_filter.field_id, - field_type: current_filter.field_type, - condition_and_content: BoxAny::new(TextFilterPB { condition, content }), - }, - }; - self - .editor - .modify_view_filters(&self.view_id, params) - .await - .unwrap(); - }, - FilterScript::CreateAndFilter { - parent_filter_id, - changed, - } => { - self.subscribe_view_changed().await; - self.assert_future_changed(changed).await; - let params = FilterChangeset::Insert { - parent_filter_id, - data: FilterInner::And { children: vec![] }, - }; - self - .editor - .modify_view_filters(&self.view_id, params) - .await - .unwrap(); - }, - FilterScript::CreateOrFilter { - parent_filter_id, - changed, - } => { - self.subscribe_view_changed().await; - self.assert_future_changed(changed).await; - let params = FilterChangeset::Insert { - parent_filter_id, - data: FilterInner::Or { children: vec![] }, - }; - self - .editor - .modify_view_filters(&self.view_id, params) - .await - .unwrap(); - }, - FilterScript::AssertFilterCount { count } => { - let filters = self.editor.get_all_filters(&self.view_id).await.items; - assert_eq!(count, filters.len()); - }, - FilterScript::DeleteFilter { filter_id, changed } => { - self.subscribe_view_changed().await; - self.assert_future_changed(changed).await; - let params = FilterChangeset::Delete { filter_id }; - self - .editor - .modify_view_filters(&self.view_id, params) - .await - .unwrap(); - }, - FilterScript::AssertGridSetting { expected_setting } => { - let setting = self - .editor - .get_database_view_setting(&self.view_id) - .await - .unwrap(); - assert_eq!(expected_setting, setting); - }, - FilterScript::AssertFilters { expected } => { - let actual = self.get_all_filters().await; - for (actual_filter, expected_filter) in actual.iter().zip(expected.iter()) { - Self::assert_filter(actual_filter, expected_filter); - } + condition_and_content: data, }, - FilterScript::AssertNumberOfVisibleRows { expected } => { - let (tx, rx) = tokio::sync::oneshot::channel(); - let _ = self - .editor - .open_database_view(&self.view_id, Some(tx)) - .await - .unwrap(); - rx.await.unwrap(); - - let rows = self.editor.get_all_rows(&self.view_id).await.unwrap(); - assert_eq!(rows.len(), expected); - }, - FilterScript::Wait { millisecond } => { - tokio::time::sleep(Duration::from_millis(millisecond)).await; + }; + self + .editor + .modify_view_filters(&self.view_id, params) + .await + .unwrap(); + } + + pub async fn update_text_filter( + &mut self, + filter: FilterPB, + condition: TextFilterConditionPB, + content: String, + changed: Option, + ) { + self.subscribe_view_changed().await; + self.assert_future_changed(changed).await; + let current_filter = filter.data.unwrap(); + let params = FilterChangeset::UpdateData { + filter_id: filter.id, + data: FilterInner::Data { + field_id: current_filter.field_id, + field_type: current_filter.field_type, + condition_and_content: BoxAny::new(TextFilterPB { condition, content }), }, + }; + self + .editor + .modify_view_filters(&self.view_id, params) + .await + .unwrap(); + } + + pub async fn create_and_filter( + &mut self, + parent_filter_id: Option, + changed: Option, + ) { + self.subscribe_view_changed().await; + self.assert_future_changed(changed).await; + let params = FilterChangeset::Insert { + parent_filter_id, + data: FilterInner::And { children: vec![] }, + }; + self + .editor + .modify_view_filters(&self.view_id, params) + .await + .unwrap(); + } + + pub async fn create_or_filter( + &mut self, + parent_filter_id: Option, + changed: Option, + ) { + self.subscribe_view_changed().await; + self.assert_future_changed(changed).await; + let params = FilterChangeset::Insert { + parent_filter_id, + data: FilterInner::Or { children: vec![] }, + }; + self + .editor + .modify_view_filters(&self.view_id, params) + .await + .unwrap(); + } + + pub async fn delete_filter(&mut self, filter_id: String, changed: Option) { + self.subscribe_view_changed().await; + self.assert_future_changed(changed).await; + let params = FilterChangeset::Delete { filter_id }; + self + .editor + .modify_view_filters(&self.view_id, params) + .await + .unwrap(); + } + + pub async fn assert_filter_count(&self, count: usize) { + let filters = self.editor.get_all_filters(&self.view_id).await.items; + assert_eq!(count, filters.len()); + } + + pub async fn assert_grid_setting(&self, expected_setting: DatabaseViewSettingPB) { + let setting = self + .editor + .get_database_view_setting(&self.view_id) + .await + .unwrap(); + assert_eq!(expected_setting, setting); + } + + pub async fn assert_filters(&self, expected: Vec) { + let actual = self.get_all_filters().await; + for (actual_filter, expected_filter) in actual.iter().zip(expected.iter()) { + Self::assert_filter(actual_filter, expected_filter); } } + pub async fn assert_number_of_visible_rows(&self, expected: usize) { + let (tx, rx) = tokio::sync::oneshot::channel(); + let _ = self + .editor + .open_database_view(&self.view_id, Some(tx)) + .await + .unwrap(); + rx.await.unwrap(); + + let rows = self.editor.get_all_rows(&self.view_id).await.unwrap(); + assert_eq!(rows.len(), expected); + } + + pub async fn wait(&self, millisecond: u64) { + tokio::time::sleep(Duration::from_millis(millisecond)).await; + } + async fn subscribe_view_changed(&mut self) { self.recv = Some( self diff --git a/frontend/rust-lib/flowy-database2/tests/database/filter_test/select_option_filter_test.rs b/frontend/rust-lib/flowy-database2/tests/database/filter_test/select_option_filter_test.rs index c5abcf3336dc..ed6c2a62ca38 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/filter_test/select_option_filter_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/filter_test/select_option_filter_test.rs @@ -1,43 +1,47 @@ +use crate::database::filter_test::script::{DatabaseFilterTest, FilterRowChanged}; use flowy_database2::entities::{FieldType, SelectOptionFilterConditionPB, SelectOptionFilterPB}; use lib_infra::box_any::BoxAny; -use crate::database::filter_test::script::FilterScript::*; -use crate::database::filter_test::script::{DatabaseFilterTest, FilterRowChanged}; - #[tokio::test] async fn grid_filter_multi_select_is_empty_test() { let mut test = DatabaseFilterTest::new().await; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::MultiSelect, - data: BoxAny::new(SelectOptionFilterPB { + + // Create Multi-Select "Is Empty" filter + test + .create_data_filter( + None, + FieldType::MultiSelect, + BoxAny::new(SelectOptionFilterPB { condition: SelectOptionFilterConditionPB::OptionIsEmpty, option_ids: vec![], }), - changed: None, - }, - AssertNumberOfVisibleRows { expected: 2 }, - ]; - test.run_scripts(scripts).await; + None, + ) + .await; + + // Assert the number of visible rows + test.assert_number_of_visible_rows(2).await; } #[tokio::test] async fn grid_filter_multi_select_is_not_empty_test() { let mut test = DatabaseFilterTest::new().await; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::MultiSelect, - data: BoxAny::new(SelectOptionFilterPB { + + // Create Multi-Select "Is Not Empty" filter + test + .create_data_filter( + None, + FieldType::MultiSelect, + BoxAny::new(SelectOptionFilterPB { condition: SelectOptionFilterConditionPB::OptionIsNotEmpty, option_ids: vec![], }), - changed: None, - }, - AssertNumberOfVisibleRows { expected: 5 }, - ]; - test.run_scripts(scripts).await; + None, + ) + .await; + + // Assert the number of visible rows + test.assert_number_of_visible_rows(5).await; } #[tokio::test] @@ -45,19 +49,22 @@ async fn grid_filter_multi_select_is_test() { let mut test = DatabaseFilterTest::new().await; let field = test.get_first_field(FieldType::MultiSelect).await; let mut options = test.get_multi_select_type_option(&field.id).await; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::MultiSelect, - data: BoxAny::new(SelectOptionFilterPB { + + // Create Multi-Select "Is" filter with specific option IDs + test + .create_data_filter( + None, + FieldType::MultiSelect, + BoxAny::new(SelectOptionFilterPB { condition: SelectOptionFilterConditionPB::OptionIs, option_ids: vec![options.remove(0).id, options.remove(0).id], }), - changed: None, - }, - AssertNumberOfVisibleRows { expected: 1 }, - ]; - test.run_scripts(scripts).await; + None, + ) + .await; + + // Assert the number of visible rows + test.assert_number_of_visible_rows(1).await; } #[tokio::test] @@ -65,19 +72,22 @@ async fn grid_filter_multi_select_is_test2() { let mut test = DatabaseFilterTest::new().await; let field = test.get_first_field(FieldType::MultiSelect).await; let mut options = test.get_multi_select_type_option(&field.id).await; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::MultiSelect, - data: BoxAny::new(SelectOptionFilterPB { + + // Create Multi-Select "Is" filter with a specific option ID + test + .create_data_filter( + None, + FieldType::MultiSelect, + BoxAny::new(SelectOptionFilterPB { condition: SelectOptionFilterConditionPB::OptionIs, option_ids: vec![options.remove(1).id], }), - changed: None, - }, - AssertNumberOfVisibleRows { expected: 1 }, - ]; - test.run_scripts(scripts).await; + None, + ) + .await; + + // Assert the number of visible rows + test.assert_number_of_visible_rows(1).await; } #[tokio::test] @@ -85,22 +95,25 @@ async fn grid_filter_single_select_is_empty_test() { let mut test = DatabaseFilterTest::new().await; let expected = 3; let row_count = test.rows.len(); - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::SingleSelect, - data: BoxAny::new(SelectOptionFilterPB { + + // Create Single-Select "Is Empty" filter + test + .create_data_filter( + None, + FieldType::SingleSelect, + BoxAny::new(SelectOptionFilterPB { condition: SelectOptionFilterConditionPB::OptionIsEmpty, option_ids: vec![], }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, }), - }, - AssertNumberOfVisibleRows { expected }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + // Assert the number of visible rows + test.assert_number_of_visible_rows(expected).await; } #[tokio::test] @@ -110,22 +123,25 @@ async fn grid_filter_single_select_is_test() { let mut options = test.get_single_select_type_option(&field.id).await; let expected = 2; let row_count = test.rows.len(); - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::SingleSelect, - data: BoxAny::new(SelectOptionFilterPB { + + // Create Single-Select "Is" filter with a specific option ID + test + .create_data_filter( + None, + FieldType::SingleSelect, + BoxAny::new(SelectOptionFilterPB { condition: SelectOptionFilterConditionPB::OptionIs, option_ids: vec![options.remove(0).id], }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, }), - }, - AssertNumberOfVisibleRows { expected: 2 }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + // Assert the number of visible rows + test.assert_number_of_visible_rows(expected).await; } #[tokio::test] @@ -137,37 +153,42 @@ async fn grid_filter_single_select_is_test2() { let option = options.remove(0); let row_count = test.rows.len(); - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::SingleSelect, - data: BoxAny::new(SelectOptionFilterPB { + // Create Single-Select "Is" filter + test + .create_data_filter( + None, + FieldType::SingleSelect, + BoxAny::new(SelectOptionFilterPB { condition: SelectOptionFilterConditionPB::OptionIs, option_ids: vec![option.id.clone()], }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - 2, }), - }, - AssertNumberOfVisibleRows { expected: 2 }, - UpdateSingleSelectCell { - row_id: row_details[1].id.clone(), - option_id: option.id.clone(), - changed: None, - }, - AssertNumberOfVisibleRows { expected: 3 }, - UpdateSingleSelectCell { - row_id: row_details[1].id.clone(), - option_id: "".to_string(), - changed: Some(FilterRowChanged { + ) + .await; + + test.assert_number_of_visible_rows(2).await; + + // Update single-select cell to match the filter + test + .update_single_select_cell_with_change(row_details[1].id.clone(), option.id.clone(), None) + .await; + test.assert_number_of_visible_rows(3).await; + + // Update single-select cell to remove the option + test + .update_single_select_cell_with_change( + row_details[1].id.clone(), + "".to_string(), + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: 1, }), - }, - AssertNumberOfVisibleRows { expected: 2 }, - ]; - test.run_scripts(scripts).await; + ) + .await; + test.assert_number_of_visible_rows(2).await; } #[tokio::test] @@ -175,19 +196,22 @@ async fn grid_filter_multi_select_contains_test() { let mut test = DatabaseFilterTest::new().await; let field = test.get_first_field(FieldType::MultiSelect).await; let mut options = test.get_multi_select_type_option(&field.id).await; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::MultiSelect, - data: BoxAny::new(SelectOptionFilterPB { + + // Create Multi-Select "Contains" filter + test + .create_data_filter( + None, + FieldType::MultiSelect, + BoxAny::new(SelectOptionFilterPB { condition: SelectOptionFilterConditionPB::OptionContains, option_ids: vec![options.remove(0).id, options.remove(0).id], }), - changed: None, - }, - AssertNumberOfVisibleRows { expected: 5 }, - ]; - test.run_scripts(scripts).await; + None, + ) + .await; + + // Assert the number of visible rows + test.assert_number_of_visible_rows(5).await; } #[tokio::test] @@ -195,17 +219,20 @@ async fn grid_filter_multi_select_contains_test2() { let mut test = DatabaseFilterTest::new().await; let field = test.get_first_field(FieldType::MultiSelect).await; let mut options = test.get_multi_select_type_option(&field.id).await; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::MultiSelect, - data: BoxAny::new(SelectOptionFilterPB { + + // Create Multi-Select "Contains" filter with a specific option ID + test + .create_data_filter( + None, + FieldType::MultiSelect, + BoxAny::new(SelectOptionFilterPB { condition: SelectOptionFilterConditionPB::OptionContains, option_ids: vec![options.remove(1).id], }), - changed: None, - }, - AssertNumberOfVisibleRows { expected: 4 }, - ]; - test.run_scripts(scripts).await; + None, + ) + .await; + + // Assert the number of visible rows + test.assert_number_of_visible_rows(4).await; } diff --git a/frontend/rust-lib/flowy-database2/tests/database/filter_test/text_filter_test.rs b/frontend/rust-lib/flowy-database2/tests/database/filter_test/text_filter_test.rs index 466dafc40402..88b2c0382f12 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/filter_test/text_filter_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/filter_test/text_filter_test.rs @@ -1,101 +1,110 @@ +use crate::database::filter_test::script::{DatabaseFilterTest, FilterRowChanged}; use flowy_database2::entities::{FieldType, TextFilterConditionPB, TextFilterPB}; use lib_infra::box_any::BoxAny; -use crate::database::filter_test::script::FilterScript::*; -use crate::database::filter_test::script::*; - #[tokio::test] async fn grid_filter_text_is_empty_test() { let mut test = DatabaseFilterTest::new().await; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::RichText, - data: BoxAny::new(TextFilterPB { + + // Create Text "Is Empty" filter + test + .create_data_filter( + None, + FieldType::RichText, + BoxAny::new(TextFilterPB { condition: TextFilterConditionPB::TextIsEmpty, content: "".to_string(), }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: 5, }), - }, - AssertFilterCount { count: 1 }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + // Assert filter count + test.assert_filter_count(1).await; } #[tokio::test] async fn grid_filter_text_is_not_empty_test() { let mut test = DatabaseFilterTest::new().await; - // Only one row's text of the initial rows is "" - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::RichText, - data: BoxAny::new(TextFilterPB { + + // Create Text "Is Not Empty" filter + test + .create_data_filter( + None, + FieldType::RichText, + BoxAny::new(TextFilterPB { condition: TextFilterConditionPB::TextIsNotEmpty, content: "".to_string(), }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: 1, }), - }, - AssertFilterCount { count: 1 }, - ]; - test.run_scripts(scripts).await; + ) + .await; - let filter = test.database_filters().await.pop().unwrap(); + // Assert filter count + test.assert_filter_count(1).await; + + // Delete the filter + let filter = test.get_all_filters().await.pop().unwrap(); test - .run_scripts(vec![ - DeleteFilter { - filter_id: filter.id, - changed: Some(FilterRowChanged { - showing_num_of_rows: 1, - hiding_num_of_rows: 0, - }), - }, - AssertFilterCount { count: 0 }, - ]) + .delete_filter( + filter.id, + Some(FilterRowChanged { + showing_num_of_rows: 1, + hiding_num_of_rows: 0, + }), + ) .await; + + // Assert filter count after deletion + test.assert_filter_count(0).await; } #[tokio::test] async fn grid_filter_is_text_test() { let mut test = DatabaseFilterTest::new().await; - // Only one row's text of the initial rows is "A" - let scripts = vec![CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::RichText, - data: BoxAny::new(TextFilterPB { - condition: TextFilterConditionPB::TextIs, - content: "A".to_string(), - }), - changed: Some(FilterRowChanged { - showing_num_of_rows: 0, - hiding_num_of_rows: 5, - }), - }]; - test.run_scripts(scripts).await; + + // Create Text "Is" filter + test + .create_data_filter( + None, + FieldType::RichText, + BoxAny::new(TextFilterPB { + condition: TextFilterConditionPB::TextIs, + content: "A".to_string(), + }), + Some(FilterRowChanged { + showing_num_of_rows: 0, + hiding_num_of_rows: 5, + }), + ) + .await; } #[tokio::test] async fn grid_filter_contain_text_test() { let mut test = DatabaseFilterTest::new().await; - let scripts = vec![CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::RichText, - data: BoxAny::new(TextFilterPB { - condition: TextFilterConditionPB::TextContains, - content: "A".to_string(), - }), - changed: Some(FilterRowChanged { - showing_num_of_rows: 0, - hiding_num_of_rows: 2, - }), - }]; - test.run_scripts(scripts).await; + + // Create Text "Contains" filter + test + .create_data_filter( + None, + FieldType::RichText, + BoxAny::new(TextFilterPB { + condition: TextFilterConditionPB::TextContains, + content: "A".to_string(), + }), + Some(FilterRowChanged { + showing_num_of_rows: 0, + hiding_num_of_rows: 2, + }), + ) + .await; } #[tokio::test] @@ -103,181 +112,203 @@ async fn grid_filter_contain_text_test2() { let mut test = DatabaseFilterTest::new().await; let row_detail = test.rows.clone(); - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::RichText, - data: BoxAny::new(TextFilterPB { + // Create Text "Contains" filter + test + .create_data_filter( + None, + FieldType::RichText, + BoxAny::new(TextFilterPB { condition: TextFilterConditionPB::TextContains, content: "A".to_string(), }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: 2, }), - }, - UpdateTextCell { - row_id: row_detail[1].id.clone(), - text: "ABC".to_string(), - changed: Some(FilterRowChanged { + ) + .await; + + // Update the text of a row + test + .update_text_cell_with_change( + row_detail[1].id.clone(), + "ABC".to_string(), + Some(FilterRowChanged { showing_num_of_rows: 1, hiding_num_of_rows: 0, }), - }, - ]; - test.run_scripts(scripts).await; + ) + .await; } #[tokio::test] async fn grid_filter_does_not_contain_text_test() { let mut test = DatabaseFilterTest::new().await; - // None of the initial rows contains the text "AB" - let scripts = vec![CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::RichText, - data: BoxAny::new(TextFilterPB { - condition: TextFilterConditionPB::TextDoesNotContain, - content: "AB".to_string(), - }), - changed: Some(FilterRowChanged { - showing_num_of_rows: 0, - hiding_num_of_rows: 0, - }), - }]; - test.run_scripts(scripts).await; + + // Create Text "Does Not Contain" filter + test + .create_data_filter( + None, + FieldType::RichText, + BoxAny::new(TextFilterPB { + condition: TextFilterConditionPB::TextDoesNotContain, + content: "AB".to_string(), + }), + Some(FilterRowChanged { + showing_num_of_rows: 0, + hiding_num_of_rows: 0, + }), + ) + .await; } #[tokio::test] async fn grid_filter_start_with_text_test() { let mut test = DatabaseFilterTest::new().await; - let scripts = vec![CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::RichText, - data: BoxAny::new(TextFilterPB { - condition: TextFilterConditionPB::TextStartsWith, - content: "A".to_string(), - }), - changed: Some(FilterRowChanged { - showing_num_of_rows: 0, - hiding_num_of_rows: 3, - }), - }]; - test.run_scripts(scripts).await; + + // Create Text "Starts With" filter + test + .create_data_filter( + None, + FieldType::RichText, + BoxAny::new(TextFilterPB { + condition: TextFilterConditionPB::TextStartsWith, + content: "A".to_string(), + }), + Some(FilterRowChanged { + showing_num_of_rows: 0, + hiding_num_of_rows: 3, + }), + ) + .await; } #[tokio::test] async fn grid_filter_ends_with_text_test() { let mut test = DatabaseFilterTest::new().await; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::RichText, - data: BoxAny::new(TextFilterPB { + + // Create Text "Ends With" filter + test + .create_data_filter( + None, + FieldType::RichText, + BoxAny::new(TextFilterPB { condition: TextFilterConditionPB::TextEndsWith, content: "A".to_string(), }), - changed: None, - }, - AssertNumberOfVisibleRows { expected: 2 }, - ]; - test.run_scripts(scripts).await; + None, + ) + .await; + + // Assert number of visible rows + test.assert_number_of_visible_rows(2).await; } #[tokio::test] async fn grid_update_text_filter_test() { let mut test = DatabaseFilterTest::new().await; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::RichText, - data: BoxAny::new(TextFilterPB { + + // Create Text "Ends With" filter + test + .create_data_filter( + None, + FieldType::RichText, + BoxAny::new(TextFilterPB { condition: TextFilterConditionPB::TextEndsWith, content: "A".to_string(), }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: 4, }), - }, - AssertNumberOfVisibleRows { expected: 2 }, - AssertFilterCount { count: 1 }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + // Assert number of visible rows and filter count + test.assert_number_of_visible_rows(2).await; + test.assert_filter_count(1).await; // Update the filter let filter = test.get_all_filters().await.pop().unwrap(); - let scripts = vec![ - UpdateTextFilter { + test + .update_text_filter( filter, - condition: TextFilterConditionPB::TextIs, - content: "A".to_string(), - changed: Some(FilterRowChanged { + TextFilterConditionPB::TextIs, + "A".to_string(), + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: 1, }), - }, - AssertNumberOfVisibleRows { expected: 1 }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + // Assert number of visible rows after update + test.assert_number_of_visible_rows(1).await; } #[tokio::test] async fn grid_filter_delete_test() { let mut test = DatabaseFilterTest::new().await; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::RichText, - changed: None, - data: BoxAny::new(TextFilterPB { + + // Create Text "Is Empty" filter + test + .create_data_filter( + None, + FieldType::RichText, + BoxAny::new(TextFilterPB { condition: TextFilterConditionPB::TextIsEmpty, content: "".to_string(), }), - }, - AssertFilterCount { count: 1 }, - AssertNumberOfVisibleRows { expected: 1 }, - ]; - test.run_scripts(scripts).await; - - let filter = test.database_filters().await.pop().unwrap(); - test - .run_scripts(vec![ - DeleteFilter { - filter_id: filter.id, - changed: None, - }, - AssertFilterCount { count: 0 }, - AssertNumberOfVisibleRows { expected: 7 }, - ]) + None, + ) .await; + + // Assert filter count and number of visible rows + test.assert_filter_count(1).await; + test.assert_number_of_visible_rows(1).await; + + // Delete the filter + let filter = test.get_all_filters().await.pop().unwrap(); + test.delete_filter(filter.id, None).await; + + // Assert filter count and number of visible rows after deletion + test.assert_filter_count(0).await; + test.assert_number_of_visible_rows(7).await; } #[tokio::test] async fn grid_filter_update_empty_text_cell_test() { let mut test = DatabaseFilterTest::new().await; let row = test.rows.clone(); - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::RichText, - data: BoxAny::new(TextFilterPB { + + // Create Text "Is Empty" filter + test + .create_data_filter( + None, + FieldType::RichText, + BoxAny::new(TextFilterPB { condition: TextFilterConditionPB::TextIsEmpty, content: "".to_string(), }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: 5, }), - }, - AssertFilterCount { count: 1 }, - UpdateTextCell { - row_id: row[0].id.clone(), - text: "".to_string(), - changed: Some(FilterRowChanged { + ) + .await; + + // Assert filter count + test.assert_filter_count(1).await; + + // Update the text of a row + test + .update_text_cell_with_change( + row[0].id.clone(), + "".to_string(), + Some(FilterRowChanged { showing_num_of_rows: 1, hiding_num_of_rows: 0, }), - }, - ]; - test.run_scripts(scripts).await; + ) + .await; } diff --git a/frontend/rust-lib/flowy-database2/tests/database/filter_test/time_filter_test.rs b/frontend/rust-lib/flowy-database2/tests/database/filter_test/time_filter_test.rs index 82a9e523dd3d..6512947c1620 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/filter_test/time_filter_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/filter_test/time_filter_test.rs @@ -1,30 +1,31 @@ +use crate::database::filter_test::script::{DatabaseFilterTest, FilterRowChanged}; use flowy_database2::entities::{FieldType, NumberFilterConditionPB, TimeFilterPB}; use lib_infra::box_any::BoxAny; -use crate::database::filter_test::script::FilterScript::*; -use crate::database::filter_test::script::{DatabaseFilterTest, FilterRowChanged}; - #[tokio::test] async fn grid_filter_time_is_equal_test() { let mut test = DatabaseFilterTest::new().await; let row_count = test.rows.len(); let expected = 1; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::Time, - data: BoxAny::new(TimeFilterPB { + + // Create Time "Equal" filter + test + .create_data_filter( + None, + FieldType::Time, + BoxAny::new(TimeFilterPB { condition: NumberFilterConditionPB::Equal, content: "75".to_string(), }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, }), - }, - AssertNumberOfVisibleRows { expected }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + // Assert number of visible rows + test.assert_number_of_visible_rows(expected).await; } #[tokio::test] @@ -32,23 +33,25 @@ async fn grid_filter_time_is_less_than_test() { let mut test = DatabaseFilterTest::new().await; let row_count = test.rows.len(); let expected = 1; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::Time, - data: BoxAny::new(TimeFilterPB { + // Create Time "Less Than" filter + test + .create_data_filter( + None, + FieldType::Time, + BoxAny::new(TimeFilterPB { condition: NumberFilterConditionPB::LessThan, content: "80".to_string(), }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, }), - }, - AssertNumberOfVisibleRows { expected }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + // Assert number of visible rows + test.assert_number_of_visible_rows(expected).await; } #[tokio::test] @@ -56,22 +59,25 @@ async fn grid_filter_time_is_less_than_or_equal_test() { let mut test = DatabaseFilterTest::new().await; let row_count = test.rows.len(); let expected = 1; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::Time, - data: BoxAny::new(TimeFilterPB { + + // Create Time "Less Than or Equal" filter + test + .create_data_filter( + None, + FieldType::Time, + BoxAny::new(TimeFilterPB { condition: NumberFilterConditionPB::LessThanOrEqualTo, content: "75".to_string(), }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, }), - }, - AssertNumberOfVisibleRows { expected }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + // Assert number of visible rows + test.assert_number_of_visible_rows(expected).await; } #[tokio::test] @@ -79,22 +85,25 @@ async fn grid_filter_time_is_empty_test() { let mut test = DatabaseFilterTest::new().await; let row_count = test.rows.len(); let expected = 6; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::Time, - data: BoxAny::new(TimeFilterPB { + + // Create Time "Is Empty" filter + test + .create_data_filter( + None, + FieldType::Time, + BoxAny::new(TimeFilterPB { condition: NumberFilterConditionPB::NumberIsEmpty, content: "".to_string(), }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, }), - }, - AssertNumberOfVisibleRows { expected }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + // Assert number of visible rows + test.assert_number_of_visible_rows(expected).await; } #[tokio::test] @@ -102,20 +111,23 @@ async fn grid_filter_time_is_not_empty_test() { let mut test = DatabaseFilterTest::new().await; let row_count = test.rows.len(); let expected = 1; - let scripts = vec![ - CreateDataFilter { - parent_filter_id: None, - field_type: FieldType::Time, - data: BoxAny::new(TimeFilterPB { + + // Create Time "Is Not Empty" filter + test + .create_data_filter( + None, + FieldType::Time, + BoxAny::new(TimeFilterPB { condition: NumberFilterConditionPB::NumberIsNotEmpty, content: "".to_string(), }), - changed: Some(FilterRowChanged { + Some(FilterRowChanged { showing_num_of_rows: 0, hiding_num_of_rows: row_count - expected, }), - }, - AssertNumberOfVisibleRows { expected }, - ]; - test.run_scripts(scripts).await; + ) + .await; + + // Assert number of visible rows + test.assert_number_of_visible_rows(expected).await; } diff --git a/frontend/rust-lib/flowy-database2/tests/database/group_test/date_group_test.rs b/frontend/rust-lib/flowy-database2/tests/database/group_test/date_group_test.rs index f7ccb3d60936..1110e0a8d755 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/group_test/date_group_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/group_test/date_group_test.rs @@ -1,18 +1,13 @@ -use std::collections::HashMap; -use std::vec; - -use chrono::NaiveDateTime; -use chrono::{offset, Duration}; +use crate::database::group_test::script::DatabaseGroupTest; +use chrono::{offset, Duration, NaiveDateTime}; use collab_database::fields::date_type_option::DateCellData; use flowy_database2::entities::{CreateRowPayloadPB, FieldType}; - -use crate::database::group_test::script::DatabaseGroupTest; -use crate::database::group_test::script::GroupScript::*; +use std::collections::HashMap; #[tokio::test] async fn group_by_date_test() { let date_diffs = vec![-1, 0, 7, -15, -1]; - let mut test = DatabaseGroupTest::new().await; + let test = DatabaseGroupTest::new().await; let date_field = test.get_field(FieldType::DateTime).await; for diff in date_diffs { @@ -52,136 +47,68 @@ async fn group_by_date_test() { .format("%Y/%m/%d") .to_string(); - let scripts = vec![ - GroupByField { - field_id: date_field.id.clone(), - }, - AssertGroupCount(7), - AssertGroupRowCount { - group_index: 0, - row_count: 0, - }, - // Added via `make_test_board` - AssertGroupId { - group_index: 1, - group_id: "2022/03/01".to_string(), - }, - AssertGroupRowCount { - group_index: 1, - row_count: 3, - }, - // Added via `make_test_board` - AssertGroupId { - group_index: 2, - group_id: "2022/11/01".to_string(), - }, - AssertGroupRowCount { - group_index: 2, - row_count: 2, - }, - AssertGroupId { - group_index: 3, - group_id: last_30_days, - }, - AssertGroupRowCount { - group_index: 3, - row_count: 1, - }, - AssertGroupId { - group_index: 4, - group_id: last_day, - }, - AssertGroupRowCount { - group_index: 4, - row_count: 2, - }, - AssertGroupId { - group_index: 5, - group_id: today.format("%Y/%m/%d").to_string(), - }, - AssertGroupRowCount { - group_index: 5, - row_count: 1, - }, - AssertGroupId { - group_index: 6, - group_id: next_7_days, - }, - AssertGroupRowCount { - group_index: 6, - row_count: 1, - }, - ]; - test.run_scripts(scripts).await; + // Group by date field + test.group_by_field(&date_field.id).await; + test.assert_group_count(7).await; + + test.assert_group_row_count(0, 0).await; // Empty group + test.assert_group_id(1, "2022/03/01").await; + test.assert_group_row_count(1, 3).await; + test.assert_group_id(2, "2022/11/01").await; + test.assert_group_row_count(2, 2).await; + test.assert_group_id(3, &last_30_days).await; + test.assert_group_row_count(3, 1).await; + test.assert_group_id(4, &last_day).await; + test.assert_group_row_count(4, 2).await; + test + .assert_group_id(5, &today.format("%Y/%m/%d").to_string()) + .await; + test.assert_group_row_count(5, 1).await; + test.assert_group_id(6, &next_7_days).await; + test.assert_group_row_count(6, 1).await; } #[tokio::test] async fn change_row_group_on_date_cell_changed_test() { - let mut test = DatabaseGroupTest::new().await; + let test = DatabaseGroupTest::new().await; let date_field = test.get_field(FieldType::DateTime).await; - let scripts = vec![ - GroupByField { - field_id: date_field.id.clone(), - }, - AssertGroupCount(3), - // Nov 2, 2022 - UpdateGroupedCellWithData { - from_group_index: 1, - row_index: 0, - cell_data: "1667408732".to_string(), - }, - AssertGroupRowCount { - group_index: 1, - row_count: 2, - }, - AssertGroupRowCount { - group_index: 2, - row_count: 3, - }, - ]; - test.run_scripts(scripts).await; + + // Group by date field + test.group_by_field(&date_field.id).await; + test.assert_group_count(3).await; + + // Update date cell to a new timestamp + test + .update_grouped_cell_with_data(1, 0, "1667408732".to_string()) + .await; + + // Check that row counts in groups have updated correctly + test.assert_group_row_count(1, 2).await; + test.assert_group_row_count(2, 3).await; } #[tokio::test] async fn change_date_on_moving_row_to_another_group() { - let mut test = DatabaseGroupTest::new().await; + let test = DatabaseGroupTest::new().await; let date_field = test.get_field(FieldType::DateTime).await; - let scripts = vec![ - GroupByField { - field_id: date_field.id.clone(), - }, - AssertGroupCount(3), - AssertGroupRowCount { - group_index: 1, - row_count: 3, - }, - AssertGroupRowCount { - group_index: 2, - row_count: 2, - }, - MoveRow { - from_group_index: 1, - from_row_index: 0, - to_group_index: 2, - to_row_index: 0, - }, - AssertGroupRowCount { - group_index: 1, - row_count: 2, - }, - AssertGroupRowCount { - group_index: 2, - row_count: 3, - }, - AssertGroupId { - group_index: 2, - group_id: "2022/11/01".to_string(), - }, - ]; - test.run_scripts(scripts).await; + // Group by date field + test.group_by_field(&date_field.id).await; + test.assert_group_count(3).await; + test.assert_group_row_count(1, 3).await; + test.assert_group_row_count(2, 2).await; + + // Move a row from one group to another + test.move_row(1, 0, 2, 0).await; + + // Verify row counts after the move + test.assert_group_row_count(1, 2).await; + test.assert_group_row_count(2, 3).await; + test.assert_group_id(2, "2022/11/01").await; + + // Verify the timestamp of the moved row matches the new group's date let group = test.group_at_index(2).await; - let rows = group.clone().rows; + let rows = group.rows; let row_id = &rows.first().unwrap().id; let row = test .get_rows() @@ -189,13 +116,13 @@ async fn change_date_on_moving_row_to_another_group() { .into_iter() .find(|r| r.id.to_string() == *row_id) .unwrap(); - let cell = row.cells.get(&date_field.id.clone()).unwrap(); + let cell = row.cells.get(&date_field.id).unwrap(); let date_cell = DateCellData::from(cell); - let date_time = + let expected_date_time = NaiveDateTime::parse_from_str("2022/11/01 00:00:00", "%Y/%m/%d %H:%M:%S").unwrap(); assert_eq!( - date_time.and_utc().timestamp(), + expected_date_time.and_utc().timestamp(), date_cell.timestamp.unwrap() ); } diff --git a/frontend/rust-lib/flowy-database2/tests/database/group_test/script.rs b/frontend/rust-lib/flowy-database2/tests/database/group_test/script.rs index f37b37cbbfa3..ca34b550f827 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/group_test/script.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/group_test/script.rs @@ -1,3 +1,4 @@ +use crate::database::database_editor::DatabaseEditorTest; use collab_database::fields::select_type_option::{SelectOption, SingleSelectTypeOption}; use collab_database::fields::Field; use collab_database::rows::RowId; @@ -10,274 +11,185 @@ use flowy_database2::services::field::{ }; use std::time::Duration; -use crate::database::database_editor::DatabaseEditorTest; +pub struct DatabaseGroupTest { + inner: DatabaseEditorTest, +} -pub enum GroupScript { - AssertGroupRowCount { - group_index: usize, - row_count: usize, - }, - AssertGroupCount(usize), - AssertGroup { - group_index: usize, - expected_group: GroupPB, - }, - AssertRow { - group_index: usize, - row_index: usize, - row: RowMetaPB, - }, - MoveRow { +impl DatabaseGroupTest { + pub async fn new() -> Self { + let editor_test = DatabaseEditorTest::new_board().await; + Self { inner: editor_test } + } + + pub async fn assert_group_row_count(&self, group_index: usize, row_count: usize) { + tokio::time::sleep(Duration::from_secs(3)).await; // Sleep to allow updates to complete + assert_eq!(row_count, self.group_at_index(group_index).await.rows.len()); + } + + pub async fn assert_group_count(&self, count: usize) { + let groups = self.editor.load_groups(&self.view_id).await.unwrap(); + assert_eq!(count, groups.len()); + } + + pub async fn move_row( + &self, from_group_index: usize, from_row_index: usize, to_group_index: usize, to_row_index: usize, - }, - CreateRow { - group_index: usize, - }, - DeleteRow { - group_index: usize, - row_index: usize, - }, - UpdateGroupedCell { + ) { + let groups: Vec = self.editor.load_groups(&self.view_id).await.unwrap().items; + let from_group = groups.get(from_group_index).unwrap(); + let from_row = from_group.rows.get(from_row_index).unwrap(); + let to_group = groups.get(to_group_index).unwrap(); + let to_row = to_group.rows.get(to_row_index).unwrap(); + let from_row = RowId::from(from_row.id.clone()); + let to_row = RowId::from(to_row.id.clone()); + + self + .editor + .move_group_row( + &self.view_id, + &from_group.group_id, + &to_group.group_id, + from_row, + Some(to_row), + ) + .await + .unwrap(); + } + + pub async fn assert_row(&self, group_index: usize, row_index: usize, row: RowMetaPB) { + let group = self.group_at_index(group_index).await; + let compare_row = group.rows.get(row_index).unwrap().clone(); + assert_eq!(row.id, compare_row.id); + } + + pub async fn create_row(&self, group_index: usize) { + let group = self.group_at_index(group_index).await; + let params = CreateRowPayloadPB { + view_id: self.view_id.clone(), + row_position: Default::default(), + group_id: Some(group.group_id), + data: Default::default(), + }; + self.editor.create_row(params).await.unwrap(); + } + + pub async fn delete_row(&self, group_index: usize, row_index: usize) { + let row = self.row_at_index(group_index, row_index).await; + let row_ids = vec![RowId::from(row.id)]; + self.editor.delete_rows(&row_ids).await; + tokio::time::sleep(Duration::from_secs(1)).await; // Sleep to allow deletion to propagate + } + + pub async fn update_grouped_cell( + &self, from_group_index: usize, row_index: usize, to_group_index: usize, - }, - UpdateGroupedCellWithData { + ) { + let from_group = self.group_at_index(from_group_index).await; + let to_group = self.group_at_index(to_group_index).await; + let field_id = from_group.field_id; + let field = self.editor.get_field(&field_id).await.unwrap(); + let field_type = FieldType::from(field.field_type); + + let cell = if to_group.is_default { + match field_type { + FieldType::SingleSelect | FieldType::MultiSelect => { + delete_select_option_cell(vec![to_group.group_id.clone()], &field) + }, + _ => panic!("Unsupported group field type"), + } + } else { + match field_type { + FieldType::SingleSelect | FieldType::MultiSelect => { + insert_select_option_cell(vec![to_group.group_id.clone()], &field) + }, + FieldType::URL => insert_url_cell(to_group.group_id.clone(), &field), + _ => panic!("Unsupported group field type"), + } + }; + + let row_id = RowId::from(self.row_at_index(from_group_index, row_index).await.id); + self + .editor + .update_cell(&self.view_id, &row_id, &field_id, cell) + .await + .unwrap(); + } + + pub async fn update_grouped_cell_with_data( + &self, from_group_index: usize, row_index: usize, cell_data: String, - }, - MoveGroup { - from_group_index: usize, - to_group_index: usize, - }, - UpdateSingleSelectSelectOption { - inserted_options: Vec, - }, - GroupByField { - field_id: String, - }, - AssertGroupId { - group_index: usize, - group_id: String, - }, - CreateGroup { - name: String, - }, -} - -pub struct DatabaseGroupTest { - inner: DatabaseEditorTest, -} - -impl DatabaseGroupTest { - pub async fn new() -> Self { - let editor_test = DatabaseEditorTest::new_board().await; - Self { inner: editor_test } + ) { + let from_group = self.group_at_index(from_group_index).await; + let field_id = from_group.field_id; + let field = self.editor.get_field(&field_id).await.unwrap(); + let field_type = FieldType::from(field.field_type); + let cell = match field_type { + FieldType::URL => insert_url_cell(cell_data, &field), + FieldType::DateTime => insert_date_cell( + cell_data.parse::().unwrap(), + None, + None, + Some(true), + &field, + ), + _ => panic!("Unsupported group field type"), + }; + + let row_id = RowId::from(self.row_at_index(from_group_index, row_index).await.id); + self + .editor + .update_cell(&self.view_id, &row_id, &field_id, cell) + .await + .unwrap(); } - pub async fn run_scripts(&mut self, scripts: Vec) { - for script in scripts { - self.run_script(script).await; - } + pub async fn move_group(&self, from_group_index: usize, to_group_index: usize) { + let from_group = self.group_at_index(from_group_index).await; + let to_group = self.group_at_index(to_group_index).await; + self + .editor + .move_group(&self.view_id, &from_group.group_id, &to_group.group_id) + .await + .unwrap(); } - pub async fn run_script(&mut self, script: GroupScript) { - match script { - GroupScript::AssertGroupRowCount { - group_index, - row_count, - } => { - // sleep for 2 seconds to wait for the row count to be updated - tokio::time::sleep(Duration::from_secs(3)).await; - assert_eq!(row_count, self.group_at_index(group_index).await.rows.len()); - }, - GroupScript::AssertGroupCount(count) => { - let groups = self.editor.load_groups(&self.view_id).await.unwrap(); - assert_eq!(count, groups.len()); - }, - GroupScript::MoveRow { - from_group_index, - from_row_index, - to_group_index, - to_row_index, - } => { - let groups: Vec = self.editor.load_groups(&self.view_id).await.unwrap().items; - let from_group = groups.get(from_group_index).unwrap(); - let from_row = from_group.rows.get(from_row_index).unwrap(); - let to_group = groups.get(to_group_index).unwrap(); - let to_row = to_group.rows.get(to_row_index).unwrap(); - let from_row = RowId::from(from_row.id.clone()); - let to_row = RowId::from(to_row.id.clone()); + pub async fn assert_group(&self, group_index: usize, expected_group: GroupPB) { + let group = self.group_at_index(group_index).await; + assert_eq!(group.group_id, expected_group.group_id); + } - self - .editor - .move_group_row( - &self.view_id, - &from_group.group_id, - &to_group.group_id, - from_row, - Some(to_row), - ) - .await - .unwrap(); - }, - GroupScript::AssertRow { - group_index, - row_index, - row, - } => { - // - let group = self.group_at_index(group_index).await; - let compare_row = group.rows.get(row_index).unwrap().clone(); - assert_eq!(row.id, compare_row.id); - }, - GroupScript::CreateRow { group_index } => { - let group = self.group_at_index(group_index).await; - let params = CreateRowPayloadPB { - view_id: self.view_id.clone(), - row_position: Default::default(), - group_id: Some(group.group_id), - data: Default::default(), - }; - let _ = self.editor.create_row(params).await.unwrap(); - }, - GroupScript::DeleteRow { - group_index, - row_index, - } => { - let row = self.row_at_index(group_index, row_index).await; - let row_ids = vec![RowId::from(row.id)]; - self.editor.delete_rows(&row_ids).await; - // sleep for 1 second to wait for the row observation callback - tokio::time::sleep(Duration::from_secs(1)).await; - }, - GroupScript::UpdateGroupedCell { - from_group_index, - row_index, - to_group_index, - } => { - let from_group = self.group_at_index(from_group_index).await; - let to_group = self.group_at_index(to_group_index).await; - let field_id = from_group.field_id; - let field = self.editor.get_field(&field_id).await.unwrap(); - let field_type = FieldType::from(field.field_type); + pub async fn update_single_select_option(&self, inserted_options: Vec) { + self + .edit_single_select_type_option(|type_option| { + for inserted_option in inserted_options { + type_option.insert_option(inserted_option); + } + }) + .await; + } - let cell = if to_group.is_default { - match field_type { - FieldType::SingleSelect => { - delete_select_option_cell(vec![to_group.group_id.clone()], &field) - }, - FieldType::MultiSelect => { - delete_select_option_cell(vec![to_group.group_id.clone()], &field) - }, - _ => { - panic!("Unsupported group field type"); - }, - } - } else { - match field_type { - FieldType::SingleSelect => { - insert_select_option_cell(vec![to_group.group_id.clone()], &field) - }, - FieldType::MultiSelect => { - insert_select_option_cell(vec![to_group.group_id.clone()], &field) - }, - FieldType::URL => insert_url_cell(to_group.group_id.clone(), &field), - _ => { - panic!("Unsupported group field type"); - }, - } - }; + pub async fn group_by_field(&self, field_id: &str) { + self + .editor + .group_by_field(&self.view_id, field_id) + .await + .unwrap(); + } - let row_id = RowId::from(self.row_at_index(from_group_index, row_index).await.id); - self - .editor - .update_cell(&self.view_id, &row_id, &field_id, cell) - .await - .unwrap(); - }, - GroupScript::UpdateGroupedCellWithData { - from_group_index, - row_index, - cell_data, - } => { - let from_group = self.group_at_index(from_group_index).await; - let field_id = from_group.field_id; - let field = self.editor.get_field(&field_id).await.unwrap(); - let field_type = FieldType::from(field.field_type); - let cell = match field_type { - FieldType::URL => insert_url_cell(cell_data, &field), - FieldType::DateTime => insert_date_cell( - cell_data.parse::().unwrap(), - None, - None, - Some(true), - &field, - ), - _ => { - panic!("Unsupported group field type"); - }, - }; + pub async fn assert_group_id(&self, group_index: usize, group_id: &str) { + let group = self.group_at_index(group_index).await; + assert_eq!(group_id, group.group_id, "group index: {}", group_index); + } - let row_id = RowId::from(self.row_at_index(from_group_index, row_index).await.id); - self - .editor - .update_cell(&self.view_id, &row_id, &field_id, cell) - .await - .unwrap(); - }, - GroupScript::MoveGroup { - from_group_index, - to_group_index, - } => { - let from_group = self.group_at_index(from_group_index).await; - let to_group = self.group_at_index(to_group_index).await; - self - .editor - .move_group(&self.view_id, &from_group.group_id, &to_group.group_id) - .await - .unwrap(); - }, - GroupScript::AssertGroup { - group_index, - expected_group: group_pb, - } => { - let group = self.group_at_index(group_index).await; - assert_eq!(group.group_id, group_pb.group_id); - }, - GroupScript::UpdateSingleSelectSelectOption { inserted_options } => { - self - .edit_single_select_type_option(|type_option| { - for inserted_option in inserted_options { - type_option.insert_option(inserted_option); - } - }) - .await; - }, - GroupScript::GroupByField { field_id } => { - self - .editor - .group_by_field(&self.view_id, &field_id) - .await - .unwrap(); - }, - GroupScript::AssertGroupId { - group_index, - group_id, - } => { - let group = self.group_at_index(group_index).await; - assert_eq!(group_id, group.group_id, "group index: {}", group_index); - }, - GroupScript::CreateGroup { name } => self - .editor - .create_group(&self.view_id, &name) - .await - .unwrap(), - } + pub async fn create_group(&self, name: &str) { + self.editor.create_group(&self.view_id, name).await.unwrap(); } pub async fn group_at_index(&self, index: usize) -> GroupPB { @@ -319,10 +231,7 @@ impl DatabaseGroupTest { .get_fields() .await .into_iter() - .find(|field| { - let ft = FieldType::from(field.field_type); - ft == field_type - }) + .find(|field| FieldType::from(field.field_type) == field_type) .unwrap() } } diff --git a/frontend/rust-lib/flowy-database2/tests/database/group_test/test.rs b/frontend/rust-lib/flowy-database2/tests/database/group_test/test.rs index a543f519d22d..b93df800e184 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/group_test/test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/group_test/test.rs @@ -1,517 +1,234 @@ use crate::database::group_test::script::DatabaseGroupTest; -use crate::database::group_test::script::GroupScript::*; use collab_database::fields::select_type_option::SelectOption; #[tokio::test] async fn group_init_test() { - let mut test = DatabaseGroupTest::new().await; - let scripts = vec![ - AssertGroupCount(4), - AssertGroupRowCount { - group_index: 1, - row_count: 2, - }, - AssertGroupRowCount { - group_index: 2, - row_count: 2, - }, - AssertGroupRowCount { - group_index: 3, - row_count: 1, - }, - AssertGroupRowCount { - group_index: 0, - row_count: 0, - }, - ]; - test.run_scripts(scripts).await; + let test = DatabaseGroupTest::new().await; + test.assert_group_count(4).await; + test.assert_group_row_count(1, 2).await; + test.assert_group_row_count(2, 2).await; + test.assert_group_row_count(3, 1).await; + test.assert_group_row_count(0, 0).await; } #[tokio::test] async fn group_move_row_test() { - let mut test = DatabaseGroupTest::new().await; + let test = DatabaseGroupTest::new().await; let group = test.group_at_index(1).await; - let scripts = vec![ - // Move the row at 0 in group0 to group1 at 1 - MoveRow { - from_group_index: 1, - from_row_index: 0, - to_group_index: 1, - to_row_index: 1, - }, - AssertGroupRowCount { - group_index: 1, - row_count: 2, - }, - AssertRow { - group_index: 1, - row_index: 1, - row: group.rows.first().unwrap().clone(), - }, - ]; - test.run_scripts(scripts).await; + + test.move_row(1, 0, 1, 1).await; + test.assert_group_row_count(1, 2).await; + test + .assert_row(1, 1, group.rows.first().unwrap().clone()) + .await; } #[tokio::test] async fn test_row_movement_between_groups_with_assertions() { - let mut test = DatabaseGroupTest::new().await; + let test = DatabaseGroupTest::new().await; for _ in 0..5 { - let scripts = vec![ - MoveRow { - from_group_index: 1, - from_row_index: 0, - to_group_index: 2, - to_row_index: 1, - }, - AssertGroupRowCount { - group_index: 1, - row_count: 1, - }, - AssertGroupRowCount { - group_index: 2, - row_count: 3, - }, - // Move the row back to origin group - MoveRow { - from_group_index: 2, - from_row_index: 1, - to_group_index: 1, - to_row_index: 0, - }, - AssertGroupRowCount { - group_index: 2, - row_count: 2, - }, - AssertGroupRowCount { - group_index: 1, - row_count: 2, - }, - ]; - test.run_scripts(scripts).await; + test.move_row(1, 0, 2, 1).await; + test.assert_group_row_count(1, 1).await; + test.assert_group_row_count(2, 3).await; + + // Move the row back to the original group + test.move_row(2, 1, 1, 0).await; + test.assert_group_row_count(2, 2).await; + test.assert_group_row_count(1, 2).await; + tokio::time::sleep(tokio::time::Duration::from_millis(500)).await; } } #[tokio::test] async fn group_move_two_row_to_other_group_test() { - let mut test = DatabaseGroupTest::new().await; + let test = DatabaseGroupTest::new().await; let group_1 = test.group_at_index(1).await; - let scripts = vec![ - // Move row at index 0 from group 1 to group 2 at index 1 - MoveRow { - from_group_index: 1, - from_row_index: 0, - to_group_index: 2, - to_row_index: 1, - }, - AssertGroupRowCount { - group_index: 1, - row_count: 1, - }, - AssertGroupRowCount { - group_index: 2, - row_count: 3, - }, - AssertRow { - group_index: 2, - row_index: 1, - row: group_1.rows.first().unwrap().clone(), - }, - ]; - test.run_scripts(scripts).await; + + test.move_row(1, 0, 2, 1).await; + test.assert_group_row_count(1, 1).await; + test.assert_group_row_count(2, 3).await; + test + .assert_row(2, 1, group_1.rows.first().unwrap().clone()) + .await; let group_1 = test.group_at_index(1).await; - // Move row at index 0 from group 1 to group 2 at index 1 - let scripts = vec![ - MoveRow { - from_group_index: 1, - from_row_index: 0, - to_group_index: 2, - to_row_index: 1, - }, - AssertGroupRowCount { - group_index: 1, - row_count: 0, - }, - AssertGroupRowCount { - group_index: 2, - row_count: 4, - }, - AssertRow { - group_index: 2, - row_index: 1, - row: group_1.rows.first().unwrap().clone(), - }, - ]; - test.run_scripts(scripts).await; + test.move_row(1, 0, 2, 1).await; + test.assert_group_row_count(1, 0).await; + test.assert_group_row_count(2, 4).await; + test + .assert_row(2, 1, group_1.rows.first().unwrap().clone()) + .await; } #[tokio::test] async fn group_move_row_to_other_group_and_reorder_from_up_to_down_test() { - let mut test = DatabaseGroupTest::new().await; + let test = DatabaseGroupTest::new().await; let group_1 = test.group_at_index(1).await; let group_2 = test.group_at_index(2).await; - let scripts = vec![ - MoveRow { - from_group_index: 1, - from_row_index: 0, - to_group_index: 2, - to_row_index: 1, - }, - AssertRow { - group_index: 2, - row_index: 1, - row: group_1.rows.first().unwrap().clone(), - }, - ]; - test.run_scripts(scripts).await; - - let scripts = vec![ - MoveRow { - from_group_index: 2, - from_row_index: 0, - to_group_index: 2, - to_row_index: 2, - }, - AssertRow { - group_index: 2, - row_index: 2, - row: group_2.rows.first().unwrap().clone(), - }, - ]; - test.run_scripts(scripts).await; + + test.move_row(1, 0, 2, 1).await; + test + .assert_row(2, 1, group_1.rows.first().unwrap().clone()) + .await; + + test.move_row(2, 0, 2, 2).await; + test + .assert_row(2, 2, group_2.rows.first().unwrap().clone()) + .await; } #[tokio::test] async fn group_move_row_to_other_group_and_reorder_from_bottom_to_up_test() { - let mut test = DatabaseGroupTest::new().await; - let scripts = vec![MoveRow { - from_group_index: 1, - from_row_index: 0, - to_group_index: 2, - to_row_index: 1, - }]; - test.run_scripts(scripts).await; + let test = DatabaseGroupTest::new().await; + test.move_row(1, 0, 2, 1).await; let group = test.group_at_index(2).await; - let scripts = vec![ - AssertGroupRowCount { - group_index: 2, - row_count: 3, - }, - MoveRow { - from_group_index: 2, - from_row_index: 2, - to_group_index: 2, - to_row_index: 0, - }, - AssertRow { - group_index: 2, - row_index: 0, - row: group.rows.get(2).unwrap().clone(), - }, - ]; - test.run_scripts(scripts).await; + test.assert_group_row_count(2, 3).await; + + test.move_row(2, 2, 2, 0).await; + test + .assert_row(2, 0, group.rows.get(2).unwrap().clone()) + .await; } + #[tokio::test] async fn group_create_row_test() { - let mut test = DatabaseGroupTest::new().await; - let scripts = vec![ - CreateRow { group_index: 1 }, - AssertGroupRowCount { - group_index: 1, - row_count: 3, - }, - CreateRow { group_index: 2 }, - CreateRow { group_index: 2 }, - AssertGroupRowCount { - group_index: 2, - row_count: 4, - }, - ]; - test.run_scripts(scripts).await; + let test = DatabaseGroupTest::new().await; + test.create_row(1).await; + test.assert_group_row_count(1, 3).await; + + test.create_row(2).await; + test.create_row(2).await; + test.assert_group_row_count(2, 4).await; } #[tokio::test] async fn group_delete_row_test() { - let mut test = DatabaseGroupTest::new().await; - let scripts = vec![ - DeleteRow { - group_index: 1, - row_index: 0, - }, - AssertGroupRowCount { - group_index: 1, - row_count: 1, - }, - ]; - test.run_scripts(scripts).await; + let test = DatabaseGroupTest::new().await; + test.delete_row(1, 0).await; + test.assert_group_row_count(1, 1).await; } #[tokio::test] async fn group_delete_all_row_test() { - let mut test = DatabaseGroupTest::new().await; - let scripts = vec![ - DeleteRow { - group_index: 1, - row_index: 0, - }, - DeleteRow { - group_index: 1, - row_index: 0, - }, - AssertGroupRowCount { - group_index: 1, - row_count: 0, - }, - ]; - test.run_scripts(scripts).await; + let test = DatabaseGroupTest::new().await; + test.delete_row(1, 0).await; + test.delete_row(1, 0).await; + test.assert_group_row_count(1, 0).await; } #[tokio::test] async fn group_update_row_test() { - let mut test = DatabaseGroupTest::new().await; - let scripts = vec![ - // Update the row at 0 in group0 by setting the row's group field data - UpdateGroupedCell { - from_group_index: 1, - row_index: 0, - to_group_index: 2, - }, - AssertGroupRowCount { - group_index: 1, - row_count: 1, - }, - AssertGroupRowCount { - group_index: 2, - row_count: 3, - }, - ]; - test.run_scripts(scripts).await; + let test = DatabaseGroupTest::new().await; + test.update_grouped_cell(1, 0, 2).await; + test.assert_group_row_count(1, 1).await; + test.assert_group_row_count(2, 3).await; } #[tokio::test] async fn group_reorder_group_test() { - let mut test = DatabaseGroupTest::new().await; - let scripts = vec![ - // Update the row at 0 in group0 by setting the row's group field data - UpdateGroupedCell { - from_group_index: 1, - row_index: 0, - to_group_index: 2, - }, - AssertGroupRowCount { - group_index: 1, - row_count: 1, - }, - AssertGroupRowCount { - group_index: 2, - row_count: 3, - }, - ]; - test.run_scripts(scripts).await; + let test = DatabaseGroupTest::new().await; + test.update_grouped_cell(1, 0, 2).await; + test.assert_group_row_count(1, 1).await; + test.assert_group_row_count(2, 3).await; } #[tokio::test] async fn group_move_to_default_group_test() { - let mut test = DatabaseGroupTest::new().await; - let scripts = vec![ - UpdateGroupedCell { - from_group_index: 1, - row_index: 0, - to_group_index: 0, - }, - AssertGroupRowCount { - group_index: 1, - row_count: 1, - }, - AssertGroupRowCount { - group_index: 0, - row_count: 1, - }, - ]; - test.run_scripts(scripts).await; + let test = DatabaseGroupTest::new().await; + test.update_grouped_cell(1, 0, 0).await; + test.assert_group_row_count(1, 1).await; + test.assert_group_row_count(0, 1).await; } #[tokio::test] async fn group_move_from_default_group_test() { - let mut test = DatabaseGroupTest::new().await; - // Move one row from group 1 to group 0 - let scripts = vec![ - UpdateGroupedCell { - from_group_index: 1, - row_index: 0, - to_group_index: 0, - }, - AssertGroupRowCount { - group_index: 1, - row_count: 1, - }, - AssertGroupRowCount { - group_index: 0, - row_count: 1, - }, - ]; - test.run_scripts(scripts).await; - - // Move one row from group 0 to group 1 - let scripts = vec![ - UpdateGroupedCell { - from_group_index: 0, - row_index: 0, - to_group_index: 1, - }, - AssertGroupRowCount { - group_index: 1, - row_count: 2, - }, - AssertGroupRowCount { - group_index: 0, - row_count: 0, - }, - ]; - test.run_scripts(scripts).await; + let test = DatabaseGroupTest::new().await; + test.update_grouped_cell(1, 0, 0).await; + test.assert_group_row_count(1, 1).await; + test.assert_group_row_count(0, 1).await; + + test.update_grouped_cell(0, 0, 1).await; + test.assert_group_row_count(1, 2).await; + test.assert_group_row_count(0, 0).await; } #[tokio::test] async fn group_move_group_test() { - let mut test = DatabaseGroupTest::new().await; + let test = DatabaseGroupTest::new().await; let group_0 = test.group_at_index(0).await; let group_1 = test.group_at_index(1).await; - let scripts = vec![ - MoveGroup { - from_group_index: 0, - to_group_index: 1, - }, - AssertGroupRowCount { - group_index: 0, - row_count: 2, - }, - AssertGroup { - group_index: 0, - expected_group: group_1, - }, - AssertGroupRowCount { - group_index: 1, - row_count: 0, - }, - AssertGroup { - group_index: 1, - expected_group: group_0, - }, - ]; - test.run_scripts(scripts).await; + + test.move_group(0, 1).await; + test.assert_group_row_count(0, 2).await; + test.assert_group(0, group_1).await; + test.assert_group_row_count(1, 0).await; + test.assert_group(1, group_0).await; } #[tokio::test] async fn group_move_group_row_after_move_group_test() { - let mut test = DatabaseGroupTest::new().await; + let test = DatabaseGroupTest::new().await; let group_1 = test.group_at_index(1).await; let group_2 = test.group_at_index(2).await; - let scripts = vec![ - MoveGroup { - from_group_index: 1, - to_group_index: 2, - }, - AssertGroup { - group_index: 1, - expected_group: group_2, - }, - AssertGroup { - group_index: 2, - expected_group: group_1, - }, - MoveRow { - from_group_index: 1, - from_row_index: 0, - to_group_index: 2, - to_row_index: 0, - }, - AssertGroupRowCount { - group_index: 1, - row_count: 1, - }, - AssertGroupRowCount { - group_index: 2, - row_count: 3, - }, - ]; - test.run_scripts(scripts).await; + + test.move_group(1, 2).await; + test.assert_group(1, group_2).await; + test.assert_group(2, group_1).await; + + test.move_row(1, 0, 2, 0).await; + test.assert_group_row_count(1, 1).await; + test.assert_group_row_count(2, 3).await; } #[tokio::test] async fn group_move_group_to_default_group_pos_test() { - let mut test = DatabaseGroupTest::new().await; + let test = DatabaseGroupTest::new().await; let group_0 = test.group_at_index(0).await; let group_3 = test.group_at_index(3).await; - let scripts = vec![ - MoveGroup { - from_group_index: 3, - to_group_index: 0, - }, - AssertGroup { - group_index: 0, - expected_group: group_3, - }, - AssertGroup { - group_index: 1, - expected_group: group_0, - }, - ]; - test.run_scripts(scripts).await; + + test.move_group(3, 0).await; + test.assert_group(0, group_3).await; + test.assert_group(1, group_0).await; } #[tokio::test] async fn group_insert_single_select_option_test() { - let mut test = DatabaseGroupTest::new().await; + let test = DatabaseGroupTest::new().await; let new_option_name = "New option"; - let scripts = vec![ - AssertGroupCount(4), - UpdateSingleSelectSelectOption { - inserted_options: vec![SelectOption { - id: new_option_name.to_string(), - name: new_option_name.to_string(), - color: Default::default(), - }], - }, - AssertGroupCount(5), - ]; - test.run_scripts(scripts).await; + + test.assert_group_count(4).await; + test + .update_single_select_option(vec![SelectOption { + id: new_option_name.to_string(), + name: new_option_name.to_string(), + color: Default::default(), + }]) + .await; + + test.assert_group_count(5).await; let new_group = test.group_at_index(4).await; assert_eq!(new_group.group_id, new_option_name); } #[tokio::test] async fn group_group_by_other_field() { - let mut test = DatabaseGroupTest::new().await; + let test = DatabaseGroupTest::new().await; let multi_select_field = test.get_multi_select_field().await; - let scripts = vec![ - GroupByField { - field_id: multi_select_field.id.clone(), - }, - AssertGroupRowCount { - group_index: 1, - row_count: 3, - }, - AssertGroupRowCount { - group_index: 2, - row_count: 2, - }, - AssertGroupCount(4), - ]; - test.run_scripts(scripts).await; + + test.group_by_field(&multi_select_field.id).await; + test.assert_group_row_count(1, 3).await; + test.assert_group_row_count(2, 2).await; + test.assert_group_count(4).await; } #[tokio::test] async fn group_manual_create_new_group() { - let mut test = DatabaseGroupTest::new().await; + let test = DatabaseGroupTest::new().await; let new_group_name = "Resumed"; - let scripts = vec![ - AssertGroupCount(4), - CreateGroup { - name: new_group_name.to_string(), - }, - AssertGroupCount(5), - ]; - test.run_scripts(scripts).await; + + test.assert_group_count(4).await; + test.create_group(new_group_name).await; + test.assert_group_count(5).await; } diff --git a/frontend/rust-lib/flowy-database2/tests/database/group_test/url_group_test.rs b/frontend/rust-lib/flowy-database2/tests/database/group_test/url_group_test.rs index 83a38b07d371..182d7742e135 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/group_test/url_group_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/group_test/url_group_test.rs @@ -1,148 +1,80 @@ use crate::database::group_test::script::DatabaseGroupTest; -use crate::database::group_test::script::GroupScript::*; #[tokio::test] async fn group_group_by_url() { - let mut test = DatabaseGroupTest::new().await; + let test = DatabaseGroupTest::new().await; let url_field = test.get_url_field().await; - let scripts = vec![ - GroupByField { - field_id: url_field.id.clone(), - }, - // no status group - AssertGroupRowCount { - group_index: 0, - row_count: 2, - }, - // https://appflowy.io - AssertGroupRowCount { - group_index: 1, - row_count: 2, - }, - // https://github.com/AppFlowy-IO/AppFlowy - AssertGroupRowCount { - group_index: 2, - row_count: 1, - }, - AssertGroupCount(3), - ]; - test.run_scripts(scripts).await; + + // Group by URL field + test.group_by_field(&url_field.id).await; + + // Check group row counts + test.assert_group_row_count(0, 2).await; // No status group + test.assert_group_row_count(1, 2).await; // https://appflowy.io group + test.assert_group_row_count(2, 1).await; // https://github.com/AppFlowy-IO/AppFlowy group + test.assert_group_count(3).await; } #[tokio::test] async fn group_alter_url_to_another_group_url_test() { - let mut test = DatabaseGroupTest::new().await; + let test = DatabaseGroupTest::new().await; let url_field = test.get_url_field().await; - let scripts = vec![ - GroupByField { - field_id: url_field.id.clone(), - }, - // no status group - AssertGroupRowCount { - group_index: 0, - row_count: 2, - }, - // https://appflowy.io - AssertGroupRowCount { - group_index: 1, - row_count: 2, - }, - // https://github.com/AppFlowy-IO/AppFlowy - AssertGroupRowCount { - group_index: 2, - row_count: 1, - }, - // When moving the last row from 2nd group to 1nd group, the 2nd group will be removed - UpdateGroupedCell { - from_group_index: 2, - row_index: 0, - to_group_index: 1, - }, - AssertGroupCount(2), - ]; - test.run_scripts(scripts).await; + + // Group by URL field + test.group_by_field(&url_field.id).await; + + // Check initial group row counts + test.assert_group_row_count(0, 2).await; // No status group + test.assert_group_row_count(1, 2).await; // https://appflowy.io group + test.assert_group_row_count(2, 1).await; // https://github.com/AppFlowy-IO/AppFlowy group + + // Move the last row from group 2 to group 1 + test.update_grouped_cell(2, 0, 1).await; + + // Verify group counts after moving + test.assert_group_count(2).await; } #[tokio::test] async fn group_alter_url_to_new_url_test() { - let mut test = DatabaseGroupTest::new().await; + let test = DatabaseGroupTest::new().await; let url_field = test.get_url_field().await; - let scripts = vec![ - GroupByField { - field_id: url_field.id.clone(), - }, - // When moving the last row from 2nd group to 1nd group, the 2nd group will be removed - UpdateGroupedCellWithData { - from_group_index: 0, - row_index: 0, - cell_data: "https://github.com/AppFlowy-IO".to_string(), - }, - // no status group - AssertGroupRowCount { - group_index: 0, - row_count: 1, - }, - // https://appflowy.io - AssertGroupRowCount { - group_index: 1, - row_count: 2, - }, - // https://github.com/AppFlowy-IO/AppFlowy - AssertGroupRowCount { - group_index: 2, - row_count: 1, - }, - AssertGroupRowCount { - group_index: 3, - row_count: 1, - }, - AssertGroupCount(4), - ]; - test.run_scripts(scripts).await; + + // Group by URL field + test.group_by_field(&url_field.id).await; + + // Change the URL of a row to a new value + test + .update_grouped_cell_with_data(0, 0, "https://github.com/AppFlowy-IO".to_string()) + .await; + + // Verify group row counts after URL update + test.assert_group_row_count(0, 1).await; // No status group + test.assert_group_row_count(1, 2).await; // https://appflowy.io group + test.assert_group_row_count(2, 1).await; // https://github.com/AppFlowy-IO/AppFlowy group + test.assert_group_row_count(3, 1).await; // https://github.com/AppFlowy-IO group + test.assert_group_count(4).await; } #[tokio::test] async fn group_move_url_group_row_test() { - let mut test = DatabaseGroupTest::new().await; + let test = DatabaseGroupTest::new().await; let url_field = test.get_url_field().await; - let scripts = vec![ - GroupByField { - field_id: url_field.id.clone(), - }, - // no status group - AssertGroupRowCount { - group_index: 0, - row_count: 2, - }, - // https://appflowy.io - AssertGroupRowCount { - group_index: 1, - row_count: 2, - }, - // https://github.com/AppFlowy-IO/AppFlowy - AssertGroupRowCount { - group_index: 2, - row_count: 1, - }, - AssertGroupCount(3), - MoveRow { - from_group_index: 0, - from_row_index: 0, - to_group_index: 1, - to_row_index: 0, - }, - AssertGroupRowCount { - group_index: 0, - row_count: 1, - }, - AssertGroupRowCount { - group_index: 1, - row_count: 3, - }, - AssertGroupRowCount { - group_index: 2, - row_count: 1, - }, - ]; - test.run_scripts(scripts).await; + + // Group by URL field + test.group_by_field(&url_field.id).await; + + // Check initial group row counts + test.assert_group_row_count(0, 2).await; // No status group + test.assert_group_row_count(1, 2).await; // https://appflowy.io group + test.assert_group_row_count(2, 1).await; // https://github.com/AppFlowy-IO/AppFlowy group + test.assert_group_count(3).await; + + // Move a row from one group to another + test.move_row(0, 0, 1, 0).await; + + // Verify row counts after the move + test.assert_group_row_count(0, 1).await; + test.assert_group_row_count(1, 3).await; + test.assert_group_row_count(2, 1).await; } diff --git a/frontend/rust-lib/flowy-database2/tests/database/layout_test/script.rs b/frontend/rust-lib/flowy-database2/tests/database/layout_test/script.rs index 6da423d3713a..61a619389861 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/layout_test/script.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/layout_test/script.rs @@ -6,15 +6,6 @@ use flowy_database2::services::setting::{BoardLayoutSetting, CalendarLayoutSetti use crate::database::database_editor::DatabaseEditorTest; -pub enum LayoutScript { - AssertBoardLayoutSetting { expected: BoardLayoutSetting }, - AssertCalendarLayoutSetting { expected: CalendarLayoutSetting }, - UpdateBoardLayoutSetting { new_setting: BoardLayoutSetting }, - AssertDefaultAllCalendarEvents, - AssertAllCalendarEventsCount { expected: usize }, - UpdateDatabaseLayout { layout: DatabaseLayout }, -} - pub struct DatabaseLayoutTest { database_test: DatabaseEditorTest, } @@ -55,100 +46,97 @@ impl DatabaseLayoutTest { .unwrap() } - pub async fn run_scripts(&mut self, scripts: Vec) { - for script in scripts { - self.run_script(script).await; - } + pub async fn update_database_layout(&mut self, layout: DatabaseLayout) { + self + .database_test + .editor + .update_view_layout(&self.database_test.view_id, layout) + .await + .unwrap(); + } + + pub async fn assert_all_calendar_events_count(&self, expected: usize) { + let events = self + .database_test + .editor + .get_all_calendar_events(&self.database_test.view_id) + .await; + assert_eq!(events.len(), expected); + } + + pub async fn assert_board_layout_setting(&self, expected: BoardLayoutSetting) { + let view_id = self.database_test.view_id.clone(); + let layout_ty = DatabaseLayout::Board; + + let layout_settings = self.get_layout_setting(&view_id, layout_ty).await; + + assert!(layout_settings.calendar.is_none()); + assert_eq!( + layout_settings.board.unwrap().hide_ungrouped_column, + expected.hide_ungrouped_column + ); + } + + pub async fn assert_calendar_layout_setting(&self, expected: CalendarLayoutSetting) { + let view_id = self.database_test.view_id.clone(); + let layout_ty = DatabaseLayout::Calendar; + + let layout_settings = self.get_layout_setting(&view_id, layout_ty).await; + + assert!(layout_settings.board.is_none()); + + let calendar_setting = layout_settings.calendar.unwrap(); + assert_eq!(calendar_setting.layout_ty, expected.layout_ty); + assert_eq!( + calendar_setting.first_day_of_week, + expected.first_day_of_week + ); + assert_eq!(calendar_setting.show_weekends, expected.show_weekends); + } + + pub async fn update_board_layout_setting(&mut self, new_setting: BoardLayoutSetting) { + let changeset = LayoutSettingChangeset { + view_id: self.database_test.view_id.clone(), + layout_type: DatabaseLayout::Board, + board: Some(new_setting), + calendar: None, + }; + self + .database_test + .editor + .set_layout_setting(&self.database_test.view_id, changeset) + .await + .unwrap(); } - pub async fn run_script(&mut self, script: LayoutScript) { - match script { - LayoutScript::UpdateDatabaseLayout { layout } => { - self - .database_test - .editor - .update_view_layout(&self.database_test.view_id, layout) - .await - .unwrap(); - }, - LayoutScript::AssertAllCalendarEventsCount { expected } => { - let events = self - .database_test - .editor - .get_all_calendar_events(&self.database_test.view_id) - .await; - assert_eq!(events.len(), expected); - }, - LayoutScript::AssertBoardLayoutSetting { expected } => { - let view_id = self.database_test.view_id.clone(); - let layout_ty = DatabaseLayout::Board; - - let layout_settings = self.get_layout_setting(&view_id, layout_ty).await; - - assert!(layout_settings.calendar.is_none()); - assert_eq!( - layout_settings.board.unwrap().hide_ungrouped_column, - expected.hide_ungrouped_column - ); - }, - LayoutScript::AssertCalendarLayoutSetting { expected } => { - let view_id = self.database_test.view_id.clone(); - let layout_ty = DatabaseLayout::Calendar; - - let layout_settings = self.get_layout_setting(&view_id, layout_ty).await; - - assert!(layout_settings.board.is_none()); - - let calendar_setting = layout_settings.calendar.unwrap(); - assert_eq!(calendar_setting.layout_ty, expected.layout_ty); - assert_eq!( - calendar_setting.first_day_of_week, - expected.first_day_of_week - ); - assert_eq!(calendar_setting.show_weekends, expected.show_weekends); - }, - LayoutScript::UpdateBoardLayoutSetting { new_setting } => { - let changeset = LayoutSettingChangeset { - view_id: self.database_test.view_id.clone(), - layout_type: DatabaseLayout::Board, - board: Some(new_setting), - calendar: None, - }; - self - .database_test - .editor - .set_layout_setting(&self.database_test.view_id, changeset) - .await - .unwrap() - }, - LayoutScript::AssertDefaultAllCalendarEvents => { - let events = self - .database_test - .editor - .get_all_calendar_events(&self.database_test.view_id) - .await; - assert_eq!(events.len(), 5); - - for (index, event) in events.into_iter().enumerate() { - if index == 0 { - assert_eq!(event.title, "A"); - assert_eq!(event.timestamp, Some(1678090778)); - } - - if index == 1 { - assert_eq!(event.title, "B"); - assert_eq!(event.timestamp, Some(1677917978)); - } - if index == 2 { - assert_eq!(event.title, "C"); - assert_eq!(event.timestamp, Some(1679213978)); - } - if index == 4 { - assert_eq!(event.title, "E"); - assert_eq!(event.timestamp, Some(1678695578)); - } - } - }, + pub async fn assert_default_all_calendar_events(&self) { + let events = self + .database_test + .editor + .get_all_calendar_events(&self.database_test.view_id) + .await; + assert_eq!(events.len(), 5); + + for (index, event) in events.into_iter().enumerate() { + match index { + 0 => { + assert_eq!(event.title, "A"); + assert_eq!(event.timestamp, Some(1678090778)); + }, + 1 => { + assert_eq!(event.title, "B"); + assert_eq!(event.timestamp, Some(1677917978)); + }, + 2 => { + assert_eq!(event.title, "C"); + assert_eq!(event.timestamp, Some(1679213978)); + }, + 4 => { + assert_eq!(event.title, "E"); + assert_eq!(event.timestamp, Some(1678695578)); + }, + _ => {}, + } } } } diff --git a/frontend/rust-lib/flowy-database2/tests/database/layout_test/test.rs b/frontend/rust-lib/flowy-database2/tests/database/layout_test/test.rs index 41f2f88d0eef..e949bd917959 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/layout_test/test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/layout_test/test.rs @@ -1,9 +1,6 @@ -use collab_database::views::DatabaseLayout; -use flowy_database2::services::setting::BoardLayoutSetting; -use flowy_database2::services::setting::CalendarLayoutSetting; - use crate::database::layout_test::script::DatabaseLayoutTest; -use crate::database::layout_test::script::LayoutScript::*; +use collab_database::views::DatabaseLayout; +use flowy_database2::services::setting::{BoardLayoutSetting, CalendarLayoutSetting}; #[tokio::test] async fn board_layout_setting_test() { @@ -13,46 +10,44 @@ async fn board_layout_setting_test() { hide_ungrouped_column: true, ..default_board_setting }; - let scripts = vec![ - AssertBoardLayoutSetting { - expected: default_board_setting, - }, - UpdateBoardLayoutSetting { - new_setting: new_board_setting.clone(), - }, - AssertBoardLayoutSetting { - expected: new_board_setting, - }, - ]; - test.run_scripts(scripts).await; + + // Assert the initial default board layout setting + test + .assert_board_layout_setting(default_board_setting) + .await; + + // Update the board layout setting and assert the changes + test + .update_board_layout_setting(new_board_setting.clone()) + .await; + test.assert_board_layout_setting(new_board_setting).await; } #[tokio::test] async fn calendar_initial_layout_setting_test() { - let mut test = DatabaseLayoutTest::new_calendar().await; + let test = DatabaseLayoutTest::new_calendar().await; let date_field = test.get_first_date_field().await; let default_calendar_setting = CalendarLayoutSetting::new(date_field.id.clone()); - let scripts = vec![AssertCalendarLayoutSetting { - expected: default_calendar_setting, - }]; - test.run_scripts(scripts).await; + + // Assert the initial calendar layout setting + test + .assert_calendar_layout_setting(default_calendar_setting) + .await; } #[tokio::test] async fn calendar_get_events_test() { - let mut test = DatabaseLayoutTest::new_calendar().await; - let scripts = vec![AssertDefaultAllCalendarEvents]; - test.run_scripts(scripts).await; + let test = DatabaseLayoutTest::new_calendar().await; + + // Assert the default calendar events + test.assert_default_all_calendar_events().await; } #[tokio::test] async fn grid_to_calendar_layout_test() { let mut test = DatabaseLayoutTest::new_no_date_grid().await; - let scripts = vec![ - UpdateDatabaseLayout { - layout: DatabaseLayout::Calendar, - }, - AssertAllCalendarEventsCount { expected: 3 }, - ]; - test.run_scripts(scripts).await; + + // Update layout to calendar and assert the number of calendar events + test.update_database_layout(DatabaseLayout::Calendar).await; + test.assert_all_calendar_events_count(3).await; } diff --git a/frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/pre_fill_row_according_to_filter_test.rs b/frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/pre_fill_row_according_to_filter_test.rs index e391eabce872..a40dac350e69 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/pre_fill_row_according_to_filter_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/pre_fill_row_according_to_filter_test.rs @@ -1,6 +1,4 @@ -use crate::database::pre_fill_cell_test::script::{ - DatabasePreFillRowCellTest, PreFillRowCellTestScript::*, -}; +use crate::database::pre_fill_cell_test::script::DatabasePreFillRowCellTest; use collab_database::fields::select_type_option::SELECTION_IDS_SEPARATOR; use flowy_database2::entities::{ CheckboxFilterConditionPB, CheckboxFilterPB, DateFilterConditionPB, DateFilterPB, FieldType, @@ -8,287 +6,223 @@ use flowy_database2::entities::{ TextFilterPB, }; -// This suite of tests cover creating an empty row into a database that has -// active filters. Where appropriate, the row's cell data will be pre-filled -// into the row's cells before creating it in collab. - #[tokio::test] async fn according_to_text_contains_filter_test() { let mut test = DatabasePreFillRowCellTest::new().await; - let text_field = test.get_first_field(FieldType::RichText).await; - let scripts = vec![ - InsertFilter { - filter: FilterDataPB { - field_id: text_field.id.clone(), - field_type: FieldType::RichText, - data: TextFilterPB { - condition: TextFilterConditionPB::TextContains, - content: "sample".to_string(), - } - .try_into() - .unwrap(), - }, - }, - Wait { milliseconds: 100 }, - CreateEmptyRow, - Wait { milliseconds: 100 }, - ]; - - test.run_scripts(scripts).await; - - let scripts = vec![ - AssertCellExistence { + test + .insert_filter(FilterDataPB { field_id: text_field.id.clone(), - row_index: test.rows.len() - 1, - exists: true, - }, - AssertCellContent { - field_id: text_field.id, - row_index: test.rows.len() - 1, - - expected_content: "sample".to_string(), - }, - ]; - - test.run_scripts(scripts).await; + field_type: FieldType::RichText, + data: TextFilterPB { + condition: TextFilterConditionPB::TextContains, + content: "sample".to_string(), + } + .try_into() + .unwrap(), + }) + .await; + + test.wait(100).await; + test.create_empty_row().await; + test.wait(100).await; + + test + .assert_cell_existence(text_field.id.clone(), test.rows.len() - 1, true) + .await; + test + .assert_cell_content(text_field.id, test.rows.len() - 1, "sample".to_string()) + .await; } #[tokio::test] async fn according_to_empty_text_contains_filter_test() { let mut test = DatabasePreFillRowCellTest::new().await; - let text_field = test.get_first_field(FieldType::RichText).await; - let scripts = vec![ - InsertFilter { - filter: FilterDataPB { - field_id: text_field.id.clone(), - field_type: FieldType::RichText, - data: TextFilterPB { - condition: TextFilterConditionPB::TextContains, - content: "".to_string(), - } - .try_into() - .unwrap(), - }, - }, - Wait { milliseconds: 100 }, - CreateEmptyRow, - Wait { milliseconds: 100 }, - ]; - - test.run_scripts(scripts).await; - - let scripts = vec![AssertCellExistence { - field_id: text_field.id.clone(), - row_index: test.rows.len() - 1, - exists: false, - }]; - - test.run_scripts(scripts).await; + test + .insert_filter(FilterDataPB { + field_id: text_field.id.clone(), + field_type: FieldType::RichText, + data: TextFilterPB { + condition: TextFilterConditionPB::TextContains, + content: "".to_string(), + } + .try_into() + .unwrap(), + }) + .await; + + test.wait(100).await; + test.create_empty_row().await; + test.wait(100).await; + + test + .assert_cell_existence(text_field.id.clone(), test.rows.len() - 1, false) + .await; } #[tokio::test] async fn according_to_text_is_not_empty_filter_test() { let mut test = DatabasePreFillRowCellTest::new().await; - let text_field = test.get_first_field(FieldType::RichText).await; - let scripts = vec![ - AssertRowCount(7), - InsertFilter { - filter: FilterDataPB { - field_id: text_field.id.clone(), - field_type: FieldType::RichText, - data: TextFilterPB { - condition: TextFilterConditionPB::TextIsNotEmpty, - content: "".to_string(), - } - .try_into() - .unwrap(), - }, - }, - Wait { milliseconds: 100 }, - AssertRowCount(6), - CreateEmptyRow, - Wait { milliseconds: 100 }, - AssertRowCount(6), - ]; - - test.run_scripts(scripts).await; + test.assert_row_count(7).await; + + test + .insert_filter(FilterDataPB { + field_id: text_field.id.clone(), + field_type: FieldType::RichText, + data: TextFilterPB { + condition: TextFilterConditionPB::TextIsNotEmpty, + content: "".to_string(), + } + .try_into() + .unwrap(), + }) + .await; + + test.wait(100).await; + test.assert_row_count(6).await; + test.create_empty_row().await; + test.wait(100).await; + test.assert_row_count(6).await; } #[tokio::test] async fn according_to_checkbox_is_unchecked_filter_test() { let mut test = DatabasePreFillRowCellTest::new().await; - let checkbox_field = test.get_first_field(FieldType::Checkbox).await; - let scripts = vec![ - AssertRowCount(7), - InsertFilter { - filter: FilterDataPB { - field_id: checkbox_field.id.clone(), - field_type: FieldType::Checkbox, - data: CheckboxFilterPB { - condition: CheckboxFilterConditionPB::IsUnChecked, - } - .try_into() - .unwrap(), - }, - }, - Wait { milliseconds: 100 }, - AssertRowCount(4), - CreateEmptyRow, - Wait { milliseconds: 100 }, - AssertRowCount(5), - ]; - - test.run_scripts(scripts).await; - - let scripts = vec![AssertCellExistence { - field_id: checkbox_field.id.clone(), - row_index: 4, - exists: false, - }]; - - test.run_scripts(scripts).await; + test.assert_row_count(7).await; + + test + .insert_filter(FilterDataPB { + field_id: checkbox_field.id.clone(), + field_type: FieldType::Checkbox, + data: CheckboxFilterPB { + condition: CheckboxFilterConditionPB::IsUnChecked, + } + .try_into() + .unwrap(), + }) + .await; + + test.wait(100).await; + test.assert_row_count(4).await; + test.create_empty_row().await; + test.wait(100).await; + test.assert_row_count(5).await; + + test + .assert_cell_existence(checkbox_field.id.clone(), 4, false) + .await; } #[tokio::test] async fn according_to_checkbox_is_checked_filter_test() { let mut test = DatabasePreFillRowCellTest::new().await; - let checkbox_field = test.get_first_field(FieldType::Checkbox).await; - let scripts = vec![ - AssertRowCount(7), - InsertFilter { - filter: FilterDataPB { - field_id: checkbox_field.id.clone(), - field_type: FieldType::Checkbox, - data: CheckboxFilterPB { - condition: CheckboxFilterConditionPB::IsChecked, - } - .try_into() - .unwrap(), - }, - }, - Wait { milliseconds: 100 }, - AssertRowCount(3), - CreateEmptyRow, - Wait { milliseconds: 100 }, - AssertRowCount(4), - ]; - - test.run_scripts(scripts).await; - - let scripts = vec![ - AssertCellExistence { + test.assert_row_count(7).await; + + test + .insert_filter(FilterDataPB { field_id: checkbox_field.id.clone(), - row_index: 3, - exists: true, - }, - AssertCellContent { - field_id: checkbox_field.id, - row_index: 3, - - expected_content: "Yes".to_string(), - }, - ]; - - test.run_scripts(scripts).await; + field_type: FieldType::Checkbox, + data: CheckboxFilterPB { + condition: CheckboxFilterConditionPB::IsChecked, + } + .try_into() + .unwrap(), + }) + .await; + + test.wait(100).await; + test.assert_row_count(3).await; + test.create_empty_row().await; + test.wait(100).await; + test.assert_row_count(4).await; + + test + .assert_cell_existence(checkbox_field.id.clone(), 3, true) + .await; + test + .assert_cell_content(checkbox_field.id, 3, "Yes".to_string()) + .await; } #[tokio::test] async fn according_to_date_time_is_filter_test() { let mut test = DatabasePreFillRowCellTest::new().await; - let datetime_field = test.get_first_field(FieldType::DateTime).await; - let scripts = vec![ - AssertRowCount(7), - InsertFilter { - filter: FilterDataPB { - field_id: datetime_field.id.clone(), - field_type: FieldType::DateTime, - data: DateFilterPB { - condition: DateFilterConditionPB::DateStartsOn, - timestamp: Some(1710510086), - ..Default::default() - } - .try_into() - .unwrap(), - }, - }, - Wait { milliseconds: 100 }, - AssertRowCount(0), - CreateEmptyRow, - Wait { milliseconds: 100 }, - AssertRowCount(1), - ]; - - test.run_scripts(scripts).await; - - let scripts = vec![ - AssertCellExistence { + test.assert_row_count(7).await; + + test + .insert_filter(FilterDataPB { field_id: datetime_field.id.clone(), - row_index: 0, - exists: true, - }, - AssertCellContent { - field_id: datetime_field.id, - row_index: 0, - - expected_content: "2024/03/15".to_string(), - }, - ]; - - test.run_scripts(scripts).await; + field_type: FieldType::DateTime, + data: DateFilterPB { + condition: DateFilterConditionPB::DateStartsOn, + timestamp: Some(1710510086), + ..Default::default() + } + .try_into() + .unwrap(), + }) + .await; + + test.wait(100).await; + test.assert_row_count(0).await; + test.create_empty_row().await; + test.wait(100).await; + test.assert_row_count(1).await; + + test + .assert_cell_existence(datetime_field.id.clone(), 0, true) + .await; + test + .assert_cell_content(datetime_field.id, 0, "2024/03/15".to_string()) + .await; } #[tokio::test] async fn according_to_invalid_date_time_is_filter_test() { let mut test = DatabasePreFillRowCellTest::new().await; - let datetime_field = test.get_first_field(FieldType::DateTime).await; - let scripts = vec![ - AssertRowCount(7), - InsertFilter { - filter: FilterDataPB { - field_id: datetime_field.id.clone(), - field_type: FieldType::DateTime, - data: DateFilterPB { - condition: DateFilterConditionPB::DateStartsOn, - timestamp: None, - ..Default::default() - } - .try_into() - .unwrap(), - }, - }, - Wait { milliseconds: 100 }, - AssertRowCount(7), - CreateEmptyRow, - Wait { milliseconds: 100 }, - AssertRowCount(8), - AssertCellExistence { + test.assert_row_count(7).await; + + test + .insert_filter(FilterDataPB { field_id: datetime_field.id.clone(), - row_index: test.rows.len(), - exists: false, - }, - ]; + field_type: FieldType::DateTime, + data: DateFilterPB { + condition: DateFilterConditionPB::DateStartsOn, + timestamp: None, + ..Default::default() + } + .try_into() + .unwrap(), + }) + .await; + + test.wait(100).await; + test.assert_row_count(7).await; + test.create_empty_row().await; + test.wait(100).await; + test.assert_row_count(8).await; - test.run_scripts(scripts).await; + test + .assert_cell_existence(datetime_field.id.clone(), test.rows.len() - 1, false) + .await; } #[tokio::test] async fn according_to_select_option_is_filter_test() { let mut test = DatabasePreFillRowCellTest::new().await; - let multi_select_field = test.get_first_field(FieldType::MultiSelect).await; let options = test .get_multi_select_type_option(&multi_select_field.id) @@ -305,45 +239,38 @@ async fn according_to_select_option_is_filter_test() { .collect::>() .join(SELECTION_IDS_SEPARATOR); - let scripts = vec![ - AssertRowCount(7), - InsertFilter { - filter: FilterDataPB { - field_id: multi_select_field.id.clone(), - field_type: FieldType::MultiSelect, - data: SelectOptionFilterPB { - condition: SelectOptionFilterConditionPB::OptionIs, - option_ids: ids, - } - .try_into() - .unwrap(), - }, - }, - Wait { milliseconds: 100 }, - AssertRowCount(1), - CreateEmptyRow, - Wait { milliseconds: 100 }, - AssertRowCount(2), - AssertCellExistence { + test.assert_row_count(7).await; + + test + .insert_filter(FilterDataPB { field_id: multi_select_field.id.clone(), - row_index: 1, - exists: true, - }, - AssertCellContent { - field_id: multi_select_field.id, - row_index: 1, - - expected_content: stringified_expected, - }, - ]; - - test.run_scripts(scripts).await; + field_type: FieldType::MultiSelect, + data: SelectOptionFilterPB { + condition: SelectOptionFilterConditionPB::OptionIs, + option_ids: ids, + } + .try_into() + .unwrap(), + }) + .await; + + test.wait(100).await; + test.assert_row_count(1).await; + test.create_empty_row().await; + test.wait(100).await; + test.assert_row_count(2).await; + + test + .assert_cell_existence(multi_select_field.id.clone(), 1, true) + .await; + test + .assert_cell_content(multi_select_field.id, 1, stringified_expected) + .await; } #[tokio::test] async fn according_to_select_option_contains_filter_test() { let mut test = DatabasePreFillRowCellTest::new().await; - let multi_select_field = test.get_first_field(FieldType::MultiSelect).await; let options = test .get_multi_select_type_option(&multi_select_field.id) @@ -356,45 +283,38 @@ async fn according_to_select_option_contains_filter_test() { .collect(); let stringified_expected = filtering_options.first().unwrap().name.clone(); - let scripts = vec![ - AssertRowCount(7), - InsertFilter { - filter: FilterDataPB { - field_id: multi_select_field.id.clone(), - field_type: FieldType::MultiSelect, - data: SelectOptionFilterPB { - condition: SelectOptionFilterConditionPB::OptionContains, - option_ids: ids, - } - .try_into() - .unwrap(), - }, - }, - Wait { milliseconds: 100 }, - AssertRowCount(5), - CreateEmptyRow, - Wait { milliseconds: 100 }, - AssertRowCount(6), - AssertCellExistence { + test.assert_row_count(7).await; + + test + .insert_filter(FilterDataPB { field_id: multi_select_field.id.clone(), - row_index: 5, - exists: true, - }, - AssertCellContent { - field_id: multi_select_field.id, - row_index: 5, - - expected_content: stringified_expected, - }, - ]; - - test.run_scripts(scripts).await; + field_type: FieldType::MultiSelect, + data: SelectOptionFilterPB { + condition: SelectOptionFilterConditionPB::OptionContains, + option_ids: ids, + } + .try_into() + .unwrap(), + }) + .await; + + test.wait(100).await; + test.assert_row_count(5).await; + test.create_empty_row().await; + test.wait(100).await; + test.assert_row_count(6).await; + + test + .assert_cell_existence(multi_select_field.id.clone(), 5, true) + .await; + test + .assert_cell_content(multi_select_field.id, 5, stringified_expected) + .await; } #[tokio::test] async fn according_to_select_option_is_not_empty_filter_test() { let mut test = DatabasePreFillRowCellTest::new().await; - let multi_select_field = test.get_first_field(FieldType::MultiSelect).await; let options = test .get_multi_select_type_option(&multi_select_field.id) @@ -402,37 +322,31 @@ async fn according_to_select_option_is_not_empty_filter_test() { let stringified_expected = options.first().unwrap().name.clone(); - let scripts = vec![ - AssertRowCount(7), - InsertFilter { - filter: FilterDataPB { - field_id: multi_select_field.id.clone(), - field_type: FieldType::MultiSelect, - data: SelectOptionFilterPB { - condition: SelectOptionFilterConditionPB::OptionIsNotEmpty, - ..Default::default() - } - .try_into() - .unwrap(), - }, - }, - Wait { milliseconds: 100 }, - AssertRowCount(5), - CreateEmptyRow, - Wait { milliseconds: 100 }, - AssertRowCount(6), - AssertCellExistence { + test.assert_row_count(7).await; + + test + .insert_filter(FilterDataPB { field_id: multi_select_field.id.clone(), - row_index: 5, - exists: true, - }, - AssertCellContent { - field_id: multi_select_field.id, - row_index: 5, - - expected_content: stringified_expected, - }, - ]; - - test.run_scripts(scripts).await; + field_type: FieldType::MultiSelect, + data: SelectOptionFilterPB { + condition: SelectOptionFilterConditionPB::OptionIsNotEmpty, + ..Default::default() + } + .try_into() + .unwrap(), + }) + .await; + + test.wait(100).await; + test.assert_row_count(5).await; + test.create_empty_row().await; + test.wait(100).await; + test.assert_row_count(6).await; + + test + .assert_cell_existence(multi_select_field.id.clone(), 5, true) + .await; + test + .assert_cell_content(multi_select_field.id, 5, stringified_expected) + .await; } diff --git a/frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/pre_fill_row_with_payload_test.rs b/frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/pre_fill_row_with_payload_test.rs index 213eade83901..8c5bea419d23 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/pre_fill_row_with_payload_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/pre_fill_row_with_payload_test.rs @@ -1,155 +1,113 @@ -use crate::database::pre_fill_cell_test::script::{ - DatabasePreFillRowCellTest, PreFillRowCellTestScript::*, -}; +use crate::database::pre_fill_cell_test::script::DatabasePreFillRowCellTest; use collab_database::fields::date_type_option::DateCellData; use collab_database::fields::select_type_option::SELECTION_IDS_SEPARATOR; use flowy_database2::entities::{CreateRowPayloadPB, FieldType}; use std::collections::HashMap; -// This suite of tests cover creating a row using `CreateRowPayloadPB` that passes -// in some cell data in its `data` field of `HashMap` which is a -// map of `field_id` to its corresponding cell data as a String. If valid, the cell -// data will be pre-filled into the row's cells before creating it in collab. - #[tokio::test] async fn row_data_payload_with_empty_hashmap_test() { let mut test = DatabasePreFillRowCellTest::new().await; - let text_field = test.get_first_field(FieldType::RichText).await; - let scripts = vec![ - CreateRowWithPayload { - payload: CreateRowPayloadPB { - view_id: test.view_id.clone(), - data: HashMap::new(), - ..Default::default() - }, - }, - Wait { milliseconds: 100 }, - AssertCellExistence { - field_id: text_field.id.clone(), - row_index: test.rows.len(), - exists: false, - }, - AssertCellContent { - field_id: text_field.id, - row_index: test.rows.len(), - - expected_content: "".to_string(), - }, - ]; - - test.run_scripts(scripts).await; + test + .create_row_with_payload(CreateRowPayloadPB { + view_id: test.view_id.clone(), + data: HashMap::new(), + ..Default::default() + }) + .await; + + test.wait(100).await; + let index = test.rows.len() - 1; + test + .assert_cell_existence(text_field.id.clone(), index, false) + .await; + test + .assert_cell_content(text_field.id, index, "".to_string()) + .await; } #[tokio::test] async fn row_data_payload_with_unknown_field_id_test() { let mut test = DatabasePreFillRowCellTest::new().await; - let text_field = test.get_first_field(FieldType::RichText).await; let malformed_field_id = "this_field_id_will_never_exist"; - let scripts = vec![ - CreateRowWithPayload { - payload: CreateRowPayloadPB { - view_id: test.view_id.clone(), - data: HashMap::from([( - malformed_field_id.to_string(), - "sample cell data".to_string(), - )]), - ..Default::default() - }, - }, - Wait { milliseconds: 100 }, - AssertCellExistence { - field_id: text_field.id.clone(), - row_index: test.rows.len(), - exists: false, - }, - AssertCellContent { - field_id: text_field.id.clone(), - row_index: test.rows.len(), - - expected_content: "".to_string(), - }, - AssertCellExistence { - field_id: malformed_field_id.to_string(), - row_index: test.rows.len(), - exists: false, - }, - ]; - - test.run_scripts(scripts).await; + test + .create_row_with_payload(CreateRowPayloadPB { + view_id: test.view_id.clone(), + data: HashMap::from([( + malformed_field_id.to_string(), + "sample cell data".to_string(), + )]), + ..Default::default() + }) + .await; + + test.wait(100).await; + let index = test.rows.len() - 1; + test + .assert_cell_existence(text_field.id.clone(), index, false) + .await; + test + .assert_cell_content(text_field.id.clone(), index, "".to_string()) + .await; + test + .assert_cell_existence(malformed_field_id.to_string(), index, false) + .await; } #[tokio::test] async fn row_data_payload_with_empty_string_text_data_test() { let mut test = DatabasePreFillRowCellTest::new().await; - let text_field = test.get_first_field(FieldType::RichText).await; let cell_data = ""; - let scripts = vec![ - CreateRowWithPayload { - payload: CreateRowPayloadPB { - view_id: test.view_id.clone(), - data: HashMap::from([(text_field.id.clone(), cell_data.to_string())]), - ..Default::default() - }, - }, - Wait { milliseconds: 100 }, - AssertCellExistence { - field_id: text_field.id.clone(), - row_index: test.rows.len(), - exists: true, - }, - AssertCellContent { - field_id: text_field.id, - row_index: test.rows.len(), - - expected_content: cell_data.to_string(), - }, - ]; - - test.run_scripts(scripts).await; + test + .create_row_with_payload(CreateRowPayloadPB { + view_id: test.view_id.clone(), + data: HashMap::from([(text_field.id.clone(), cell_data.to_string())]), + ..Default::default() + }) + .await; + + test.wait(100).await; + let index = test.rows.len() - 1; + test + .assert_cell_existence(text_field.id.clone(), index, true) + .await; + test + .assert_cell_content(text_field.id, index, cell_data.to_string()) + .await; } #[tokio::test] async fn row_data_payload_with_text_data_test() { let mut test = DatabasePreFillRowCellTest::new().await; - let text_field = test.get_first_field(FieldType::RichText).await; let cell_data = "sample cell data"; - let scripts = vec![ - CreateRowWithPayload { - payload: CreateRowPayloadPB { - view_id: test.view_id.clone(), - data: HashMap::from([(text_field.id.clone(), cell_data.to_string())]), - ..Default::default() - }, - }, - Wait { milliseconds: 100 }, - AssertCellExistence { - field_id: text_field.id.clone(), - row_index: test.rows.len(), - exists: true, - }, - AssertCellContent { - field_id: text_field.id.clone(), - row_index: test.rows.len(), - - expected_content: cell_data.to_string(), - }, - ]; - - test.run_scripts(scripts).await; + test + .create_row_with_payload(CreateRowPayloadPB { + view_id: test.view_id.clone(), + data: HashMap::from([(text_field.id.clone(), cell_data.to_string())]), + ..Default::default() + }) + .await; + + test.wait(100).await; + let index = test.rows.len() - 1; + test + .assert_cell_existence(text_field.id.clone(), index, true) + .await; + test + .assert_cell_content(text_field.id.clone(), index, cell_data.to_string()) + .await; } #[tokio::test] async fn row_data_payload_with_multi_text_data_test() { let mut test = DatabasePreFillRowCellTest::new().await; - let text_field = test.get_first_field(FieldType::RichText).await; let number_field = test.get_first_field(FieldType::Number).await; let url_field = test.get_first_field(FieldType::URL).await; @@ -158,93 +116,67 @@ async fn row_data_payload_with_multi_text_data_test() { let number_cell_data = "1234"; let url_cell_data = "appflowy.io"; - let scripts = vec![ - CreateRowWithPayload { - payload: CreateRowPayloadPB { - view_id: test.view_id.clone(), - data: HashMap::from([ - (text_field.id.clone(), text_cell_data.to_string()), - (number_field.id.clone(), number_cell_data.to_string()), - (url_field.id.clone(), url_cell_data.to_string()), - ]), - ..Default::default() - }, - }, - Wait { milliseconds: 100 }, - AssertCellExistence { - field_id: text_field.id.clone(), - row_index: test.rows.len(), - exists: true, - }, - AssertCellContent { - field_id: text_field.id, - row_index: test.rows.len(), - - expected_content: text_cell_data.to_string(), - }, - AssertCellExistence { - field_id: number_field.id.clone(), - row_index: test.rows.len(), - exists: true, - }, - AssertCellContent { - field_id: number_field.id, - row_index: test.rows.len(), - - expected_content: "$1,234".to_string(), - }, - AssertCellExistence { - field_id: url_field.id.clone(), - row_index: test.rows.len(), - exists: true, - }, - AssertCellContent { - field_id: url_field.id, - row_index: test.rows.len(), - - expected_content: url_cell_data.to_string(), - }, - ]; - - test.run_scripts(scripts).await; + test + .create_row_with_payload(CreateRowPayloadPB { + view_id: test.view_id.clone(), + data: HashMap::from([ + (text_field.id.clone(), text_cell_data.to_string()), + (number_field.id.clone(), number_cell_data.to_string()), + (url_field.id.clone(), url_cell_data.to_string()), + ]), + ..Default::default() + }) + .await; + + test.wait(100).await; + let index = test.rows.len() - 1; + test + .assert_cell_existence(text_field.id.clone(), index, true) + .await; + test + .assert_cell_content(text_field.id, index, text_cell_data.to_string()) + .await; + test + .assert_cell_existence(number_field.id.clone(), index, true) + .await; + test + .assert_cell_content(number_field.id, index, "$1,234".to_string()) + .await; + test + .assert_cell_existence(url_field.id.clone(), index, true) + .await; + test + .assert_cell_content(url_field.id, index, url_cell_data.to_string()) + .await; } #[tokio::test] async fn row_data_payload_with_date_time_test() { let mut test = DatabasePreFillRowCellTest::new().await; - let date_field = test.get_first_field(FieldType::DateTime).await; let cell_data = "1710510086"; - let scripts = vec![ - CreateRowWithPayload { - payload: CreateRowPayloadPB { - view_id: test.view_id.clone(), - data: HashMap::from([(date_field.id.clone(), cell_data.to_string())]), - ..Default::default() - }, - }, - Wait { milliseconds: 100 }, - AssertCellExistence { - field_id: date_field.id.clone(), - row_index: test.rows.len(), - exists: true, - }, - AssertCellContent { - field_id: date_field.id.clone(), - row_index: test.rows.len(), - - expected_content: "2024/03/15".to_string(), - }, - ]; - - test.run_scripts(scripts).await; + test + .create_row_with_payload(CreateRowPayloadPB { + view_id: test.view_id.clone(), + data: HashMap::from([(date_field.id.clone(), cell_data.to_string())]), + ..Default::default() + }) + .await; + + test.wait(100).await; + let index = test.rows.len() - 1; + test + .assert_cell_existence(date_field.id.clone(), index, true) + .await; + test + .assert_cell_content(date_field.id.clone(), index, "2024/03/15".to_string()) + .await; } #[tokio::test] async fn row_data_payload_with_invalid_date_time_test() { let mut test = DatabasePreFillRowCellTest::new().await; - let date_field = test.get_first_field(FieldType::DateTime).await; let cell_data = DateCellData { timestamp: Some(1710510086), @@ -252,61 +184,47 @@ async fn row_data_payload_with_invalid_date_time_test() { } .to_string(); - let scripts = vec![ - CreateRowWithPayload { - payload: CreateRowPayloadPB { - view_id: test.view_id.clone(), - data: HashMap::from([(date_field.id.clone(), cell_data.to_string())]), - ..Default::default() - }, - }, - Wait { milliseconds: 100 }, - AssertCellExistence { - field_id: date_field.id.clone(), - row_index: test.rows.len(), - exists: false, - }, - ]; - - test.run_scripts(scripts).await; + test + .create_row_with_payload(CreateRowPayloadPB { + view_id: test.view_id.clone(), + data: HashMap::from([(date_field.id.clone(), cell_data.to_string())]), + ..Default::default() + }) + .await; + + test.wait(100).await; + let index = test.rows.len() - 1; + test + .assert_cell_existence(date_field.id.clone(), index, false) + .await; } #[tokio::test] async fn row_data_payload_with_checkbox_test() { let mut test = DatabasePreFillRowCellTest::new().await; - let checkbox_field = test.get_first_field(FieldType::Checkbox).await; let cell_data = "Yes"; - let scripts = vec![ - CreateRowWithPayload { - payload: CreateRowPayloadPB { - view_id: test.view_id.clone(), - data: HashMap::from([(checkbox_field.id.clone(), cell_data.to_string())]), - ..Default::default() - }, - }, - Wait { milliseconds: 100 }, - AssertCellExistence { - field_id: checkbox_field.id.clone(), - row_index: test.rows.len(), - exists: true, - }, - AssertCellContent { - field_id: checkbox_field.id.clone(), - row_index: test.rows.len(), - - expected_content: cell_data.to_string(), - }, - ]; - - test.run_scripts(scripts).await; + test + .create_row_with_payload(CreateRowPayloadPB { + view_id: test.view_id.clone(), + data: HashMap::from([(checkbox_field.id.clone(), cell_data.to_string())]), + ..Default::default() + }) + .await; + let index = test.rows.len() - 1; + test.wait(100).await; + test + .assert_cell_existence(checkbox_field.id.clone(), index, true) + .await; + test + .assert_cell_content(checkbox_field.id.clone(), index, cell_data.to_string()) + .await; } #[tokio::test] async fn row_data_payload_with_select_option_test() { let mut test = DatabasePreFillRowCellTest::new().await; - let multi_select_field = test.get_first_field(FieldType::MultiSelect).await; let options = test .get_multi_select_type_option(&multi_select_field.id) @@ -324,35 +242,27 @@ async fn row_data_payload_with_select_option_test() { .collect::>() .join(SELECTION_IDS_SEPARATOR); - let scripts = vec![ - CreateRowWithPayload { - payload: CreateRowPayloadPB { - view_id: test.view_id.clone(), - data: HashMap::from([(multi_select_field.id.clone(), ids)]), - ..Default::default() - }, - }, - Wait { milliseconds: 100 }, - AssertCellExistence { - field_id: multi_select_field.id.clone(), - row_index: test.rows.len(), - exists: true, - }, - AssertCellContent { - field_id: multi_select_field.id.clone(), - row_index: test.rows.len(), - - expected_content: stringified_cell_data, - }, - ]; - - test.run_scripts(scripts).await; + test + .create_row_with_payload(CreateRowPayloadPB { + view_id: test.view_id.clone(), + data: HashMap::from([(multi_select_field.id.clone(), ids)]), + ..Default::default() + }) + .await; + + test.wait(100).await; + let index = test.rows.len() - 1; + test + .assert_cell_existence(multi_select_field.id.clone(), index, true) + .await; + test + .assert_cell_content(multi_select_field.id.clone(), index, stringified_cell_data) + .await; } #[tokio::test] async fn row_data_payload_with_invalid_select_option_id_test() { let mut test = DatabasePreFillRowCellTest::new().await; - let multi_select_field = test.get_first_field(FieldType::MultiSelect).await; let mut options = test .get_multi_select_type_option(&multi_select_field.id) @@ -361,34 +271,27 @@ async fn row_data_payload_with_invalid_select_option_id_test() { let first_id = options.swap_remove(0).id; let ids = [first_id.clone(), "nonsense".to_string()].join(SELECTION_IDS_SEPARATOR); - let scripts = vec![ - CreateRowWithPayload { - payload: CreateRowPayloadPB { - view_id: test.view_id.clone(), - data: HashMap::from([(multi_select_field.id.clone(), ids.to_string())]), - ..Default::default() - }, - }, - Wait { milliseconds: 100 }, - AssertCellExistence { - field_id: multi_select_field.id.clone(), - row_index: test.rows.len(), - exists: true, - }, - AssertSelectOptionCellStrict { - field_id: multi_select_field.id.clone(), - row_index: test.rows.len(), - expected_content: first_id, - }, - ]; - - test.run_scripts(scripts).await; + test + .create_row_with_payload(CreateRowPayloadPB { + view_id: test.view_id.clone(), + data: HashMap::from([(multi_select_field.id.clone(), ids.to_string())]), + ..Default::default() + }) + .await; + + test.wait(100).await; + let index = test.rows.len() - 1; + test + .assert_cell_existence(multi_select_field.id.clone(), index, true) + .await; + test + .assert_select_option_cell_strict(multi_select_field.id.clone(), index, first_id) + .await; } #[tokio::test] async fn row_data_payload_with_too_many_select_option_test() { let mut test = DatabasePreFillRowCellTest::new().await; - let single_select_field = test.get_first_field(FieldType::SingleSelect).await; let mut options = test .get_single_select_type_option(&single_select_field.id) @@ -402,26 +305,20 @@ async fn row_data_payload_with_too_many_select_option_test() { let stringified_cell_data = options.swap_remove(0).id; - let scripts = vec![ - CreateRowWithPayload { - payload: CreateRowPayloadPB { - view_id: test.view_id.clone(), - data: HashMap::from([(single_select_field.id.clone(), ids.to_string())]), - ..Default::default() - }, - }, - Wait { milliseconds: 100 }, - AssertCellExistence { - field_id: single_select_field.id.clone(), - row_index: test.rows.len(), - exists: true, - }, - AssertSelectOptionCellStrict { - field_id: single_select_field.id.clone(), - row_index: test.rows.len(), - expected_content: stringified_cell_data, - }, - ]; - - test.run_scripts(scripts).await; + test + .create_row_with_payload(CreateRowPayloadPB { + view_id: test.view_id.clone(), + data: HashMap::from([(single_select_field.id.clone(), ids.to_string())]), + ..Default::default() + }) + .await; + + test.wait(100).await; + let index = test.rows.len() - 1; + test + .assert_cell_existence(single_select_field.id.clone(), index, true) + .await; + test + .assert_select_option_cell_strict(single_select_field.id.clone(), index, stringified_cell_data) + .await; } diff --git a/frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/script.rs b/frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/script.rs index cc6000a62d92..8bc93cf0de27 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/script.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/pre_fill_cell_test/script.rs @@ -5,35 +5,6 @@ use flowy_database2::services::cell::stringify_cell; use std::ops::{Deref, DerefMut}; use std::time::Duration; -pub enum PreFillRowCellTestScript { - CreateEmptyRow, - CreateRowWithPayload { - payload: CreateRowPayloadPB, - }, - InsertFilter { - filter: FilterDataPB, - }, - AssertRowCount(usize), - AssertCellExistence { - field_id: String, - row_index: usize, - exists: bool, - }, - AssertCellContent { - field_id: String, - row_index: usize, - expected_content: String, - }, - AssertSelectOptionCellStrict { - field_id: String, - row_index: usize, - expected_content: String, - }, - Wait { - milliseconds: u64, - }, -} - pub struct DatabasePreFillRowCellTest { inner: DatabaseEditorTest, } @@ -44,87 +15,83 @@ impl DatabasePreFillRowCellTest { Self { inner: editor_test } } - pub async fn run_scripts(&mut self, scripts: Vec) { - for script in scripts { - self.run_script(script).await; - } + pub async fn create_empty_row(&mut self) { + let params = CreateRowPayloadPB { + view_id: self.view_id.clone(), + ..Default::default() + }; + let row_detail = self.editor.create_row(params).await.unwrap().unwrap(); + self + .row_by_row_id + .insert(row_detail.row.id.to_string(), row_detail.into()); + self.rows = self.get_rows().await; } - pub async fn run_script(&mut self, script: PreFillRowCellTestScript) { - match script { - PreFillRowCellTestScript::CreateEmptyRow => { - let params = CreateRowPayloadPB { - view_id: self.view_id.clone(), - ..Default::default() - }; - let row_detail = self.editor.create_row(params).await.unwrap().unwrap(); - self - .row_by_row_id - .insert(row_detail.row.id.to_string(), row_detail.into()); - self.rows = self.get_rows().await; - }, - PreFillRowCellTestScript::CreateRowWithPayload { payload } => { - let row_detail = self.editor.create_row(payload).await.unwrap().unwrap(); - self - .row_by_row_id - .insert(row_detail.row.id.to_string(), row_detail.into()); - self.rows = self.get_rows().await; - }, - PreFillRowCellTestScript::InsertFilter { filter } => self - .editor - .modify_view_filters( - &self.view_id, - InsertFilterPB { - parent_filter_id: None, - data: filter, - } - .try_into() - .unwrap(), - ) - .await + pub async fn create_row_with_payload(&mut self, payload: CreateRowPayloadPB) { + let row_detail = self.editor.create_row(payload).await.unwrap().unwrap(); + self + .row_by_row_id + .insert(row_detail.row.id.to_string(), row_detail.into()); + self.rows = self.get_rows().await; + } + + pub async fn insert_filter(&mut self, filter: FilterDataPB) { + self + .editor + .modify_view_filters( + &self.view_id, + InsertFilterPB { + parent_filter_id: None, + data: filter, + } + .try_into() .unwrap(), - PreFillRowCellTestScript::AssertRowCount(expected_row_count) => { - let rows = self.editor.get_all_rows(&self.view_id).await.unwrap(); - assert_eq!(expected_row_count, rows.len()); - }, - PreFillRowCellTestScript::AssertCellExistence { - field_id, - row_index, - exists, - } => { - let rows = self.editor.get_all_rows(&self.view_id).await.unwrap(); - let row = rows.get(row_index).unwrap(); - let cell = row.cells.get(&field_id).cloned(); - assert_eq!(exists, cell.is_some()); - }, - PreFillRowCellTestScript::AssertCellContent { - field_id, - row_index, - expected_content, - } => { - let field = self.editor.get_field(&field_id).await.unwrap(); + ) + .await + .unwrap(); + } + + pub async fn assert_row_count(&self, expected_row_count: usize) { + let rows = self.editor.get_all_rows(&self.view_id).await.unwrap(); + assert_eq!(expected_row_count, rows.len()); + } + + pub async fn assert_cell_existence(&self, field_id: String, row_index: usize, exists: bool) { + let rows = self.editor.get_all_rows(&self.view_id).await.unwrap(); + let row = rows.get(row_index).unwrap(); + let cell = row.cells.get(&field_id).cloned(); + assert_eq!(exists, cell.is_some()); + } + + pub async fn assert_cell_content( + &self, + field_id: String, + row_index: usize, + expected_content: String, + ) { + let field = self.editor.get_field(&field_id).await.unwrap(); + let rows = self.editor.get_all_rows(&self.view_id).await.unwrap(); + let row = rows.get(row_index).unwrap(); + let cell = row.cells.get(&field_id).cloned().unwrap_or_default(); + let content = stringify_cell(&cell, &field); + assert_eq!(content, expected_content); + } + + pub async fn assert_select_option_cell_strict( + &self, + field_id: String, + row_index: usize, + expected_content: String, + ) { + let rows = self.editor.get_all_rows(&self.view_id).await.unwrap(); + let row = rows.get(row_index).unwrap(); + let cell = row.cells.get(&field_id).cloned().unwrap_or_default(); + let content = SelectOptionIds::from(&cell).join(SELECTION_IDS_SEPARATOR); + assert_eq!(content, expected_content); + } - let rows = self.editor.get_all_rows(&self.view_id).await.unwrap(); - let row = rows.get(row_index).unwrap(); - let cell = row.cells.get(&field_id).cloned().unwrap_or_default(); - let content = stringify_cell(&cell, &field); - assert_eq!(content, expected_content); - }, - PreFillRowCellTestScript::AssertSelectOptionCellStrict { - field_id, - row_index, - expected_content, - } => { - let rows = self.editor.get_all_rows(&self.view_id).await.unwrap(); - let row = rows.get(row_index).unwrap(); - let cell = row.cells.get(&field_id).cloned().unwrap_or_default(); - let content = SelectOptionIds::from(&cell).join(SELECTION_IDS_SEPARATOR); - assert_eq!(content, expected_content); - }, - PreFillRowCellTestScript::Wait { milliseconds } => { - tokio::time::sleep(Duration::from_millis(milliseconds)).await; - }, - } + pub async fn wait(&self, milliseconds: u64) { + tokio::time::sleep(Duration::from_millis(milliseconds)).await; } } diff --git a/frontend/rust-lib/flowy-database2/tests/database/sort_test/multi_sort_test.rs b/frontend/rust-lib/flowy-database2/tests/database/sort_test/multi_sort_test.rs index d7fe529d1398..ca15cc309bf7 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/sort_test/multi_sort_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/sort_test/multi_sort_test.rs @@ -2,50 +2,64 @@ use flowy_database2::entities::FieldType; use flowy_database2::services::sort::SortCondition; use crate::database::sort_test::script::DatabaseSortTest; -use crate::database::sort_test::script::SortScript::*; #[tokio::test] async fn sort_checkbox_and_then_text_by_descending_test() { let mut test = DatabaseSortTest::new().await; let checkbox_field = test.get_first_field(FieldType::Checkbox).await; let text_field = test.get_first_field(FieldType::RichText).await; - let scripts = vec![ - AssertCellContentOrder { - field_id: checkbox_field.id.clone(), - orders: vec!["Yes", "Yes", "No", "No", "No", "Yes", ""], - }, - AssertCellContentOrder { - field_id: text_field.id.clone(), - orders: vec!["A", "", "C", "DA", "AE", "AE", "CB"], - }, - // Insert checkbox sort - InsertSort { - field: checkbox_field.clone(), - condition: SortCondition::Descending, - }, - AssertCellContentOrder { - field_id: checkbox_field.id.clone(), - orders: vec!["Yes", "Yes", "Yes", "No", "No", "No", ""], - }, - AssertCellContentOrder { - field_id: text_field.id.clone(), - orders: vec!["A", "", "AE", "C", "DA", "AE", "CB"], - }, - // Insert text sort - InsertSort { - field: text_field.clone(), - condition: SortCondition::Ascending, - }, - AssertCellContentOrder { - field_id: checkbox_field.id.clone(), - orders: vec!["Yes", "Yes", "Yes", "No", "No", "", "No"], - }, - AssertCellContentOrder { - field_id: text_field.id.clone(), - orders: vec!["A", "AE", "", "AE", "C", "CB", "DA"], - }, - ]; - test.run_scripts(scripts).await; + + // Assert initial cell content order for checkbox and text fields + test + .assert_cell_content_order( + checkbox_field.id.clone(), + vec!["Yes", "Yes", "No", "No", "No", "Yes", ""], + ) + .await; + test + .assert_cell_content_order( + text_field.id.clone(), + vec!["A", "", "C", "DA", "AE", "AE", "CB"], + ) + .await; + + // Insert checkbox sort (Descending) + test + .insert_sort(checkbox_field.clone(), SortCondition::Descending) + .await; + + // Assert sorted order for checkbox and text fields + test + .assert_cell_content_order( + checkbox_field.id.clone(), + vec!["Yes", "Yes", "Yes", "No", "No", "No", ""], + ) + .await; + test + .assert_cell_content_order( + text_field.id.clone(), + vec!["A", "", "AE", "C", "DA", "AE", "CB"], + ) + .await; + + // Insert text sort (Ascending) + test + .insert_sort(text_field.clone(), SortCondition::Ascending) + .await; + + // Assert sorted order after adding text sort + test + .assert_cell_content_order( + checkbox_field.id.clone(), + vec!["Yes", "Yes", "Yes", "No", "No", "", "No"], + ) + .await; + test + .assert_cell_content_order( + text_field.id.clone(), + vec!["A", "AE", "", "AE", "C", "CB", "DA"], + ) + .await; } #[tokio::test] @@ -53,49 +67,60 @@ async fn reorder_sort_test() { let mut test = DatabaseSortTest::new().await; let checkbox_field = test.get_first_field(FieldType::Checkbox).await; let text_field = test.get_first_field(FieldType::RichText).await; - // Use the same sort set up as above - let scripts = vec![ - AssertCellContentOrder { - field_id: checkbox_field.id.clone(), - orders: vec!["Yes", "Yes", "No", "No", "No", "Yes", ""], - }, - AssertCellContentOrder { - field_id: text_field.id.clone(), - orders: vec!["A", "", "C", "DA", "AE", "AE", "CB"], - }, - InsertSort { - field: checkbox_field.clone(), - condition: SortCondition::Descending, - }, - InsertSort { - field: text_field.clone(), - condition: SortCondition::Ascending, - }, - AssertCellContentOrder { - field_id: checkbox_field.id.clone(), - orders: vec!["Yes", "Yes", "Yes", "No", "No", "", "No"], - }, - AssertCellContentOrder { - field_id: text_field.id.clone(), - orders: vec!["A", "AE", "", "AE", "C", "CB", "DA"], - }, - ]; - test.run_scripts(scripts).await; + // Assert initial cell content order for checkbox and text fields + test + .assert_cell_content_order( + checkbox_field.id.clone(), + vec!["Yes", "Yes", "No", "No", "No", "Yes", ""], + ) + .await; + test + .assert_cell_content_order( + text_field.id.clone(), + vec!["A", "", "C", "DA", "AE", "AE", "CB"], + ) + .await; + + // Insert checkbox and text sorts + test + .insert_sort(checkbox_field.clone(), SortCondition::Descending) + .await; + test + .insert_sort(text_field.clone(), SortCondition::Ascending) + .await; + + // Assert sorted order after applying both sorts + test + .assert_cell_content_order( + checkbox_field.id.clone(), + vec!["Yes", "Yes", "Yes", "No", "No", "", "No"], + ) + .await; + test + .assert_cell_content_order( + text_field.id.clone(), + vec!["A", "AE", "", "AE", "C", "CB", "DA"], + ) + .await; + + // Reorder sorts let sorts = test.editor.get_all_sorts(&test.view_id).await.items; - let scripts = vec![ - ReorderSort { - from_sort_id: sorts[1].id.clone(), - to_sort_id: sorts[0].id.clone(), - }, - AssertCellContentOrder { - field_id: checkbox_field.id.clone(), - orders: vec!["Yes", "Yes", "No", "No", "", "No", "Yes"], - }, - AssertCellContentOrder { - field_id: text_field.id.clone(), - orders: vec!["A", "AE", "AE", "C", "CB", "DA", ""], - }, - ]; - test.run_scripts(scripts).await; + test + .reorder_sort(sorts[1].id.clone(), sorts[0].id.clone()) + .await; + + // Assert the order after reorder + test + .assert_cell_content_order( + checkbox_field.id.clone(), + vec!["Yes", "Yes", "No", "No", "", "No", "Yes"], + ) + .await; + test + .assert_cell_content_order( + text_field.id.clone(), + vec!["A", "AE", "AE", "C", "CB", "DA", ""], + ) + .await; } diff --git a/frontend/rust-lib/flowy-database2/tests/database/sort_test/script.rs b/frontend/rust-lib/flowy-database2/tests/database/sort_test/script.rs index 612028920224..75694401b6cc 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/sort_test/script.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/sort_test/script.rs @@ -17,40 +17,6 @@ use flowy_database2::services::filter::{FilterChangeset, FilterInner}; use flowy_database2::services::sort::SortCondition; use lib_infra::box_any::BoxAny; -pub enum SortScript { - InsertSort { - field: Field, - condition: SortCondition, - }, - InsertFilter { - field_type: FieldType, - data: BoxAny, - }, - ReorderSort { - from_sort_id: String, - to_sort_id: String, - }, - DeleteSort { - sort_id: String, - }, - AssertCellContentOrder { - field_id: String, - orders: Vec<&'static str>, - }, - UpdateTextCell { - row_id: RowId, - text: String, - }, - AddNewRow, - AssertSortChanged { - old_row_orders: Vec<&'static str>, - new_row_orders: Vec<&'static str>, - }, - Wait { - millis: u64, - }, -} - pub struct DatabaseSortTest { inner: DatabaseEditorTest, recv: Option>, @@ -64,148 +30,145 @@ impl DatabaseSortTest { recv: None, } } - pub async fn run_scripts(&mut self, scripts: Vec) { - for script in scripts { - self.run_script(script).await; - } + + pub async fn insert_sort(&mut self, field: Field, condition: SortCondition) { + self.recv = Some( + self + .editor + .subscribe_view_changed(&self.view_id) + .await + .unwrap(), + ); + let params = UpdateSortPayloadPB { + view_id: self.view_id.clone(), + field_id: field.id.clone(), + sort_id: None, + condition: condition.into(), + }; + self.editor.create_or_update_sort(params).await.unwrap(); } - pub async fn run_script(&mut self, script: SortScript) { - match script { - SortScript::InsertSort { condition, field } => { - self.recv = Some( - self - .editor - .subscribe_view_changed(&self.view_id) - .await - .unwrap(), - ); - let params = UpdateSortPayloadPB { - view_id: self.view_id.clone(), - field_id: field.id.clone(), - sort_id: None, - condition: condition.into(), - }; - let _ = self.editor.create_or_update_sort(params).await.unwrap(); - }, - SortScript::InsertFilter { field_type, data } => { - let field = self.get_first_field(field_type).await; - let params = FilterChangeset::Insert { - parent_filter_id: None, - data: FilterInner::Data { - field_id: field.id, - field_type, - condition_and_content: data, - }, - }; - self - .editor - .modify_view_filters(&self.view_id, params) - .await - .unwrap(); - }, - SortScript::ReorderSort { - from_sort_id, - to_sort_id, - } => { - self.recv = Some( - self - .editor - .subscribe_view_changed(&self.view_id) - .await - .unwrap(), - ); - let params = ReorderSortPayloadPB { - view_id: self.view_id.clone(), - from_sort_id, - to_sort_id, - }; - self.editor.reorder_sort(params).await.unwrap(); - }, - SortScript::DeleteSort { sort_id } => { - self.recv = Some( - self - .editor - .subscribe_view_changed(&self.view_id) - .await - .unwrap(), - ); - let params = DeleteSortPayloadPB { - view_id: self.view_id.clone(), - sort_id, - }; - self.editor.delete_sort(params).await.unwrap(); - }, - SortScript::AssertCellContentOrder { field_id, orders } => { - let mut cells = vec![]; - let rows = self.editor.get_all_rows(&self.view_id).await.unwrap(); - let field = self.editor.get_field(&field_id).await.unwrap(); - for row in rows { - if let Some(cell) = row.cells.get(&field_id) { - let content = stringify_cell(cell, &field); - cells.push(content); - } else { - cells.push("".to_string()); - } - } - if orders.is_empty() { - assert_eq!(cells, orders); - } else { - let len = min(cells.len(), orders.len()); - assert_eq!(cells.split_at(len).0, orders); - } - }, - SortScript::UpdateTextCell { row_id, text } => { - self.recv = Some( - self - .editor - .subscribe_view_changed(&self.view_id) - .await - .unwrap(), - ); - self.update_text_cell(row_id, &text).await.unwrap(); - }, - SortScript::AddNewRow => { - self.recv = Some( - self - .editor - .subscribe_view_changed(&self.view_id) - .await - .unwrap(), - ); - self - .editor - .create_row(CreateRowPayloadPB { - view_id: self.view_id.clone(), - ..Default::default() - }) - .await - .unwrap(); - }, - SortScript::AssertSortChanged { - new_row_orders, - old_row_orders, - } => { - if let Some(receiver) = self.recv.take() { - assert_sort_changed( - receiver, - new_row_orders - .into_iter() - .map(|order| order.to_owned()) - .collect(), - old_row_orders - .into_iter() - .map(|order| order.to_owned()) - .collect(), - ) - .await; - } - }, - SortScript::Wait { millis } => { - tokio::time::sleep(Duration::from_millis(millis)).await; + pub async fn insert_filter(&mut self, field_type: FieldType, data: BoxAny) { + let field = self.get_first_field(field_type).await; + let params = FilterChangeset::Insert { + parent_filter_id: None, + data: FilterInner::Data { + field_id: field.id, + field_type, + condition_and_content: data, }, + }; + self + .editor + .modify_view_filters(&self.view_id, params) + .await + .unwrap(); + } + + pub async fn reorder_sort(&mut self, from_sort_id: String, to_sort_id: String) { + self.recv = Some( + self + .editor + .subscribe_view_changed(&self.view_id) + .await + .unwrap(), + ); + let params = ReorderSortPayloadPB { + view_id: self.view_id.clone(), + from_sort_id, + to_sort_id, + }; + self.editor.reorder_sort(params).await.unwrap(); + } + + pub async fn delete_sort(&mut self, sort_id: String) { + self.recv = Some( + self + .editor + .subscribe_view_changed(&self.view_id) + .await + .unwrap(), + ); + let params = DeleteSortPayloadPB { + view_id: self.view_id.clone(), + sort_id, + }; + self.editor.delete_sort(params).await.unwrap(); + } + + pub async fn assert_cell_content_order(&mut self, field_id: String, orders: Vec<&'static str>) { + let mut cells = vec![]; + let rows = self.editor.get_all_rows(&self.view_id).await.unwrap(); + let field = self.editor.get_field(&field_id).await.unwrap(); + for row in rows { + if let Some(cell) = row.cells.get(&field_id) { + let content = stringify_cell(cell, &field); + cells.push(content); + } else { + cells.push("".to_string()); + } + } + if orders.is_empty() { + assert_eq!(cells, orders); + } else { + let len = min(cells.len(), orders.len()); + assert_eq!(cells.split_at(len).0, orders); + } + } + + pub async fn update_text_cell(&mut self, row_id: RowId, text: String) { + self.recv = Some( + self + .editor + .subscribe_view_changed(&self.view_id) + .await + .unwrap(), + ); + self.inner.update_text_cell(row_id, &text).await.unwrap(); + } + + pub async fn add_new_row(&mut self) { + self.recv = Some( + self + .editor + .subscribe_view_changed(&self.view_id) + .await + .unwrap(), + ); + self + .editor + .create_row(CreateRowPayloadPB { + view_id: self.view_id.clone(), + ..Default::default() + }) + .await + .unwrap(); + } + + pub async fn assert_sort_changed( + &mut self, + new_row_orders: Vec<&'static str>, + old_row_orders: Vec<&'static str>, + ) { + if let Some(receiver) = self.recv.take() { + assert_sort_changed( + receiver, + new_row_orders + .into_iter() + .map(|order| order.to_owned()) + .collect(), + old_row_orders + .into_iter() + .map(|order| order.to_owned()) + .collect(), + ) + .await; } } + + pub async fn wait(&mut self, millis: u64) { + tokio::time::sleep(Duration::from_millis(millis)).await; + } } async fn assert_sort_changed( diff --git a/frontend/rust-lib/flowy-database2/tests/database/sort_test/single_sort_test.rs b/frontend/rust-lib/flowy-database2/tests/database/sort_test/single_sort_test.rs index 9293b55762c6..dbcf86ad4fad 100644 --- a/frontend/rust-lib/flowy-database2/tests/database/sort_test/single_sort_test.rs +++ b/frontend/rust-lib/flowy-database2/tests/database/sort_test/single_sort_test.rs @@ -1,4 +1,4 @@ -use crate::database::sort_test::script::{DatabaseSortTest, SortScript::*}; +use crate::database::sort_test::script::DatabaseSortTest; use flowy_database2::entities::{CheckboxFilterConditionPB, CheckboxFilterPB, FieldType}; use flowy_database2::services::sort::SortCondition; use lib_infra::box_any::BoxAny; @@ -7,193 +7,199 @@ use lib_infra::box_any::BoxAny; async fn sort_text_by_ascending_test() { let mut test = DatabaseSortTest::new().await; let text_field = test.get_first_field(FieldType::RichText).await; - let scripts = vec![ - AssertCellContentOrder { - field_id: text_field.id.clone(), - orders: vec!["A", "", "C", "DA", "AE", "AE", "CB"], - }, - InsertSort { - field: text_field.clone(), - condition: SortCondition::Ascending, - }, - AssertCellContentOrder { - field_id: text_field.id.clone(), - orders: vec!["A", "AE", "AE", "C", "CB", "DA", ""], - }, - InsertFilter { - field_type: FieldType::Checkbox, - data: BoxAny::new(CheckboxFilterPB { - condition: CheckboxFilterConditionPB::IsChecked, - }), - }, - AssertCellContentOrder { - field_id: text_field.id.clone(), - orders: vec!["A", "AE", ""], - }, - ]; - test.run_scripts(scripts).await; + + test + .assert_cell_content_order( + text_field.id.clone(), + vec!["A", "", "C", "DA", "AE", "AE", "CB"], + ) + .await; + test + .insert_sort(text_field.clone(), SortCondition::Ascending) + .await; + test + .assert_cell_content_order( + text_field.id.clone(), + vec!["A", "AE", "AE", "C", "CB", "DA", ""], + ) + .await; + + let checkbox_filter = CheckboxFilterPB { + condition: CheckboxFilterConditionPB::IsChecked, + }; + test + .insert_filter(FieldType::Checkbox, BoxAny::new(checkbox_filter)) + .await; + + test + .assert_cell_content_order(text_field.id.clone(), vec!["A", "AE", ""]) + .await; } #[tokio::test] async fn sort_text_by_descending_test() { let mut test = DatabaseSortTest::new().await; let text_field = test.get_first_field(FieldType::RichText).await; - let scripts = vec![ - AssertCellContentOrder { - field_id: text_field.id.clone(), - orders: vec!["A", "", "C", "DA", "AE", "AE", "CB"], - }, - InsertSort { - field: text_field.clone(), - condition: SortCondition::Descending, - }, - AssertCellContentOrder { - field_id: text_field.id.clone(), - orders: vec!["DA", "CB", "C", "AE", "AE", "A", ""], - }, - ]; - test.run_scripts(scripts).await; + + test + .assert_cell_content_order( + text_field.id.clone(), + vec!["A", "", "C", "DA", "AE", "AE", "CB"], + ) + .await; + test + .insert_sort(text_field.clone(), SortCondition::Descending) + .await; + test + .assert_cell_content_order( + text_field.id.clone(), + vec!["DA", "CB", "C", "AE", "AE", "A", ""], + ) + .await; } #[tokio::test] async fn sort_change_notification_by_update_text_test() { let mut test = DatabaseSortTest::new().await; - let text_field = test.get_first_field(FieldType::RichText).await.clone(); - let scripts = vec![ - AssertCellContentOrder { - field_id: text_field.id.clone(), - orders: vec!["A", "", "C", "DA", "AE", "AE", "CB"], - }, - InsertSort { - field: text_field.clone(), - condition: SortCondition::Ascending, - }, - AssertCellContentOrder { - field_id: text_field.id.clone(), - orders: vec!["A", "AE", "AE", "C", "CB", "DA", ""], - }, - // Wait the insert task to finish. The cost of time should be less than 200 milliseconds. - Wait { millis: 200 }, - ]; - test.run_scripts(scripts).await; + let text_field = test.get_first_field(FieldType::RichText).await; + + test + .assert_cell_content_order( + text_field.id.clone(), + vec!["A", "", "C", "DA", "AE", "AE", "CB"], + ) + .await; + test + .insert_sort(text_field.clone(), SortCondition::Ascending) + .await; + test + .assert_cell_content_order( + text_field.id.clone(), + vec!["A", "AE", "AE", "C", "CB", "DA", ""], + ) + .await; + test.wait(200).await; let row = test.get_rows().await; - let scripts = vec![ - UpdateTextCell { - row_id: row[1].id.clone(), - text: "E".to_string(), - }, - AssertSortChanged { - old_row_orders: vec!["A", "E", "AE", "C", "CB", "DA", ""], - new_row_orders: vec!["A", "AE", "C", "CB", "DA", "E", ""], - }, - ]; - test.run_scripts(scripts).await; + test + .update_text_cell(row[1].id.clone(), "E".to_string()) + .await; + test + .assert_sort_changed( + vec!["A", "AE", "C", "CB", "DA", "E", ""], + vec!["A", "E", "AE", "C", "CB", "DA", ""], + ) + .await; } #[tokio::test] async fn sort_after_new_row_test() { let mut test = DatabaseSortTest::new().await; let checkbox_field = test.get_first_field(FieldType::Checkbox).await; - let scripts = vec![ - AssertCellContentOrder { - field_id: checkbox_field.id.clone(), - orders: vec!["Yes", "Yes", "No", "No", "No", "Yes", ""], - }, - InsertSort { - field: checkbox_field.clone(), - condition: SortCondition::Ascending, - }, - AssertCellContentOrder { - field_id: checkbox_field.id.clone(), - orders: vec!["No", "No", "No", "", "Yes", "Yes", "Yes"], - }, - AddNewRow {}, - AssertCellContentOrder { - field_id: checkbox_field.id, - orders: vec!["No", "No", "No", "", "", "Yes", "Yes", "Yes"], - }, - ]; - test.run_scripts(scripts).await; + + test + .assert_cell_content_order( + checkbox_field.id.clone(), + vec!["Yes", "Yes", "No", "No", "No", "Yes", ""], + ) + .await; + test + .insert_sort(checkbox_field.clone(), SortCondition::Ascending) + .await; + test + .assert_cell_content_order( + checkbox_field.id.clone(), + vec!["No", "No", "No", "", "Yes", "Yes", "Yes"], + ) + .await; + + test.add_new_row().await; + test + .assert_cell_content_order( + checkbox_field.id.clone(), + vec!["No", "No", "No", "", "", "Yes", "Yes", "Yes"], + ) + .await; } #[tokio::test] async fn sort_text_by_ascending_and_delete_sort_test() { let mut test = DatabaseSortTest::new().await; let text_field = test.get_first_field(FieldType::RichText).await; - let scripts = vec![ - InsertSort { - field: text_field.clone(), - condition: SortCondition::Ascending, - }, - AssertCellContentOrder { - field_id: text_field.id.clone(), - orders: vec!["A", "AE", "AE", "C", "CB", "DA", ""], - }, - ]; - test.run_scripts(scripts).await; + + test + .insert_sort(text_field.clone(), SortCondition::Ascending) + .await; + test + .assert_cell_content_order( + text_field.id.clone(), + vec!["A", "AE", "AE", "C", "CB", "DA", ""], + ) + .await; let sort = test.editor.get_all_sorts(&test.view_id).await.items[0].clone(); - let scripts = vec![ - DeleteSort { sort_id: sort.id }, - AssertCellContentOrder { - field_id: text_field.id.clone(), - orders: vec!["A", "", "C", "DA", "AE", "AE", "CB"], - }, - ]; - test.run_scripts(scripts).await; + test.delete_sort(sort.id.clone()).await; + test + .assert_cell_content_order( + text_field.id.clone(), + vec!["A", "", "C", "DA", "AE", "AE", "CB"], + ) + .await; } #[tokio::test] async fn sort_checkbox_by_ascending_test() { let mut test = DatabaseSortTest::new().await; let checkbox_field = test.get_first_field(FieldType::Checkbox).await; - let scripts = vec![ - AssertCellContentOrder { - field_id: checkbox_field.id.clone(), - orders: vec!["Yes", "Yes", "No", "No", "No", "Yes", ""], - }, - InsertSort { - field: checkbox_field.clone(), - condition: SortCondition::Ascending, - }, - AssertCellContentOrder { - field_id: checkbox_field.id.clone(), - orders: vec!["No", "No", "No", "", "Yes", "Yes", "Yes"], - }, - ]; - test.run_scripts(scripts).await; + + test + .assert_cell_content_order( + checkbox_field.id.clone(), + vec!["Yes", "Yes", "No", "No", "No", "Yes", ""], + ) + .await; + test + .insert_sort(checkbox_field.clone(), SortCondition::Ascending) + .await; + test + .assert_cell_content_order( + checkbox_field.id.clone(), + vec!["No", "No", "No", "", "Yes", "Yes", "Yes"], + ) + .await; } #[tokio::test] async fn sort_checkbox_by_descending_test() { let mut test = DatabaseSortTest::new().await; let checkbox_field = test.get_first_field(FieldType::Checkbox).await; - let scripts = vec![ - AssertCellContentOrder { - field_id: checkbox_field.id.clone(), - orders: vec!["Yes", "Yes", "No", "No", "No", "Yes", ""], - }, - InsertSort { - field: checkbox_field.clone(), - condition: SortCondition::Descending, - }, - AssertCellContentOrder { - field_id: checkbox_field.id.clone(), - orders: vec!["Yes", "Yes", "Yes", "No", "No", "No", ""], - }, - ]; - test.run_scripts(scripts).await; + + test + .assert_cell_content_order( + checkbox_field.id.clone(), + vec!["Yes", "Yes", "No", "No", "No", "Yes", ""], + ) + .await; + test + .insert_sort(checkbox_field.clone(), SortCondition::Descending) + .await; + test + .assert_cell_content_order( + checkbox_field.id.clone(), + vec!["Yes", "Yes", "Yes", "No", "No", "No", ""], + ) + .await; } #[tokio::test] async fn sort_date_by_ascending_test() { let mut test = DatabaseSortTest::new().await; let date_field = test.get_first_field(FieldType::DateTime).await; - let scripts = vec![ - AssertCellContentOrder { - field_id: date_field.id.clone(), - orders: vec![ + + test + .assert_cell_content_order( + date_field.id.clone(), + vec![ "2022/03/14", "2022/03/14", "2022/03/14", @@ -202,14 +208,15 @@ async fn sort_date_by_ascending_test() { "2022/12/25", "", ], - }, - InsertSort { - field: date_field.clone(), - condition: SortCondition::Ascending, - }, - AssertCellContentOrder { - field_id: date_field.id.clone(), - orders: vec![ + ) + .await; + test + .insert_sort(date_field.clone(), SortCondition::Ascending) + .await; + test + .assert_cell_content_order( + date_field.id.clone(), + vec![ "2022/03/14", "2022/03/14", "2022/03/14", @@ -218,19 +225,19 @@ async fn sort_date_by_ascending_test() { "2022/12/25", "", ], - }, - ]; - test.run_scripts(scripts).await; + ) + .await; } #[tokio::test] async fn sort_date_by_descending_test() { let mut test = DatabaseSortTest::new().await; let date_field = test.get_first_field(FieldType::DateTime).await; - let scripts = vec![ - AssertCellContentOrder { - field_id: date_field.id.clone(), - orders: vec![ + + test + .assert_cell_content_order( + date_field.id.clone(), + vec![ "2022/03/14", "2022/03/14", "2022/03/14", @@ -239,14 +246,15 @@ async fn sort_date_by_descending_test() { "2022/12/25", "", ], - }, - InsertSort { - field: date_field.clone(), - condition: SortCondition::Descending, - }, - AssertCellContentOrder { - field_id: date_field.id.clone(), - orders: vec![ + ) + .await; + test + .insert_sort(date_field.clone(), SortCondition::Descending) + .await; + test + .assert_cell_content_order( + date_field.id.clone(), + vec![ "2022/12/25", "2022/11/17", "2022/11/13", @@ -255,239 +263,50 @@ async fn sort_date_by_descending_test() { "2022/03/14", "", ], - }, - ]; - test.run_scripts(scripts).await; + ) + .await; } #[tokio::test] async fn sort_number_by_ascending_test() { let mut test = DatabaseSortTest::new().await; let number_field = test.get_first_field(FieldType::Number).await; - let scripts = vec![ - AssertCellContentOrder { - field_id: number_field.id.clone(), - orders: vec!["$1", "$2", "$3", "$14", "", "$5", ""], - }, - InsertSort { - field: number_field.clone(), - condition: SortCondition::Ascending, - }, - AssertCellContentOrder { - field_id: number_field.id.clone(), - orders: vec!["$1", "$2", "$3", "$5", "$14", "", ""], - }, - ]; - test.run_scripts(scripts).await; + + test + .assert_cell_content_order( + number_field.id.clone(), + vec!["$1", "$2", "$3", "$14", "", "$5", ""], + ) + .await; + test + .insert_sort(number_field.clone(), SortCondition::Ascending) + .await; + test + .assert_cell_content_order( + number_field.id.clone(), + vec!["$1", "$2", "$3", "$5", "$14", "", ""], + ) + .await; } #[tokio::test] async fn sort_number_by_descending_test() { let mut test = DatabaseSortTest::new().await; let number_field = test.get_first_field(FieldType::Number).await; - let scripts = vec![ - AssertCellContentOrder { - field_id: number_field.id.clone(), - orders: vec!["$1", "$2", "$3", "$14", "", "$5", ""], - }, - InsertSort { - field: number_field.clone(), - condition: SortCondition::Descending, - }, - AssertCellContentOrder { - field_id: number_field.id.clone(), - orders: vec!["$14", "$5", "$3", "$2", "$1", "", ""], - }, - ]; - test.run_scripts(scripts).await; -} - -#[tokio::test] -async fn sort_single_select_by_ascending_test() { - let mut test = DatabaseSortTest::new().await; - let single_select = test.get_first_field(FieldType::SingleSelect).await; - let scripts = vec![ - AssertCellContentOrder { - field_id: single_select.id.clone(), - orders: vec!["", "", "Completed", "Completed", "Planned", "Planned", ""], - }, - InsertSort { - field: single_select.clone(), - condition: SortCondition::Ascending, - }, - AssertCellContentOrder { - field_id: single_select.id.clone(), - orders: vec!["Completed", "Completed", "Planned", "Planned", "", "", ""], - }, - ]; - test.run_scripts(scripts).await; -} - -#[tokio::test] -async fn sort_single_select_by_descending_test() { - let mut test = DatabaseSortTest::new().await; - let single_select = test.get_first_field(FieldType::SingleSelect).await; - let scripts = vec![ - AssertCellContentOrder { - field_id: single_select.id.clone(), - orders: vec!["", "", "Completed", "Completed", "Planned", "Planned", ""], - }, - InsertSort { - field: single_select.clone(), - condition: SortCondition::Descending, - }, - AssertCellContentOrder { - field_id: single_select.id.clone(), - orders: vec!["Planned", "Planned", "Completed", "Completed", "", "", ""], - }, - ]; - test.run_scripts(scripts).await; -} - -#[tokio::test] -async fn sort_multi_select_by_ascending_test() { - let mut test = DatabaseSortTest::new().await; - let multi_select = test.get_first_field(FieldType::MultiSelect).await; - let scripts = vec![ - AssertCellContentOrder { - field_id: multi_select.id.clone(), - orders: vec![ - "Google,Facebook", - "Google,Twitter", - "Facebook,Google,Twitter", - "", - "Facebook,Twitter", - "Facebook", - "", - ], - }, - InsertSort { - field: multi_select.clone(), - condition: SortCondition::Ascending, - }, - AssertCellContentOrder { - field_id: multi_select.id.clone(), - orders: vec![ - "Facebook", - "Facebook,Twitter", - "Google,Facebook", - "Google,Twitter", - "Facebook,Google,Twitter", - "", - "", - ], - }, - ]; - test.run_scripts(scripts).await; -} -#[tokio::test] -async fn sort_multi_select_by_descending_test() { - let mut test = DatabaseSortTest::new().await; - let multi_select = test.get_first_field(FieldType::MultiSelect).await; - let scripts = vec![ - AssertCellContentOrder { - field_id: multi_select.id.clone(), - orders: vec![ - "Google,Facebook", - "Google,Twitter", - "Facebook,Google,Twitter", - "", - "Facebook,Twitter", - "Facebook", - "", - ], - }, - InsertSort { - field: multi_select.clone(), - condition: SortCondition::Descending, - }, - AssertCellContentOrder { - field_id: multi_select.id.clone(), - orders: vec![ - "Facebook,Google,Twitter", - "Google,Twitter", - "Google,Facebook", - "Facebook,Twitter", - "Facebook", - "", - "", - ], - }, - ]; - test.run_scripts(scripts).await; -} - -#[tokio::test] -async fn sort_checklist_by_ascending_test() { - let mut test = DatabaseSortTest::new().await; - let checklist_field = test.get_first_field(FieldType::Checklist).await; - let scripts = vec![ - AssertCellContentOrder { - field_id: checklist_field.id.clone(), - orders: vec![ - "First thing", - "Have breakfast,Have lunch,Take a nap,Have dinner,Shower and head to bed", - "", - "Task 1", - "", - "Sprint,Sprint some more,Rest", - "", - ], - }, - InsertSort { - field: checklist_field.clone(), - condition: SortCondition::Ascending, - }, - AssertCellContentOrder { - field_id: checklist_field.id.clone(), - orders: vec![ - "First thing", - "Have breakfast,Have lunch,Take a nap,Have dinner,Shower and head to bed", - "Sprint,Sprint some more,Rest", - "Task 1", - "", - "", - "", - ], - }, - ]; - test.run_scripts(scripts).await; -} - -#[tokio::test] -async fn sort_checklist_by_descending_test() { - let mut test = DatabaseSortTest::new().await; - let checklist_field = test.get_first_field(FieldType::Checklist).await; - let scripts = vec![ - AssertCellContentOrder { - field_id: checklist_field.id.clone(), - orders: vec![ - "First thing", - "Have breakfast,Have lunch,Take a nap,Have dinner,Shower and head to bed", - "", - "Task 1", - "", - "Sprint,Sprint some more,Rest", - "", - ], - }, - InsertSort { - field: checklist_field.clone(), - condition: SortCondition::Descending, - }, - AssertCellContentOrder { - field_id: checklist_field.id.clone(), - orders: vec![ - "Task 1", - "Sprint,Sprint some more,Rest", - "Have breakfast,Have lunch,Take a nap,Have dinner,Shower and head to bed", - "First thing", - "", - "", - "", - ], - }, - ]; - test.run_scripts(scripts).await; + test + .assert_cell_content_order( + number_field.id.clone(), + vec!["$1", "$2", "$3", "$14", "", "$5", ""], + ) + .await; + test + .insert_sort(number_field.clone(), SortCondition::Descending) + .await; + test + .assert_cell_content_order( + number_field.id.clone(), + vec!["$14", "$5", "$3", "$2", "$1", "", ""], + ) + .await; }