use mecha10_cli::services::config::*;
use serial_test::serial;
use tempfile::TempDir;
fn create_test_config(dir: &Path) -> PathBuf {
let config_path = dir.join("mecha10.json");
std::fs::write(
&config_path,
r#"{
"robot_id": "test-robot-001",
"nodes": {
"drivers": [],
"custom": []
},
"services": {}
}"#,
)
.unwrap();
config_path
}
#[test]
fn test_is_initialized() {
let temp_dir = TempDir::new().unwrap();
assert!(!ConfigService::is_initialized(temp_dir.path()));
create_test_config(temp_dir.path());
assert!(ConfigService::is_initialized(temp_dir.path()));
}
#[tokio::test]
async fn test_load_from() {
let temp_dir = TempDir::new().unwrap();
let config_path = create_test_config(temp_dir.path());
let config = ConfigService::load_from(&config_path).await.unwrap();
assert_eq!(config.robot.id, "test-robot-001");
}
#[tokio::test]
async fn test_load_from_nonexistent() {
let result = ConfigService::load_from(&PathBuf::from("nonexistent.json")).await;
assert!(result.is_err());
assert!(result.unwrap_err().to_string().contains("not found"));
}
#[tokio::test]
async fn test_load_robot_id() {
let temp_dir = TempDir::new().unwrap();
let config_path = create_test_config(temp_dir.path());
let robot_id = ConfigService::load_robot_id(&config_path).await.unwrap();
assert_eq!(robot_id, "test-robot-001");
}
#[test]
fn test_find_config_from() {
let temp_dir = TempDir::new().unwrap();
create_test_config(temp_dir.path());
let found = ConfigService::find_config_from(temp_dir.path()).unwrap();
assert_eq!(found, temp_dir.path().join("mecha10.json"));
let sub_dir = temp_dir.path().join("subdir");
std::fs::create_dir(&sub_dir).unwrap();
let found = ConfigService::find_config_from(&sub_dir).unwrap();
assert_eq!(found, temp_dir.path().join("mecha10.json"));
}
#[test]
fn test_find_config_not_found() {
let temp_dir = TempDir::new().unwrap();
let result = ConfigService::find_config_from(temp_dir.path());
assert!(result.is_err());
assert!(result.unwrap_err().to_string().contains("No mecha10.json found"));
}
#[tokio::test]
async fn test_load_from_invalid_json() {
let temp_dir = TempDir::new().unwrap();
let config_path = temp_dir.path().join("mecha10.json");
std::fs::write(&config_path, "{ invalid json }").unwrap();
let result = ConfigService::load_from(&config_path).await;
assert!(result.is_err());
assert!(result.unwrap_err().to_string().contains("Failed to parse"));
}
#[tokio::test]
async fn test_load_from_missing_robot_field() {
let temp_dir = TempDir::new().unwrap();
let config_path = temp_dir.path().join("mecha10.json");
std::fs::write(
&config_path,
r#"{
"nodes": {
"drivers": [],
"custom": []
},
"services": {}
}"#,
)
.unwrap();
let result = ConfigService::load_from(&config_path).await;
assert!(result.is_err());
}
#[tokio::test]
async fn test_load_from_empty_file() {
let temp_dir = TempDir::new().unwrap();
let config_path = temp_dir.path().join("mecha10.json");
std::fs::write(&config_path, "").unwrap();
let result = ConfigService::load_from(&config_path).await;
assert!(result.is_err());
}
#[test]
#[serial]
fn test_is_initialized_here() {
let temp_dir = TempDir::new().unwrap();
std::env::set_current_dir(temp_dir.path()).unwrap();
assert!(!ConfigService::is_initialized_here());
create_test_config(temp_dir.path());
assert!(ConfigService::is_initialized_here());
}
#[test]
fn test_find_config_from_nested_subdirectory() {
let temp_dir = TempDir::new().unwrap();
create_test_config(temp_dir.path());
let level1 = temp_dir.path().join("level1");
let level2 = level1.join("level2");
let level3 = level2.join("level3");
std::fs::create_dir_all(&level3).unwrap();
let found = ConfigService::find_config_from(&level3).unwrap();
assert_eq!(found, temp_dir.path().join("mecha10.json"));
}
#[test]
fn test_find_config_from_prefers_nearest() {
let temp_dir = TempDir::new().unwrap();
create_test_config(temp_dir.path());
let subdir = temp_dir.path().join("subdir");
std::fs::create_dir(&subdir).unwrap();
let subdir_config = create_test_config(&subdir);
let found = ConfigService::find_config_from(&subdir).unwrap();
assert_eq!(found, subdir_config);
}
#[tokio::test]
async fn test_load_robot_id_from_nonexistent() {
let result = ConfigService::load_robot_id(&PathBuf::from("nonexistent.json")).await;
assert!(result.is_err());
}
#[tokio::test]
async fn test_load_from_permission_denied() {
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let temp_dir = TempDir::new().unwrap();
let config_path = create_test_config(temp_dir.path());
let mut perms = std::fs::metadata(&config_path).unwrap().permissions();
perms.set_mode(0o000);
std::fs::set_permissions(&config_path, perms).unwrap();
let result = ConfigService::load_from(&config_path).await;
assert!(result.is_err());
let mut perms = std::fs::metadata(&config_path).unwrap().permissions();
perms.set_mode(0o644);
std::fs::set_permissions(&config_path, perms).unwrap();
}
}
#[test]
fn test_validate_nonexistent_file() {
let result = ConfigService::validate(&PathBuf::from("nonexistent.json"));
assert!(result.is_err());
let err_msg = result.unwrap_err().to_string();
assert!(err_msg.contains("not found"));
assert!(err_msg.contains("mecha10 init"));
}