test(mcp): update import tests for v3.7.0 unified structure

- Fix import_from_claude_merges_into_config: check unified mcp.servers
- Fix import_from_codex_adds_servers_from_mcp_servers_table: verify apps.codex enabled
- Fix import_from_codex_merges_into_existing_entries: test smart merge preserves existing config
- Replace cc_switch_lib::app_config:: with public exports (McpServer, McpApps)

All 24 import_export_sync tests now passing.
This commit is contained in:
Jason
2025-11-14 23:39:34 +08:00
parent ea8f2095e2
commit e11c7d84cd

View File

@@ -487,16 +487,12 @@ url = "https://example.com"
let changed = cc_switch_lib::import_from_codex(&mut config).expect("import codex"); let changed = cc_switch_lib::import_from_codex(&mut config).expect("import codex");
assert!(changed >= 2, "should import both servers"); assert!(changed >= 2, "should import both servers");
let servers = &config.mcp.codex.servers; // v3.7.0: 检查统一结构
let echo = servers let servers = config.mcp.servers.as_ref().expect("unified servers should exist");
.get("echo_server")
.and_then(|v| v.as_object()) let echo = servers.get("echo_server").expect("echo server");
.expect("echo server"); assert_eq!(echo.apps.codex, true, "Codex app should be enabled for echo_server");
assert_eq!(echo.get("enabled").and_then(|v| v.as_bool()), Some(true)); let server_spec = echo.server.as_object().expect("server spec");
let server_spec = echo
.get("server")
.and_then(|v| v.as_object())
.expect("server spec");
assert_eq!( assert_eq!(
server_spec server_spec
.get("command") .get("command")
@@ -505,14 +501,9 @@ url = "https://example.com"
"echo" "echo"
); );
let http = servers let http = servers.get("http_server").expect("http server");
.get("http_server") assert_eq!(http.apps.codex, true, "Codex app should be enabled for http_server");
.and_then(|v| v.as_object()) let http_spec = http.server.as_object().expect("http spec");
.expect("http server");
let http_spec = http
.get("server")
.and_then(|v| v.as_object())
.expect("http spec");
assert_eq!( assert_eq!(
http_spec.get("url").and_then(|v| v.as_str()).unwrap_or(""), http_spec.get("url").and_then(|v| v.as_str()).unwrap_or(""),
"https://example.com" "https://example.com"
@@ -537,36 +528,51 @@ command = "echo"
.expect("write codex config"); .expect("write codex config");
let mut config = MultiAppConfig::default(); let mut config = MultiAppConfig::default();
config.mcp.codex.servers.insert( // v3.7.0: 在统一结构中创建已存在的服务器
"existing".into(), config.mcp.servers = Some(std::collections::HashMap::new());
json!({ config.mcp.servers.as_mut().unwrap().insert(
"id": "existing", "existing".to_string(),
"name": "existing", cc_switch_lib::McpServer {
"enabled": false, id: "existing".to_string(),
"server": { name: "existing".to_string(),
server: json!({
"type": "stdio", "type": "stdio",
"command": "prev" "command": "prev"
} }),
}), apps: cc_switch_lib::McpApps {
claude: false,
codex: false, // 初始未启用
gemini: false,
},
description: None,
homepage: None,
docs: None,
tags: Vec::new(),
},
); );
let changed = cc_switch_lib::import_from_codex(&mut config).expect("import codex"); let changed = cc_switch_lib::import_from_codex(&mut config).expect("import codex");
assert!(changed >= 1, "should mark change for enabled flag"); assert!(changed >= 1, "should mark change for enabled flag");
// v3.7.0: 检查统一结构
let entry = config let entry = config
.mcp .mcp
.codex
.servers .servers
.as_ref()
.unwrap()
.get("existing") .get("existing")
.and_then(|v| v.as_object())
.expect("existing entry"); .expect("existing entry");
assert_eq!(entry.get("enabled").and_then(|v| v.as_bool()), Some(true));
let spec = entry // 验证 Codex 应用已启用
.get("server") assert_eq!(entry.apps.codex, true, "Codex app should be enabled after import");
.and_then(|v| v.as_object())
.expect("server spec"); // 验证现有配置被保留server 不应被覆盖)
// 保留原 command确保导入不会覆盖现有 server 细节 let spec = entry.server.as_object().expect("server spec");
assert_eq!(spec.get("command").and_then(|v| v.as_str()), Some("prev")); assert_eq!(
spec.get("command").and_then(|v| v.as_str()),
Some("prev"),
"existing server config should be preserved, not overwritten by import"
);
} }
#[test] #[test]
@@ -644,34 +650,46 @@ fn import_from_claude_merges_into_config() {
.expect("write claude json"); .expect("write claude json");
let mut config = MultiAppConfig::default(); let mut config = MultiAppConfig::default();
config.mcp.claude.servers.insert( // v3.7.0: 在统一结构中创建已存在的服务器
"stdio-enabled".into(), config.mcp.servers = Some(std::collections::HashMap::new());
json!({ config.mcp.servers.as_mut().unwrap().insert(
"id": "stdio-enabled", "stdio-enabled".to_string(),
"name": "stdio-enabled", cc_switch_lib::McpServer {
"enabled": false, id: "stdio-enabled".to_string(),
"server": { name: "stdio-enabled".to_string(),
server: json!({
"type": "stdio", "type": "stdio",
"command": "prev" "command": "prev"
} }),
}), apps: cc_switch_lib::McpApps {
claude: false, // 初始未启用
codex: false,
gemini: false,
},
description: None,
homepage: None,
docs: None,
tags: Vec::new(),
},
); );
let changed = cc_switch_lib::import_from_claude(&mut config).expect("import from claude"); let changed = cc_switch_lib::import_from_claude(&mut config).expect("import from claude");
assert!(changed >= 1, "should mark at least one change"); assert!(changed >= 1, "should mark at least one change");
// v3.7.0: 检查统一结构
let entry = config let entry = config
.mcp .mcp
.claude
.servers .servers
.as_ref()
.unwrap()
.get("stdio-enabled") .get("stdio-enabled")
.and_then(|v| v.as_object())
.expect("entry exists"); .expect("entry exists");
assert_eq!(entry.get("enabled").and_then(|v| v.as_bool()), Some(true));
let server = entry // 验证 Claude 应用已启用
.get("server") assert_eq!(entry.apps.claude, true, "Claude app should be enabled after import");
.and_then(|v| v.as_object())
.expect("server obj"); // 验证现有配置被保留server 不应被覆盖)
let server = entry.server.as_object().expect("server obj");
assert_eq!( assert_eq!(
server.get("command").and_then(|v| v.as_str()).unwrap_or(""), server.get("command").and_then(|v| v.as_str()).unwrap_or(""),
"prev", "prev",