"""Test MCP server functionality using FastMCP testing patterns.""" import pytest from unittest.mock import patch, Mock from fastmcp import testing from mcp_namecheap.fastmcp_server import mcp_server from .conftest import create_mock_response class TestMCPServer: """Test MCP server tools and resources.""" @pytest.fixture def mcp_client(self): """Create FastMCP test client.""" return testing.create_client(mcp_server) @pytest.mark.mcp async def test_list_domains_tool(self, mcp_client, sample_domains_response): """Test list domains tool.""" with patch('mcp_namecheap.domains.get_client') as mock_get_client: mock_client = Mock() mock_client.list_domains.return_value = sample_domains_response["DomainGetListResult"]["Domain"] mock_get_client.return_value = mock_client result = await mcp_client.call_tool("list_domains") assert result["success"] is True assert len(result["data"]) == 2 assert result["data"][0]["@Name"] == "example.com" @pytest.mark.mcp async def test_get_domain_info_tool(self, mcp_client, sample_domain_info_response): """Test get domain info tool.""" with patch('mcp_namecheap.domains.get_client') as mock_get_client: mock_client = Mock() mock_client.get_domain_info.return_value = sample_domain_info_response mock_get_client.return_value = mock_client result = await mcp_client.call_tool("get_domain_info", domain_identifier="example.com") assert result["success"] is True assert result["data"]["DomainGetInfoResult"]["@DomainName"] == "example.com" @pytest.mark.mcp async def test_check_domain_availability_tool(self, mcp_client, sample_domain_check_response): """Test check domain availability tool.""" with patch('mcp_namecheap.domains.get_client') as mock_get_client: mock_client = Mock() mock_client.check_domain_availability.return_value = sample_domain_check_response["DomainCheckResult"] mock_get_client.return_value = mock_client result = await mcp_client.call_tool("check_domain_availability", { "domains": ["available-domain.com", "taken-domain.com"] }) assert result["success"] is True assert len(result["data"]) == 2 assert result["data"][0]["@Available"] == "true" assert result["data"][1]["@Available"] == "false" @pytest.mark.mcp async def test_get_dns_records_tool(self, mcp_client, sample_dns_records_response): """Test get DNS records tool.""" with patch('mcp_namecheap.dns.get_client') as mock_get_client: mock_client = Mock() mock_client.get_dns_records.return_value = sample_dns_records_response["DomainDNSGetHostsResult"]["host"] mock_get_client.return_value = mock_client result = await mcp_client.call_tool("get_dns_records", domain_identifier="example.com") assert result["success"] is True assert len(result["data"]) == 2 assert result["data"][0]["@Type"] == "A" assert result["data"][1]["@Type"] == "CNAME" @pytest.mark.mcp async def test_set_dns_records_tool(self, mcp_client): """Test set DNS records tool.""" with patch('mcp_namecheap.dns.get_client') as mock_get_client: mock_client = Mock() mock_client.set_dns_records.return_value = {"Status": "OK"} mock_get_client.return_value = mock_client result = await mcp_client.call_tool("set_dns_records", { "domain_identifier": "example.com", "records": [ { "hostname": "@", "record_type": "A", "address": "192.168.1.1", "ttl": 1800 } ] }) assert result["success"] is True @pytest.mark.mcp async def test_list_ssl_certificates_tool(self, mcp_client, sample_ssl_certificates_response): """Test list SSL certificates tool.""" with patch('mcp_namecheap.ssl.get_client') as mock_get_client: mock_client = Mock() mock_client.list_ssl_certificates.return_value = sample_ssl_certificates_response["SSLListResult"]["SSL"] mock_get_client.return_value = mock_client result = await mcp_client.call_tool("list_ssl_certificates") assert result["success"] is True assert len(result["data"]) == 1 assert result["data"][0]["@HostName"] == "example.com" @pytest.mark.mcp async def test_get_account_info_tool(self, mcp_client, sample_account_info_response): """Test get account info tool.""" with patch('mcp_namecheap.account.get_client') as mock_get_client: mock_client = Mock() mock_client.get_account_info.return_value = sample_account_info_response mock_get_client.return_value = mock_client result = await mcp_client.call_tool("get_account_info") assert result["success"] is True assert result["data"]["UserGetAccountResult"]["@UserName"] == "test_user" @pytest.mark.mcp async def test_get_account_balance_tool(self, mcp_client, sample_balance_response): """Test get account balance tool.""" with patch('mcp_namecheap.account.get_client') as mock_get_client: mock_client = Mock() mock_client.get_account_balance.return_value = sample_balance_response mock_get_client.return_value = mock_client result = await mcp_client.call_tool("get_account_balance") assert result["success"] is True assert result["data"]["UserGetBalancesResult"]["@AccountBalance"] == "100.00" @pytest.mark.mcp async def test_domains_resource(self, mcp_client, sample_domains_response): """Test domains resource.""" with patch('mcp_namecheap.domains.get_client') as mock_get_client: mock_client = Mock() mock_client.list_domains.return_value = sample_domains_response["DomainGetListResult"]["Domain"] mock_get_client.return_value = mock_client result = await mcp_client.read_resource("namecheap://domains") assert "Domains in Account:" in result assert "example.com" in result assert "test.org" in result @pytest.mark.mcp async def test_domain_resource(self, mcp_client, sample_domain_info_response): """Test individual domain resource.""" with patch('mcp_namecheap.domains.get_client') as mock_get_client: mock_client = Mock() mock_client.get_domain_info.return_value = sample_domain_info_response mock_get_client.return_value = mock_client result = await mcp_client.read_resource("namecheap://domain/example.com") assert "Domain Information: example.com" in result assert "test_user" in result @pytest.mark.mcp async def test_dns_resource(self, mcp_client, sample_dns_records_response): """Test DNS records resource.""" with patch('mcp_namecheap.dns.get_client') as mock_get_client: mock_client = Mock() mock_client.get_dns_records.return_value = sample_dns_records_response["DomainDNSGetHostsResult"]["host"] mock_get_client.return_value = mock_client result = await mcp_client.read_resource("namecheap://dns/example.com") assert "DNS Records for example.com" in result assert "192.168.1.1" in result @pytest.mark.mcp async def test_ssl_resource(self, mcp_client, sample_ssl_certificates_response): """Test SSL certificates resource.""" with patch('mcp_namecheap.ssl.get_client') as mock_get_client: mock_client = Mock() mock_client.list_ssl_certificates.return_value = sample_ssl_certificates_response["SSLListResult"]["SSL"] mock_get_client.return_value = mock_client result = await mcp_client.read_resource("namecheap://ssl") assert "SSL Certificates in Account:" in result assert "example.com" in result @pytest.mark.mcp async def test_account_resource(self, mcp_client, sample_account_info_response): """Test account resource.""" with patch('mcp_namecheap.account.get_client') as mock_get_client: mock_client = Mock() mock_client.get_account_info.return_value = sample_account_info_response mock_get_client.return_value = mock_client result = await mcp_client.read_resource("namecheap://account") assert "Account Information" in result assert "test_user" in result @pytest.mark.mcp async def test_balance_resource(self, mcp_client, sample_balance_response): """Test balance resource.""" with patch('mcp_namecheap.account.get_client') as mock_get_client: mock_client = Mock() mock_client.get_account_balance.return_value = sample_balance_response mock_get_client.return_value = mock_client result = await mcp_client.read_resource("namecheap://balance") assert "Account Balance" in result assert "100.00" in result class TestMCPErrorHandling: """Test MCP server error handling.""" @pytest.fixture def mcp_client(self): """Create FastMCP test client.""" return testing.create_client(mcp_server) @pytest.mark.mcp async def test_domain_not_found_error(self, mcp_client): """Test domain not found error handling.""" from mcp_namecheap.server import NameCheapNotFoundError with patch('mcp_namecheap.domains.get_client') as mock_get_client: mock_client = Mock() mock_client.get_domain_info.side_effect = NameCheapNotFoundError("Domain not found") mock_get_client.return_value = mock_client result = await mcp_client.call_tool("get_domain_info", domain_identifier="nonexistent.com") assert result["success"] is False assert "Domain not found" in result["error"] @pytest.mark.mcp async def test_validation_error(self, mcp_client): """Test validation error handling.""" from pydantic import ValidationError with pytest.raises(ValidationError): await mcp_client.call_tool("check_domain_availability", { "domains": [] # Empty list should fail validation }) @pytest.mark.mcp async def test_api_error_handling(self, mcp_client): """Test API error handling.""" from mcp_namecheap.server import NameCheapAPIError with patch('mcp_namecheap.domains.get_client') as mock_get_client: mock_client = Mock() mock_client.list_domains.side_effect = NameCheapAPIError("API Error") mock_get_client.return_value = mock_client result = await mcp_client.call_tool("list_domains") assert result["success"] is False assert "API Error" in result["error"]