Skip to main content
Glama
pedrof
by pedrof
test_tools_schemas.py13.4 kB
""" Unit tests for MCP tool schema definitions. Tests ensure all tool schemas are properly defined with correct parameters, types, and required fields. """ import pytest from hue_mcp_server.tools import TOOLS class TestToolsRegistry: """Tests for the TOOLS registry structure.""" def test_tools_registry_exists(self): """Test that TOOLS registry is defined.""" assert TOOLS is not None assert isinstance(TOOLS, dict) def test_tools_registry_not_empty(self): """Test that TOOLS registry contains tools.""" assert len(TOOLS) > 0 def test_expected_tools_are_registered(self): """Test that all expected tools are registered.""" expected_tools = [ "list_lights", "get_light_state", "turn_light_on", "turn_light_off", "set_brightness", "set_color_temp", "set_color", "list_groups", "control_group", "list_scenes", "activate_scene", ] for tool_name in expected_tools: assert tool_name in TOOLS, f"Tool '{tool_name}' not found in TOOLS registry" def test_all_tools_have_required_keys(self): """Test that all tools have function, description, and parameters.""" for tool_name, tool_def in TOOLS.items(): assert "function" in tool_def, f"Tool '{tool_name}' missing 'function' key" assert ( "description" in tool_def ), f"Tool '{tool_name}' missing 'description' key" assert ( "parameters" in tool_def ), f"Tool '{tool_name}' missing 'parameters' key" def test_all_tool_functions_are_callable(self): """Test that all tool functions are callable.""" for tool_name, tool_def in TOOLS.items(): assert callable( tool_def["function"] ), f"Tool '{tool_name}' function is not callable" def test_all_tool_descriptions_are_strings(self): """Test that all tool descriptions are non-empty strings.""" for tool_name, tool_def in TOOLS.items(): desc = tool_def["description"] assert isinstance( desc, str ), f"Tool '{tool_name}' description is not a string" assert len(desc) > 0, f"Tool '{tool_name}' has empty description" class TestToolParameterSchemas: """Tests for tool parameter schemas.""" def test_all_tools_have_object_type_parameters(self): """Test that all tool parameters are defined as type 'object'.""" for tool_name, tool_def in TOOLS.items(): params = tool_def["parameters"] assert params["type"] == "object", f"Tool '{tool_name}' parameters not type 'object'" def test_all_tools_have_properties_key(self): """Test that all tool parameters have 'properties' key.""" for tool_name, tool_def in TOOLS.items(): params = tool_def["parameters"] assert ( "properties" in params ), f"Tool '{tool_name}' parameters missing 'properties'" assert isinstance(params["properties"], dict) def test_all_tools_have_required_key(self): """Test that all tool parameters have 'required' key.""" for tool_name, tool_def in TOOLS.items(): params = tool_def["parameters"] assert ( "required" in params ), f"Tool '{tool_name}' parameters missing 'required'" assert isinstance(params["required"], list) class TestLightControlToolsSchemas: """Tests for light control tool schemas.""" def test_list_lights_has_no_required_parameters(self): """Test that list_lights requires no parameters.""" schema = TOOLS["list_lights"]["parameters"] assert schema["required"] == [] assert schema["properties"] == {} def test_get_light_state_requires_light_id(self): """Test that get_light_state requires light_id.""" schema = TOOLS["get_light_state"]["parameters"] assert "light_id" in schema["required"] assert "light_id" in schema["properties"] assert schema["properties"]["light_id"]["type"] == "string" def test_turn_light_on_requires_light_id(self): """Test that turn_light_on requires light_id.""" schema = TOOLS["turn_light_on"]["parameters"] assert "light_id" in schema["required"] assert "light_id" in schema["properties"] def test_turn_light_on_has_optional_brightness(self): """Test that turn_light_on has optional brightness parameter.""" schema = TOOLS["turn_light_on"]["parameters"] assert "brightness" in schema["properties"] assert "brightness" not in schema["required"] assert schema["properties"]["brightness"]["type"] == "number" def test_turn_light_off_requires_light_id(self): """Test that turn_light_off requires light_id.""" schema = TOOLS["turn_light_off"]["parameters"] assert "light_id" in schema["required"] assert len(schema["required"]) == 1 def test_set_brightness_requires_light_id_and_brightness(self): """Test that set_brightness requires both light_id and brightness.""" schema = TOOLS["set_brightness"]["parameters"] assert "light_id" in schema["required"] assert "brightness" in schema["required"] assert len(schema["required"]) == 2 def test_set_brightness_has_correct_range(self): """Test that set_brightness has correct min/max for brightness.""" schema = TOOLS["set_brightness"]["parameters"] brightness_schema = schema["properties"]["brightness"] assert brightness_schema["minimum"] == 0 assert brightness_schema["maximum"] == 254 def test_set_color_temp_requires_light_id_and_color_temp(self): """Test that set_color_temp requires both parameters.""" schema = TOOLS["set_color_temp"]["parameters"] assert "light_id" in schema["required"] assert "color_temp" in schema["required"] def test_set_color_temp_has_correct_range(self): """Test that set_color_temp has correct min/max for color_temp.""" schema = TOOLS["set_color_temp"]["parameters"] color_temp_schema = schema["properties"]["color_temp"] assert color_temp_schema["minimum"] == 153 assert color_temp_schema["maximum"] == 500 def test_set_color_requires_light_id_and_xy(self): """Test that set_color requires both parameters.""" schema = TOOLS["set_color"]["parameters"] assert "light_id" in schema["required"] assert "xy" in schema["required"] def test_set_color_xy_is_array_type(self): """Test that set_color xy parameter is defined as array.""" schema = TOOLS["set_color"]["parameters"] xy_schema = schema["properties"]["xy"] assert xy_schema["type"] == "array" assert xy_schema["minItems"] == 2 assert xy_schema["maxItems"] == 2 def test_set_color_xy_items_have_correct_range(self): """Test that set_color xy items have correct min/max.""" schema = TOOLS["set_color"]["parameters"] xy_schema = schema["properties"]["xy"] items_schema = xy_schema["items"] assert items_schema["type"] == "number" assert items_schema["minimum"] == 0 assert items_schema["maximum"] == 1 class TestGroupControlToolsSchemas: """Tests for group control tool schemas.""" def test_list_groups_has_no_required_parameters(self): """Test that list_groups requires no parameters.""" schema = TOOLS["list_groups"]["parameters"] assert schema["required"] == [] def test_control_group_requires_group_id(self): """Test that control_group requires group_id.""" schema = TOOLS["control_group"]["parameters"] assert "group_id" in schema["required"] assert len(schema["required"]) == 1 def test_control_group_has_optional_on_parameter(self): """Test that control_group has optional 'on' parameter.""" schema = TOOLS["control_group"]["parameters"] assert "on" in schema["properties"] assert "on" not in schema["required"] assert schema["properties"]["on"]["type"] == "boolean" def test_control_group_has_optional_brightness(self): """Test that control_group has optional brightness parameter.""" schema = TOOLS["control_group"]["parameters"] assert "brightness" in schema["properties"] assert "brightness" not in schema["required"] def test_control_group_has_optional_color_temp(self): """Test that control_group has optional color_temp parameter.""" schema = TOOLS["control_group"]["parameters"] assert "color_temp" in schema["properties"] assert "color_temp" not in schema["required"] def test_control_group_has_optional_xy(self): """Test that control_group has optional xy parameter.""" schema = TOOLS["control_group"]["parameters"] assert "xy" in schema["properties"] assert "xy" not in schema["required"] class TestSceneControlToolsSchemas: """Tests for scene control tool schemas.""" def test_list_scenes_has_no_required_parameters(self): """Test that list_scenes requires no parameters.""" schema = TOOLS["list_scenes"]["parameters"] assert schema["required"] == [] def test_activate_scene_requires_scene_id(self): """Test that activate_scene requires scene_id.""" schema = TOOLS["activate_scene"]["parameters"] assert "scene_id" in schema["required"] assert len(schema["required"]) == 1 assert "scene_id" in schema["properties"] class TestToolDescriptions: """Tests for tool descriptions quality.""" def test_all_descriptions_are_descriptive(self): """Test that all tool descriptions are reasonably descriptive.""" for tool_name, tool_def in TOOLS.items(): desc = tool_def["description"] # Descriptions should be at least 15 characters (some are naturally brief) assert ( len(desc) >= 15 ), f"Tool '{tool_name}' has very short description: '{desc}'" def test_parameter_descriptions_exist(self): """Test that all parameters have descriptions.""" for tool_name, tool_def in TOOLS.items(): params = tool_def["parameters"] for param_name, param_def in params.get("properties", {}).items(): assert ( "description" in param_def ), f"Parameter '{param_name}' in tool '{tool_name}' missing description" assert ( len(param_def["description"]) > 0 ), f"Parameter '{param_name}' in tool '{tool_name}' has empty description" class TestSchemaConsistency: """Tests for consistency across tool schemas.""" def test_all_light_id_parameters_are_consistent(self): """Test that all light_id parameters have consistent definition.""" tools_with_light_id = [ "get_light_state", "turn_light_on", "turn_light_off", "set_brightness", "set_color_temp", "set_color", ] for tool_name in tools_with_light_id: schema = TOOLS[tool_name]["parameters"] light_id_schema = schema["properties"]["light_id"] assert light_id_schema["type"] == "string" assert "description" in light_id_schema def test_all_brightness_parameters_have_same_range(self): """Test that all brightness parameters have consistent range.""" tools_with_brightness = ["turn_light_on", "set_brightness", "control_group"] for tool_name in tools_with_brightness: schema = TOOLS[tool_name]["parameters"] brightness_schema = schema["properties"]["brightness"] assert brightness_schema["type"] == "number" assert brightness_schema["minimum"] == 0 assert brightness_schema["maximum"] == 254 def test_all_color_temp_parameters_have_same_range(self): """Test that all color_temp parameters have consistent range.""" tools_with_color_temp = ["set_color_temp", "control_group"] for tool_name in tools_with_color_temp: schema = TOOLS[tool_name]["parameters"] color_temp_schema = schema["properties"]["color_temp"] assert color_temp_schema["type"] == "number" assert color_temp_schema["minimum"] == 153 assert color_temp_schema["maximum"] == 500 def test_all_xy_parameters_have_same_structure(self): """Test that all xy parameters have consistent structure.""" tools_with_xy = ["set_color", "control_group"] for tool_name in tools_with_xy: schema = TOOLS[tool_name]["parameters"] xy_schema = schema["properties"]["xy"] assert xy_schema["type"] == "array" assert xy_schema["minItems"] == 2 assert xy_schema["maxItems"] == 2 assert xy_schema["items"]["type"] == "number" assert xy_schema["items"]["minimum"] == 0 assert xy_schema["items"]["maximum"] == 1

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/pedrof/hue-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server