refactor: Upload extractor, 429 refusal test, stricter contract test
This commit is contained in:
@@ -18,30 +18,31 @@ fn operations(spec: &serde_json::Value) -> Vec<(String, String, serde_json::Valu
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn every_operation_that_can_succeed_with_a_body_declares_its_shape() {
|
||||
fn the_spec_is_not_vacuous() {
|
||||
let spec = spec();
|
||||
assert!(!operations(&spec).is_empty());
|
||||
assert!(spec["components"]["schemas"]["ErrorResponse"].is_object());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn every_2xx_json_response_declares_a_schema() {
|
||||
let spec = spec();
|
||||
let mut untyped = Vec::new();
|
||||
|
||||
for (verb, path, op) in operations(&spec) {
|
||||
let responses = op["responses"].as_object().unwrap();
|
||||
let typed = responses.iter().any(|(code, r)| {
|
||||
code.starts_with('2') && r["content"]["application/json"]["schema"].is_object()
|
||||
});
|
||||
let bodyless = responses
|
||||
.iter()
|
||||
.any(|(code, r)| code.starts_with('2') && r.get("content").is_none());
|
||||
let binary = responses.iter().any(|(code, r)| {
|
||||
code.starts_with('2')
|
||||
&& r["content"]
|
||||
.as_object()
|
||||
.is_some_and(|c| !c.contains_key("application/json"))
|
||||
});
|
||||
if !typed && !bodyless && !binary {
|
||||
untyped.push(format!("{verb} {path}"));
|
||||
for (code, r) in op["responses"].as_object().unwrap() {
|
||||
if !code.starts_with('2') {
|
||||
continue;
|
||||
}
|
||||
if let Some(json) = r["content"].get("application/json")
|
||||
&& !json["schema"].is_object()
|
||||
{
|
||||
untyped.push(format!("{verb} {path} -> {code}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert!(untyped.is_empty(), "2xx without a schema: {untyped:?}");
|
||||
assert!(untyped.is_empty(), "2xx JSON without a schema: {untyped:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user