use crate::brain::tools::a2a_send::{A2aSendTool, profile_disabled_error};
use crate::brain::tools::profile_list::{
ProfileA2aRow, ProfileListTool, effective_a2a_url, render_roster,
};
use crate::brain::tools::{Tool, ToolExecutionContext};
use crate::config::types::A2aConfig;
fn ctx() -> ToolExecutionContext {
ToolExecutionContext::new(uuid::Uuid::new_v4())
}
fn row(name: &str, cfg: A2aConfig) -> ProfileA2aRow {
ProfileA2aRow {
name: name.to_string(),
description: None,
a2a: cfg,
config_found: true,
}
}
#[test]
fn schema_exposes_profile_param() {
let tool = A2aSendTool::new();
let schema = tool.input_schema();
let props = schema["properties"].as_object().unwrap();
assert!(props.contains_key("profile"));
assert!(props.contains_key("url"));
}
#[test]
fn profile_list_never_surfaces_api_key() {
let secret = A2aConfig {
enabled: true,
api_key: Some("sk-super-secret-value-123".to_string()),
..Default::default()
};
let out = render_roster(&[row("truelens", secret)]);
assert!(!out.contains("api_key"), "leaked field name: {out}");
assert!(
!out.contains("sk-super-secret-value-123"),
"leaked key value: {out}"
);
assert!(out.contains("truelens"));
assert!(out.contains("enabled"));
}
#[test]
fn effective_url_prefers_advertise_url_over_bind_port() {
let adv = A2aConfig {
enabled: true,
advertise_url: Some("http://crab.example.ts.net:9999/".to_string()),
..Default::default()
};
assert_eq!(effective_a2a_url(&adv), "http://crab.example.ts.net:9999");
let plain = A2aConfig {
enabled: true,
..Default::default()
};
assert_eq!(effective_a2a_url(&plain), "http://127.0.0.1:18790");
}
#[tokio::test]
async fn a2a_send_rejects_url_and_profile_together() {
let tool = A2aSendTool::new();
let result = tool
.execute(
serde_json::json!({
"action": "discover",
"url": "http://127.0.0.1:18790",
"profile": "ops"
}),
&ctx(),
)
.await
.unwrap();
assert!(!result.success);
let err = result.error.unwrap_or_default();
assert!(err.contains("mutually exclusive"), "was: {err}");
}
#[tokio::test]
async fn a2a_send_requires_a_target() {
let tool = A2aSendTool::new();
let result = tool
.execute(serde_json::json!({"action": "discover"}), &ctx())
.await
.unwrap();
assert!(!result.success);
let err = result.error.unwrap_or_default();
assert!(err.contains("'url' or 'profile'"), "was: {err}");
}
#[test]
fn disabled_target_error_names_profile_and_fix() {
let err = profile_disabled_error("truelens");
assert!(err.contains("'truelens'"), "was: {err}");
assert!(err.contains("enabled=true"), "was: {err}");
assert!(err.contains("has a2a disabled"), "wording drifted: {err}");
}
#[test]
fn collision_warning_fires_for_enabled_profiles_sharing_port() {
let a = A2aConfig {
enabled: true,
..Default::default()
};
let b = A2aConfig {
enabled: true,
..Default::default()
};
let out = render_roster(&[row("ops", a), row("truelens", b)]);
assert!(
out.contains("warning: ops and truelens both on 18790"),
"was: {out}"
);
assert!(out.contains("fail to bind"));
let off = A2aConfig {
enabled: false,
..Default::default()
};
let on = A2aConfig {
enabled: true,
..Default::default()
};
let out2 = render_roster(&[row("ops", on), row("quiet", off)]);
assert!(!out2.contains("warning:"), "was: {out2}");
}
#[test]
fn agent_card_carries_profile_name() {
let card = crate::config::profile::with_profile_home(Some("truelens"), || {
crate::a2a::agent_card::build_agent_card("127.0.0.1", 18790, None)
});
assert!(
card.name.contains("'truelens'"),
"card name was: {}",
card.name
);
assert!(card.name.starts_with("OpenCrabs "));
assert!(card.name.contains(crate::VERSION));
}
#[test]
fn profile_list_tool_shape() {
let tool = ProfileListTool::new();
assert_eq!(tool.name(), "profile_list");
let schema = tool.input_schema();
assert_eq!(schema["properties"].as_object().unwrap().len(), 0);
assert!(tool.hints().read_only);
}