mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
chore: fix test
This commit is contained in:
@ -164,11 +164,16 @@ pub struct CreateFieldPayloadPB {
|
|||||||
|
|
||||||
#[pb(index = 2)]
|
#[pb(index = 2)]
|
||||||
pub field_type: FieldType,
|
pub field_type: FieldType,
|
||||||
|
|
||||||
|
#[pb(index = 3, one_of)]
|
||||||
|
pub type_option_data: Option<Vec<u8>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct CreateFieldParams {
|
pub struct CreateFieldParams {
|
||||||
pub grid_id: String,
|
pub grid_id: String,
|
||||||
pub field_type: FieldType,
|
pub field_type: FieldType,
|
||||||
|
pub type_option_data: Option<Vec<u8>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryInto<CreateFieldParams> for CreateFieldPayloadPB {
|
impl TryInto<CreateFieldParams> for CreateFieldPayloadPB {
|
||||||
@ -179,6 +184,7 @@ impl TryInto<CreateFieldParams> for CreateFieldPayloadPB {
|
|||||||
Ok(CreateFieldParams {
|
Ok(CreateFieldParams {
|
||||||
grid_id: grid_id.0,
|
grid_id: grid_id.0,
|
||||||
field_type: self.field_type,
|
field_type: self.field_type,
|
||||||
|
type_option_data: self.type_option_data,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -314,50 +320,6 @@ impl std::convert::From<String> for RepeatedFieldIdPB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(ProtoBuf, Default)]
|
|
||||||
pub struct InsertFieldPayloadPB {
|
|
||||||
#[pb(index = 1)]
|
|
||||||
pub grid_id: String,
|
|
||||||
|
|
||||||
#[pb(index = 2)]
|
|
||||||
pub field: FieldPB,
|
|
||||||
|
|
||||||
#[pb(index = 3)]
|
|
||||||
pub type_option_data: Vec<u8>,
|
|
||||||
|
|
||||||
#[pb(index = 4, one_of)]
|
|
||||||
pub start_field_id: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct InsertFieldParams {
|
|
||||||
pub grid_id: String,
|
|
||||||
pub field: FieldPB,
|
|
||||||
pub type_option_data: Vec<u8>,
|
|
||||||
pub start_field_id: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryInto<InsertFieldParams> for InsertFieldPayloadPB {
|
|
||||||
type Error = ErrorCode;
|
|
||||||
|
|
||||||
fn try_into(self) -> Result<InsertFieldParams, Self::Error> {
|
|
||||||
let grid_id = NotEmptyStr::parse(self.grid_id).map_err(|_| ErrorCode::GridIdIsEmpty)?;
|
|
||||||
let _ = NotEmptyStr::parse(self.field.id.clone()).map_err(|_| ErrorCode::FieldIdIsEmpty)?;
|
|
||||||
|
|
||||||
let start_field_id = match self.start_field_id {
|
|
||||||
None => None,
|
|
||||||
Some(id) => Some(NotEmptyStr::parse(id).map_err(|_| ErrorCode::FieldIdIsEmpty)?.0),
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(InsertFieldParams {
|
|
||||||
grid_id: grid_id.0,
|
|
||||||
field: self.field,
|
|
||||||
type_option_data: self.type_option_data,
|
|
||||||
start_field_id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// [UpdateFieldTypeOptionPayloadPB] is used to update the type option data.
|
/// [UpdateFieldTypeOptionPayloadPB] is used to update the type option data.
|
||||||
#[derive(ProtoBuf, Default)]
|
#[derive(ProtoBuf, Default)]
|
||||||
pub struct UpdateFieldTypeOptionPayloadPB {
|
pub struct UpdateFieldTypeOptionPayloadPB {
|
||||||
|
@ -192,7 +192,9 @@ pub(crate) async fn create_field_type_option_data_handler(
|
|||||||
) -> DataResult<FieldTypeOptionDataPB, FlowyError> {
|
) -> DataResult<FieldTypeOptionDataPB, FlowyError> {
|
||||||
let params: CreateFieldParams = data.into_inner().try_into()?;
|
let params: CreateFieldParams = data.into_inner().try_into()?;
|
||||||
let editor = manager.get_grid_editor(¶ms.grid_id)?;
|
let editor = manager.get_grid_editor(¶ms.grid_id)?;
|
||||||
let field_rev = editor.create_next_field_rev(¶ms.field_type).await?;
|
let field_rev = editor
|
||||||
|
.create_new_field_rev(¶ms.field_type, params.type_option_data)
|
||||||
|
.await?;
|
||||||
let field_type: FieldType = field_rev.ty.into();
|
let field_type: FieldType = field_rev.ty.into();
|
||||||
let type_option_data = get_type_option_data(&field_rev, &field_type).await?;
|
let type_option_data = get_type_option_data(&field_rev, &field_type).await?;
|
||||||
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
use crate::entities::{FieldPB, FieldType};
|
use crate::entities::{FieldPB, FieldType};
|
||||||
use crate::services::field::type_options::*;
|
|
||||||
use bytes::Bytes;
|
use crate::services::field::{default_type_option_builder_from_type, TypeOptionBuilder};
|
||||||
use flowy_grid_data_model::revision::{FieldRevision, TypeOptionDataFormat};
|
|
||||||
|
use flowy_grid_data_model::revision::FieldRevision;
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
pub struct FieldBuilder {
|
pub struct FieldBuilder {
|
||||||
@ -82,47 +83,3 @@ impl FieldBuilder {
|
|||||||
field_rev
|
field_rev
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TypeOptionBuilder {
|
|
||||||
fn field_type(&self) -> FieldType;
|
|
||||||
fn data_format(&self) -> &dyn TypeOptionDataFormat;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn default_type_option_builder_from_type(field_type: &FieldType) -> Box<dyn TypeOptionBuilder> {
|
|
||||||
let s: String = match field_type {
|
|
||||||
FieldType::RichText => RichTextTypeOptionPB::default().into(),
|
|
||||||
FieldType::Number => NumberTypeOptionPB::default().into(),
|
|
||||||
FieldType::DateTime => DateTypeOptionPB::default().into(),
|
|
||||||
FieldType::SingleSelect => SingleSelectTypeOptionPB::default().into(),
|
|
||||||
FieldType::MultiSelect => MultiSelectTypeOptionPB::default().into(),
|
|
||||||
FieldType::Checkbox => CheckboxTypeOptionPB::default().into(),
|
|
||||||
FieldType::URL => URLTypeOptionPB::default().into(),
|
|
||||||
};
|
|
||||||
|
|
||||||
type_option_builder_from_json_str(&s, field_type)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn type_option_builder_from_json_str(s: &str, field_type: &FieldType) -> Box<dyn TypeOptionBuilder> {
|
|
||||||
match field_type {
|
|
||||||
FieldType::RichText => Box::new(RichTextTypeOptionBuilder::from_json_str(s)),
|
|
||||||
FieldType::Number => Box::new(NumberTypeOptionBuilder::from_json_str(s)),
|
|
||||||
FieldType::DateTime => Box::new(DateTypeOptionBuilder::from_json_str(s)),
|
|
||||||
FieldType::SingleSelect => Box::new(SingleSelectTypeOptionBuilder::from_json_str(s)),
|
|
||||||
FieldType::MultiSelect => Box::new(MultiSelectTypeOptionBuilder::from_json_str(s)),
|
|
||||||
FieldType::Checkbox => Box::new(CheckboxTypeOptionBuilder::from_json_str(s)),
|
|
||||||
FieldType::URL => Box::new(URLTypeOptionBuilder::from_json_str(s)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn type_option_builder_from_bytes<T: Into<Bytes>>(bytes: T, field_type: &FieldType) -> Box<dyn TypeOptionBuilder> {
|
|
||||||
let bytes = bytes.into();
|
|
||||||
match field_type {
|
|
||||||
FieldType::RichText => Box::new(RichTextTypeOptionBuilder::from_protobuf_bytes(bytes)),
|
|
||||||
FieldType::Number => Box::new(NumberTypeOptionBuilder::from_protobuf_bytes(bytes)),
|
|
||||||
FieldType::DateTime => Box::new(DateTypeOptionBuilder::from_protobuf_bytes(bytes)),
|
|
||||||
FieldType::SingleSelect => Box::new(SingleSelectTypeOptionBuilder::from_protobuf_bytes(bytes)),
|
|
||||||
FieldType::MultiSelect => Box::new(MultiSelectTypeOptionBuilder::from_protobuf_bytes(bytes)),
|
|
||||||
FieldType::Checkbox => Box::new(CheckboxTypeOptionBuilder::from_protobuf_bytes(bytes)),
|
|
||||||
FieldType::URL => Box::new(URLTypeOptionBuilder::from_protobuf_bytes(bytes)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
mod field_builder;
|
mod field_builder;
|
||||||
mod field_operation;
|
mod field_operation;
|
||||||
|
mod type_option_builder;
|
||||||
pub(crate) mod type_options;
|
pub(crate) mod type_options;
|
||||||
|
|
||||||
pub use field_builder::*;
|
pub use field_builder::*;
|
||||||
pub use field_operation::*;
|
pub use field_operation::*;
|
||||||
|
pub use type_option_builder::*;
|
||||||
pub use type_options::*;
|
pub use type_options::*;
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
use crate::entities::FieldType;
|
||||||
|
use crate::services::field::type_options::*;
|
||||||
|
use bytes::Bytes;
|
||||||
|
use flowy_grid_data_model::revision::TypeOptionDataFormat;
|
||||||
|
|
||||||
|
pub trait TypeOptionBuilder {
|
||||||
|
fn field_type(&self) -> FieldType;
|
||||||
|
fn data_format(&self) -> &dyn TypeOptionDataFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn default_type_option_builder_from_type(field_type: &FieldType) -> Box<dyn TypeOptionBuilder> {
|
||||||
|
let s: String = match field_type {
|
||||||
|
FieldType::RichText => RichTextTypeOptionPB::default().into(),
|
||||||
|
FieldType::Number => NumberTypeOptionPB::default().into(),
|
||||||
|
FieldType::DateTime => DateTypeOptionPB::default().into(),
|
||||||
|
FieldType::SingleSelect => SingleSelectTypeOptionPB::default().into(),
|
||||||
|
FieldType::MultiSelect => MultiSelectTypeOptionPB::default().into(),
|
||||||
|
FieldType::Checkbox => CheckboxTypeOptionPB::default().into(),
|
||||||
|
FieldType::URL => URLTypeOptionPB::default().into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
type_option_builder_from_json_str(&s, field_type)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn type_option_builder_from_json_str(s: &str, field_type: &FieldType) -> Box<dyn TypeOptionBuilder> {
|
||||||
|
match field_type {
|
||||||
|
FieldType::RichText => Box::new(RichTextTypeOptionBuilder::from_json_str(s)),
|
||||||
|
FieldType::Number => Box::new(NumberTypeOptionBuilder::from_json_str(s)),
|
||||||
|
FieldType::DateTime => Box::new(DateTypeOptionBuilder::from_json_str(s)),
|
||||||
|
FieldType::SingleSelect => Box::new(SingleSelectTypeOptionBuilder::from_json_str(s)),
|
||||||
|
FieldType::MultiSelect => Box::new(MultiSelectTypeOptionBuilder::from_json_str(s)),
|
||||||
|
FieldType::Checkbox => Box::new(CheckboxTypeOptionBuilder::from_json_str(s)),
|
||||||
|
FieldType::URL => Box::new(URLTypeOptionBuilder::from_json_str(s)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn type_option_builder_from_bytes<T: Into<Bytes>>(bytes: T, field_type: &FieldType) -> Box<dyn TypeOptionBuilder> {
|
||||||
|
let bytes = bytes.into();
|
||||||
|
match field_type {
|
||||||
|
FieldType::RichText => Box::new(RichTextTypeOptionBuilder::from_protobuf_bytes(bytes)),
|
||||||
|
FieldType::Number => Box::new(NumberTypeOptionBuilder::from_protobuf_bytes(bytes)),
|
||||||
|
FieldType::DateTime => Box::new(DateTypeOptionBuilder::from_protobuf_bytes(bytes)),
|
||||||
|
FieldType::SingleSelect => Box::new(SingleSelectTypeOptionBuilder::from_protobuf_bytes(bytes)),
|
||||||
|
FieldType::MultiSelect => Box::new(MultiSelectTypeOptionBuilder::from_protobuf_bytes(bytes)),
|
||||||
|
FieldType::Checkbox => Box::new(CheckboxTypeOptionBuilder::from_protobuf_bytes(bytes)),
|
||||||
|
FieldType::URL => Box::new(URLTypeOptionBuilder::from_protobuf_bytes(bytes)),
|
||||||
|
}
|
||||||
|
}
|
@ -87,43 +87,6 @@ impl GridRevisionEditor {
|
|||||||
Ok(editor)
|
Ok(editor)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn insert_field(&self, params: InsertFieldParams) -> FlowyResult<()> {
|
|
||||||
let InsertFieldParams {
|
|
||||||
field,
|
|
||||||
type_option_data,
|
|
||||||
start_field_id,
|
|
||||||
grid_id,
|
|
||||||
} = params;
|
|
||||||
let field_id = field.id.clone();
|
|
||||||
if self.contain_field(&field_id).await {
|
|
||||||
let changeset = FieldChangesetParams {
|
|
||||||
field_id: field.id,
|
|
||||||
grid_id,
|
|
||||||
name: Some(field.name),
|
|
||||||
desc: Some(field.desc),
|
|
||||||
field_type: Some(field.field_type.clone().into()),
|
|
||||||
frozen: Some(field.frozen),
|
|
||||||
visibility: Some(field.visibility),
|
|
||||||
width: Some(field.width),
|
|
||||||
type_option_data: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let _ = self.update_field_rev(changeset, field.field_type).await?;
|
|
||||||
let _ = self.notify_did_update_grid_field(&field_id).await?;
|
|
||||||
} else {
|
|
||||||
let _ = self
|
|
||||||
.modify(|grid| {
|
|
||||||
let builder = type_option_builder_from_bytes(type_option_data, &field.field_type);
|
|
||||||
let field_rev = FieldBuilder::from_field(field, builder).build();
|
|
||||||
Ok(grid.create_field_rev(field_rev, start_field_id)?)
|
|
||||||
})
|
|
||||||
.await?;
|
|
||||||
let _ = self.notify_did_insert_grid_field(&field_id).await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn update_field_type_option(
|
pub async fn update_field_type_option(
|
||||||
&self,
|
&self,
|
||||||
grid_id: &str,
|
grid_id: &str,
|
||||||
@ -153,8 +116,16 @@ impl GridRevisionEditor {
|
|||||||
Ok(field_rev)
|
Ok(field_rev)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_next_field_rev(&self, field_type: &FieldType) -> FlowyResult<FieldRevision> {
|
pub async fn create_new_field_rev(
|
||||||
let field_rev = self.next_field_rev(field_type).await?;
|
&self,
|
||||||
|
field_type: &FieldType,
|
||||||
|
type_option_data: Option<Vec<u8>>,
|
||||||
|
) -> FlowyResult<FieldRevision> {
|
||||||
|
let mut field_rev = self.next_field_rev(field_type).await?;
|
||||||
|
if let Some(type_option_data) = type_option_data {
|
||||||
|
let type_option_builder = type_option_builder_from_bytes(type_option_data, field_type);
|
||||||
|
field_rev.insert_type_option(type_option_builder.data_format());
|
||||||
|
}
|
||||||
let _ = self
|
let _ = self
|
||||||
.modify(|grid| Ok(grid.create_field_rev(field_rev.clone(), None)?))
|
.modify(|grid| Ok(grid.create_field_rev(field_rev.clone(), None)?))
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use crate::grid::grid_editor::GridEditorTest;
|
use crate::grid::grid_editor::GridEditorTest;
|
||||||
use flowy_grid::entities::{FieldChangesetParams, InsertFieldParams};
|
use flowy_grid::entities::{CreateFieldParams, FieldChangesetParams};
|
||||||
use flowy_grid_data_model::revision::FieldRevision;
|
use flowy_grid_data_model::revision::FieldRevision;
|
||||||
|
|
||||||
pub enum FieldScript {
|
pub enum FieldScript {
|
||||||
CreateField {
|
CreateField {
|
||||||
params: InsertFieldParams,
|
params: CreateFieldParams,
|
||||||
},
|
},
|
||||||
UpdateField {
|
UpdateField {
|
||||||
changeset: FieldChangesetParams,
|
changeset: FieldChangesetParams,
|
||||||
@ -13,9 +13,9 @@ pub enum FieldScript {
|
|||||||
field_rev: FieldRevision,
|
field_rev: FieldRevision,
|
||||||
},
|
},
|
||||||
AssertFieldCount(usize),
|
AssertFieldCount(usize),
|
||||||
AssertFieldEqual {
|
AssertFieldTypeOptionEqual {
|
||||||
field_index: usize,
|
field_index: usize,
|
||||||
field_rev: FieldRevision,
|
expected_type_option_data: String,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,11 +46,11 @@ impl GridFieldTest {
|
|||||||
pub async fn run_script(&mut self, script: FieldScript) {
|
pub async fn run_script(&mut self, script: FieldScript) {
|
||||||
match script {
|
match script {
|
||||||
FieldScript::CreateField { params } => {
|
FieldScript::CreateField { params } => {
|
||||||
if !self.editor.contain_field(¶ms.field.id).await {
|
self.field_count += 1;
|
||||||
self.field_count += 1;
|
self.editor
|
||||||
}
|
.create_new_field_rev(¶ms.field_type, params.type_option_data)
|
||||||
|
.await
|
||||||
self.editor.insert_field(params).await.unwrap();
|
.unwrap();
|
||||||
self.field_revs = self.editor.get_field_revs(None).await.unwrap();
|
self.field_revs = self.editor.get_field_revs(None).await.unwrap();
|
||||||
assert_eq!(self.field_count, self.field_revs.len());
|
assert_eq!(self.field_count, self.field_revs.len());
|
||||||
}
|
}
|
||||||
@ -70,9 +70,14 @@ impl GridFieldTest {
|
|||||||
FieldScript::AssertFieldCount(count) => {
|
FieldScript::AssertFieldCount(count) => {
|
||||||
assert_eq!(self.editor.get_field_revs(None).await.unwrap().len(), count);
|
assert_eq!(self.editor.get_field_revs(None).await.unwrap().len(), count);
|
||||||
}
|
}
|
||||||
FieldScript::AssertFieldEqual { field_index, field_rev } => {
|
FieldScript::AssertFieldTypeOptionEqual {
|
||||||
|
field_index,
|
||||||
|
expected_type_option_data,
|
||||||
|
} => {
|
||||||
let field_revs = self.editor.get_field_revs(None).await.unwrap();
|
let field_revs = self.editor.get_field_revs(None).await.unwrap();
|
||||||
assert_eq!(field_revs[field_index].as_ref(), &field_rev);
|
let field_rev = field_revs[field_index].as_ref();
|
||||||
|
let type_option_data = field_rev.get_type_option_str(field_rev.ty.clone()).unwrap();
|
||||||
|
assert_eq!(type_option_data, expected_type_option_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,9 @@ async fn grid_create_field() {
|
|||||||
|
|
||||||
let scripts = vec![
|
let scripts = vec![
|
||||||
CreateField { params },
|
CreateField { params },
|
||||||
AssertFieldEqual {
|
AssertFieldTypeOptionEqual {
|
||||||
field_index: test.field_count(),
|
field_index: test.field_count(),
|
||||||
field_rev,
|
expected_type_option_data: field_rev.get_type_option_str(field_rev.ty.clone()).unwrap(),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
test.run_scripts(scripts).await;
|
test.run_scripts(scripts).await;
|
||||||
@ -23,9 +23,9 @@ async fn grid_create_field() {
|
|||||||
let (params, field_rev) = create_single_select_field(&test.grid_id());
|
let (params, field_rev) = create_single_select_field(&test.grid_id());
|
||||||
let scripts = vec![
|
let scripts = vec![
|
||||||
CreateField { params },
|
CreateField { params },
|
||||||
AssertFieldEqual {
|
AssertFieldTypeOptionEqual {
|
||||||
field_index: test.field_count(),
|
field_index: test.field_count(),
|
||||||
field_rev,
|
expected_type_option_data: field_rev.get_type_option_str(field_rev.ty.clone()).unwrap(),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
test.run_scripts(scripts).await;
|
test.run_scripts(scripts).await;
|
||||||
@ -39,7 +39,6 @@ async fn grid_create_duplicate_field() {
|
|||||||
let expected_field_count = field_count + 1;
|
let expected_field_count = field_count + 1;
|
||||||
let scripts = vec![
|
let scripts = vec![
|
||||||
CreateField { params: params.clone() },
|
CreateField { params: params.clone() },
|
||||||
CreateField { params },
|
|
||||||
AssertFieldCount(expected_field_count),
|
AssertFieldCount(expected_field_count),
|
||||||
];
|
];
|
||||||
test.run_scripts(scripts).await;
|
test.run_scripts(scripts).await;
|
||||||
@ -48,7 +47,12 @@ async fn grid_create_duplicate_field() {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn grid_update_field_with_empty_change() {
|
async fn grid_update_field_with_empty_change() {
|
||||||
let mut test = GridFieldTest::new().await;
|
let mut test = GridFieldTest::new().await;
|
||||||
let (params, field_rev) = create_single_select_field(&test.grid_id());
|
let (params, _) = create_single_select_field(&test.grid_id());
|
||||||
|
let create_field_index = test.field_count();
|
||||||
|
let scripts = vec![CreateField { params }];
|
||||||
|
test.run_scripts(scripts).await;
|
||||||
|
|
||||||
|
let field_rev = (&*test.field_revs.clone().pop().unwrap()).clone();
|
||||||
let changeset = FieldChangesetParams {
|
let changeset = FieldChangesetParams {
|
||||||
field_id: field_rev.id.clone(),
|
field_id: field_rev.id.clone(),
|
||||||
grid_id: test.grid_id(),
|
grid_id: test.grid_id(),
|
||||||
@ -56,11 +60,10 @@ async fn grid_update_field_with_empty_change() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let scripts = vec![
|
let scripts = vec![
|
||||||
CreateField { params },
|
|
||||||
UpdateField { changeset },
|
UpdateField { changeset },
|
||||||
AssertFieldEqual {
|
AssertFieldTypeOptionEqual {
|
||||||
field_index: test.field_count(),
|
field_index: create_field_index,
|
||||||
field_rev,
|
expected_type_option_data: field_rev.get_type_option_str(field_rev.ty.clone()).unwrap(),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
test.run_scripts(scripts).await;
|
test.run_scripts(scripts).await;
|
||||||
@ -69,10 +72,15 @@ async fn grid_update_field_with_empty_change() {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn grid_update_field() {
|
async fn grid_update_field() {
|
||||||
let mut test = GridFieldTest::new().await;
|
let mut test = GridFieldTest::new().await;
|
||||||
let (params, single_select_field) = create_single_select_field(&test.grid_id());
|
let (params, _) = create_single_select_field(&test.grid_id());
|
||||||
|
let scripts = vec![CreateField { params }];
|
||||||
|
let create_field_index = test.field_count();
|
||||||
|
test.run_scripts(scripts).await;
|
||||||
|
//
|
||||||
|
let single_select_field = (&*test.field_revs.clone().pop().unwrap()).clone();
|
||||||
let mut single_select_type_option = SingleSelectTypeOptionPB::from(&single_select_field);
|
let mut single_select_type_option = SingleSelectTypeOptionPB::from(&single_select_field);
|
||||||
single_select_type_option.options.push(SelectOptionPB::new("Unknown"));
|
single_select_type_option.options.push(SelectOptionPB::new("Unknown"));
|
||||||
|
|
||||||
let changeset = FieldChangesetParams {
|
let changeset = FieldChangesetParams {
|
||||||
field_id: single_select_field.id.clone(),
|
field_id: single_select_field.id.clone(),
|
||||||
grid_id: test.grid_id(),
|
grid_id: test.grid_id(),
|
||||||
@ -89,11 +97,12 @@ async fn grid_update_field() {
|
|||||||
expected_field_rev.insert_type_option(&single_select_type_option);
|
expected_field_rev.insert_type_option(&single_select_type_option);
|
||||||
|
|
||||||
let scripts = vec![
|
let scripts = vec![
|
||||||
CreateField { params },
|
|
||||||
UpdateField { changeset },
|
UpdateField { changeset },
|
||||||
AssertFieldEqual {
|
AssertFieldTypeOptionEqual {
|
||||||
field_index: test.field_count(),
|
field_index: create_field_index,
|
||||||
field_rev: expected_field_rev,
|
expected_type_option_data: expected_field_rev
|
||||||
|
.get_type_option_str(expected_field_rev.ty.clone())
|
||||||
|
.unwrap(),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
test.run_scripts(scripts).await;
|
test.run_scripts(scripts).await;
|
||||||
@ -103,9 +112,12 @@ async fn grid_update_field() {
|
|||||||
async fn grid_delete_field() {
|
async fn grid_delete_field() {
|
||||||
let mut test = GridFieldTest::new().await;
|
let mut test = GridFieldTest::new().await;
|
||||||
let original_field_count = test.field_count();
|
let original_field_count = test.field_count();
|
||||||
let (params, text_field_rev) = create_text_field(&test.grid_id());
|
let (params, _) = create_text_field(&test.grid_id());
|
||||||
|
let scripts = vec![CreateField { params }];
|
||||||
|
test.run_scripts(scripts).await;
|
||||||
|
|
||||||
|
let text_field_rev = (&*test.field_revs.clone().pop().unwrap()).clone();
|
||||||
let scripts = vec![
|
let scripts = vec![
|
||||||
CreateField { params },
|
|
||||||
DeleteField {
|
DeleteField {
|
||||||
field_rev: text_field_rev,
|
field_rev: text_field_rev,
|
||||||
},
|
},
|
||||||
|
@ -3,8 +3,8 @@ use flowy_grid::services::field::selection_type_option::SelectOptionPB;
|
|||||||
use flowy_grid::services::field::*;
|
use flowy_grid::services::field::*;
|
||||||
use flowy_grid_data_model::revision::*;
|
use flowy_grid_data_model::revision::*;
|
||||||
|
|
||||||
pub fn create_text_field(grid_id: &str) -> (InsertFieldParams, FieldRevision) {
|
pub fn create_text_field(grid_id: &str) -> (CreateFieldParams, FieldRevision) {
|
||||||
let field_rev = FieldBuilder::new(RichTextTypeOptionBuilder::default())
|
let mut field_rev = FieldBuilder::new(RichTextTypeOptionBuilder::default())
|
||||||
.name("Name")
|
.name("Name")
|
||||||
.visibility(true)
|
.visibility(true)
|
||||||
.build();
|
.build();
|
||||||
@ -17,32 +17,23 @@ pub fn create_text_field(grid_id: &str) -> (InsertFieldParams, FieldRevision) {
|
|||||||
.protobuf_bytes()
|
.protobuf_bytes()
|
||||||
.to_vec();
|
.to_vec();
|
||||||
|
|
||||||
let field = FieldPB {
|
let type_option_builder = type_option_builder_from_bytes(type_option_data.clone(), &field_rev.ty.into());
|
||||||
id: field_rev.id,
|
field_rev.insert_type_option(type_option_builder.data_format());
|
||||||
name: field_rev.name,
|
|
||||||
desc: field_rev.desc,
|
|
||||||
field_type: field_rev.ty.into(),
|
|
||||||
frozen: field_rev.frozen,
|
|
||||||
visibility: field_rev.visibility,
|
|
||||||
width: field_rev.width,
|
|
||||||
is_primary: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
let params = InsertFieldParams {
|
let params = CreateFieldParams {
|
||||||
grid_id: grid_id.to_owned(),
|
grid_id: grid_id.to_owned(),
|
||||||
field,
|
field_type: field_rev.ty.into(),
|
||||||
type_option_data,
|
type_option_data: Some(type_option_data),
|
||||||
start_field_id: None,
|
|
||||||
};
|
};
|
||||||
(params, cloned_field_rev)
|
(params, cloned_field_rev)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_single_select_field(grid_id: &str) -> (InsertFieldParams, FieldRevision) {
|
pub fn create_single_select_field(grid_id: &str) -> (CreateFieldParams, FieldRevision) {
|
||||||
let single_select = SingleSelectTypeOptionBuilder::default()
|
let single_select = SingleSelectTypeOptionBuilder::default()
|
||||||
.add_option(SelectOptionPB::new("Done"))
|
.add_option(SelectOptionPB::new("Done"))
|
||||||
.add_option(SelectOptionPB::new("Progress"));
|
.add_option(SelectOptionPB::new("Progress"));
|
||||||
|
|
||||||
let field_rev = FieldBuilder::new(single_select).name("Name").visibility(true).build();
|
let mut field_rev = FieldBuilder::new(single_select).name("Name").visibility(true).build();
|
||||||
let cloned_field_rev = field_rev.clone();
|
let cloned_field_rev = field_rev.clone();
|
||||||
let type_option_data = field_rev
|
let type_option_data = field_rev
|
||||||
.get_type_option::<SingleSelectTypeOptionPB>(field_rev.ty)
|
.get_type_option::<SingleSelectTypeOptionPB>(field_rev.ty)
|
||||||
@ -50,22 +41,13 @@ pub fn create_single_select_field(grid_id: &str) -> (InsertFieldParams, FieldRev
|
|||||||
.protobuf_bytes()
|
.protobuf_bytes()
|
||||||
.to_vec();
|
.to_vec();
|
||||||
|
|
||||||
let field = FieldPB {
|
let type_option_builder = type_option_builder_from_bytes(type_option_data.clone(), &field_rev.ty.into());
|
||||||
id: field_rev.id,
|
field_rev.insert_type_option(type_option_builder.data_format());
|
||||||
name: field_rev.name,
|
|
||||||
desc: field_rev.desc,
|
|
||||||
field_type: field_rev.ty.into(),
|
|
||||||
frozen: field_rev.frozen,
|
|
||||||
visibility: field_rev.visibility,
|
|
||||||
width: field_rev.width,
|
|
||||||
is_primary: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
let params = InsertFieldParams {
|
let params = CreateFieldParams {
|
||||||
grid_id: grid_id.to_owned(),
|
grid_id: grid_id.to_owned(),
|
||||||
field,
|
field_type: field_rev.ty.into(),
|
||||||
type_option_data,
|
type_option_data: Some(type_option_data),
|
||||||
start_field_id: None,
|
|
||||||
};
|
};
|
||||||
(params, cloned_field_rev)
|
(params, cloned_field_rev)
|
||||||
}
|
}
|
||||||
|
@ -157,7 +157,6 @@ impl FieldRevision {
|
|||||||
|
|
||||||
pub fn get_type_option<T: TypeOptionDataDeserializer>(&self, field_type_rev: FieldTypeRevision) -> Option<T> {
|
pub fn get_type_option<T: TypeOptionDataDeserializer>(&self, field_type_rev: FieldTypeRevision) -> Option<T> {
|
||||||
let id = field_type_rev.to_string();
|
let id = field_type_rev.to_string();
|
||||||
// TODO: cache the deserialized type option
|
|
||||||
self.type_options.get(&id).map(|s| T::from_json_str(s))
|
self.type_options.get(&id).map(|s| T::from_json_str(s))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,7 +472,7 @@ mod tests {
|
|||||||
use flowy_folder_data_model::revision::{
|
use flowy_folder_data_model::revision::{
|
||||||
AppRevision, FolderRevision, TrashRevision, ViewRevision, WorkspaceRevision,
|
AppRevision, FolderRevision, TrashRevision, ViewRevision, WorkspaceRevision,
|
||||||
};
|
};
|
||||||
use lib_ot::core::{DeltaBuilder, OperationTransform};
|
use lib_ot::core::OperationTransform;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn folder_add_workspace() {
|
fn folder_add_workspace() {
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use crate::core::{AttributeHashMap, DeltaOperation, DeltaOperations, OperationBuilder, OperationTransform};
|
use crate::core::{AttributeHashMap, DeltaOperation, DeltaOperations, OperationBuilder};
|
||||||
use std::fmt::Debug;
|
|
||||||
|
|
||||||
pub type TextOperations = DeltaOperations<AttributeHashMap>;
|
pub type TextOperations = DeltaOperations<AttributeHashMap>;
|
||||||
pub type TextOperationBuilder = OperationBuilder<AttributeHashMap>;
|
pub type TextOperationBuilder = OperationBuilder<AttributeHashMap>;
|
||||||
|
Reference in New Issue
Block a user