mirror of https://github.com/microsoft/autogen.git
203 lines
7.9 KiB
Python
203 lines
7.9 KiB
Python
import json
|
|
|
|
import httpx
|
|
import pytest
|
|
from autogen_core import CancellationToken, Component, ComponentModel
|
|
from autogen_ext.tools.http import HttpTool
|
|
from pydantic import ValidationError
|
|
|
|
|
|
def test_tool_schema_generation(test_config: ComponentModel) -> None:
|
|
tool = HttpTool.load_component(test_config)
|
|
schema = tool.schema
|
|
|
|
assert schema["name"] == "TestHttpTool"
|
|
assert "description" in schema
|
|
assert schema["description"] == "A test HTTP tool"
|
|
assert "parameters" in schema
|
|
assert schema["parameters"]["type"] == "object"
|
|
assert "properties" in schema["parameters"]
|
|
assert schema["parameters"]["properties"]["query"]["description"] == "The test query"
|
|
assert schema["parameters"]["properties"]["query"]["type"] == "string"
|
|
assert schema["parameters"]["properties"]["value"]["description"] == "A test value"
|
|
assert schema["parameters"]["properties"]["value"]["type"] == "integer"
|
|
assert "required" in schema["parameters"]
|
|
assert set(schema["parameters"]["required"]) == {"query", "value"}
|
|
|
|
|
|
def test_tool_properties(test_config: ComponentModel) -> None:
|
|
tool = HttpTool.load_component(test_config)
|
|
|
|
assert tool.name == "TestHttpTool"
|
|
assert tool.description == "A test HTTP tool"
|
|
assert tool.server_params.host == "localhost"
|
|
assert tool.server_params.port == 8000
|
|
assert tool.server_params.path == "/test"
|
|
assert tool.server_params.scheme == "http"
|
|
assert tool.server_params.method == "POST"
|
|
|
|
|
|
def test_component_base_class(test_config: ComponentModel) -> None:
|
|
tool = HttpTool.load_component(test_config)
|
|
assert tool.dump_component() is not None
|
|
assert HttpTool.load_component(tool.dump_component(), HttpTool) is not None
|
|
assert isinstance(tool, Component)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_post_request(test_config: ComponentModel, test_server: None) -> None:
|
|
tool = HttpTool.load_component(test_config)
|
|
result = await tool.run_json({"query": "test query", "value": 42}, CancellationToken())
|
|
|
|
assert isinstance(result, str)
|
|
assert json.loads(result)["result"] == "Received: test query with value 42"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_post_request_json_return(test_config: ComponentModel, test_server: None) -> None:
|
|
# Modify config to use json return type
|
|
config = test_config.model_copy()
|
|
config.config["return_type"] = "json"
|
|
tool = HttpTool.load_component(config)
|
|
result = await tool.run_json({"query": "test query", "value": 45}, CancellationToken())
|
|
|
|
assert isinstance(result, dict)
|
|
assert result["result"] == "Received: test query with value 45"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_get_request(test_config: ComponentModel, test_server: None) -> None:
|
|
# Modify config for GET request
|
|
config = test_config.model_copy()
|
|
config.config["method"] = "GET"
|
|
tool = HttpTool.load_component(config)
|
|
|
|
result = await tool.run_json({"query": "test query", "value": 42}, CancellationToken())
|
|
|
|
assert isinstance(result, str)
|
|
assert json.loads(result)["result"] == "Received: test query with value 42"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_put_request(test_config: ComponentModel, test_server: None) -> None:
|
|
# Modify config for PUT request
|
|
config = test_config.model_copy()
|
|
config.config["method"] = "PUT"
|
|
tool = HttpTool.load_component(config)
|
|
|
|
result = await tool.run_json({"query": "test query", "value": 42}, CancellationToken())
|
|
|
|
assert isinstance(result, str)
|
|
assert json.loads(result)["result"] == "Received: test query with value 42"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_path_params(test_config: ComponentModel, test_server: None) -> None:
|
|
# Modify config to use path parameters
|
|
config = test_config.model_copy()
|
|
config.config["path"] = "/test/{query}/{value}"
|
|
tool = HttpTool.load_component(config)
|
|
|
|
result = await tool.run_json({"query": "test query", "value": 42}, CancellationToken())
|
|
|
|
assert isinstance(result, str)
|
|
assert json.loads(result)["result"] == "Received: test query with value 42"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_path_params_and_body(test_config: ComponentModel, test_server: None) -> None:
|
|
# Modify config to use path parameters and include body parameters
|
|
config = test_config.model_copy()
|
|
config.config["method"] = "PUT"
|
|
config.config["path"] = "/test/{query}/{value}"
|
|
config.config["json_schema"] = {
|
|
"type": "object",
|
|
"properties": {
|
|
"query": {"type": "string", "description": "The test query"},
|
|
"value": {"type": "integer", "description": "A test value"},
|
|
"extra": {"type": "string", "description": "Extra body parameter"},
|
|
},
|
|
"required": ["query", "value", "extra"],
|
|
}
|
|
tool = HttpTool.load_component(config)
|
|
|
|
result = await tool.run_json({"query": "test query", "value": 42, "extra": "extra data"}, CancellationToken())
|
|
|
|
assert isinstance(result, str)
|
|
assert json.loads(result)["result"] == "Received: test query with value 42 and extra extra data"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_delete_request(test_config: ComponentModel, test_server: None) -> None:
|
|
# Modify config for DELETE request
|
|
config = test_config.model_copy()
|
|
config.config["method"] = "DELETE"
|
|
tool = HttpTool.load_component(config)
|
|
|
|
result = await tool.run_json({"query": "test query", "value": 42}, CancellationToken())
|
|
|
|
assert isinstance(result, str)
|
|
assert json.loads(result)["result"] == "Received: test query with value 42"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_patch_request(test_config: ComponentModel, test_server: None) -> None:
|
|
# Modify config for PATCH request
|
|
config = test_config.model_copy()
|
|
config.config["method"] = "PATCH"
|
|
tool = HttpTool.load_component(config)
|
|
|
|
result = await tool.run_json({"query": "test query", "value": 42}, CancellationToken())
|
|
|
|
assert isinstance(result, str)
|
|
assert json.loads(result)["result"] == "Received: test query with value 42"
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_invalid_schema(test_config: ComponentModel, test_server: None) -> None:
|
|
# Create an invalid schema missing required properties
|
|
config: ComponentModel = test_config.model_copy()
|
|
config.config["host"] = True # Incorrect type
|
|
|
|
with pytest.raises(ValidationError):
|
|
# Should fail when trying to create model from invalid schema
|
|
HttpTool.load_component(config)
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_invalid_request(test_config: ComponentModel, test_server: None) -> None:
|
|
# Use an invalid URL
|
|
config = test_config.model_copy()
|
|
config.config["host"] = "fake"
|
|
tool = HttpTool.load_component(config)
|
|
|
|
with pytest.raises(httpx.ConnectError):
|
|
await tool.run_json({"query": "test query", "value": 42}, CancellationToken())
|
|
|
|
|
|
def test_config_serialization(test_config: ComponentModel) -> None:
|
|
tool = HttpTool.load_component(test_config)
|
|
config = tool.dump_component()
|
|
|
|
assert config.config["name"] == test_config.config["name"]
|
|
assert config.config["description"] == test_config.config["description"]
|
|
assert config.config["host"] == test_config.config["host"]
|
|
assert config.config["port"] == test_config.config["port"]
|
|
assert config.config["path"] == test_config.config["path"]
|
|
assert config.config["scheme"] == test_config.config["scheme"]
|
|
assert config.config["method"] == test_config.config["method"]
|
|
assert config.config["headers"] == test_config.config["headers"]
|
|
|
|
|
|
def test_config_deserialization(test_config: ComponentModel) -> None:
|
|
tool = HttpTool.load_component(test_config)
|
|
|
|
assert tool.name == test_config.config["name"]
|
|
assert tool.description == test_config.config["description"]
|
|
assert tool.server_params.host == test_config.config["host"]
|
|
assert tool.server_params.port == test_config.config["port"]
|
|
assert tool.server_params.path == test_config.config["path"]
|
|
assert tool.server_params.scheme == test_config.config["scheme"]
|
|
assert tool.server_params.method == test_config.config["method"]
|
|
assert tool.server_params.headers == test_config.config["headers"]
|