feat: allow expecting result, for testing APIs
This commit is contained in:
parent
8fbf224506
commit
5de9e7884e
3 changed files with 23 additions and 12 deletions
|
@ -34,6 +34,9 @@ pub enum PostWomanError {
|
||||||
#[error("request didn't match expected status code: {0:?}")]
|
#[error("request didn't match expected status code: {0:?}")]
|
||||||
UnexpectedStatusCode(reqwest::Response),
|
UnexpectedStatusCode(reqwest::Response),
|
||||||
|
|
||||||
|
#[error("request didn't match expected result: got '{0}' expected '{1}'")]
|
||||||
|
UnexpectedResult(String, String),
|
||||||
|
|
||||||
#[error("invalid Json Query: {0}")]
|
#[error("invalid Json Query: {0}")]
|
||||||
JQError(String),
|
JQError(String),
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ impl PrintableResult for RunResult {
|
||||||
fn print(self) {
|
fn print(self) {
|
||||||
let (result, _namespace, _name, _elapsed) = self;
|
let (result, _namespace, _name, _elapsed) = self;
|
||||||
match result {
|
match result {
|
||||||
Ok(x) => print!("{x}"),
|
Ok(x) => println!("{x}"),
|
||||||
Err(e) => eprintln!(" ! {e}"),
|
Err(e) => eprintln!(" ! {e}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,10 +26,12 @@ pub struct EndpointConfig {
|
||||||
pub headers: Option<Vec<String>>,
|
pub headers: Option<Vec<String>>,
|
||||||
/// body, optional string
|
/// body, optional string
|
||||||
pub body: Option<StringOr<toml::Table>>,
|
pub body: Option<StringOr<toml::Table>>,
|
||||||
/// expected error code, will fail if different
|
/// expected error code, will fail if different, defaults to 200
|
||||||
pub expect: Option<u16>,
|
pub status: Option<u16>,
|
||||||
/// response extractor
|
/// response extractor
|
||||||
pub extract: Option<StringOr<ExtractorConfig>>,
|
pub extract: Option<StringOr<ExtractorConfig>>,
|
||||||
|
/// expected result, will fail if different when provided
|
||||||
|
pub expect: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EndpointConfig {
|
impl EndpointConfig {
|
||||||
|
@ -145,26 +147,25 @@ impl EndpointConfig {
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
if res.status().as_u16() != self.expect.unwrap_or(200) {
|
if res.status().as_u16() != self.status.unwrap_or(200) {
|
||||||
return Err(PostWomanError::UnexpectedStatusCode(res));
|
return Err(PostWomanError::UnexpectedStatusCode(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(match self.extract.unwrap_or_default() {
|
let res = match self.extract.unwrap_or_default() {
|
||||||
StringOr::T(ExtractorConfig::Discard) => "".to_string(),
|
StringOr::T(ExtractorConfig::Discard) => "".to_string(),
|
||||||
StringOr::T(ExtractorConfig::Body) => format_body(res).await?,
|
StringOr::T(ExtractorConfig::Body) => format_body(res).await?,
|
||||||
StringOr::T(ExtractorConfig::Debug) => {
|
StringOr::T(ExtractorConfig::Debug) => {
|
||||||
// TODO needless double format
|
// TODO needless double format
|
||||||
let res_dbg = format!("{res:#?}");
|
let res_dbg = format!("{res:#?}");
|
||||||
let body = format_body(res).await?;
|
let body = format_body(res).await?;
|
||||||
format!("{res_dbg}\nBody: {body}\n")
|
format!("{res_dbg}\nBody: {body}")
|
||||||
},
|
},
|
||||||
StringOr::T(ExtractorConfig::Header { key }) => res
|
StringOr::T(ExtractorConfig::Header { key }) => res
|
||||||
.headers()
|
.headers()
|
||||||
.get(&key)
|
.get(&key)
|
||||||
.ok_or(PostWomanError::HeaderNotFound(key))?
|
.ok_or(PostWomanError::HeaderNotFound(key))?
|
||||||
.to_str()?
|
.to_str()?
|
||||||
.to_string()
|
.to_string(),
|
||||||
+ "\n",
|
|
||||||
StringOr::T(ExtractorConfig::Regex { pattern }) => {
|
StringOr::T(ExtractorConfig::Regex { pattern }) => {
|
||||||
let pattern = regex::Regex::new(&pattern)?;
|
let pattern = regex::Regex::new(&pattern)?;
|
||||||
let body = format_body(res).await?;
|
let body = format_body(res).await?;
|
||||||
|
@ -172,19 +173,26 @@ impl EndpointConfig {
|
||||||
.ok_or_else(|| PostWomanError::NoMatch(body.clone()))?
|
.ok_or_else(|| PostWomanError::NoMatch(body.clone()))?
|
||||||
.as_str()
|
.as_str()
|
||||||
.to_string()
|
.to_string()
|
||||||
+ "\n"
|
|
||||||
},
|
},
|
||||||
// bare string defaults to JQL query
|
// bare string defaults to JQL query
|
||||||
StringOr::T(ExtractorConfig::JQ { query }) | StringOr::Str(query) => {
|
StringOr::T(ExtractorConfig::JQ { query }) | StringOr::Str(query) => {
|
||||||
let json: serde_json::Value = res.json().await?;
|
let json: serde_json::Value = res.json().await?;
|
||||||
let selection = jq(&query, json)?;
|
let selection = jq(&query, json)?;
|
||||||
if selection.len() == 1 {
|
if selection.len() == 1 {
|
||||||
stringify_json(&selection[0]) + "\n"
|
stringify_json(&selection[0])
|
||||||
} else {
|
} else {
|
||||||
serde_json::to_string_pretty(&selection)? + "\n"
|
serde_json::to_string_pretty(&selection)?
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
};
|
||||||
|
|
||||||
|
if let Some(expected) = self.expect {
|
||||||
|
if expected != res {
|
||||||
|
return Err(PostWomanError::UnexpectedResult(res, expected));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue