
- Production-ready MCP server for Name Cheap API integration - Domain management (registration, renewal, availability checking) - DNS management (records, nameserver configuration) - SSL certificate management and monitoring - Account information and balance checking - Smart identifier resolution for improved UX - Comprehensive error handling with specific exception types - 80%+ test coverage with unit, integration, and MCP tests - CLI and MCP server interfaces - FastMCP 2.10.5+ implementation with full MCP spec compliance 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
213 lines
5.8 KiB
Python
213 lines
5.8 KiB
Python
"""Test configuration and fixtures."""
|
|
|
|
import pytest
|
|
from unittest.mock import Mock, patch
|
|
from typing import Dict, Any, List
|
|
|
|
from mcp_namecheap.server import NameCheapAPIServer, NameCheapConfig
|
|
from mcp_namecheap.client import NameCheapClient
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_config():
|
|
"""Mock Name Cheap configuration."""
|
|
return NameCheapConfig(
|
|
api_key="test_api_key",
|
|
username="test_user",
|
|
client_ip="127.0.0.1",
|
|
sandbox=True
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_server(mock_config):
|
|
"""Mock Name Cheap API server."""
|
|
with patch('mcp_namecheap.server.httpx.Client') as mock_client_class:
|
|
mock_client = Mock()
|
|
mock_client_class.return_value = mock_client
|
|
|
|
server = NameCheapAPIServer(mock_config)
|
|
server.client = mock_client
|
|
return server
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_client(mock_server):
|
|
"""Mock Name Cheap client."""
|
|
return NameCheapClient(mock_server)
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_domains_response():
|
|
"""Sample domains list response."""
|
|
return {
|
|
"DomainGetListResult": {
|
|
"Domain": [
|
|
{
|
|
"@ID": "12345",
|
|
"@Name": "example.com",
|
|
"@User": "test_user",
|
|
"@Created": "01/15/2020",
|
|
"@Expires": "01/15/2025",
|
|
"@IsExpired": "false",
|
|
"@IsLocked": "false",
|
|
"@AutoRenew": "false",
|
|
"@WhoisGuard": "ENABLED"
|
|
},
|
|
{
|
|
"@ID": "12346",
|
|
"@Name": "test.org",
|
|
"@User": "test_user",
|
|
"@Created": "03/20/2021",
|
|
"@Expires": "03/20/2026",
|
|
"@IsExpired": "false",
|
|
"@IsLocked": "true",
|
|
"@AutoRenew": "true",
|
|
"@WhoisGuard": "DISABLED"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_domain_info_response():
|
|
"""Sample domain info response."""
|
|
return {
|
|
"DomainGetInfoResult": {
|
|
"@Status": "Ok",
|
|
"@ID": "12345",
|
|
"@DomainName": "example.com",
|
|
"@OwnerName": "test_user",
|
|
"@IsOwner": "true",
|
|
"DomainDetails": {
|
|
"@CreatedDate": "01/15/2020",
|
|
"@ExpiredDate": "01/15/2025",
|
|
"@NumYears": "5"
|
|
},
|
|
"DnsDetails": {
|
|
"@ProviderType": "CUSTOM",
|
|
"Nameserver": [
|
|
"ns1.example.com",
|
|
"ns2.example.com"
|
|
]
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_dns_records_response():
|
|
"""Sample DNS records response."""
|
|
return {
|
|
"DomainDNSGetHostsResult": {
|
|
"host": [
|
|
{
|
|
"@HostId": "1",
|
|
"@Name": "@",
|
|
"@Type": "A",
|
|
"@Address": "192.168.1.1",
|
|
"@MXPref": "10",
|
|
"@TTL": "1800"
|
|
},
|
|
{
|
|
"@HostId": "2",
|
|
"@Name": "www",
|
|
"@Type": "CNAME",
|
|
"@Address": "example.com",
|
|
"@MXPref": "10",
|
|
"@TTL": "1800"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_ssl_certificates_response():
|
|
"""Sample SSL certificates response."""
|
|
return {
|
|
"SSLListResult": {
|
|
"SSL": [
|
|
{
|
|
"@CertificateID": "111111",
|
|
"@HostName": "example.com",
|
|
"@SSLType": "PositiveSSL",
|
|
"@PurchaseDate": "01/15/2023",
|
|
"@ExpireDate": "01/15/2024",
|
|
"@ActivationExpireDate": "01/15/2024",
|
|
"@IsExpiredYN": "false",
|
|
"@Status": "active"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_domain_check_response():
|
|
"""Sample domain availability check response."""
|
|
return {
|
|
"DomainCheckResult": [
|
|
{
|
|
"@Domain": "available-domain.com",
|
|
"@Available": "true",
|
|
"@ErrorNo": "",
|
|
"@Description": "",
|
|
"@IsPremiumName": "false",
|
|
"@PremiumRegistrationPrice": "",
|
|
"@PremiumRenewalPrice": ""
|
|
},
|
|
{
|
|
"@Domain": "taken-domain.com",
|
|
"@Available": "false",
|
|
"@ErrorNo": "",
|
|
"@Description": "",
|
|
"@IsPremiumName": "false",
|
|
"@PremiumRegistrationPrice": "",
|
|
"@PremiumRenewalPrice": ""
|
|
}
|
|
]
|
|
}
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_account_info_response():
|
|
"""Sample account info response."""
|
|
return {
|
|
"UserGetAccountResult": {
|
|
"@ID": "12345",
|
|
"@UserName": "test_user",
|
|
"@FirstName": "Test",
|
|
"@LastName": "User",
|
|
"@Email": "test@example.com",
|
|
"@AccountCreateDate": "01/01/2020",
|
|
"@Company": "Test Company",
|
|
"@Phone": "+1.5551234567",
|
|
"@IsEmailVerified": "true",
|
|
"@IsPhoneVerified": "true",
|
|
"@AccountStatus": "Ok"
|
|
}
|
|
}
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_balance_response():
|
|
"""Sample account balance response."""
|
|
return {
|
|
"UserGetBalancesResult": {
|
|
"@Currency": "USD",
|
|
"@AccountBalance": "100.00",
|
|
"@AvailableBalance": "95.00"
|
|
}
|
|
}
|
|
|
|
|
|
def create_mock_response(data: Dict[str, Any], status: str = "OK"):
|
|
"""Create a mock XML response."""
|
|
return {
|
|
"ApiResponse": {
|
|
"@Status": status,
|
|
"CommandResponse": data
|
|
}
|
|
} |