#![cfg(feature = "validation")]
use openapi_trait::serde_valid::Validate as _;
#[openapi_trait::axum("assets/testdata/validation.openapi.yaml")]
pub mod example {}
fn valid_widget() -> example::Widget {
example::Widget {
name: "gadget".into(),
count: 25,
ratio: 0.5,
tags: vec!["a".into(), "b".into()],
inner: example::Inner { code: "abc".into() },
id: "w-1".into(),
labels: None,
}
}
#[test]
fn valid_widget_passes() {
assert!(valid_widget().validate().is_ok());
}
#[test]
fn string_min_length_enforced() {
let mut w = valid_widget();
w.name = "a".into(); assert!(w.validate().is_err());
}
#[test]
fn string_max_length_enforced() {
let mut w = valid_widget();
w.name = "abcdefghijk".into(); assert!(w.validate().is_err());
}
#[test]
fn string_pattern_enforced() {
let mut w = valid_widget();
w.name = "ABC".into(); assert!(w.validate().is_err());
}
#[test]
fn integer_bounds_and_multiple_of_enforced() {
let mut w = valid_widget();
w.count = 0; assert!(w.validate().is_err());
let mut w = valid_widget();
w.count = 200; assert!(w.validate().is_err());
let mut w = valid_widget();
w.count = 23; assert!(w.validate().is_err());
}
#[test]
fn number_exclusive_maximum_enforced() {
let mut w = valid_widget();
w.ratio = 1.0; assert!(w.validate().is_err());
}
#[test]
fn array_min_items_enforced() {
let mut w = valid_widget();
w.tags = vec![]; assert!(w.validate().is_err());
}
#[test]
fn array_unique_items_enforced() {
let mut w = valid_widget();
w.tags = vec!["dup".into(), "dup".into()]; assert!(w.validate().is_err());
}
#[test]
fn scalar_and_map_alias_refs_do_not_break_validation() {
let mut w = valid_widget();
w.labels = Some(
[
("env".to_string(), "prod".to_string()),
("tier".to_string(), "gold".to_string()),
]
.into_iter()
.collect(),
);
assert!(w.validate().is_ok());
}
#[test]
fn nested_ref_is_validated_recursively() {
let mut w = valid_widget();
w.inner.code = "xy".into(); assert!(
w.validate().is_err(),
"top-level validate() should recurse into the referenced Inner model"
);
}