use serde_json::{Map, Value, json};
use super::super::framing::{INVALID_PARAMS, UNSUPPORTED_PROTOCOL_VERSION};
use super::{Era, LEGACY, MODERN, Refusal, Session};
fn params(value: &Value) -> Map<String, Value> {
value.as_object().cloned().unwrap_or_default()
}
#[test]
fn modern_meta_selects_the_modern_era() -> Result<(), super::Refusal> {
let session = Session::new();
let era = session.era_of(¶ms(&json!({
"_meta": {
"io.modelcontextprotocol/protocolVersion": MODERN,
"io.modelcontextprotocol/clientCapabilities": {},
}
})))?;
assert_eq!(era, Era::Modern);
Ok(())
}
#[test]
fn initialize_opens_the_legacy_session_and_bare_requests_follow() -> Result<(), super::Refusal> {
let mut session = Session::new();
assert_eq!(
session.era_of(&Map::new()).map_err(|r| r.code),
Err(INVALID_PARAMS)
);
let answer = session.initialize(¶ms(&json!({ "protocolVersion": LEGACY })))?;
assert_eq!(answer["protocolVersion"], LEGACY);
assert_eq!(session.era_of(&Map::new())?, Era::Legacy);
Ok(())
}
#[test]
fn an_initialize_for_another_version_is_answered_with_the_legacy_version() -> Result<(), Refusal> {
let mut session = Session::new();
let answer = session.initialize(¶ms(&json!({ "protocolVersion": "2025-06-18" })))?;
assert_eq!(answer["protocolVersion"], LEGACY);
assert!(session.is_legacy());
Ok(())
}
#[test]
fn a_modern_request_naming_an_unknown_version_is_refused() {
let session = Session::new();
let refusal = session
.era_of(¶ms(&json!({
"_meta": { "io.modelcontextprotocol/protocolVersion": "1900-01-01" }
})))
.err();
assert_eq!(refusal.map(|r| r.code), Some(UNSUPPORTED_PROTOCOL_VERSION));
}
#[test]
fn modern_request_without_capabilities_is_invalid_params() {
let session = Session::new();
let refusal = session
.era_of(¶ms(&json!({
"_meta": { "io.modelcontextprotocol/protocolVersion": MODERN }
})))
.err();
assert!(refusal.is_some(), "missing capabilities were accepted");
let Some(refusal) = refusal else { return };
assert_eq!(refusal.code, INVALID_PARAMS);
assert!(
refusal.message.contains("clientCapabilities"),
"{}",
refusal.message
);
}