use std::collections::HashMap;
use hyper::Request;
use serde_json::{Value, json};
use super::Body;
use super::body_kind::BodyKind;
use crate::parsed_request::ParsedRequest;
fn parse_body(toml_text: &str) -> Body {
let wrapped = format!("[body]\n{}", toml_text);
#[derive(serde::Deserialize)]
struct Wrapper {
body: Body,
}
let w: Wrapper = toml::from_str(&wrapped).expect("parse body TOML");
w.body
}
fn make_parsed_request(body_json: Option<Value>) -> ParsedRequest {
let req = Request::builder()
.method("POST")
.uri("/test")
.body(())
.expect("build request");
let (component_parts, _) = req.into_parts();
ParsedRequest {
url_path: "/test".to_owned(),
component_parts,
body_json,
}
}
#[test]
fn is_match_no_body_returns_false() {
let body = parse_body(r#"json."x" = { value = "y" }"#);
let req = make_parsed_request(None);
assert!(!body.is_match(&req));
}
#[test]
fn is_match_no_json_kind_returns_false() {
let body = Body(HashMap::new());
let req = make_parsed_request(Some(json!({"x": "y"})));
assert!(!body.is_match(&req));
}
#[test]
fn is_match_empty_json_kind_returns_false() {
let mut outer = HashMap::new();
outer.insert(BodyKind::Json, HashMap::new());
let body = Body(outer);
let req = make_parsed_request(Some(json!({"x": "y"})));
assert!(!body.is_match(&req));
}
#[test]
fn is_match_jsonpath_hit_equal() {
let body = parse_body(r#"json."action" = { op = "equal", value = "go" }"#);
let req = make_parsed_request(Some(json!({"action": "go"})));
assert!(body.is_match(&req));
}
#[test]
fn is_match_jsonpath_hit_starts_with() {
let body = parse_body(r#"json."tag" = { op = "starts_with", value = "v1" }"#);
let req = make_parsed_request(Some(json!({"tag": "v1.2.3"})));
assert!(body.is_match(&req));
}
#[test]
fn is_match_jsonpath_hit_contains() {
let body = parse_body(r#"json."message" = { op = "contains", value = "error" }"#);
let req = make_parsed_request(Some(json!({"message": "an error occurred"})));
assert!(body.is_match(&req));
}
#[test]
fn is_match_jsonpath_miss_returns_false() {
let body = parse_body(r#"json."missing" = { value = "x" }"#);
let req = make_parsed_request(Some(json!({"present": "x"})));
assert!(!body.is_match(&req));
}
#[test]
fn is_match_jsonpath_value_number_coerced_to_string() {
let body = parse_body(r#"json."count" = { value = "42" }"#);
let req = make_parsed_request(Some(json!({"count": 42})));
assert!(body.is_match(&req));
}
#[test]
fn is_match_jsonpath_value_object_coerced_to_string() {
let body = parse_body(r#"json."obj" = { value = "{\"k\":\"v\"}" }"#);
let req = make_parsed_request(Some(json!({"obj": {"k": "v"}})));
assert!(body.is_match(&req));
}
#[test]
fn is_match_multiple_jsonpaths_all_match() {
let body = parse_body(
r#"json."action" = { value = "go" }
json."user" = { op = "starts_with", value = "alice" }"#,
);
let req = make_parsed_request(Some(json!({"action": "go", "user": "alice42"})));
assert!(body.is_match(&req));
}
#[test]
fn is_match_multiple_jsonpaths_one_fails() {
let body = parse_body(
r#"json."action" = { value = "go" }
json."user" = { op = "starts_with", value = "alice" }"#,
);
let req = make_parsed_request(Some(json!({"action": "go", "user": "bob"})));
assert!(!body.is_match(&req));
}
#[test]
fn validate_empty_outer_returns_false() {
let body = Body(HashMap::new());
assert!(!body.validate());
}
#[test]
fn validate_empty_inner_returns_false() {
let mut outer = HashMap::new();
outer.insert(BodyKind::Json, HashMap::new());
let body = Body(outer);
assert!(!body.validate());
}
#[test]
fn validate_non_empty_returns_true() {
let body = parse_body(r#"json."x" = { value = "y" }"#);
assert!(body.validate());
}
#[test]
fn deserialize_simple_jsonpath() {
let body = parse_body(r#"json."foo" = { value = "bar" }"#);
let inner = body.0.get(&BodyKind::Json).expect("json kind present");
assert!(inner.contains_key("foo"));
assert_eq!(inner["foo"].value, "bar");
}
#[test]
fn deserialize_nested_jsonpath() {
let body = parse_body(r#"json."user.address.city" = { value = "Tokyo" }"#);
let inner = body.0.get(&BodyKind::Json).unwrap();
assert!(inner.contains_key("user.address.city"));
}
#[test]
fn deserialize_multiple_jsonpaths() {
let body = parse_body(
r#"json."a" = { value = "1" }
json."b" = { op = "equal", value = "2" }
json."c" = { op = "starts_with", value = "3" }"#,
);
let inner = body.0.get(&BodyKind::Json).unwrap();
assert_eq!(inner.len(), 3);
}