|
| 1 | +""" |
| 2 | +Additional tests to boost coverage to 65%+. |
| 3 | +""" |
| 4 | + |
| 5 | +import pytest |
| 6 | + |
| 7 | + |
| 8 | +class TestAdditionalCoverage: |
| 9 | + """Additional tests for better coverage.""" |
| 10 | + |
| 11 | + def test_constants_conversion_edge_cases(self): |
| 12 | + """Test edge cases for conversion functions.""" |
| 13 | + from solana_ai_registries.constants import ( |
| 14 | + a2ampl_to_base_units, |
| 15 | + base_units_to_a2ampl, |
| 16 | + ) |
| 17 | + |
| 18 | + # Zero case |
| 19 | + assert a2ampl_to_base_units(0) == 0 |
| 20 | + assert base_units_to_a2ampl(0) == 0.0 |
| 21 | + |
| 22 | + # Large numbers |
| 23 | + large_amount = 1000000.5 |
| 24 | + base_units = a2ampl_to_base_units(large_amount) |
| 25 | + assert base_units == 1000000500000000 |
| 26 | + |
| 27 | + # Small fractions |
| 28 | + small_amount = 0.000000001 |
| 29 | + base_units = a2ampl_to_base_units(small_amount) |
| 30 | + assert base_units == 1 |
| 31 | + |
| 32 | + def test_validation_functions(self): |
| 33 | + """Test validation functions in constants module.""" |
| 34 | + from solana_ai_registries.constants import validate_string_length, validate_url |
| 35 | + |
| 36 | + # Valid cases |
| 37 | + validate_string_length("test", 10, "test_field") |
| 38 | + validate_url("https://example.com", "test_url") |
| 39 | + validate_url("http://example.com", "test_url") |
| 40 | + |
| 41 | + # Invalid cases |
| 42 | + with pytest.raises(ValueError, match="test_field must be at most"): |
| 43 | + validate_string_length("too_long_string", 5, "test_field") |
| 44 | + |
| 45 | + with pytest.raises(ValueError, match="test_url must be a valid URL"): |
| 46 | + validate_url("not_a_url", "test_url") |
| 47 | + |
| 48 | + with pytest.raises(ValueError, match="test_url must start with one of"): |
| 49 | + validate_url("ftp://example.com", "test_url") |
| 50 | + |
| 51 | + def test_client_async_context_manager(self): |
| 52 | + """Test client async context manager functionality.""" |
| 53 | + import asyncio |
| 54 | + |
| 55 | + from solana_ai_registries.client import SolanaAIRegistriesClient |
| 56 | + |
| 57 | + async def test_context_manager(): |
| 58 | + async with SolanaAIRegistriesClient() as client: |
| 59 | + assert client is not None |
| 60 | + # Test that client property works |
| 61 | + rpc_client = client.client |
| 62 | + assert rpc_client is not None |
| 63 | + |
| 64 | + asyncio.run(test_context_manager()) |
| 65 | + |
| 66 | + def test_client_properties(self): |
| 67 | + """Test client properties for coverage.""" |
| 68 | + from solana_ai_registries.client import SolanaAIRegistriesClient |
| 69 | + |
| 70 | + client = SolanaAIRegistriesClient() |
| 71 | + |
| 72 | + # Test commitment property access |
| 73 | + assert client.commitment is not None |
| 74 | + |
| 75 | + # Test program ID properties |
| 76 | + assert client.agent_program_id is not None |
| 77 | + assert client.mcp_program_id is not None |
| 78 | + |
| 79 | + # Test RPC URL property |
| 80 | + assert client.rpc_url is not None |
| 81 | + |
| 82 | + def test_exception_hierarchy(self): |
| 83 | + """Test exception classes and inheritance.""" |
| 84 | + from solana_ai_registries.exceptions import ( |
| 85 | + AgentExistsError, |
| 86 | + SolanaAIRegistriesError, |
| 87 | + ValidationError, |
| 88 | + ) |
| 89 | + |
| 90 | + # Test base exception |
| 91 | + base_error = SolanaAIRegistriesError("base error") |
| 92 | + assert str(base_error) == "base error" |
| 93 | + |
| 94 | + # Test specific exceptions with their fields |
| 95 | + agent_error = AgentExistsError("test_agent", "owner123") |
| 96 | + assert agent_error.agent_id == "test_agent" |
| 97 | + assert agent_error.owner == "owner123" |
| 98 | + |
| 99 | + validation_error = ValidationError( |
| 100 | + "test_field", "test_constraint", "test_value" |
| 101 | + ) |
| 102 | + assert validation_error.field == "test_field" |
| 103 | + assert validation_error.constraint == "test_constraint" |
| 104 | + assert validation_error.value == "test_value" |
| 105 | + |
| 106 | + # Test inheritance |
| 107 | + assert isinstance(agent_error, SolanaAIRegistriesError) |
| 108 | + assert isinstance(validation_error, SolanaAIRegistriesError) |
| 109 | + |
| 110 | + def test_types_validation_edge_cases(self): |
| 111 | + """Test edge cases for type validation.""" |
| 112 | + from solana_ai_registries.types import ( |
| 113 | + AgentSkill, |
| 114 | + PaymentType, |
| 115 | + ServiceEndpoint, |
| 116 | + StakingTier, |
| 117 | + ) |
| 118 | + |
| 119 | + # ServiceEndpoint with minimal data |
| 120 | + endpoint = ServiceEndpoint(url="https://api.test.com") |
| 121 | + assert endpoint.protocol == "https" |
| 122 | + assert endpoint.description is None |
| 123 | + |
| 124 | + # AgentSkill with all optional fields |
| 125 | + skill = AgentSkill( |
| 126 | + skill_id="test_skill", |
| 127 | + name="Test Skill", |
| 128 | + description="A test skill", |
| 129 | + category="testing", |
| 130 | + tags=["tag1", "tag2"], |
| 131 | + metadata={"version": "1.0"}, |
| 132 | + ) |
| 133 | + assert skill.description == "A test skill" |
| 134 | + assert skill.category == "testing" |
| 135 | + assert len(skill.tags) == 2 |
| 136 | + assert skill.metadata["version"] == "1.0" |
| 137 | + |
| 138 | + # Test enum values |
| 139 | + assert PaymentType.PREPAY.value == "prepay" |
| 140 | + assert PaymentType.PAY_AS_YOU_GO.value == "pyg" |
| 141 | + assert StakingTier.BRONZE.value == "bronze" |
| 142 | + |
| 143 | + def test_idl_loader_cache_operations(self): |
| 144 | + """Test IDL loader cache operations.""" |
| 145 | + from solana_ai_registries.idl import IDLLoader |
| 146 | + |
| 147 | + loader = IDLLoader() |
| 148 | + |
| 149 | + # Test initial state |
| 150 | + assert len(loader._cached_idls) == 0 |
| 151 | + |
| 152 | + # Test cache clearing |
| 153 | + loader.clear_cache() |
| 154 | + assert len(loader._cached_idls) == 0 |
| 155 | + |
| 156 | + # Test loading non-existent IDL (should raise error) |
| 157 | + with pytest.raises(Exception): # Could be IDLError or other |
| 158 | + loader.load_idl("nonexistent_program") |
| 159 | + |
| 160 | + def test_registry_classes_initialization(self): |
| 161 | + """Test registry class initialization.""" |
| 162 | + from solana_ai_registries.agent import AgentRegistry |
| 163 | + from solana_ai_registries.client import SolanaAIRegistriesClient |
| 164 | + from solana_ai_registries.mcp import McpServerRegistry |
| 165 | + from solana_ai_registries.payments import PaymentManager |
| 166 | + |
| 167 | + client = SolanaAIRegistriesClient() |
| 168 | + |
| 169 | + # Test agent registry |
| 170 | + agent_registry = AgentRegistry(client) |
| 171 | + assert agent_registry.client == client |
| 172 | + |
| 173 | + # Test MCP registry |
| 174 | + mcp_registry = McpServerRegistry(client) |
| 175 | + assert mcp_registry.client == client |
| 176 | + |
| 177 | + # Test payment manager variations |
| 178 | + payment_manager_devnet = PaymentManager(client, use_mainnet=False) |
| 179 | + payment_manager_mainnet = PaymentManager(client, use_mainnet=True) |
| 180 | + |
| 181 | + assert payment_manager_devnet.client == client |
| 182 | + assert payment_manager_mainnet.client == client |
| 183 | + assert payment_manager_devnet.token_mint != payment_manager_mainnet.token_mint |
| 184 | + |
| 185 | + def test_type_field_validation(self): |
| 186 | + """Test validation of type fields.""" |
| 187 | + from solana_ai_registries.types import AgentSkill |
| 188 | + |
| 189 | + # Test tags validation (max 5 tags) |
| 190 | + with pytest.raises(ValueError, match="Maximum 5 tags allowed"): |
| 191 | + AgentSkill( |
| 192 | + skill_id="test", |
| 193 | + name="Test", |
| 194 | + tags=["tag1", "tag2", "tag3", "tag4", "tag5", "tag6"], |
| 195 | + ) |
| 196 | + |
| 197 | + # Test valid case with 5 tags |
| 198 | + skill = AgentSkill( |
| 199 | + skill_id="test", name="Test", tags=["tag1", "tag2", "tag3", "tag4", "tag5"] |
| 200 | + ) |
| 201 | + assert len(skill.tags) == 5 |
| 202 | + |
| 203 | + def test_service_endpoint_auth_variations(self): |
| 204 | + """Test ServiceEndpoint with different auth configurations.""" |
| 205 | + from solana_ai_registries.types import ServiceEndpoint |
| 206 | + |
| 207 | + # No auth |
| 208 | + endpoint1 = ServiceEndpoint(url="https://api.example.com") |
| 209 | + assert endpoint1.auth_type is None |
| 210 | + assert endpoint1.auth_config is None |
| 211 | + |
| 212 | + # Bearer token auth |
| 213 | + endpoint2 = ServiceEndpoint( |
| 214 | + url="https://api.example.com", |
| 215 | + auth_type="bearer", |
| 216 | + auth_config={"header": "Authorization"}, |
| 217 | + ) |
| 218 | + assert endpoint2.auth_type == "bearer" |
| 219 | + assert endpoint2.auth_config["header"] == "Authorization" |
| 220 | + |
| 221 | + # API key auth |
| 222 | + endpoint3 = ServiceEndpoint( |
| 223 | + url="https://api.example.com", |
| 224 | + auth_type="api_key", |
| 225 | + description="API with key authentication", |
| 226 | + auth_config={"key_param": "api_key"}, |
| 227 | + ) |
| 228 | + assert endpoint3.auth_type == "api_key" |
| 229 | + assert endpoint3.description == "API with key authentication" |
| 230 | + |
| 231 | + def test_import_all_submodules(self): |
| 232 | + """Test importing all submodules for coverage.""" |
| 233 | + import solana_ai_registries |
| 234 | + import solana_ai_registries.agent |
| 235 | + import solana_ai_registries.client |
| 236 | + import solana_ai_registries.constants |
| 237 | + import solana_ai_registries.exceptions |
| 238 | + import solana_ai_registries.idl |
| 239 | + import solana_ai_registries.mcp |
| 240 | + import solana_ai_registries.payments |
| 241 | + import solana_ai_registries.types |
| 242 | + |
| 243 | + # Basic availability checks |
| 244 | + assert hasattr(solana_ai_registries, "__version__") |
| 245 | + assert hasattr(solana_ai_registries.agent, "AgentRegistry") |
| 246 | + assert hasattr(solana_ai_registries.client, "SolanaAIRegistriesClient") |
| 247 | + assert hasattr(solana_ai_registries.exceptions, "SolanaAIRegistriesError") |
| 248 | + assert hasattr(solana_ai_registries.types, "AgentStatus") |
| 249 | + |
| 250 | + def test_constants_all_values(self): |
| 251 | + """Test accessing all constant values.""" |
| 252 | + from solana_ai_registries.constants import ( |
| 253 | + A2AMPL_BASE_UNIT, |
| 254 | + A2AMPL_TOKEN_MINT_DEVNET, |
| 255 | + A2AMPL_TOKEN_MINT_MAINNET, |
| 256 | + AGENT_REGISTRY_PROGRAM_ID, |
| 257 | + BRONZE_TIER_STAKE, |
| 258 | + DEFAULT_DEVNET_RPC, |
| 259 | + GOLD_TIER_STAKE, |
| 260 | + MAX_AGENT_DESCRIPTION_LEN, |
| 261 | + MAX_AGENT_ID_LEN, |
| 262 | + MAX_AGENT_NAME_LEN, |
| 263 | + MAX_SERVER_ID_LEN, |
| 264 | + MAX_SERVER_NAME_LEN, |
| 265 | + MCP_SERVER_REGISTRY_PROGRAM_ID, |
| 266 | + PLATINUM_TIER_STAKE, |
| 267 | + SILVER_TIER_STAKE, |
| 268 | + ) |
| 269 | + |
| 270 | + # Ensure all constants are defined and have expected types |
| 271 | + assert isinstance(AGENT_REGISTRY_PROGRAM_ID, str) |
| 272 | + assert isinstance(MCP_SERVER_REGISTRY_PROGRAM_ID, str) |
| 273 | + assert isinstance(DEFAULT_DEVNET_RPC, str) |
| 274 | + assert isinstance(MAX_AGENT_ID_LEN, int) and MAX_AGENT_ID_LEN > 0 |
| 275 | + assert isinstance(MAX_AGENT_NAME_LEN, int) and MAX_AGENT_NAME_LEN > 0 |
| 276 | + assert ( |
| 277 | + isinstance(MAX_AGENT_DESCRIPTION_LEN, int) and MAX_AGENT_DESCRIPTION_LEN > 0 |
| 278 | + ) |
| 279 | + assert isinstance(MAX_SERVER_ID_LEN, int) and MAX_SERVER_ID_LEN > 0 |
| 280 | + assert isinstance(MAX_SERVER_NAME_LEN, int) and MAX_SERVER_NAME_LEN > 0 |
| 281 | + assert isinstance(A2AMPL_BASE_UNIT, int) and A2AMPL_BASE_UNIT > 0 |
| 282 | + assert isinstance(A2AMPL_TOKEN_MINT_DEVNET, str) |
| 283 | + assert isinstance(A2AMPL_TOKEN_MINT_MAINNET, str) |
| 284 | + assert isinstance(BRONZE_TIER_STAKE, int) |
| 285 | + assert isinstance(SILVER_TIER_STAKE, int) |
| 286 | + assert isinstance(GOLD_TIER_STAKE, int) |
| 287 | + assert isinstance(PLATINUM_TIER_STAKE, int) |
| 288 | + |
| 289 | + # Test stake tier ordering |
| 290 | + assert BRONZE_TIER_STAKE < SILVER_TIER_STAKE |
| 291 | + assert SILVER_TIER_STAKE < GOLD_TIER_STAKE |
| 292 | + assert GOLD_TIER_STAKE < PLATINUM_TIER_STAKE |
0 commit comments