Skip to main content
Glama
test_tools.py12.1 kB
"""Tests for all MCP tools.""" import asyncio from unittest.mock import Mock, mock_open, patch import pytest from template_mcp_server.src.tools.code_review_tool import generate_code_review_prompt from template_mcp_server.src.tools.multiply_tool import multiply_numbers from template_mcp_server.src.tools.redhat_logo_tool import get_redhat_logo class TestMultiplyTool: """Test the multiply_numbers tool.""" def test_multiply_numbers_success(self): """Test successful multiplication of two numbers.""" # Arrange a, b = 5.0, 3.0 # Act result = multiply_numbers(a, b) # Assert assert result["status"] == "success" assert result["operation"] == "multiplication" assert result["a"] == 5.0 assert result["b"] == 3.0 assert result["result"] == 15.0 assert result["message"] == "Successfully multiplied 5.0 and 3.0" def test_multiply_numbers_integers(self): """Test multiplication with integer inputs.""" # Arrange a, b = 10, 7 # Act result = multiply_numbers(a, b) # Assert assert result["status"] == "success" assert result["result"] == 70 assert result["a"] == 10 assert result["b"] == 7 def test_multiply_numbers_negative_values(self): """Test multiplication with negative values.""" # Arrange a, b = -5.0, 3.0 # Act result = multiply_numbers(a, b) # Assert assert result["status"] == "success" assert result["result"] == -15.0 def test_multiply_numbers_zero(self): """Test multiplication with zero.""" # Arrange a, b = 10.0, 0.0 # Act result = multiply_numbers(a, b) # Assert assert result["status"] == "success" assert result["result"] == 0.0 def test_multiply_numbers_float_precision(self): """Test multiplication with floating point precision.""" # Arrange a, b = 0.1, 0.2 # Act result = multiply_numbers(a, b) # Assert assert result["status"] == "success" assert result["result"] == pytest.approx(0.02, rel=1e-10) def test_multiply_numbers_invalid_input_string(self): """Test multiplication with invalid string input.""" # Arrange a, b = "5", 3.0 # Act result = multiply_numbers(a, b) # Assert assert result["status"] == "error" assert "error" in result assert "Failed to perform multiplication" in result["message"] def test_multiply_numbers_invalid_input_none(self): """Test multiplication with None input.""" # Arrange a, b = None, 3.0 # Act result = multiply_numbers(a, b) # Assert assert result["status"] == "error" assert "error" in result assert "Failed to perform multiplication" in result["message"] def test_multiply_numbers_invalid_input_list(self): """Test multiplication with list input.""" # Arrange a, b = [1, 2], 3.0 # Act result = multiply_numbers(a, b) # Assert assert result["status"] == "error" assert "error" in result assert "Failed to perform multiplication" in result["message"] def test_multiply_numbers_both_invalid_inputs(self): """Test multiplication with both inputs invalid.""" # Arrange a, b = "invalid", "also_invalid" # Act result = multiply_numbers(a, b) # Assert assert result["status"] == "error" assert "error" in result assert "Failed to perform multiplication" in result["message"] @patch("template_mcp_server.src.tools.multiply_tool.logger") def test_multiply_numbers_logging_success(self, mock_logger): """Test that successful multiplication is logged.""" # Arrange a, b = 5.0, 3.0 # Act multiply_numbers(a, b) # Assert mock_logger.info.assert_called_with("Multiply tool called: 5.0 * 3.0 = 15.0") @patch("template_mcp_server.src.tools.multiply_tool.logger") def test_multiply_numbers_logging_error(self, mock_logger): """Test that errors are logged.""" # Arrange a, b = "invalid", 3.0 # Act multiply_numbers(a, b) # Assert mock_logger.error.assert_called() def test_multiply_numbers_return_type(self): """Test that the function returns a dictionary.""" # Arrange a, b = 5.0, 3.0 # Act result = multiply_numbers(a, b) # Assert assert isinstance(result, dict) assert "status" in result assert "operation" in result assert "a" in result assert "b" in result assert "result" in result assert "message" in result def test_multiply_numbers_error_return_structure(self): """Test that error responses have the correct structure.""" # Arrange a, b = "invalid", 3.0 # Act result = multiply_numbers(a, b) # Assert assert isinstance(result, dict) assert result["status"] == "error" assert "error" in result assert "message" in result assert "Failed to perform multiplication" in result["message"] def test_multiply_numbers_commutative_property(self): """Test that multiplication is commutative.""" # Arrange a, b = 5.0, 3.0 # Act result1 = multiply_numbers(a, b) result2 = multiply_numbers(b, a) # Assert assert result1["result"] == result2["result"] assert result1["status"] == "success" assert result2["status"] == "success" class TestCodeReviewTool: """Test the code review tool functionality.""" def test_generate_code_review_prompt_basic(self): """Test basic code review prompt generation.""" # Arrange code = "def add(a, b): return a + b" language = "python" # Act result = asyncio.run(generate_code_review_prompt(code, language)) # Assert assert isinstance(result, dict) assert result["status"] == "success" assert result["operation"] == "code_review_prompt" assert result["language"] == language assert code in result["prompt"] assert language in result["prompt"] def test_generate_code_review_prompt_default_language(self): """Test code review prompt with default language.""" # Arrange code = "function add(a, b) { return a + b; }" # Act result = asyncio.run(generate_code_review_prompt(code)) # Assert assert isinstance(result, dict) assert result["status"] == "success" assert result["language"] == "python" # Default language assert code in result["prompt"] def test_generate_code_review_prompt_empty_code(self): """Test code review prompt with empty code.""" # Arrange code = "" language = "python" # Act result = asyncio.run(generate_code_review_prompt(code, language)) # Assert assert isinstance(result, dict) assert result["status"] == "error" assert "Code must be a non-empty string" in result["error"] def test_generate_code_review_prompt_invalid_language(self): """Test code review prompt with invalid language.""" # Arrange code = "def test(): pass" language = "" # Act result = asyncio.run(generate_code_review_prompt(code, language)) # Assert assert isinstance(result, dict) assert result["status"] == "error" assert "Language must be a non-empty string" in result["error"] def test_generate_code_review_prompt_content_structure(self): """Test that the prompt content has the expected structure.""" # Arrange code = "def test_function(): pass" language = "python" # Act result = asyncio.run(generate_code_review_prompt(code, language)) content = result["prompt"] # Assert assert result["status"] == "success" assert "Please review the following" in content assert f"```{language}" in content assert code in content assert "Focus on:" in content assert "Code quality and readability" in content assert "Potential bugs or issues" in content assert "Best practices" in content assert "Performance considerations" in content class TestRedHatLogoTool: """Test the Red Hat logo tool functionality.""" @patch("builtins.open", new_callable=mock_open, read_data=b"fake_png_data") @patch("template_mcp_server.src.tools.redhat_logo_tool.Path") def test_get_redhat_logo_success(self, mock_path, mock_file): """Test successful reading of Red Hat logo.""" # Arrange mock_path_instance = Mock() mock_path_instance.parent = Mock() mock_path_instance.parent.parent = Mock() # Go up from tools to src assets_dir = Mock() assets_dir.__truediv__ = Mock(return_value=Mock()) mock_path_instance.parent.parent.__truediv__ = Mock(return_value=assets_dir) mock_path.return_value = mock_path_instance # Act result = asyncio.run(get_redhat_logo()) # Assert assert result["status"] == "success" assert result["operation"] == "get_redhat_logo" assert result["name"] == "Red Hat Logo" assert result["description"] == "Red Hat logo as base64 encoded PNG" assert result["mimeType"] == "image/png" assert isinstance(result["data"], str) assert len(result["data"]) > 0 assert result["size_bytes"] == 13 # Length of b"fake_png_data" @patch("template_mcp_server.src.tools.redhat_logo_tool.Path") def test_get_redhat_logo_file_not_found(self, mock_path): """Test handling when logo file is not found.""" # Arrange mock_path_instance = Mock() mock_path_instance.parent = Mock() mock_path_instance.parent.parent = Mock() assets_dir = Mock() logo_path = Mock() logo_path.__str__ = Mock(return_value="/path/to/logo.png") assets_dir.__truediv__ = Mock(return_value=logo_path) mock_path_instance.parent.parent.__truediv__ = Mock(return_value=assets_dir) mock_path.return_value = mock_path_instance # Configure open to raise FileNotFoundError with patch("builtins.open", side_effect=FileNotFoundError("File not found")): # Act result = asyncio.run(get_redhat_logo()) # Assert assert result["status"] == "error" assert result["operation"] == "get_redhat_logo" assert result["error"] == "file_not_found" assert "Could not find logo file" in result["message"] @patch("template_mcp_server.src.tools.redhat_logo_tool.Path") def test_get_redhat_logo_permission_error(self, mock_path): """Test handling when logo file has permission issues.""" # Arrange mock_path_instance = Mock() mock_path_instance.parent = Mock() mock_path_instance.parent.parent = Mock() assets_dir = Mock() logo_path = Mock() logo_path.__str__ = Mock(return_value="/path/to/logo.png") assets_dir.__truediv__ = Mock(return_value=logo_path) mock_path_instance.parent.parent.__truediv__ = Mock(return_value=assets_dir) mock_path.return_value = mock_path_instance # Configure open to raise PermissionError with patch("builtins.open", side_effect=PermissionError("Permission denied")): # Act result = asyncio.run(get_redhat_logo()) # Assert assert result["status"] == "error" assert result["operation"] == "get_redhat_logo" assert result["error"] == "permission_denied" assert "Permission denied reading logo file" in result["message"]

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/redhat-data-and-ai/template-mcp-server'

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