Skip to content

Commit ee52d70

Browse files
committed
Enhance APISpec: handle default status code
1 parent 0c3793a commit ee52d70

File tree

1 file changed

+52
-17
lines changed

1 file changed

+52
-17
lines changed

mithril-network/mithril-aggregator/src/apispec.rs

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -62,24 +62,42 @@ impl<'a> APISpec<'a> {
6262

6363
let path = self.path.unwrap();
6464
let method = self.method.unwrap().to_lowercase();
65-
let status_code = status.as_str();
66-
67-
let response_spec =
68-
&mut self.openapi.clone()["paths"][path][method]["responses"][status_code];
69-
let response_schema = &mut response_spec.clone()["content"]["application/json"]["schema"];
70-
if body.is_empty() {
71-
match response_spec.as_object() {
72-
Some(_) => match response_schema.as_object() {
73-
Some(_) => Err("non empty body expected".to_string()),
74-
None => Ok(self),
75-
},
76-
None => Err("empty body expected".to_string()),
65+
let mut openapi = self.openapi.clone();
66+
67+
let response_spec = {
68+
match &mut openapi["paths"][path][&method]["responses"] {
69+
Null => None,
70+
response_spec => {
71+
let status_code = status.as_str();
72+
if response_spec.as_object().unwrap().contains_key(status_code) {
73+
Some(&response_spec[status_code])
74+
} else {
75+
Some(&response_spec["default"])
76+
}
77+
}
7778
}
78-
} else {
79-
match &serde_json::from_slice(&body) {
80-
Ok(value) => self.validate_conformity(value, response_schema),
81-
Err(_) => Err("non empty body expected".to_string()),
79+
};
80+
81+
match response_spec {
82+
Some(response_spec) => {
83+
let response_schema =
84+
&mut response_spec.clone()["content"]["application/json"]["schema"];
85+
if body.is_empty() {
86+
match response_spec.as_object() {
87+
Some(_) => match response_schema.as_object() {
88+
Some(_) => Err("non empty body expected".to_string()),
89+
None => Ok(self),
90+
},
91+
None => Err("empty body expected".to_string()),
92+
}
93+
} else {
94+
match &serde_json::from_slice(&body) {
95+
Ok(value) => self.validate_conformity(value, response_schema),
96+
Err(_) => Err("non empty body expected".to_string()),
97+
}
98+
}
8299
}
100+
None => Err(format!("unmatched path and method: {} {}", path, method)),
83101
}
84102
}
85103

@@ -116,9 +134,10 @@ impl<'a> APISpec<'a> {
116134

117135
#[cfg(test)]
118136
mod tests {
119-
use warp::http::Method;
137+
use warp::{http::Method, http::StatusCode};
120138

121139
use super::*;
140+
use crate::entities;
122141
use crate::fake_data;
123142

124143
#[test]
@@ -144,6 +163,22 @@ mod tests {
144163
.unwrap()
145164
.validate_response(&Response::<Bytes>::new(Bytes::new()))
146165
.is_err());
166+
167+
// Route exists and matches default status code
168+
let mut response = Response::<Bytes>::new(Bytes::from(
169+
json!(&entities::Error::new(
170+
"MITHRIL-E0001".to_string(),
171+
"an error occurred".to_string(),
172+
))
173+
.to_string()
174+
.into_bytes(),
175+
));
176+
*response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
177+
assert!(APISpec::from_file(API_SPEC_FILE)
178+
.method(&Method::POST.as_str())
179+
.path(&"/register-signer")
180+
.validate_response(&response)
181+
.is_ok());
147182
}
148183

149184
#[test]

0 commit comments

Comments
 (0)