Skip to main content
Glama
conftest.py7.75 kB
"""Test configuration and fixtures for Aerospace MCP tests.""" from typing import Any from unittest.mock import MagicMock, patch import pandas as pd import pytest from fastapi.testclient import TestClient from aerospace_mcp.core import OPENAP_AVAILABLE, AirportOut, PlanRequest from main import app # Test data fixtures @pytest.fixture def sample_airport_data() -> dict[str, dict[str, Any]]: """Mock airport data for testing.""" return { "SJC": { "iata": "SJC", "icao": "KSJC", "name": "San Jose International Airport", "city": "San Jose", "country": "US", "lat": 37.3626, "lon": -121.929, "tz": "America/Los_Angeles", }, "NRT": { "iata": "NRT", "icao": "RJAA", "name": "Narita International Airport", "city": "Tokyo", "country": "JP", "lat": 35.7647, "lon": 140.386, "tz": "Asia/Tokyo", }, "SFO": { "iata": "SFO", "icao": "KSFO", "name": "San Francisco International Airport", "city": "San Francisco", "country": "US", "lat": 37.6213, "lon": -122.379, "tz": "America/Los_Angeles", }, "JFK": { "iata": "JFK", "icao": "KJFK", "name": "John F Kennedy International Airport", "city": "New York", "country": "US", "lat": 40.6398, "lon": -73.7789, "tz": "America/New_York", }, "XXX": { # Invalid airport for error testing "iata": "XXX", "icao": "", "name": "Non-existent Airport", "city": "Nowhere", "country": "XX", "lat": 0.0, "lon": 0.0, }, } @pytest.fixture def sjc_airport() -> AirportOut: """Sample SJC airport for testing.""" return AirportOut( iata="SJC", icao="KSJC", name="San Jose International Airport", city="San Jose", country="US", lat=37.3626, lon=-121.929, tz="America/Los_Angeles", ) @pytest.fixture def nrt_airport() -> AirportOut: """Sample NRT airport for testing.""" return AirportOut( iata="NRT", icao="RJAA", name="Narita International Airport", city="Tokyo", country="JP", lat=35.7647, lon=140.386, tz="Asia/Tokyo", ) @pytest.fixture def sample_plan_request() -> PlanRequest: """Sample flight plan request for testing.""" return PlanRequest( depart_city="San Jose", arrive_city="Tokyo", depart_country="US", arrive_country="JP", ac_type="A359", cruise_alt_ft=35000, route_step_km=25.0, ) @pytest.fixture def mock_openap_flight_generator(): """Mock OpenAP FlightGenerator for testing.""" mock_gen = MagicMock() # Mock climb segment climb_data = pd.DataFrame( { "t": [0, 10, 20, 30, 40, 50], "s": [0, 1000, 2500, 4500, 7000, 10000], # meters "altitude": [1000, 5000, 10000, 15000, 20000, 25000], # feet "groundspeed": [200, 220, 240, 260, 280, 300], # knots "vertical_rate": [2000, 1800, 1600, 1400, 1200, 1000], # fpm } ) # Mock cruise segment cruise_data = pd.DataFrame( { "t": [0, 10, 20, 30], "s": [0, 5000, 10000, 15000], # meters "altitude": [35000, 35000, 35000, 35000], # feet "groundspeed": [450, 450, 450, 450], # knots "vertical_rate": [0, 0, 0, 0], # fpm } ) # Mock descent segment descent_data = pd.DataFrame( { "t": [0, 10, 20, 30, 40, 50], "s": [0, 2000, 4000, 6000, 8000, 12000], # meters "altitude": [35000, 30000, 25000, 15000, 8000, 2000], # feet "groundspeed": [420, 400, 380, 350, 320, 280], # knots "vertical_rate": [-1000, -1200, -1400, -1600, -1800, -2000], # fpm } ) mock_gen.climb.return_value = climb_data mock_gen.cruise.return_value = cruise_data mock_gen.descent.return_value = descent_data return mock_gen @pytest.fixture def mock_openap_fuel_flow(): """Mock OpenAP FuelFlow for testing.""" mock_ff = MagicMock() mock_ff.enroute.return_value = 0.5 # kg/s return mock_ff @pytest.fixture def mock_openap_props(): """Mock OpenAP aircraft properties for testing.""" return { "limits": {"MTOW": 85000.0}, # kg "mtow": 85000.0, } @pytest.fixture def mock_airports_iata(sample_airport_data): """Mock the airports IATA data loading.""" with patch("aerospace_mcp.core._AIRPORTS_IATA", sample_airport_data): with patch("main._AIRPORTS_IATA", sample_airport_data): yield sample_airport_data @pytest.fixture def client(): """FastAPI test client.""" return TestClient(app) @pytest.fixture(params=["with_openap", "without_openap"]) def openap_availability(request): """Parameterized fixture for testing with and without OpenAP.""" if request.param == "with_openap": with patch("aerospace_mcp.core.OPENAP_AVAILABLE", True): with patch("main.OPENAP_AVAILABLE", True): yield True else: with patch("aerospace_mcp.core.OPENAP_AVAILABLE", False): with patch("main.OPENAP_AVAILABLE", False): yield False # Test data for parametrized tests @pytest.fixture def airport_test_cases(): """Test cases for airport resolution.""" return [ ("SJC", "SJC", True), # Valid IATA ("sjc", "SJC", True), # Case insensitive ("INVALID", None, False), # Invalid IATA ("", None, False), # Empty string ] @pytest.fixture def city_search_test_cases(): """Test cases for city airport search.""" return [ ("San Jose", "US", ["SJC"]), # City with country ("San Jose", None, ["SJC"]), # City without country ("Tokyo", "JP", ["NRT"]), # International city ("Nonexistent", "US", []), # Non-existent city ("", "US", []), # Empty city name ] @pytest.fixture def flight_plan_test_cases(): """Test cases for flight planning.""" return [ { "name": "SJC to NRT", "request": { "depart_city": "San Jose", "arrive_city": "Tokyo", "depart_country": "US", "arrive_country": "JP", "ac_type": "A359", }, "expected_distance_range": (8000, 12000), # km "should_succeed": True, }, { "name": "Same city error", "request": { "depart_city": "San Jose", "arrive_city": "San Jose", "ac_type": "A320", }, "should_succeed": False, }, { "name": "Invalid aircraft type", "request": { "depart_city": "San Jose", "arrive_city": "Tokyo", "ac_type": "INVALID_AC", }, "should_succeed": False, }, ] # Skip decorators for optional dependencies skip_without_openap = pytest.mark.skipif( not OPENAP_AVAILABLE, reason="OpenAP not available" ) skip_with_openap = pytest.mark.skipif(OPENAP_AVAILABLE, reason="OpenAP is available") # Markers for test organization pytest.mark.unit = pytest.mark.unit pytest.mark.integration = pytest.mark.integration pytest.mark.slow = pytest.mark.slow

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/cheesejaguar/aerospace-mcp'

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