diff --git a/lib/src/model/response/body.rs b/lib/src/model/response/body.rs index af164d5c..ee63616f 100644 --- a/lib/src/model/response/body.rs +++ b/lib/src/model/response/body.rs @@ -43,7 +43,7 @@ impl BodyStub { pub fn register_json_body_template<'a, T>(&self, json_values: T) where - T: Iterator, + T: Iterator, { json_values .into_iter() @@ -55,7 +55,7 @@ impl BodyStub { Value::String(s) => self.register(s, s), Value::Object(o) => self.register_json_body_template(o.values()), Value::Array(a) => self.register_json_body_template(a.iter()), - _ => {}, + _ => {} } } @@ -67,7 +67,7 @@ impl BodyStub { fn render_json_obj(&self, json_body: &Map, data: &HandlebarsData) -> Value { let obj = json_body.into_iter().map(|(key, value)| match value { - Value::String(s) => (key.to_owned(), Self::cast_to_value(self.render(s, data).unwrap_or_default())), + Value::String(s) => (key.to_owned(), Self::unwrap_templating(self.render(s, data).unwrap_or_default())), Value::Object(o) => (key.to_owned(), self.render_json_obj(o, data)), Value::Array(a) => (key.to_owned(), self.render_json_array(a, data)), _ => (key.to_owned(), value.to_owned()), @@ -80,7 +80,7 @@ impl BodyStub { json_body .iter() .map(|value| match value { - Value::String(s) => Self::cast_to_value(self.render(s, data).unwrap_or_default()), + Value::String(s) => Self::unwrap_templating(self.render(s, data).unwrap_or_default()), Value::Object(o) => self.render_json_obj(o, data), Value::Array(a) => self.render_json_array(a, data), _ => value.to_owned(), @@ -90,23 +90,26 @@ impl BodyStub { } /// Tries to dynamically guess the "actual" json type of the string - fn cast_to_value(raw: String) -> Value { - if let Ok(i) = raw.parse::() { - Value::from(i) - } else if let Ok(b) = raw.parse::() { - Value::from(b) - } else if let Ok(f) = raw.parse::() { - Value::from(f) - } else if &raw == "null" { - Value::Null - } else { - let len = raw.len(); - match raw { - o if o.ends_with(Self::OBJECT_IDENTIFIER) => Value::from_str(&o[..len - Self::OBJECT_IDENTIFIER.len()]).unwrap_or_default(), - a if a.ends_with(Self::ARRAY_IDENTIFIER) => Value::from_str(&a[..len - Self::ARRAY_IDENTIFIER.len()]).unwrap_or_default(), - _ => Value::from(raw), + fn unwrap_templating(raw: String) -> Value { + if raw.starts_with("[[[") && raw.ends_with("]]]") { + let raw = raw.trim_start_matches("[[[").trim_end_matches("]]]"); + if let Ok(i) = raw.parse::() { + Value::from(i) + } else if let Ok(b) = raw.parse::() { + Value::from(b) + } else if let Ok(f) = raw.parse::() { + Value::from(f) + } else if raw == "null" { + Value::Null + } else { + let len = raw.len(); + match raw { + o if o.ends_with(Self::OBJECT_IDENTIFIER) => Value::from_str(&o[..len - Self::OBJECT_IDENTIFIER.len()]).unwrap_or_default(), + a if a.ends_with(Self::ARRAY_IDENTIFIER) => Value::from_str(&a[..len - Self::ARRAY_IDENTIFIER.len()]).unwrap_or_default(), + _ => Value::from(raw), + } } - } + } else { Value::String(raw) } } fn binary_body(&self) -> Option> { diff --git a/lib/src/model/response/template/helpers/json_path.rs b/lib/src/model/response/template/helpers/json_path.rs index 68e5e8a2..e43ad031 100644 --- a/lib/src/model/response/template/helpers/json_path.rs +++ b/lib/src/model/response/template/helpers/json_path.rs @@ -36,13 +36,16 @@ impl HelperDef for JsonPathHelper { .filter(|param| Self::is_supported_helper(param)) .and_then(|param| Self::get_json_path(h.params()).and_then(|p| Self::extract(param.value(), p))) .ok_or_else(|| RenderError::new("Invalid jsonpath response template")) - .map(|rendered| match rendered { - Value::Null => "null".to_string(), - Value::Bool(b) => b.to_string(), - Value::Number(n) => n.to_string(), - Value::String(s) => s, - Value::Array(a) => serde_json::to_string(&a).unwrap_or_default() + BodyStub::ARRAY_IDENTIFIER, - Value::Object(o) => serde_json::to_string(&o).unwrap_or_default() + BodyStub::OBJECT_IDENTIFIER, + .map(|rendered| { + let r = match rendered { + Value::Null => "null".to_string(), + Value::Bool(b) => b.to_string(), + Value::Number(n) => n.to_string(), + Value::String(s) => s, + Value::Array(a) => serde_json::to_string(&a).unwrap_or_default() + BodyStub::ARRAY_IDENTIFIER, + Value::Object(o) => serde_json::to_string(&o).unwrap_or_default() + BodyStub::OBJECT_IDENTIFIER, + }; + format!("[[[{r}]]]") }) .and_then(|v| out.write(&v).map_err(RenderError::from)) } diff --git a/lib/src/verify/mapping/req/body.rs b/lib/src/verify/mapping/req/body.rs index 9214cef0..b023882c 100644 --- a/lib/src/verify/mapping/req/body.rs +++ b/lib/src/verify/mapping/req/body.rs @@ -27,7 +27,7 @@ impl From<&RequestStub> for Vec { .unique() .fold(Value::default(), |mut acc, it| { if let Some(value) = it.to_partial_value() { - acc.merge(&value); + acc.merge(value); } acc }); diff --git a/lib/tests/resp/body.rs b/lib/tests/resp/body.rs index e918a367..61f6bb3e 100644 --- a/lib/tests/resp/body.rs +++ b/lib/tests/resp/body.rs @@ -86,7 +86,7 @@ mod json { #[async_std::test] #[stubr::mock("resp/body/json.json")] async fn should_map_json_response_body() { - let expected = json!({"name": "john", "age": 42, "candidate": true, "surnames": ["jdoe", "johnny"]}); + let expected = json!({"name": "john", "age": 42, "ageStr": "42", "candidate": true, "surnames": ["jdoe", "johnny"]}); get(stubr.uri()) .await .expect_status_ok() diff --git a/lib/tests/stubs/resp/body/json.json b/lib/tests/stubs/resp/body/json.json index f4ff5108..4cb4ef1a 100644 --- a/lib/tests/stubs/resp/body/json.json +++ b/lib/tests/stubs/resp/body/json.json @@ -7,11 +7,15 @@ "jsonBody": { "name": "john", "age": 42, + "ageStr": "42", "candidate": true, "surnames": [ "jdoe", "johnny" ] - } + }, + "transformers": [ + "response-template" + ] } }