Skip to main content
Glama

OpenAPI to Model Context Protocol (MCP)

test_local_file_loading.py10.2 kB
#!/usr/bin/env python3 """ Unit tests for local file loading functionality. """ import os import sys import json import tempfile from pathlib import Path # Add src to path sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src')) from openapi_loader import OpenAPILoader, OpenAPIError def test_load_json_file(): """Test loading local JSON OpenAPI spec.""" print("Testing JSON file loading...") try: # Load the test fixture spec_path = "./test/fixtures/petstore.json" spec = OpenAPILoader.load_spec(spec_path) # Verify the spec was loaded correctly assert spec is not None, "Spec should not be None" assert "openapi" in spec, "Spec should contain 'openapi' field" assert "info" in spec, "Spec should contain 'info' field" assert "paths" in spec, "Spec should contain 'paths' field" assert spec["info"]["title"] == "Test Petstore API", "Title should match" assert "/pets" in spec["paths"], "Should have /pets path" print("✓ JSON file loading successful") return True except Exception as e: print(f"✗ JSON file loading failed: {e}") return False def test_load_yaml_file(): """Test loading local YAML OpenAPI spec.""" print("Testing YAML file loading...") try: # Load the test fixture spec_path = "./test/fixtures/weather.yaml" spec = OpenAPILoader.load_spec(spec_path) # Verify the spec was loaded correctly assert spec is not None, "Spec should not be None" assert "openapi" in spec, "Spec should contain 'openapi' field" assert "info" in spec, "Spec should contain 'info' field" assert "paths" in spec, "Spec should contain 'paths' field" assert spec["info"]["title"] == "Test Weather API", "Title should match" assert "/forecast" in spec["paths"], "Should have /forecast path" print("✓ YAML file loading successful") return True except Exception as e: print(f"✗ YAML file loading failed: {e}") return False def test_relative_path(): """Test loading spec from relative path.""" print("Testing relative path loading...") try: # Save current directory original_dir = os.getcwd() # Change to test directory os.chdir(os.path.dirname(__file__)) # Load using relative path spec = OpenAPILoader.load_spec("./fixtures/petstore.json") assert spec["info"]["title"] == "Test Petstore API", "Should load from relative path" # Restore directory os.chdir(original_dir) print("✓ Relative path loading successful") return True except Exception as e: print(f"✗ Relative path loading failed: {e}") os.chdir(original_dir) # Ensure we restore the directory return False def test_absolute_path(): """Test loading spec from absolute path.""" print("Testing absolute path loading...") try: # Get absolute path to fixture abs_path = os.path.abspath("./test/fixtures/weather.yaml") spec = OpenAPILoader.load_spec(abs_path) assert spec["info"]["title"] == "Test Weather API", "Should load from absolute path" print("✓ Absolute path loading successful") return True except Exception as e: print(f"✗ Absolute path loading failed: {e}") return False def test_missing_file(): """Test error handling for missing file.""" print("Testing missing file handling...") try: # Try to load non-existent file spec = OpenAPILoader.load_spec("./test/fixtures/does_not_exist.json") print("✗ Should have raised FileNotFoundError") return False except FileNotFoundError as e: assert "does_not_exist.json" in str(e), "Error should mention the file" print("✓ Missing file error handled correctly") return True except Exception as e: print(f"✗ Unexpected error: {e}") return False def test_invalid_json(): """Test error handling for invalid JSON.""" print("Testing invalid JSON handling...") try: # Create a temporary invalid JSON file with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f: f.write('{ invalid json }') temp_path = f.name try: spec = OpenAPILoader.load_spec(temp_path) print("✗ Should have raised OpenAPIError for invalid JSON") return False finally: os.unlink(temp_path) except OpenAPIError as e: assert "Failed to parse" in str(e), "Error should mention parse failure" print("✓ Invalid JSON error handled correctly") return True except Exception as e: print(f"✗ Unexpected error: {e}") return False def test_invalid_yaml(): """Test error handling for invalid YAML.""" print("Testing invalid YAML handling...") try: # Try to load the invalid YAML fixture spec = OpenAPILoader.load_spec("./test/fixtures/invalid.yaml") print("✗ Should have raised OpenAPIError for invalid YAML") return False except OpenAPIError as e: assert "Failed to parse" in str(e) or "Failed to load" in str(e), "Error should mention parse failure" print("✓ Invalid YAML error handled correctly") return True except Exception as e: print(f"✗ Unexpected error: {e}") return False def test_invalid_openapi_spec(): """Test error handling for invalid OpenAPI spec structure.""" print("Testing invalid OpenAPI spec handling...") try: # Try to load the invalid spec fixture (valid JSON but invalid OpenAPI) spec = OpenAPILoader.load_spec("./test/fixtures/invalid.json") print("✗ Should have raised OpenAPIError for invalid spec") return False except OpenAPIError as e: assert "Missing required properties" in str(e), "Error should mention missing properties" print("✓ Invalid OpenAPI spec error handled correctly") return True except Exception as e: print(f"✗ Unexpected error: {e}") return False def test_file_size_limit(): """Test that large files are rejected.""" print("Testing file size limit...") try: # Create a file larger than 10MB with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f: # Write a large JSON structure f.write('{"info": {"title": "Test"}, "paths": {') # Add lots of paths to exceed 10MB for i in range(500000): f.write(f'"/path{i}": {{"get": {{"operationId": "op{i}"}}}},') f.write('"/final": {"get": {"operationId": "final"}}}}') temp_path = f.name try: # Check file size file_size = os.path.getsize(temp_path) if file_size <= 10 * 1024 * 1024: print(f"✗ Test file not large enough ({file_size} bytes)") return False spec = OpenAPILoader.load_spec(temp_path) print("✗ Should have raised OpenAPIError for large file") return False finally: os.unlink(temp_path) except OpenAPIError as e: assert "too large" in str(e), "Error should mention file size" print("✓ File size limit enforced correctly") return True except Exception as e: print(f"✗ Unexpected error: {e}") return False def test_remote_url_still_works(): """Test that remote URLs still work (not treated as local files).""" print("Testing remote URL detection...") try: # These should be detected as remote URLs urls = [ "https://example.com/openapi.json", "http://localhost:8000/spec.yaml" ] for url in urls: # We can't actually fetch these, but we can verify they're not treated as local files try: spec = OpenAPILoader.load_spec(url) # This will fail with connection error, not file not found except FileNotFoundError: print(f"✗ URL {url} was treated as local file") return False except Exception: # Any other error is fine - we just want to ensure it's not treated as a file pass print("✓ Remote URLs correctly identified") return True except Exception as e: print(f"✗ Unexpected error: {e}") return False def run_all_tests(): """Run all local file loading tests.""" print("\n" + "="*50) print("Local File Loading Tests") print("="*50 + "\n") tests = [ test_load_json_file, test_load_yaml_file, test_relative_path, test_absolute_path, test_missing_file, test_invalid_json, test_invalid_yaml, test_invalid_openapi_spec, test_file_size_limit, test_remote_url_still_works ] results = [] for test in tests: try: success = test() results.append(success) except Exception as e: print(f"✗ Test {test.__name__} crashed: {e}") results.append(False) print() # Add blank line between tests # Summary passed = sum(results) total = len(results) print("="*50) print(f"Results: {passed}/{total} tests passed") if passed == total: print("✓ All tests passed!") return True else: print(f"✗ {total - passed} tests failed") return False if __name__ == "__main__": success = run_all_tests() sys.exit(0 if success else 1)

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/gujord/OpenAPI-MCP'

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