use serde_json::json;
use super::*;
use crate::server::protocol::JsonRpcRequest;
fn request(method: &str, params: Option<Value>, id: i64) -> JsonRpcRequest {
JsonRpcRequest {
jsonrpc: "2.0".to_string(),
method: method.to_string(),
params,
id: Some(Some(json!(id))),
}
}
async fn initialized_state() -> SharedState {
let state: SharedState = Arc::new(Mutex::new(ServerState::default()));
let resp = handle_request(state.clone(), request("initialize", Some(json!({})), 0)).await;
assert!(resp.error.is_none(), "initialize failed: {:?}", resp.error);
state
}
#[tokio::test]
async fn a_public_subnet_is_refused_without_the_opt_in() {
let state = initialized_state().await;
let res = handle_request(
state,
request(
"tools/call",
Some(
json!({ "name": "discover_network", "arguments": { "subnet": "198.51.100.0/24" } }),
),
1,
),
)
.await;
let text = serde_json::to_string(&res).unwrap();
assert!(
text.contains("outside the local network"),
"expected a scope refusal, got: {text}"
);
}
#[tokio::test]
async fn a_local_subnet_is_still_accepted() {
let state = initialized_state().await;
let res = handle_request(
state,
request(
"tools/call",
Some(json!({ "name": "discover_network", "arguments": { "subnet": "192.168.250.0/30" } })),
2,
),
)
.await;
let text = serde_json::to_string(&res).unwrap();
assert!(
!text.contains("outside the local network"),
"a local subnet must not be refused: {text}"
);
}
#[tokio::test]
async fn a_failed_tool_is_a_result_not_a_protocol_error() {
let state = initialized_state().await;
let res = handle_request(
state,
request(
"tools/call",
Some(json!({ "name": "dns_lookup", "arguments": { "host": "no-such-host.invalid" } })),
3,
),
)
.await;
assert!(
res.error.is_none(),
"tool failure must not be a JSON-RPC error"
);
let result = res.result.expect("a result payload");
assert_eq!(result["isError"], true);
}
#[tokio::test]
async fn a_legacy_method_with_no_params_is_accepted() {
let state = initialized_state().await;
let mut req = request("list_network_interfaces", None, 4);
req.params = None;
let res = handle_request(state, req).await;
assert!(
res.error.is_none(),
"absent params must not be an error: {:?}",
res.error
);
}