Update: 将子项目从 submodule 转为完整内容
- 移除 GovAI, nomifun-tauri, 算力盒子 的 submodule 引用 - 添加所有子项目的完整源代码 - 保留原始 .git 为 .git.bak 备份
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
//! Integration tests for read-only Agent MCP config discovery.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use nomifun_common::McpSource;
|
||||
use nomifun_db::SqliteMcpServerRepository;
|
||||
use nomifun_mcp::{DetectedServer, McpAgentAdapter, McpError, McpServerTransport, McpSyncService};
|
||||
|
||||
struct MockAdapter {
|
||||
source: McpSource,
|
||||
installed: bool,
|
||||
servers: std::sync::Mutex<Vec<DetectedServer>>,
|
||||
}
|
||||
|
||||
impl MockAdapter {
|
||||
fn new(source: McpSource, installed: bool) -> Self {
|
||||
Self {
|
||||
source,
|
||||
installed,
|
||||
servers: std::sync::Mutex::new(Vec::new()),
|
||||
}
|
||||
}
|
||||
|
||||
fn with_servers(source: McpSource, servers: Vec<DetectedServer>) -> Self {
|
||||
Self {
|
||||
source,
|
||||
installed: true,
|
||||
servers: std::sync::Mutex::new(servers),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl McpAgentAdapter for MockAdapter {
|
||||
fn source(&self) -> McpSource {
|
||||
self.source
|
||||
}
|
||||
|
||||
async fn is_installed(&self) -> Result<bool, McpError> {
|
||||
Ok(self.installed)
|
||||
}
|
||||
|
||||
async fn detect_existing(&self) -> Result<Vec<DetectedServer>, McpError> {
|
||||
if !self.installed {
|
||||
return Err(McpError::AgentNotInstalled(format!("{:?}", self.source)));
|
||||
}
|
||||
Ok(self.servers.lock().unwrap().clone())
|
||||
}
|
||||
|
||||
async fn install_server(&self, _name: &str, _transport: &McpServerTransport) -> Result<(), McpError> {
|
||||
unreachable!("write-to-CLI is no longer supported")
|
||||
}
|
||||
|
||||
async fn remove_server(&self, _name: &str) -> Result<(), McpError> {
|
||||
unreachable!("write-to-CLI is no longer supported")
|
||||
}
|
||||
}
|
||||
|
||||
async fn make_service(adapters: Vec<Arc<dyn McpAgentAdapter>>) -> McpSyncService {
|
||||
let db = nomifun_db::init_database_memory().await.unwrap();
|
||||
let repo: Arc<dyn nomifun_db::IMcpServerRepository> = Arc::new(SqliteMcpServerRepository::new(db.pool().clone()));
|
||||
McpSyncService::new(repo, adapters)
|
||||
}
|
||||
|
||||
fn stdio_transport() -> McpServerTransport {
|
||||
McpServerTransport::Stdio {
|
||||
command: "npx".into(),
|
||||
args: vec!["-y".into(), "@test/server".into()],
|
||||
env: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn get_agent_configs_returns_installed_agents() {
|
||||
let adapter_claude = Arc::new(MockAdapter::with_servers(
|
||||
McpSource::Claude,
|
||||
vec![DetectedServer {
|
||||
name: "existing-srv".into(),
|
||||
transport: stdio_transport(),
|
||||
importable: true,
|
||||
import_skip_reason: None,
|
||||
}],
|
||||
));
|
||||
let adapter_gemini = Arc::new(MockAdapter::new(McpSource::Gemini, false));
|
||||
let adapter_qwen = Arc::new(MockAdapter::new(McpSource::Qwen, true));
|
||||
|
||||
let sync_svc = make_service(vec![
|
||||
adapter_claude as Arc<dyn McpAgentAdapter>,
|
||||
adapter_gemini,
|
||||
adapter_qwen,
|
||||
])
|
||||
.await;
|
||||
let configs = sync_svc.get_agent_configs().await.unwrap();
|
||||
|
||||
assert_eq!(configs.len(), 2);
|
||||
assert_eq!(configs[0].source, McpSource::Claude);
|
||||
assert_eq!(configs[0].servers.len(), 1);
|
||||
assert_eq!(configs[0].servers[0].server.name, "existing-srv");
|
||||
assert_eq!(configs[1].source, McpSource::Qwen);
|
||||
assert!(configs[1].servers.is_empty());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn get_agent_configs_empty_when_none_installed() {
|
||||
let adapter = Arc::new(MockAdapter::new(McpSource::Claude, false));
|
||||
let sync_svc = make_service(vec![adapter as Arc<dyn McpAgentAdapter>]).await;
|
||||
|
||||
let configs = sync_svc.get_agent_configs().await.unwrap();
|
||||
assert!(configs.is_empty());
|
||||
}
|
||||
Reference in New Issue
Block a user