use mockserver_client::*;
use std::sync::{Arc, Mutex};
#[test]
fn test_class_callback_serializes_callback_class() {
let cb = HttpClassCallback::new("com.example.MyCallback");
let json = serde_json::to_value(&cb).unwrap();
assert_eq!(json["callbackClass"], "com.example.MyCallback");
assert!(json.get("delay").is_none());
assert!(json.get("primary").is_none());
}
#[test]
fn test_class_callback_serializes_delay_and_primary() {
let cb = HttpClassCallback::new("com.example.MyCallback")
.delay(Delay::milliseconds(250))
.primary(true);
let json = serde_json::to_value(&cb).unwrap();
assert_eq!(json["callbackClass"], "com.example.MyCallback");
assert_eq!(json["delay"]["timeUnit"], "MILLISECONDS");
assert_eq!(json["delay"]["value"], 250);
assert_eq!(json["primary"], true);
}
#[test]
fn test_expectation_response_class_callback_field_name() {
let exp = Expectation::new(HttpRequest::new().method("GET").path("/cb"))
.respond_with_class_callback("com.example.ResponseCallback");
let json = serde_json::to_value(&exp).unwrap();
assert_eq!(
json["httpResponseClassCallback"]["callbackClass"],
"com.example.ResponseCallback"
);
assert!(json.get("http_response_class_callback").is_none());
}
#[test]
fn test_expectation_forward_class_callback_field_name() {
let exp = Expectation::new(HttpRequest::new().method("GET").path("/fwd"))
.forward_with_class_callback("com.example.ForwardCallback");
let json = serde_json::to_value(&exp).unwrap();
assert_eq!(
json["httpForwardClassCallback"]["callbackClass"],
"com.example.ForwardCallback"
);
}
#[test]
fn test_class_callback_builder_from_value() {
let exp = Expectation::new(HttpRequest::new().path("/x")).respond_class_callback(
HttpClassCallback::new("com.example.C").primary(false),
);
let json = serde_json::to_value(&exp).unwrap();
assert_eq!(json["httpResponseClassCallback"]["callbackClass"], "com.example.C");
assert_eq!(json["httpResponseClassCallback"]["primary"], false);
}
#[test]
fn test_object_callback_serializes_client_id() {
let cb = HttpObjectCallback::new("client-abc");
let json = serde_json::to_value(&cb).unwrap();
assert_eq!(json["clientId"], "client-abc");
assert!(json.get("delay").is_none());
}
#[test]
fn test_expectation_response_object_callback_field_name() {
let exp = Expectation::new(HttpRequest::new().method("GET").path("/obj"))
.respond_object_callback(HttpObjectCallback::new("client-xyz"));
let json = serde_json::to_value(&exp).unwrap();
assert_eq!(json["httpResponseObjectCallback"]["clientId"], "client-xyz");
assert!(json.get("http_response_object_callback").is_none());
}
#[test]
fn test_expectation_forward_object_callback_field_name() {
let exp = Expectation::new(HttpRequest::new().path("/obj-fwd"))
.forward_object_callback(HttpObjectCallback::new("fwd-client"));
let json = serde_json::to_value(&exp).unwrap();
assert_eq!(json["httpForwardObjectCallback"]["clientId"], "fwd-client");
}
fn make_object_request_json(correlation_id: &str) -> String {
serde_json::json!({
"method": "GET",
"path": "/echo",
"headers": {
"WebSocketCorrelationId": [correlation_id]
}
})
.to_string()
}
fn make_breakpoint_request_json(breakpoint_id: &str, correlation_id: &str) -> String {
serde_json::json!({
"method": "GET",
"path": "/echo",
"headers": {
"WebSocketCorrelationId": [correlation_id],
"X-MockServer-BreakpointId": [breakpoint_id]
}
})
.to_string()
}
#[test]
fn test_route_object_callback_produces_response_envelope() {
let handler: Arc<Mutex<Option<ObjectResponseHandler>>> = Arc::new(Mutex::new(Some(Box::new(
|req: serde_json::Value| {
let path = req["path"].as_str().unwrap_or("");
serde_json::json!({
"statusCode": 200,
"body": format!("echo {path}")
})
},
))));
let json = make_object_request_json("corr-obj-1");
let result = route_object_callback(&json, &handler);
assert!(result.is_some());
let (type_name, value) = result.unwrap();
assert_eq!(type_name, "org.mockserver.model.HttpResponse");
assert_eq!(value["statusCode"], 200);
assert_eq!(value["body"], "echo /echo");
assert_eq!(
extract_header(&value, "WebSocketCorrelationId"),
Some("corr-obj-1".to_string())
);
}
#[test]
fn test_route_object_callback_ignores_breakpoint_frames() {
let handler: Arc<Mutex<Option<ObjectResponseHandler>>> = Arc::new(Mutex::new(Some(Box::new(
|_req: serde_json::Value| serde_json::json!({ "statusCode": 200 }),
))));
let json = make_breakpoint_request_json("bp-1", "corr-bp");
assert!(route_object_callback(&json, &handler).is_none());
}
#[test]
fn test_route_object_callback_none_when_no_handler() {
let handler: Arc<Mutex<Option<ObjectResponseHandler>>> = Arc::new(Mutex::new(None));
let json = make_object_request_json("corr-none");
assert!(route_object_callback(&json, &handler).is_none());
}
#[test]
fn test_route_object_callback_panic_auto_continues() {
let handler: Arc<Mutex<Option<ObjectResponseHandler>>> = Arc::new(Mutex::new(Some(Box::new(
|_req: serde_json::Value| panic!("boom"),
))));
let json = make_object_request_json("corr-panic");
let result = route_object_callback(&json, &handler);
assert!(result.is_some());
let (type_name, value) = result.unwrap();
assert_eq!(type_name, "org.mockserver.model.HttpResponse");
assert_eq!(
extract_header(&value, "WebSocketCorrelationId"),
Some("corr-panic".to_string())
);
}