"""Pytest configuration and shared fixtures."""
import asyncio
import pytest
from unittest.mock import Mock, AsyncMock
from typing import Dict, Any
from src.utils.config import Settings
from src.server import MCPServer
@pytest.fixture(scope="session")
def event_loop():
"""Create an instance of the default event loop for the test session."""
loop = asyncio.get_event_loop_policy().new_event_loop()
yield loop
loop.close()
@pytest.fixture
def mock_settings():
"""Mock settings for testing."""
return Settings(
host="localhost",
port=8000,
debug=True,
openweather_api_key="test_weather_key",
news_api_key="test_news_key",
alpha_vantage_api_key="test_stock_key",
auth_enabled=False,
log_level="DEBUG",
)
@pytest.fixture
def mcp_server(mock_settings):
"""Create a test MCP server instance."""
return MCPServer(mock_settings)
@pytest.fixture
def sample_weather_api_response():
"""Sample OpenWeatherMap API response."""
return {
"coord": {"lon": -122.42, "lat": 37.77},
"weather": [
{
"id": 801,
"main": "Clouds",
"description": "few clouds",
"icon": "02d"
}
],
"base": "stations",
"main": {
"temp": 18.5,
"feels_like": 17.2,
"temp_min": 16.1,
"temp_max": 21.1,
"pressure": 1013,
"humidity": 72
},
"visibility": 10000,
"wind": {"speed": 3.6, "deg": 230},
"clouds": {"all": 20},
"dt": 1609459200,
"sys": {
"type": 1,
"id": 5122,
"country": "US",
"sunrise": 1609429200,
"sunset": 1609463400
},
"timezone": -28800,
"id": 5391959,
"name": "San Francisco",
"cod": 200
}
@pytest.fixture
def sample_news_api_response():
"""Sample News API response."""
return {
"status": "ok",
"totalResults": 2,
"articles": [
{
"source": {"id": "bbc-news", "name": "BBC News"},
"author": "John Doe",
"title": "Sample News Article",
"description": "This is a sample news article description.",
"url": "https://example.com/article1",
"urlToImage": "https://example.com/image1.jpg",
"publishedAt": "2023-01-01T12:00:00Z",
"content": "Sample article content..."
},
{
"source": {"id": "cnn", "name": "CNN"},
"author": "Jane Smith",
"title": "Another News Article",
"description": "Another sample news article.",
"url": "https://example.com/article2",
"urlToImage": "https://example.com/image2.jpg",
"publishedAt": "2023-01-01T11:00:00Z",
"content": "Another article content..."
}
]
}
@pytest.fixture
def sample_stock_api_response():
"""Sample Alpha Vantage API response."""
return {
"Global Quote": {
"01. symbol": "AAPL",
"02. open": "150.00",
"03. high": "152.50",
"04. low": "149.00",
"05. price": "151.25",
"06. volume": "75000000",
"07. latest trading day": "2023-01-01",
"08. previous close": "149.50",
"09. change": "1.75",
"10. change percent": "1.17%"
}
}
@pytest.fixture
def mock_aiohttp_session():
"""Mock aiohttp session for testing."""
session = AsyncMock()
session.__aenter__ = AsyncMock(return_value=session)
session.__aexit__ = AsyncMock(return_value=None)
return session
@pytest.fixture
def mock_successful_response(sample_weather_api_response):
"""Mock successful HTTP response."""
response = AsyncMock()
response.status = 200
response.json = AsyncMock(return_value=sample_weather_api_response)
response.text = AsyncMock(return_value="Success")
return response
@pytest.fixture
def mock_error_response():
"""Mock error HTTP response."""
response = AsyncMock()
response.status = 404
response.json = AsyncMock(return_value={"error": "Not found"})
response.text = AsyncMock(return_value="Not found")
return response