#![cfg(feature = "openapi")]
use radkit::tools::{BaseToolset, OpenApiToolSet};
#[tokio::test]
#[ignore = "requires network access to Petstore API"]
async fn test_openapi_spec_from_url() {
let result = OpenApiToolSet::from_url(
"petstore".to_string(),
"https://petstore3.swagger.io/api/v3/openapi.json",
None, )
.await;
assert!(
result.is_ok(),
"Failed to load OpenAPI spec: {:?}",
result.err()
);
}
#[tokio::test]
#[ignore = "requires network access to Petstore API"]
async fn test_openapi_tool_generation() {
let toolset = OpenApiToolSet::from_url(
"petstore".to_string(),
"https://petstore3.swagger.io/api/v3/openapi.json",
None,
)
.await
.expect("Failed to create toolset");
let tools = toolset.get_tools().await;
assert!(
!tools.is_empty(),
"No tools were generated from OpenAPI spec"
);
println!("Generated {} tools from Petstore API:", tools.len());
for tool in &tools {
println!(" - {}: {}", tool.name(), tool.description());
}
let tool_names: Vec<&str> = tools.iter().map(|t| t.name()).collect();
let expected_operations = vec!["findPetsByStatus", "getPetById", "addPet"];
for op in expected_operations {
assert!(
tool_names.contains(&op),
"Expected operation '{}' not found in generated tools. Available: {:?}",
op,
tool_names
);
}
}
#[tokio::test]
#[ignore = "requires network access to Petstore API"]
async fn test_openapi_tool_declaration() {
let toolset = OpenApiToolSet::from_url(
"petstore".to_string(),
"https://petstore3.swagger.io/api/v3/openapi.json",
None,
)
.await
.expect("Failed to create toolset");
let tools = toolset.get_tools().await;
for tool in tools {
let declaration = tool.declaration();
assert_eq!(
declaration.name(),
tool.name(),
"Declaration name doesn't match tool name"
);
assert!(
!declaration.description().is_empty(),
"Tool '{}' has empty description",
tool.name()
);
assert!(
declaration.parameters().is_object(),
"Tool '{}' parameters is not a JSON object",
tool.name()
);
let params = declaration.parameters();
assert!(
params.get("properties").is_some(),
"Tool '{}' has no properties field",
tool.name()
);
assert!(
params.get("required").is_some(),
"Tool '{}' has no required field",
tool.name()
);
}
}
#[tokio::test]
#[ignore = "requires network access to Petstore API"]
async fn test_parameter_schema_generation() {
let toolset = OpenApiToolSet::from_url(
"petstore".to_string(),
"https://petstore3.swagger.io/api/v3/openapi.json",
None,
)
.await
.expect("Failed to create toolset");
let tools = toolset.get_tools().await;
let get_pet_by_id = tools
.iter()
.find(|t| t.name() == "getPetById")
.expect("getPetById not found");
let declaration = get_pet_by_id.declaration();
let params = declaration.parameters();
let properties = params.get("properties").unwrap();
assert!(
properties.get("petId").is_some(),
"getPetById should have petId parameter"
);
let pet_id_schema = &properties["petId"];
assert_eq!(
pet_id_schema.get("type").and_then(|v| v.as_str()),
Some("integer"),
"petId should be integer type"
);
let find_by_status = tools
.iter()
.find(|t| t.name() == "findPetsByStatus")
.expect("findPetsByStatus not found");
let declaration = find_by_status.declaration();
let params = declaration.parameters();
let properties = params.get("properties").unwrap();
assert!(
properties.get("status").is_some(),
"findPetsByStatus should have status parameter"
);
let status_schema = &properties["status"];
assert_eq!(
status_schema.get("type").and_then(|v| v.as_str()),
Some("string"),
"status should be string type"
);
assert!(
status_schema.get("enum").is_some(),
"status parameter should have enum values"
);
println!("✅ Parameter schema generation working correctly!");
println!(
"getPetById parameters: {}",
serde_json::to_string_pretty(¶ms).unwrap()
);
}