From 5de9e7884eeef52a860b6c8a8bd452603bd00292 Mon Sep 17 00:00:00 2001 From: alemi Date: Sun, 20 Oct 2024 15:28:53 +0200 Subject: [PATCH] feat: allow expecting result, for testing APIs --- src/errors.rs | 3 +++ src/fmt.rs | 2 +- src/model/endpoint.rs | 30 +++++++++++++++++++----------- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/errors.rs b/src/errors.rs index 429671b..75c810b 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -34,6 +34,9 @@ pub enum PostWomanError { #[error("request didn't match expected status code: {0:?}")] UnexpectedStatusCode(reqwest::Response), + #[error("request didn't match expected result: got '{0}' expected '{1}'")] + UnexpectedResult(String, String), + #[error("invalid Json Query: {0}")] JQError(String), diff --git a/src/fmt.rs b/src/fmt.rs index 09921f0..d0474f6 100644 --- a/src/fmt.rs +++ b/src/fmt.rs @@ -19,7 +19,7 @@ impl PrintableResult for RunResult { fn print(self) { let (result, _namespace, _name, _elapsed) = self; match result { - Ok(x) => print!("{x}"), + Ok(x) => println!("{x}"), Err(e) => eprintln!(" ! {e}"), } } diff --git a/src/model/endpoint.rs b/src/model/endpoint.rs index 1dbd6a7..ddb98c2 100644 --- a/src/model/endpoint.rs +++ b/src/model/endpoint.rs @@ -26,10 +26,12 @@ pub struct EndpointConfig { pub headers: Option>, /// body, optional string pub body: Option>, - /// expected error code, will fail if different - pub expect: Option, + /// expected error code, will fail if different, defaults to 200 + pub status: Option, /// response extractor pub extract: Option>, + /// expected result, will fail if different when provided + pub expect: Option, } impl EndpointConfig { @@ -145,26 +147,25 @@ impl EndpointConfig { .send() .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)); } - Ok(match self.extract.unwrap_or_default() { + let res = match self.extract.unwrap_or_default() { StringOr::T(ExtractorConfig::Discard) => "".to_string(), StringOr::T(ExtractorConfig::Body) => format_body(res).await?, StringOr::T(ExtractorConfig::Debug) => { // TODO needless double format let res_dbg = format!("{res:#?}"); let body = format_body(res).await?; - format!("{res_dbg}\nBody: {body}\n") + format!("{res_dbg}\nBody: {body}") }, StringOr::T(ExtractorConfig::Header { key }) => res .headers() .get(&key) .ok_or(PostWomanError::HeaderNotFound(key))? .to_str()? - .to_string() - + "\n", + .to_string(), StringOr::T(ExtractorConfig::Regex { pattern }) => { let pattern = regex::Regex::new(&pattern)?; let body = format_body(res).await?; @@ -172,19 +173,26 @@ impl EndpointConfig { .ok_or_else(|| PostWomanError::NoMatch(body.clone()))? .as_str() .to_string() - + "\n" }, // bare string defaults to JQL query StringOr::T(ExtractorConfig::JQ { query }) | StringOr::Str(query) => { let json: serde_json::Value = res.json().await?; let selection = jq(&query, json)?; if selection.len() == 1 { - stringify_json(&selection[0]) + "\n" + stringify_json(&selection[0]) } 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) } }