]> git.proxmox.com Git - proxmox.git/blob - proxmox-schema/tests/schema_verification.rs
Merge branch 'proxmox-apt-merge'
[proxmox.git] / proxmox-schema / tests / schema_verification.rs
1 use anyhow::{bail, Error};
2 use serde_json::{json, Value};
3
4 use proxmox_schema::*;
5
6 static STRING_SCHEMA: Schema = StringSchema::new("A test string").schema();
7
8 static SIMPLE_OBJECT_SCHEMA: Schema = ObjectSchema::new(
9 "simple object schema",
10 &[
11 ("prop1", false, &STRING_SCHEMA),
12 ("prop2", true, &STRING_SCHEMA),
13 ("prop3", false, &STRING_SCHEMA),
14 ],
15 )
16 .schema();
17
18 static SIMPLE_PROPERTY_STRING_SCHEMA: Schema = StringSchema::new("simple property string")
19 .format(&ApiStringFormat::PropertyString(&SIMPLE_OBJECT_SCHEMA))
20 .schema();
21
22 static SIMPLE_ARRAY_SCHEMA: Schema = ArraySchema::new("String list.", &STRING_SCHEMA).schema();
23
24 static NESTED_OBJECT_SCHEMA: Schema = ObjectSchema::new(
25 "nested object schema",
26 &[
27 ("arr1", false, &SIMPLE_ARRAY_SCHEMA),
28 ("obj1", false, &SIMPLE_OBJECT_SCHEMA),
29 ("prop1", false, &STRING_SCHEMA),
30 ],
31 )
32 .schema();
33
34 static NESTED_PROPERTY_SCHEMA: Schema = ObjectSchema::new(
35 "object with property strings",
36 &[("ps1", false, &SIMPLE_PROPERTY_STRING_SCHEMA)],
37 )
38 .schema();
39
40 fn compare_error(expected: &[(&str, &str)], err: Error) -> Result<(), Error> {
41 let err = match err.downcast_ref::<ParameterError>() {
42 Some(err) => err,
43 None => bail!("unable to downcast error: {}", err),
44 };
45
46 let result = (move || {
47 let errors = err.errors();
48
49 if errors.len() != expected.len() {
50 bail!(
51 "error list has different length: {} != {}",
52 expected.len(),
53 errors.len()
54 );
55 }
56
57 for i in 0..expected.len() {
58 if expected[i].0 != errors[i].0 {
59 bail!(
60 "error {} path differs: '{}' != '{}'",
61 i,
62 expected[i].0,
63 errors[i].0
64 );
65 }
66 if expected[i].1 != errors[i].1.to_string() {
67 bail!(
68 "error {} message differs: '{}' != '{}'",
69 i,
70 expected[i].1,
71 errors[i].1
72 );
73 }
74 }
75
76 Ok(())
77 })();
78
79 if result.is_err() {
80 println!("GOT: {:?}", err);
81 }
82
83 result
84 }
85
86 fn test_verify(
87 schema: &Schema,
88 data: &Value,
89 expected_errors: &[(&str, &str)],
90 ) -> Result<(), Error> {
91 match schema.verify_json(data) {
92 Ok(_) => bail!("expected errors, but got Ok()"),
93 Err(err) => compare_error(expected_errors, err)?,
94 }
95 Ok(())
96 }
97
98 #[test]
99 fn verify_simple_object() -> Result<(), Error> {
100 let simple_value = json!({"prop1": 1, "prop4": "abc"});
101
102 test_verify(
103 &SIMPLE_OBJECT_SCHEMA,
104 &simple_value,
105 &[
106 ("prop1", "Expected string value."),
107 ("prop4", "schema does not allow additional properties."),
108 ("prop3", "property is missing and it is not optional."),
109 ],
110 )?;
111
112 Ok(())
113 }
114
115 #[test]
116 fn verify_nested_object1() -> Result<(), Error> {
117 let nested_value = json!({"prop1": 1, "prop4": "abc"});
118
119 test_verify(
120 &NESTED_OBJECT_SCHEMA,
121 &nested_value,
122 &[
123 ("prop1", "Expected string value."),
124 ("prop4", "schema does not allow additional properties."),
125 ("arr1", "property is missing and it is not optional."),
126 ("obj1", "property is missing and it is not optional."),
127 ],
128 )?;
129
130 Ok(())
131 }
132
133 #[test]
134 fn verify_nested_object2() -> Result<(), Error> {
135 let nested_value = json!({"prop1": 1, "prop4": "abc", "obj1": {}, "arr1": ["abc", 0]});
136
137 test_verify(
138 &NESTED_OBJECT_SCHEMA,
139 &nested_value,
140 &[
141 ("arr1/[1]", "Expected string value."),
142 ("obj1/prop1", "property is missing and it is not optional."),
143 ("obj1/prop3", "property is missing and it is not optional."),
144 ("prop1", "Expected string value."),
145 ("prop4", "schema does not allow additional properties."),
146 ],
147 )?;
148
149 Ok(())
150 }
151
152 #[test]
153 fn verify_nested_property1() -> Result<(), Error> {
154 let value = json!({"ps1": "abc"});
155
156 test_verify(
157 &NESTED_PROPERTY_SCHEMA,
158 &value,
159 &[(
160 "ps1",
161 "Value without key, but schema does not define a default key.",
162 )],
163 )?;
164
165 Ok(())
166 }
167
168 #[test]
169 fn verify_nested_property2() -> Result<(), Error> {
170 let value = json!({"ps1": "abc=1"});
171
172 test_verify(
173 &NESTED_PROPERTY_SCHEMA,
174 &value,
175 &[("ps1/abc", "schema does not allow additional properties.")],
176 )?;
177
178 Ok(())
179 }
180
181 #[test]
182 fn verify_nested_property3() -> Result<(), Error> {
183 let value = json!({"ps1": ""});
184
185 test_verify(
186 &NESTED_PROPERTY_SCHEMA,
187 &value,
188 &[
189 ("ps1/prop1", "parameter is missing and it is not optional."),
190 ("ps1/prop3", "parameter is missing and it is not optional."),
191 ],
192 )?;
193
194 Ok(())
195 }