use super::*;
#[test]
fn a_base_url_resolves_to_the_well_known_card() {
for base in [
"https://nous.example.com",
"https://nous.example.com/",
"http://127.0.0.1:8080",
] {
let url = A2aAgentConfig::new("nous", base).card_url().expect("valid");
assert_eq!(url.path(), WELL_KNOWN_AGENT_CARD_PATH, "{base}");
}
}
#[test]
fn a_url_with_a_path_or_query_is_the_card_itself() {
for card in [
"https://example.com/agents/nous/card.json",
"https://example.com/.well-known/agent-card.json",
"https://example.com/?agent=nous",
] {
let url = A2aAgentConfig::new("nous", card).card_url().expect("valid");
assert_eq!(url.as_str(), card);
}
}
#[test]
fn invalid_names_are_refused_with_the_mcp_rules() {
for name in ["", "evil__foo", "evil_"] {
assert!(matches!(
A2aAgentConfig::new(name, "https://example.com").validate(),
Err(A2aConfigError::InvalidName(_))
));
}
}
#[test]
fn credentials_over_plaintext_to_a_remote_host_are_refused() {
let config = A2aAgentConfig::new("nous", "http://nous.example.com").with_bearer_token("sekrit");
let error = config.validate().expect_err("plaintext refused");
assert!(matches!(error, A2aConfigError::PlaintextCredentials { .. }));
assert!(!error.to_string().contains("sekrit"));
A2aAgentConfig::new("nous", "http://localhost:9000")
.with_bearer_token("sekrit")
.validate()
.expect("loopback allowed");
A2aAgentConfig::new("nous", "https://nous.example.com")
.with_bearer_token("sekrit")
.validate()
.expect("https allowed");
config
.allowing_plaintext_credentials()
.validate()
.expect("override honored");
A2aAgentConfig::new("nous", "http://nous.example.com")
.validate()
.expect("no credentials to protect");
}
#[test]
fn reserved_and_malformed_headers_are_refused_without_their_values() {
let reserved =
A2aAgentConfig::new("nous", "https://example.com").with_header("A2A-Version", "0.3");
assert!(matches!(
reserved.validate(),
Err(A2aConfigError::ReservedHeader { .. })
));
let malformed =
A2aAgentConfig::new("nous", "https://example.com").with_header("x-key", "sek\nrit");
let error = malformed.validate().expect_err("invalid value");
assert!(matches!(error, A2aConfigError::InvalidHeaderValue { .. }));
assert!(!error.to_string().contains("sek"));
}
#[test]
fn urls_outside_http_or_carrying_credentials_are_refused() {
for (url, expected) in [
("not a url", A2aUrlError::Malformed),
("file:///etc/passwd", A2aUrlError::UnsupportedScheme),
("https://user:pw@example.com", A2aUrlError::CredentialsInUrl),
] {
assert_eq!(
A2aAgentConfig::new("nous", url).validate(),
Err(A2aConfigError::Url(expected)),
"{url}"
);
}
}
#[test]
fn zero_limits_that_would_spin_or_starve_are_refused() {
let limits = A2aLimits {
poll_interval: Duration::ZERO,
..A2aLimits::default()
};
assert_eq!(
A2aAgentConfig::new("nous", "https://example.com")
.with_limits(limits)
.validate(),
Err(A2aConfigError::ZeroLimit {
name: "poll_interval"
})
);
let streaming = [
(
A2aLimits {
stream_idle_timeout: Duration::ZERO,
..A2aLimits::default()
},
"stream_idle_timeout",
),
(
A2aLimits {
max_event_bytes: 0,
..A2aLimits::default()
},
"max_event_bytes",
),
];
for (limits, name) in streaming {
assert_eq!(
A2aAgentConfig::new("nous", "https://example.com")
.with_limits(limits)
.validate(),
Err(A2aConfigError::ZeroLimit { name })
);
}
}
#[test]
fn debug_output_never_shows_a_header_value() {
let config = A2aAgentConfig::new("nous", "https://example.com").with_bearer_token("sekrit");
assert!(!format!("{config:?}").contains("sekrit"));
}
#[test]
fn deserializes_the_operator_facing_fields() {
let config: A2aAgentConfig = serde_json::from_value(serde_json::json!({
"name": "nous",
"url": "https://nous.example.com",
"headers": {"authorization": "Bearer sekrit"},
}))
.expect("deserialize");
assert_eq!(config.name, "nous");
assert!(!config.allow_plaintext_credentials);
assert_eq!(config.limits, A2aLimits::default());
assert_eq!(
config.headers["authorization"].expose_secret(),
"Bearer sekrit"
);
}
#[test]
fn neither_the_plaintext_refusal_nor_debug_repeats_a_url_credential() {
let config = A2aAgentConfig::new("nous", "http://u:pw@nous.example.com/card.json?key=sekrit")
.with_bearer_token("token");
let error = A2aConfigError::PlaintextCredentials {
host: "nous.example.com".to_string(),
};
assert!(error.to_string().contains("nous.example.com"));
let printed = format!("{config:?}");
assert!(!printed.contains("sekrit"), "{printed}");
assert!(!printed.contains("pw"), "{printed}");
assert!(!printed.contains("token"), "{printed}");
assert!(printed.contains("nous.example.com/card.json"), "{printed}");
}
#[test]
fn the_plaintext_refusal_names_the_host_and_not_the_query() {
let error = A2aAgentConfig::new("nous", "http://nous.example.com/card.json?key=sekrit")
.with_bearer_token("token")
.validate()
.expect_err("plaintext refused");
let message = error.to_string();
assert!(message.contains("nous.example.com"), "{message}");
assert!(!message.contains("sekrit"), "{message}");
}