#[test]
fn read_user_agent_from_providers_json_file() {
let temp_dir = tempfile::TempDir::new().expect("temp dir");
let data_dir = temp_dir.path().join("data");
std::fs::create_dir_all(&data_dir).expect("create data dir");
let providers_file = data_dir.join("providers.json");
std::fs::write(
&providers_file,
r#"{
"anthropic": {
"userAgent": "OpenClaw/1.0"
},
"openai": {
"userAgent": "MyCustomAgent/2.0"
}
}"#,
)
.expect("write providers.json");
fn read_provider_file_user_agent_internal(
base_dir: &std::path::Path,
provider: &str,
) -> Option<String> {
let provider_file = base_dir.join("data/providers.json");
if !provider_file.exists() {
return None;
}
let content = std::fs::read_to_string(&provider_file).ok()?;
let json: serde_json::Value = serde_json::from_str(&content).ok()?;
json.get(provider)?
.get("userAgent")?
.as_str()
.map(String::from)
}
let ua = read_provider_file_user_agent_internal(temp_dir.path(), "anthropic");
assert_eq!(ua, Some("OpenClaw/1.0".to_string()));
let ua2 = read_provider_file_user_agent_internal(temp_dir.path(), "openai");
assert_eq!(ua2, Some("MyCustomAgent/2.0".to_string()));
let ua3 = read_provider_file_user_agent_internal(temp_dir.path(), "gemini");
assert_eq!(ua3, None);
}
#[test]
fn user_agent_env_var_priority_over_file() {
let env_ua = std::env::var("RSCLAW_TEST_USER_AGENT").ok();
let file_ua = Some("FromFile".to_string());
let result = if env_ua.is_some() {
env_ua.clone()
} else {
file_ua.clone()
};
if env_ua.is_none() {
assert_eq!(result, file_ua);
}
}
#[test]
fn user_agent_none_when_no_config() {
fn read_provider_file_user_agent_internal(
base_dir: &std::path::Path,
provider: &str,
) -> Option<String> {
let provider_file = base_dir.join("data/providers.json");
if !provider_file.exists() {
return None;
}
let content = std::fs::read_to_string(&provider_file).ok()?;
let json: serde_json::Value = serde_json::from_str(&content).ok()?;
json.get(provider)?
.get("userAgent")?
.as_str()
.map(String::from)
}
let temp_dir = tempfile::TempDir::new().expect("temp dir");
let ua = read_provider_file_user_agent_internal(temp_dir.path(), "anthropic");
assert_eq!(ua, None);
}
#[test]
fn opencode_tooldef_in_tool_list() {
let source = include_str!("../src/agent/tools_builder.rs");
assert!(
source.contains(r#"name: "opencode".to_owned()"#),
"opencode tool should be defined in tools_builder.rs"
);
assert!(
source.contains("OpenCode"),
"opencode tool should mention OpenCode"
);
assert!(
source.contains(r#""task""#),
"opencode tool should have task parameter"
);
}
#[test]
fn opencode_tool_dispatch_exists() {
let source = include_str!("../src/agent/runtime.rs");
assert!(
source.contains(r#""opencode" => return self.tool_opencode(ctx, args).await"#),
"opencode tool should be dispatched in runtime"
);
let acp_source = include_str!("../src/agent/tools_acp.rs");
assert!(
acp_source.contains("async fn tool_opencode"),
"tool_opencode method should exist in tools_acp.rs"
);
}
#[test]
fn provider_config_has_user_agent_field() {
use rsclaw::config::schema::ProviderConfig;
let config = ProviderConfig {
base_url: Some("https://api.openai.com".to_string()),
api_key: None,
api: None,
models: None,
enabled: Some(true),
user_agent: Some("TestAgent/1.0".to_string()),
};
assert_eq!(config.user_agent, Some("TestAgent/1.0".to_string()));
}
#[test]
fn opencode_tool_calls_acp_client() {
let source = include_str!("../src/agent/tools_acp.rs");
assert!(
source.contains("crate::acp::client::AcpClient"),
"tool_opencode should use AcpClient"
);
assert!(
source.contains("AcpClient::spawn"),
"tool_opencode should spawn AcpClient"
);
assert!(
source.contains(".initialize("),
"tool_opencode should initialize the client"
);
assert!(
source.contains("client.create_session"),
"tool_opencode should create session"
);
assert!(
source.contains("send_prompt"),
"tool_opencode should send prompt"
);
}
#[test]
fn opencode_tool_handles_session_id() {
let source = include_str!("../src/agent/tools_acp.rs");
assert!(
source.contains("session_id"),
"tool_opencode should handle session_id"
);
}