use linked_hash_map::LinkedHashMap;
use crate::{
export, field_types::*, import, modele, validators::Validator, Hit, IndexEntryProperty,
ObjectValue, Reference, ValidationError, ValidationErrorLevel,
};
use std::rc::Rc;
use crate::{HitError, Kernel, Model, Plugins};
pub struct TestEventsKernel {
model: Rc<Model>,
}
impl Kernel for TestEventsKernel {
fn get_model(&self, _name: &str) -> Result<Rc<Model>, HitError> {
return Ok(self.model.clone());
}
fn get_instantiable_models(&self) -> Vec<&Model> {
return vec![&self.model];
}
fn get_plugins(&self) -> Plugins {
Plugins::new()
}
fn get_models(&self) -> Vec<String> {
vec!["test/test".to_string()]
}
}
struct IsNotId2Validator {}
impl Validator<Reference> for IsNotId2Validator {
fn validate(
&self,
value: &Reference,
_context: &crate::validators::ValidatorContext,
) -> Result<Option<Vec<ValidationError>>, HitError> {
if value.id == "id2" {
return Ok(Some(vec![ValidationError {
key: "TEST_ERROR".into(),
level: ValidationErrorLevel::Error,
arguments: Some(vec![("id".into(), value.id.clone())].into_iter().collect()),
}]));
}
Ok(None)
}
fn on_kernel_init(&mut self, _field_name: &str, _model_namee: &str) -> Result<(), HitError> {
Ok(())
}
}
struct OnlyIdInReferenceValidator {}
impl Validator<Reference> for OnlyIdInReferenceValidator {
fn validate(
&self,
_value: &Reference,
context: &crate::validators::ValidatorContext,
) -> Result<Option<Vec<ValidationError>>, HitError> {
if context.id == "id" && context.property == "reference" {
return Ok(Some(vec![ValidationError {
key: "TEST__CUSTOM_ERROR".into(),
level: ValidationErrorLevel::Error,
arguments: None,
}]));
}
Ok(None)
}
fn on_kernel_init(&mut self, _field_name: &str, _model_namee: &str) -> Result<(), HitError> {
Ok(())
}
}
fn create_test_events_model() -> Rc<Model> {
modele!("test/test", "Filesystem" =>
"name": FieldTypeString {
required: true
},
"subitems": FieldTypeSubobjectArray {
authorized_models: vec!["test/test".to_string()]
},
"references": FieldTypeReferenceArray {
authorized_models: vec!["test/test".to_string()],
validators: vec![Box::new(IsNotId2Validator {})],
},
"reference": FieldTypeReference {
authorized_models: vec!["test/test".to_string()],
validators: vec![Box::new(IsNotId2Validator {})],
},
"reference2": FieldTypeReference {
authorized_models: vec!["test/test".to_string()],
validators: vec![Box::new(OnlyIdInReferenceValidator {})],
}
)
}
fn create_test_events_kernel() -> TestEventsKernel {
TestEventsKernel {
model: create_test_events_model(),
}
}
fn get_test_hit() -> Hit {
let mut hit = Hit::new(
"id".into(),
"test/test".into(),
Rc::new(create_test_events_kernel()),
)
.expect("Error creating instance");
hit.insert(
"test/test".into(),
"id2".into(),
LinkedHashMap::new(),
IndexEntryProperty {
id: "id".into(),
property: "subitems".into(),
},
None,
)
.expect("Error");
hit
}
fn it_should_return_an_error_on_reference_arrays_when_validator_detects_it() {
let mut hit = get_test_hit();
hit.insert_reference(
"id",
IndexEntryProperty {
id: "id".into(),
property: "references".into(),
},
None,
)
.expect("Error");
assert!(hit.errors.get("id", "references").is_none());
hit.insert_reference(
"id2",
IndexEntryProperty {
id: "id".into(),
property: "references".into(),
},
None,
)
.expect("Error");
assert_eq!(
hit.errors.get("id", "references").unwrap(),
&vec![ValidationError {
key: "TEST_ERROR".into(),
level: ValidationErrorLevel::Error,
arguments: Some(vec![("id".into(), "id2".into())].into_iter().collect()),
}]
);
}
#[test]
fn it_should_validate_when_importing() {
let mut hit = get_test_hit();
hit.set(
"id",
"reference",
ObjectValue::Reference(Reference { id: "id2".into() }),
)
.expect("Error");
let exported = export(&hit).expect("Error");
let kernel = Rc::new(create_test_events_kernel());
let hit2 = import(&exported, kernel).expect("Error");
assert_eq!(
hit2.get_validation_errors("id", "reference").unwrap(),
&vec![ValidationError {
key: "TEST_ERROR".into(),
level: ValidationErrorLevel::Error,
arguments: Some(vec![("id".into(), "id2".into())].into_iter().collect()),
}]
);
}
#[test]
fn it_should_return_an_error_on_set_when_validator_detects_it() {
let mut hit = get_test_hit();
hit.set(
"id",
"reference",
ObjectValue::Reference(Reference { id: "id2".into() }),
)
.expect("Error");
assert_eq!(
hit.get_validation_errors("id", "reference").unwrap(),
&vec![ValidationError {
key: "TEST_ERROR".into(),
level: ValidationErrorLevel::Error,
arguments: Some(vec![("id".into(), "id2".into())].into_iter().collect()),
}]
);
hit.set(
"id",
"reference",
ObjectValue::Reference(Reference { id: "id".into() }),
)
.expect("Error");
assert!(hit.errors.get("id", "reference").is_none());
}