proxmox/proxmox-schema/tests/schema_verification.rs
Wolfgang Bumiller f6e089555e schema: verify property strings w/ new serde code
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
2023-07-13 16:19:19 +02:00

200 lines
5.0 KiB
Rust

use anyhow::{bail, Error};
use serde_json::{json, Value};
use proxmox_schema::*;
static STRING_SCHEMA: Schema = StringSchema::new("A test string").schema();
static SIMPLE_OBJECT_SCHEMA: Schema = ObjectSchema::new(
"simple object schema",
&[
("prop1", false, &STRING_SCHEMA),
("prop2", true, &STRING_SCHEMA),
("prop3", false, &STRING_SCHEMA),
],
)
.schema();
static SIMPLE_PROPERTY_STRING_SCHEMA: Schema = StringSchema::new("simple property string")
.format(&ApiStringFormat::PropertyString(&SIMPLE_OBJECT_SCHEMA))
.schema();
static SIMPLE_ARRAY_SCHEMA: Schema = ArraySchema::new("String list.", &STRING_SCHEMA).schema();
static NESTED_OBJECT_SCHEMA: Schema = ObjectSchema::new(
"nested object schema",
&[
("arr1", false, &SIMPLE_ARRAY_SCHEMA),
("obj1", false, &SIMPLE_OBJECT_SCHEMA),
("prop1", false, &STRING_SCHEMA),
],
)
.schema();
static NESTED_PROPERTY_SCHEMA: Schema = ObjectSchema::new(
"object with property strings",
&[("ps1", false, &SIMPLE_PROPERTY_STRING_SCHEMA)],
)
.schema();
fn compare_error(expected: &[(&str, &str)], err: Error) -> Result<(), Error> {
let err = match err.downcast_ref::<ParameterError>() {
Some(err) => err,
None => bail!("unable to downcast error: {}", err),
};
let result = (move || {
let errors = err.errors();
if errors.len() != expected.len() {
bail!(
"error list has different length: {} != {}",
expected.len(),
errors.len()
);
}
for i in 0..expected.len() {
if expected[i].0 != errors[i].0 {
bail!(
"error {} path differs: '{}' != '{}'",
i,
expected[i].0,
errors[i].0
);
}
if expected[i].1 != errors[i].1.to_string() {
bail!(
"error {} message differs: '{}' != '{}'",
i,
expected[i].1,
errors[i].1
);
}
}
Ok(())
})();
if result.is_err() {
println!("GOT: {:?}", err);
}
result
}
fn test_verify(
schema: &Schema,
data: &Value,
expected_errors: &[(&str, &str)],
) -> Result<(), Error> {
match schema.verify_json(data) {
Ok(_) => bail!("expected errors, but got Ok()"),
Err(err) => compare_error(expected_errors, err)?,
}
Ok(())
}
#[test]
fn verify_simple_object() -> Result<(), Error> {
let simple_value = json!({"prop1": 1, "prop4": "abc"});
test_verify(
&SIMPLE_OBJECT_SCHEMA,
&simple_value,
&[
("prop1", "Expected string value."),
("prop4", "schema does not allow additional properties."),
("prop3", "property is missing and it is not optional."),
],
)?;
Ok(())
}
#[test]
fn verify_nested_object1() -> Result<(), Error> {
let nested_value = json!({"prop1": 1, "prop4": "abc"});
test_verify(
&NESTED_OBJECT_SCHEMA,
&nested_value,
&[
("prop1", "Expected string value."),
("prop4", "schema does not allow additional properties."),
("arr1", "property is missing and it is not optional."),
("obj1", "property is missing and it is not optional."),
],
)?;
Ok(())
}
#[test]
fn verify_nested_object2() -> Result<(), Error> {
let nested_value = json!({"prop1": 1, "prop4": "abc", "obj1": {}, "arr1": ["abc", 0]});
test_verify(
&NESTED_OBJECT_SCHEMA,
&nested_value,
&[
("arr1/[1]", "Expected string value."),
("obj1/prop1", "property is missing and it is not optional."),
("obj1/prop3", "property is missing and it is not optional."),
("prop1", "Expected string value."),
("prop4", "schema does not allow additional properties."),
],
)?;
Ok(())
}
#[test]
fn verify_nested_property1() -> Result<(), Error> {
let value = json!({"ps1": "abc"});
test_verify(
&NESTED_PROPERTY_SCHEMA,
&value,
&[(
"ps1",
"value without key, but schema does not define a default key",
)],
)?;
Ok(())
}
#[test]
fn verify_nested_property2() -> Result<(), Error> {
let value = json!({"ps1": "abc=1"});
test_verify(
&NESTED_PROPERTY_SCHEMA,
&value,
&[
("ps1/abc", "schema does not allow additional properties"),
("ps1/prop1", "property is missing and it is not optional"),
("ps1/prop3", "property is missing and it is not optional"),
],
)?;
Ok(())
}
#[test]
fn verify_nested_property3() -> Result<(), Error> {
let value = json!({"ps1": ""});
test_verify(
&NESTED_PROPERTY_SCHEMA,
&value,
&[
("ps1/prop1", "property is missing and it is not optional"),
("ps1/prop3", "property is missing and it is not optional"),
],
)?;
Ok(())
}