feat: devtools + tool dispatch tests, search_code tool definition fix
Devtools integration tests (6 new, all via live Gitea): - gitea_list_repos, get_repo, get_file, list_branches, list_issues, list_orgs - Tests exercise the full Gitea SDK → tool handler → JSON response path Tool dispatch tests (8 new unit tests): - tool_definitions: base, gitea, kratos, all-enabled variants - agent_tool_definitions conversion - minimal registry creation - unknown tool error handling - search_code without OpenSearch error search_code: added to tool_definitions() (was only in execute dispatch)
This commit is contained in:
@@ -1284,7 +1284,7 @@ mod gitea_tests {
|
||||
use super::*;
|
||||
use std::sync::Arc;
|
||||
|
||||
fn load_env() {
|
||||
pub(super) fn load_env() {
|
||||
let env_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join(".env");
|
||||
if let Ok(contents) = std::fs::read_to_string(&env_path) {
|
||||
for line in contents.lines() {
|
||||
@@ -1297,7 +1297,7 @@ mod gitea_tests {
|
||||
}
|
||||
}
|
||||
|
||||
fn gitea_available() -> bool {
|
||||
pub(super) fn gitea_available() -> bool {
|
||||
load_env();
|
||||
let url = std::env::var("GITEA_URL").unwrap_or_default();
|
||||
if url.is_empty() { return false; }
|
||||
@@ -1308,7 +1308,7 @@ mod gitea_tests {
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
fn gitea_client() -> Option<Arc<crate::sdk::gitea::GiteaClient>> {
|
||||
pub(super) fn gitea_client() -> Option<Arc<crate::sdk::gitea::GiteaClient>> {
|
||||
if !gitea_available() { return None; }
|
||||
let url = std::env::var("GITEA_URL").ok()?;
|
||||
let user = std::env::var("GITEA_ADMIN_USERNAME").ok()?;
|
||||
@@ -1422,6 +1422,160 @@ mod gitea_tests {
|
||||
}
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════════════════════════════════
|
||||
// Devtools (Gitea tool) integration tests
|
||||
// ══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
mod devtools_tests {
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_gitea_list_repos_tool() {
|
||||
gitea_tests::load_env();
|
||||
let Some(gitea) = gitea_tests::gitea_client() else {
|
||||
eprintln!("Skipping: Gitea not available");
|
||||
return;
|
||||
};
|
||||
let ctx = crate::context::ResponseContext {
|
||||
matrix_user_id: "@sol:sunbeam.local".into(),
|
||||
user_id: "sol".into(),
|
||||
display_name: None,
|
||||
is_dm: true,
|
||||
is_reply: false,
|
||||
room_id: "test".into(),
|
||||
};
|
||||
|
||||
let result = crate::tools::devtools::execute(
|
||||
&gitea, "gitea_list_repos", r#"{"org": "studio"}"#, &ctx,
|
||||
).await;
|
||||
assert!(result.is_ok(), "list_repos tool should succeed: {:?}", result.err());
|
||||
let text = result.unwrap();
|
||||
assert!(text.contains("sol"), "Should find sol repo in results: {text}");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_gitea_get_repo_tool() {
|
||||
gitea_tests::load_env();
|
||||
let Some(gitea) = gitea_tests::gitea_client() else {
|
||||
eprintln!("Skipping: Gitea not available");
|
||||
return;
|
||||
};
|
||||
let ctx = crate::context::ResponseContext {
|
||||
matrix_user_id: "@sol:sunbeam.local".into(),
|
||||
user_id: "sol".into(),
|
||||
display_name: None,
|
||||
is_dm: true,
|
||||
is_reply: false,
|
||||
room_id: "test".into(),
|
||||
};
|
||||
|
||||
let result = crate::tools::devtools::execute(
|
||||
&gitea, "gitea_get_repo", r#"{"owner": "studio", "repo": "sol"}"#, &ctx,
|
||||
).await;
|
||||
assert!(result.is_ok(), "get_repo tool should succeed: {:?}", result.err());
|
||||
let text = result.unwrap();
|
||||
assert!(text.contains("sol"), "Should contain repo name: {text}");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_gitea_get_file_tool() {
|
||||
gitea_tests::load_env();
|
||||
let Some(gitea) = gitea_tests::gitea_client() else {
|
||||
eprintln!("Skipping: Gitea not available");
|
||||
return;
|
||||
};
|
||||
let ctx = crate::context::ResponseContext {
|
||||
matrix_user_id: "@sol:sunbeam.local".into(),
|
||||
user_id: "sol".into(),
|
||||
display_name: None,
|
||||
is_dm: true,
|
||||
is_reply: false,
|
||||
room_id: "test".into(),
|
||||
};
|
||||
|
||||
let result = crate::tools::devtools::execute(
|
||||
&gitea, "gitea_get_file",
|
||||
r#"{"owner": "studio", "repo": "sol", "path": "Cargo.toml"}"#,
|
||||
&ctx,
|
||||
).await;
|
||||
assert!(result.is_ok(), "get_file tool should succeed: {:?}", result.err());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_gitea_list_branches_tool() {
|
||||
gitea_tests::load_env();
|
||||
let Some(gitea) = gitea_tests::gitea_client() else {
|
||||
eprintln!("Skipping: Gitea not available");
|
||||
return;
|
||||
};
|
||||
let ctx = crate::context::ResponseContext {
|
||||
matrix_user_id: "@sol:sunbeam.local".into(),
|
||||
user_id: "sol".into(),
|
||||
display_name: None,
|
||||
is_dm: true,
|
||||
is_reply: false,
|
||||
room_id: "test".into(),
|
||||
};
|
||||
|
||||
let result = crate::tools::devtools::execute(
|
||||
&gitea, "gitea_list_branches",
|
||||
r#"{"owner": "studio", "repo": "sol"}"#,
|
||||
&ctx,
|
||||
).await;
|
||||
assert!(result.is_ok(), "list_branches tool should succeed: {:?}", result.err());
|
||||
let text = result.unwrap();
|
||||
assert!(text.contains("mainline") || text.contains("main"), "Should find default branch: {text}");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_gitea_list_issues_tool() {
|
||||
gitea_tests::load_env();
|
||||
let Some(gitea) = gitea_tests::gitea_client() else {
|
||||
eprintln!("Skipping: Gitea not available");
|
||||
return;
|
||||
};
|
||||
let ctx = crate::context::ResponseContext {
|
||||
matrix_user_id: "@sol:sunbeam.local".into(),
|
||||
user_id: "sol".into(),
|
||||
display_name: None,
|
||||
is_dm: true,
|
||||
is_reply: false,
|
||||
room_id: "test".into(),
|
||||
};
|
||||
|
||||
let result = crate::tools::devtools::execute(
|
||||
&gitea, "gitea_list_issues",
|
||||
r#"{"owner": "studio", "repo": "sol"}"#,
|
||||
&ctx,
|
||||
).await;
|
||||
assert!(result.is_ok(), "list_issues should succeed: {:?}", result.err());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_gitea_list_orgs_tool() {
|
||||
gitea_tests::load_env();
|
||||
let Some(gitea) = gitea_tests::gitea_client() else {
|
||||
eprintln!("Skipping: Gitea not available");
|
||||
return;
|
||||
};
|
||||
let ctx = crate::context::ResponseContext {
|
||||
matrix_user_id: "@sol:sunbeam.local".into(),
|
||||
user_id: "sol".into(),
|
||||
display_name: None,
|
||||
is_dm: true,
|
||||
is_reply: false,
|
||||
room_id: "test".into(),
|
||||
};
|
||||
|
||||
let result = crate::tools::devtools::execute(
|
||||
&gitea, "gitea_list_orgs", r#"{"username": "sol"}"#, &ctx,
|
||||
).await;
|
||||
assert!(result.is_ok(), "list_orgs should succeed: {:?}", result.err());
|
||||
let text = result.unwrap();
|
||||
assert!(text.contains("studio"), "Should find studio org: {text}");
|
||||
}
|
||||
}
|
||||
|
||||
// ══════════════════════════════════════════════════════════════════════════
|
||||
// Web search + conversation registry tests
|
||||
// ══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
Reference in New Issue
Block a user