feat: allow expecting result, for testing APIs

This commit is contained in:
əlemi 2024-10-20 15:28:53 +02:00
parent 8fbf224506
commit 5de9e7884e
Signed by: alemi
GPG key ID: A4895B84D311642C
3 changed files with 23 additions and 12 deletions

View file

@ -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),

View file

@ -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}"),
} }
} }

View file

@ -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)
} }
} }