"""Unit tests for OpenF1 API Client"""
import pytest
import asyncio
from unittest.mock import AsyncMock, patch, MagicMock
from src.openf1_client import OpenF1Client
@pytest.fixture
def client():
"""Create a test client"""
return OpenF1Client()
@pytest.mark.asyncio
async def test_client_context_manager():
"""Test that client can be used as async context manager"""
async with OpenF1Client() as client:
assert client.session is not None
@pytest.mark.asyncio
async def test_get_drivers(client):
"""Test fetching drivers"""
mock_response = [
{"driver_number": 1, "name": "Max Verstappen", "team": "Red Bull Racing"},
{"driver_number": 2, "name": "Sergio Perez", "team": "Red Bull Racing"}
]
with patch.object(client, '_get', new_callable=AsyncMock, return_value=mock_response):
result = await client.get_drivers()
assert result == mock_response
assert len(result) == 2
assert result[0]["driver_number"] == 1
@pytest.mark.asyncio
async def test_get_drivers_with_season(client):
"""Test fetching drivers with season filter"""
mock_response = [
{"driver_number": 1, "name": "Max Verstappen", "season": 2024}
]
with patch.object(client, '_get', new_callable=AsyncMock, return_value=mock_response) as mock_get:
result = await client.get_drivers(season=2024)
mock_get.assert_called_once_with("/drivers", {"season": 2024})
assert result == mock_response
@pytest.mark.asyncio
async def test_get_drivers_with_driver_number(client):
"""Test fetching specific driver by number"""
mock_response = [
{"driver_number": 1, "name": "Max Verstappen"}
]
with patch.object(client, '_get', new_callable=AsyncMock, return_value=mock_response) as mock_get:
result = await client.get_drivers(driver_number=1)
mock_get.assert_called_once_with("/drivers", {"driver_number": 1})
assert result[0]["driver_number"] == 1
@pytest.mark.asyncio
async def test_get_teams(client):
"""Test fetching teams"""
mock_response = [
{"team_id": 1, "name": "Red Bull Racing"},
{"team_id": 2, "name": "Mercedes"}
]
with patch.object(client, '_get', new_callable=AsyncMock, return_value=mock_response):
result = await client.get_teams()
assert len(result) == 2
assert result[0]["name"] == "Red Bull Racing"
@pytest.mark.asyncio
async def test_get_teams_with_season(client):
"""Test fetching teams filtered by season"""
mock_response = [
{"team_id": 1, "name": "Red Bull Racing", "season": 2024}
]
with patch.object(client, '_get', new_callable=AsyncMock, return_value=mock_response) as mock_get:
result = await client.get_teams(season=2024)
mock_get.assert_called_once_with("/teams", {"season": 2024})
assert result == mock_response
@pytest.mark.asyncio
async def test_get_races(client):
"""Test fetching races"""
mock_response = [
{"round": 1, "name": "Bahrain Grand Prix", "location": "Sakhir"},
{"round": 2, "name": "Saudi Arabian Grand Prix", "location": "Jeddah"}
]
with patch.object(client, '_get', new_callable=AsyncMock, return_value=mock_response):
result = await client.get_races()
assert len(result) == 2
assert result[0]["name"] == "Bahrain Grand Prix"
@pytest.mark.asyncio
async def test_get_races_with_season(client):
"""Test fetching races filtered by season"""
mock_response = [
{"round": 1, "name": "Bahrain Grand Prix", "season": 2024}
]
with patch.object(client, '_get', new_callable=AsyncMock, return_value=mock_response) as mock_get:
result = await client.get_races(season=2024)
mock_get.assert_called_once_with("/races", {"season": 2024})
assert result == mock_response
@pytest.mark.asyncio
async def test_get_races_with_round(client):
"""Test fetching races filtered by round number"""
mock_response = [
{"round": 5, "name": "Monaco Grand Prix"}
]
with patch.object(client, '_get', new_callable=AsyncMock, return_value=mock_response) as mock_get:
result = await client.get_races(round_number=5)
mock_get.assert_called_once_with("/races", {"round": 5})
assert result[0]["round"] == 5
@pytest.mark.asyncio
async def test_get_results(client):
"""Test fetching race results"""
mock_response = [
{"position": 1, "driver_number": 1, "points": 25},
{"position": 2, "driver_number": 11, "points": 18}
]
with patch.object(client, '_get', new_callable=AsyncMock, return_value=mock_response):
result = await client.get_results()
assert len(result) == 2
assert result[0]["position"] == 1
@pytest.mark.asyncio
async def test_get_results_with_session(client):
"""Test fetching results filtered by session"""
mock_response = [
{"position": 1, "driver_number": 1, "points": 25}
]
with patch.object(client, '_get', new_callable=AsyncMock, return_value=mock_response) as mock_get:
result = await client.get_results(session_key=1234)
mock_get.assert_called_once_with("/results", {"session_key": 1234})
assert result == mock_response
@pytest.mark.asyncio
async def test_get_sessions(client):
"""Test fetching sessions"""
mock_response = [
{"session_key": 1, "session_type": "Practice", "date_start": "2024-03-02"},
{"session_key": 2, "session_type": "Qualifying", "date_start": "2024-03-03"}
]
with patch.object(client, '_get', new_callable=AsyncMock, return_value=mock_response):
result = await client.get_sessions()
assert len(result) == 2
assert result[0]["session_type"] == "Practice"
@pytest.mark.asyncio
async def test_get_laps(client):
"""Test fetching lap data"""
mock_response = [
{"lap_number": 1, "driver_number": 1, "lap_duration": 90.5},
{"lap_number": 2, "driver_number": 1, "lap_duration": 89.8}
]
with patch.object(client, '_get', new_callable=AsyncMock, return_value=mock_response):
result = await client.get_laps(session_key=1234)
assert len(result) == 2
assert result[0]["lap_number"] == 1
@pytest.mark.asyncio
async def test_get_stints(client):
"""Test fetching stint data"""
mock_response = [
{"stint_number": 1, "driver_number": 1, "tyre_compound": "SOFT"},
{"stint_number": 2, "driver_number": 1, "tyre_compound": "HARD"}
]
with patch.object(client, '_get', new_callable=AsyncMock, return_value=mock_response):
result = await client.get_stints(session_key=1234)
assert len(result) == 2
assert result[0]["tyre_compound"] == "SOFT"
@pytest.mark.asyncio
async def test_get_pit_stops(client):
"""Test fetching pit stop data"""
mock_response = [
{"pit_stop_number": 1, "driver_number": 1, "lap_number": 20, "duration": 2.5},
{"pit_stop_number": 2, "driver_number": 1, "lap_number": 40, "duration": 2.3}
]
with patch.object(client, '_get', new_callable=AsyncMock, return_value=mock_response):
result = await client.get_pit_stops(session_key=1234)
assert len(result) == 2
assert result[0]["duration"] == 2.5
@pytest.mark.asyncio
async def test_get_weather(client):
"""Test fetching weather data"""
mock_response = [
{"track_temperature": 28.5, "air_temperature": 25.2, "humidity": 65}
]
with patch.object(client, '_get', new_callable=AsyncMock, return_value=mock_response):
result = await client.get_weather(session_key=1234)
assert result[0]["track_temperature"] == 28.5
@pytest.mark.asyncio
async def test_get_incidents(client):
"""Test fetching incident data"""
mock_response = [
{"incident_type": "collision", "driver_number": 1, "lap": 5},
{"incident_type": "penalty", "driver_number": 2, "lap": 10}
]
with patch.object(client, '_get', new_callable=AsyncMock, return_value=mock_response):
result = await client.get_incidents(session_key=1234)
assert len(result) == 2
assert result[0]["incident_type"] == "collision"
@pytest.mark.asyncio
async def test_get_car_data(client):
"""Test fetching car telemetry data"""
mock_response = [
{"throttle": 95, "brake": 0, "drs": True},
{"throttle": 0, "brake": 100, "drs": False}
]
with patch.object(client, '_get', new_callable=AsyncMock, return_value=mock_response):
result = await client.get_car_data(session_key=1234)
assert len(result) == 2
assert result[0]["throttle"] == 95
@pytest.mark.asyncio
async def test_get_positions(client):
"""Test fetching position data"""
mock_response = [
{"position": 1, "driver_number": 1, "lap": 1},
{"position": 2, "driver_number": 11, "lap": 1}
]
with patch.object(client, '_get', new_callable=AsyncMock, return_value=mock_response):
result = await client.get_positions(session_key=1234)
assert result[0]["position"] == 1