| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904 | use std::convert::TryFrom;use bytes::Bytes;use flowy_database2::entities::{  CellChangesetPB, CellIdPB, ChecklistCellDataChangesetPB, DatabaseLayoutPB,  DatabaseSettingChangesetPB, DatabaseViewIdPB, DateChangesetPB, FieldType, SelectOptionCellDataPB,  UpdateRowMetaChangesetPB,};use flowy_test::event_builder::EventBuilder;use flowy_test::FlowyCoreTest;use lib_infra::util::timestamp;#[tokio::test]async fn get_database_id_event_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  // The view id can be used to get the database id.  let database_id = EventBuilder::new(test.clone())    .event(flowy_database2::event_map::DatabaseEvent::GetDatabaseId)    .payload(DatabaseViewIdPB {      value: grid_view.id.clone(),    })    .async_send()    .await    .parse::<flowy_database2::entities::DatabaseIdPB>()    .value;  assert_ne!(database_id, grid_view.id);}#[tokio::test]async fn get_database_event_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  let database = test.get_database(&grid_view.id).await;  assert_eq!(database.fields.len(), 3);  assert_eq!(database.rows.len(), 3);  assert_eq!(database.layout_type, DatabaseLayoutPB::Grid);}#[tokio::test]async fn get_field_event_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  let fields = test.get_all_database_fields(&grid_view.id).await.items;  assert_eq!(fields[0].field_type, FieldType::RichText);  assert_eq!(fields[1].field_type, FieldType::SingleSelect);  assert_eq!(fields[2].field_type, FieldType::Checkbox);  assert_eq!(fields.len(), 3);}#[tokio::test]async fn create_field_event_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  test.create_field(&grid_view.id, FieldType::Checkbox).await;  let fields = test.get_all_database_fields(&grid_view.id).await.items;  assert_eq!(fields.len(), 4);  assert_eq!(fields[3].field_type, FieldType::Checkbox);}#[tokio::test]async fn delete_field_event_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  let fields = test.get_all_database_fields(&grid_view.id).await.items;  assert_eq!(fields[0].field_type, FieldType::RichText);  assert_eq!(fields[1].field_type, FieldType::SingleSelect);  assert_eq!(fields[2].field_type, FieldType::Checkbox);  let error = test.delete_field(&grid_view.id, &fields[1].id).await;  assert!(error.is_none());  let fields = test.get_all_database_fields(&grid_view.id).await.items;  assert_eq!(fields.len(), 2);}// The primary field is not allowed to be deleted.#[tokio::test]async fn delete_primary_field_event_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  let fields = test.get_all_database_fields(&grid_view.id).await.items;  // the primary field is not allowed to be deleted.  assert!(fields[0].is_primary);  let error = test.delete_field(&grid_view.id, &fields[0].id).await;  assert!(error.is_some());}#[tokio::test]async fn update_field_type_event_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  let fields = test.get_all_database_fields(&grid_view.id).await.items;  let error = test    .update_field_type(&grid_view.id, &fields[1].id, FieldType::Checklist)    .await;  assert!(error.is_none());  let fields = test.get_all_database_fields(&grid_view.id).await.items;  assert_eq!(fields[1].field_type, FieldType::Checklist);}#[tokio::test]async fn update_primary_field_type_event_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  let fields = test.get_all_database_fields(&grid_view.id).await.items;  // the primary field is not allowed to be deleted.  assert!(fields[0].is_primary);  // the primary field is not allowed to be updated.  let error = test    .update_field_type(&grid_view.id, &fields[0].id, FieldType::Checklist)    .await;  assert!(error.is_some());}#[tokio::test]async fn duplicate_field_event_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  let fields = test.get_all_database_fields(&grid_view.id).await.items;  // the primary field is not allowed to be updated.  let error = test.duplicate_field(&grid_view.id, &fields[1].id).await;  assert!(error.is_none());  let fields = test.get_all_database_fields(&grid_view.id).await.items;  assert_eq!(fields.len(), 4);}// The primary field is not allowed to be duplicated. So this test should return an error.#[tokio::test]async fn duplicate_primary_field_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  let fields = test.get_all_database_fields(&grid_view.id).await.items;  // the primary field is not allowed to be duplicated.  let error = test.duplicate_field(&grid_view.id, &fields[0].id).await;  assert!(error.is_some());}#[tokio::test]async fn get_primary_field_event_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  // By default the primary field type is RichText.  let field = test.get_primary_field(&grid_view.id).await;  assert_eq!(field.field_type, FieldType::RichText);}#[tokio::test]async fn create_row_event_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  let _ = test.create_row(&grid_view.id, None, None).await;  let database = test.get_database(&grid_view.id).await;  assert_eq!(database.rows.len(), 4);}#[tokio::test]async fn delete_row_event_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  // delete the row  let database = test.get_database(&grid_view.id).await;  let remove_row_id = database.rows[0].id.clone();  assert_eq!(database.rows.len(), 3);  let error = test.delete_row(&grid_view.id, &remove_row_id).await;  assert!(error.is_none());  let database = test.get_database(&grid_view.id).await;  assert_eq!(database.rows.len(), 2);  // get the row again and check if it is deleted.  let optional_row = test.get_row(&grid_view.id, &remove_row_id).await;  assert!(optional_row.row.is_none());}#[tokio::test]async fn get_row_event_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  let database = test.get_database(&grid_view.id).await;  let row = test.get_row(&grid_view.id, &database.rows[0].id).await.row;  assert!(row.is_some());  let row = test.get_row_meta(&grid_view.id, &database.rows[0].id).await;  assert!(!row.document_id.is_empty());}#[tokio::test]async fn update_row_meta_event_with_url_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  let database = test.get_database(&grid_view.id).await;  // By default the row icon is None.  let row = test.get_row_meta(&grid_view.id, &database.rows[0].id).await;  assert_eq!(row.icon, None);  // Insert icon url to the row.  let changeset = UpdateRowMetaChangesetPB {    id: database.rows[0].id.clone(),    view_id: grid_view.id.clone(),    icon_url: Some("icon_url".to_owned()),    cover_url: None,  };  let error = test.update_row_meta(changeset).await;  assert!(error.is_none());  // Check if the icon is updated.  let row = test.get_row_meta(&grid_view.id, &database.rows[0].id).await;  assert_eq!(row.icon, Some("icon_url".to_owned()));}#[tokio::test]async fn update_row_meta_event_with_cover_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  let database = test.get_database(&grid_view.id).await;  // By default the row icon is None.  let row = test.get_row_meta(&grid_view.id, &database.rows[0].id).await;  assert_eq!(row.cover, None);  // Insert cover to the row.  let changeset = UpdateRowMetaChangesetPB {    id: database.rows[0].id.clone(),    view_id: grid_view.id.clone(),    cover_url: Some("cover url".to_owned()),    icon_url: None,  };  let error = test.update_row_meta(changeset).await;  assert!(error.is_none());  // Check if the icon is updated.  let row = test.get_row_meta(&grid_view.id, &database.rows[0].id).await;  assert_eq!(row.cover, Some("cover url".to_owned()));}#[tokio::test]async fn delete_row_event_with_invalid_row_id_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  // delete the row with empty row_id. It should return an error.  let error = test.delete_row(&grid_view.id, "").await;  assert!(error.is_some());}#[tokio::test]async fn duplicate_row_event_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  let database = test.get_database(&grid_view.id).await;  let error = test    .duplicate_row(&grid_view.id, &database.rows[0].id)    .await;  assert!(error.is_none());  let database = test.get_database(&grid_view.id).await;  assert_eq!(database.rows.len(), 4);}#[tokio::test]async fn duplicate_row_event_with_invalid_row_id_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  let database = test.get_database(&grid_view.id).await;  assert_eq!(database.rows.len(), 3);  let error = test.duplicate_row(&grid_view.id, "").await;  assert!(error.is_some());  let database = test.get_database(&grid_view.id).await;  assert_eq!(database.rows.len(), 3);}#[tokio::test]async fn move_row_event_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  let database = test.get_database(&grid_view.id).await;  let row_1 = database.rows[0].id.clone();  let row_2 = database.rows[1].id.clone();  let row_3 = database.rows[2].id.clone();  let error = test.move_row(&grid_view.id, &row_1, &row_3).await;  assert!(error.is_none());  let database = test.get_database(&grid_view.id).await;  assert_eq!(database.rows[0].id, row_2);  assert_eq!(database.rows[1].id, row_3);  assert_eq!(database.rows[2].id, row_1);}#[tokio::test]async fn move_row_event_test2() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  let database = test.get_database(&grid_view.id).await;  let row_1 = database.rows[0].id.clone();  let row_2 = database.rows[1].id.clone();  let row_3 = database.rows[2].id.clone();  let error = test.move_row(&grid_view.id, &row_2, &row_1).await;  assert!(error.is_none());  let database = test.get_database(&grid_view.id).await;  assert_eq!(database.rows[0].id, row_2);  assert_eq!(database.rows[1].id, row_1);  assert_eq!(database.rows[2].id, row_3);}#[tokio::test]async fn move_row_event_with_invalid_row_id_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  let database = test.get_database(&grid_view.id).await;  let row_1 = database.rows[0].id.clone();  let row_2 = database.rows[1].id.clone();  let row_3 = database.rows[2].id.clone();  for i in 0..2 {    if i == 0 {      let error = test.move_row(&grid_view.id, &row_1, "").await;      assert!(error.is_some());    } else {      let error = test.move_row(&grid_view.id, "", &row_1).await;      assert!(error.is_some());    }    let database = test.get_database(&grid_view.id).await;    assert_eq!(database.rows[0].id, row_1);    assert_eq!(database.rows[1].id, row_2);    assert_eq!(database.rows[2].id, row_3);  }}#[tokio::test]async fn update_text_cell_event_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  let database = test.get_database(&grid_view.id).await;  let fields = test.get_all_database_fields(&grid_view.id).await.items;  let row_id = database.rows[0].id.clone();  let field_id = fields[0].id.clone();  assert_eq!(fields[0].field_type, FieldType::RichText);  // Update the first cell of the first row.  let error = test    .update_cell(CellChangesetPB {      view_id: grid_view.id.clone(),      row_id: row_id.clone(),      field_id: field_id.clone(),      cell_changeset: "hello world".to_string(),    })    .await;  assert!(error.is_none());  let cell = test.get_cell(&grid_view.id, &row_id, &field_id).await;  let s = String::from_utf8(cell.data).unwrap();  assert_eq!(s, "hello world");}#[tokio::test]async fn update_checkbox_cell_event_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  let database = test.get_database(&grid_view.id).await;  let fields = test.get_all_database_fields(&grid_view.id).await.items;  let row_id = database.rows[0].id.clone();  let field_id = fields[2].id.clone();  assert_eq!(fields[2].field_type, FieldType::Checkbox);  for input in &["yes", "true", "1"] {    let error = test      .update_cell(CellChangesetPB {        view_id: grid_view.id.clone(),        row_id: row_id.clone(),        field_id: field_id.clone(),        cell_changeset: input.to_string(),      })      .await;    assert!(error.is_none());    let cell = test.get_cell(&grid_view.id, &row_id, &field_id).await;    let output = String::from_utf8(cell.data).unwrap();    assert_eq!(output, "Yes");  }}#[tokio::test]async fn update_single_select_cell_event_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  let database = test.get_database(&grid_view.id).await;  let fields = test.get_all_database_fields(&grid_view.id).await.items;  let row_id = database.rows[0].id.clone();  let field_id = fields[1].id.clone();  assert_eq!(fields[1].field_type, FieldType::SingleSelect);  // Insert a new option. This should update the cell with the new option.  let error = test    .insert_option(&grid_view.id, &field_id, &row_id, "task 1")    .await;  assert!(error.is_none());  // Check that the cell data is updated.  let cell = test.get_cell(&grid_view.id, &row_id, &field_id).await;  let select_option_cell = SelectOptionCellDataPB::try_from(Bytes::from(cell.data)).unwrap();  assert_eq!(select_option_cell.options.len(), 1);  assert_eq!(select_option_cell.select_options.len(), 1);}#[tokio::test]async fn update_date_cell_event_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  let database = test.get_database(&grid_view.id).await;  // Create a date field  let date_field = test.create_field(&grid_view.id, FieldType::DateTime).await;  let cell_path = CellIdPB {    view_id: grid_view.id.clone(),    field_id: date_field.id.clone(),    row_id: database.rows[0].id.clone(),  };  // Insert data into the date cell of the first row.  let timestamp = 1686300557;  let timestamp_str = 1686300557.to_string();  let error = test    .update_date_cell(DateChangesetPB {      cell_id: cell_path,      date: Some(timestamp_str.clone()),      time: None,      include_time: None,    })    .await;  assert!(error.is_none());  // Check that the cell data is updated.  let cell = test    .get_date_cell(&grid_view.id, &database.rows[0].id, &date_field.id)    .await;  assert_eq!(cell.date, "Jun 09, 2023");  assert_eq!(cell.timestamp, timestamp);}#[tokio::test]async fn update_date_cell_event_with_empty_time_str_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  let database = test.get_database(&grid_view.id).await;  let row_id = database.rows[0].id.clone();  // Create a date field  let date_field = test.create_field(&grid_view.id, FieldType::DateTime).await;  let cell_path = CellIdPB {    view_id: grid_view.id.clone(),    field_id: date_field.id.clone(),    row_id: row_id.clone(),  };  // Insert empty timestamp string  let error = test    .update_date_cell(DateChangesetPB {      cell_id: cell_path,      date: Some("".to_string()),      ..Default::default()    })    .await;  assert!(error.is_none());  // Check that the cell data is updated.  let cell = test    .get_date_cell(&grid_view.id, &row_id, &date_field.id)    .await;  assert_eq!(cell.date, "");  assert_eq!(cell.timestamp, 0);}#[tokio::test]async fn create_checklist_field_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  // create checklist field  let checklist_field = test.create_field(&grid_view.id, FieldType::Checklist).await;  let database = test.get_database(&grid_view.id).await;  // Get the checklist cell  let cell = test    .get_checklist_cell(&grid_view.id, &checklist_field.id, &database.rows[0].id)    .await;  assert_eq!(cell.options.len(), 0);  assert_eq!(cell.selected_options.len(), 0);  assert_eq!(cell.percentage, 0.0);}#[tokio::test]async fn update_checklist_cell_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  // create checklist field  let checklist_field = test.create_field(&grid_view.id, FieldType::Checklist).await;  let database = test.get_database(&grid_view.id).await;  // update the checklist cell  let changeset = ChecklistCellDataChangesetPB {    view_id: grid_view.id.clone(),    row_id: database.rows[0].id.clone(),    field_id: checklist_field.id.clone(),    insert_options: vec![      "task 1".to_string(),      "task 2".to_string(),      "task 3".to_string(),    ],    selected_option_ids: vec![],    delete_option_ids: vec![],    update_options: vec![],  };  test.update_checklist_cell(changeset).await;  // get the cell  let cell = test    .get_checklist_cell(&grid_view.id, &checklist_field.id, &database.rows[0].id)    .await;  assert_eq!(cell.options.len(), 3);  assert_eq!(cell.selected_options.len(), 0);  // select some options  let changeset = ChecklistCellDataChangesetPB {    view_id: grid_view.id.clone(),    row_id: database.rows[0].id.clone(),    field_id: checklist_field.id.clone(),    selected_option_ids: vec![cell.options[0].id.clone(), cell.options[1].id.clone()],    ..Default::default()  };  test.update_checklist_cell(changeset).await;  // get the cell  let cell = test    .get_checklist_cell(&grid_view.id, &checklist_field.id, &database.rows[0].id)    .await;  assert_eq!(cell.options.len(), 3);  assert_eq!(cell.selected_options.len(), 2);  assert_eq!(cell.percentage, 0.6);}// The number of groups should be 0 if there is no group by field in grid#[tokio::test]async fn get_groups_event_with_grid_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my board view".to_owned(), vec![])    .await;  let groups = test.get_groups(&grid_view.id).await;  assert_eq!(groups.len(), 0);}#[tokio::test]async fn get_groups_event_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let board_view = test    .create_board(¤t_workspace.id, "my board view".to_owned(), vec![])    .await;  let groups = test.get_groups(&board_view.id).await;  assert_eq!(groups.len(), 4);}#[tokio::test]async fn move_group_event_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let board_view = test    .create_board(¤t_workspace.id, "my board view".to_owned(), vec![])    .await;  let groups = test.get_groups(&board_view.id).await;  assert_eq!(groups.len(), 4);  let group_1 = groups[0].group_id.clone();  let group_2 = groups[1].group_id.clone();  let group_3 = groups[2].group_id.clone();  let group_4 = groups[3].group_id.clone();  let error = test.move_group(&board_view.id, &group_2, &group_3).await;  assert!(error.is_none());  let groups = test.get_groups(&board_view.id).await;  assert_eq!(groups[0].group_id, group_1);  assert_eq!(groups[1].group_id, group_3);  assert_eq!(groups[2].group_id, group_2);  assert_eq!(groups[3].group_id, group_4);  let error = test.move_group(&board_view.id, &group_1, &group_4).await;  assert!(error.is_none());  let groups = test.get_groups(&board_view.id).await;  assert_eq!(groups[0].group_id, group_3);  assert_eq!(groups[1].group_id, group_2);  assert_eq!(groups[2].group_id, group_4);  assert_eq!(groups[3].group_id, group_1);}#[tokio::test]async fn move_group_event_with_invalid_id_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let board_view = test    .create_board(¤t_workspace.id, "my board view".to_owned(), vec![])    .await;  // Empty to group id  let groups = test.get_groups(&board_view.id).await;  let error = test    .move_group(&board_view.id, &groups[0].group_id, "")    .await;  assert!(error.is_some());  // empty from group id  let error = test    .move_group(&board_view.id, "", &groups[1].group_id)    .await;  assert!(error.is_some());}#[tokio::test]async fn rename_group_event_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let board_view = test    .create_board(¤t_workspace.id, "my board view".to_owned(), vec![])    .await;  // Empty to group id  let groups = test.get_groups(&board_view.id).await;  let error = test    .update_group(      &board_view.id,      &groups[0].group_id,      Some("new name".to_owned()),      None,    )    .await;  assert!(error.is_none());  let groups = test.get_groups(&board_view.id).await;  assert_eq!(groups[0].group_name, "new name".to_owned());}#[tokio::test]async fn hide_group_event_test2() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let board_view = test    .create_board(¤t_workspace.id, "my board view".to_owned(), vec![])    .await;  // Empty to group id  let groups = test.get_groups(&board_view.id).await;  assert_eq!(groups.len(), 4);  let error = test    .update_group(&board_view.id, &groups[0].group_id, None, Some(false))    .await;  assert!(error.is_none());  let groups = test.get_groups(&board_view.id).await;  assert_eq!(groups.len(), 3);}// Update the database layout type from grid to board#[tokio::test]async fn update_database_layout_event_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  let error = test    .update_setting(DatabaseSettingChangesetPB {      view_id: grid_view.id.clone(),      layout_type: Some(DatabaseLayoutPB::Board),      ..Default::default()    })    .await;  assert!(error.is_none());  let database = test.get_database(&grid_view.id).await;  assert_eq!(database.layout_type, DatabaseLayoutPB::Board);}// Update the database layout type from grid to board. Set the checkbox field as the grouping field#[tokio::test]async fn update_database_layout_event_test2() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let grid_view = test    .create_grid(¤t_workspace.id, "my grid view".to_owned(), vec![])    .await;  let fields = test.get_all_database_fields(&grid_view.id).await.items;  let checkbox_field = fields    .iter()    .find(|field| field.field_type == FieldType::Checkbox)    .unwrap();  test    .set_group_by_field(&grid_view.id, &checkbox_field.id)    .await;  let error = test    .update_setting(DatabaseSettingChangesetPB {      view_id: grid_view.id.clone(),      layout_type: Some(DatabaseLayoutPB::Board),      ..Default::default()    })    .await;  assert!(error.is_none());  // Empty to group id  let groups = test.get_groups(&grid_view.id).await;  assert_eq!(groups.len(), 2);}// Create a checkbox field in the default board and then set it as the grouping field.#[tokio::test]async fn set_group_by_checkbox_field_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let board_view = test    .create_board(¤t_workspace.id, "my board view".to_owned(), vec![])    .await;  let checkbox_field = test.create_field(&board_view.id, FieldType::Checkbox).await;  test    .set_group_by_field(&board_view.id, &checkbox_field.id)    .await;  let groups = test.get_groups(&board_view.id).await;  assert_eq!(groups.len(), 2);}#[tokio::test]async fn get_all_calendar_event_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let calendar_view = test    .create_calendar(¤t_workspace.id, "my calendar view".to_owned(), vec![])    .await;  // By default, there should be no events  let events = test.get_all_calendar_events(&calendar_view.id).await;  assert!(events.is_empty());}#[tokio::test]async fn create_calendar_event_test() {  let test = FlowyCoreTest::new_with_user().await;  let current_workspace = test.get_current_workspace().await.workspace;  let calendar_view = test    .create_calendar(¤t_workspace.id, "my calendar view".to_owned(), vec![])    .await;  let fields = test.get_all_database_fields(&calendar_view.id).await.items;  let date_field = fields    .iter()    .find(|field| field.field_type == FieldType::DateTime)    .unwrap();  // create a new row  let row = test.create_row(&calendar_view.id, None, None).await;  // Insert data into the date cell of the first row.  let timestamp_str = timestamp().to_string();  let error = test    .update_date_cell(DateChangesetPB {      cell_id: CellIdPB {        view_id: calendar_view.id.clone(),        field_id: date_field.id.clone(),        row_id: row.id,      },      date: Some(timestamp_str.clone()),      time: None,      include_time: None,    })    .await;  assert!(error.is_none());  let events = test.get_all_calendar_events(&calendar_view.id).await;  assert_eq!(events.len(), 1);}
 |