Add GET /tools/environment endpoint that fetches weather, forecast, sun times, and air quality data from user's volatile Qdrant collection. - Add qdrant-client dependency - Create QdrantReadClient wrapper for read-only queries - Add environment schemas and service in tools domain - Parse weather, forecast, sun times, and air quality from Qdrant payloads - Support user-specific collections via preferred_username from OIDC - Add comprehensive service tests (13 tests) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
160 lines
6.0 KiB
Python
160 lines
6.0 KiB
Python
"""Tests for environment service and schemas."""
|
|
import pytest
|
|
from datetime import datetime
|
|
|
|
|
|
class TestEnvironmentService:
|
|
"""Test EnvironmentService methods."""
|
|
|
|
def test_aqi_to_quality_good(self):
|
|
"""AQI 0-50 should return Good."""
|
|
from src.domains.tools.environment.service import EnvironmentService
|
|
service = EnvironmentService.__new__(EnvironmentService)
|
|
|
|
assert service._aqi_to_quality(0) == "Good"
|
|
assert service._aqi_to_quality(25) == "Good"
|
|
assert service._aqi_to_quality(50) == "Good"
|
|
|
|
def test_aqi_to_quality_moderate(self):
|
|
"""AQI 51-100 should return Moderate."""
|
|
from src.domains.tools.environment.service import EnvironmentService
|
|
service = EnvironmentService.__new__(EnvironmentService)
|
|
|
|
assert service._aqi_to_quality(51) == "Moderate"
|
|
assert service._aqi_to_quality(75) == "Moderate"
|
|
assert service._aqi_to_quality(100) == "Moderate"
|
|
|
|
def test_aqi_to_quality_unhealthy_sensitive(self):
|
|
"""AQI 101-150 should return Unhealthy for Sensitive Groups."""
|
|
from src.domains.tools.environment.service import EnvironmentService
|
|
service = EnvironmentService.__new__(EnvironmentService)
|
|
|
|
assert service._aqi_to_quality(101) == "Unhealthy for Sensitive Groups"
|
|
assert service._aqi_to_quality(150) == "Unhealthy for Sensitive Groups"
|
|
|
|
def test_aqi_to_quality_unhealthy(self):
|
|
"""AQI 151-200 should return Unhealthy."""
|
|
from src.domains.tools.environment.service import EnvironmentService
|
|
service = EnvironmentService.__new__(EnvironmentService)
|
|
|
|
assert service._aqi_to_quality(151) == "Unhealthy"
|
|
assert service._aqi_to_quality(200) == "Unhealthy"
|
|
|
|
def test_aqi_to_quality_very_unhealthy(self):
|
|
"""AQI 201-300 should return Very Unhealthy."""
|
|
from src.domains.tools.environment.service import EnvironmentService
|
|
service = EnvironmentService.__new__(EnvironmentService)
|
|
|
|
assert service._aqi_to_quality(201) == "Very Unhealthy"
|
|
assert service._aqi_to_quality(300) == "Very Unhealthy"
|
|
|
|
def test_aqi_to_quality_hazardous(self):
|
|
"""AQI >300 should return Hazardous."""
|
|
from src.domains.tools.environment.service import EnvironmentService
|
|
service = EnvironmentService.__new__(EnvironmentService)
|
|
|
|
assert service._aqi_to_quality(301) == "Hazardous"
|
|
assert service._aqi_to_quality(500) == "Hazardous"
|
|
|
|
def test_parse_weather_with_valid_data(self):
|
|
"""Parse weather should return WeatherData for valid input."""
|
|
from src.domains.tools.environment.service import EnvironmentService
|
|
service = EnvironmentService.__new__(EnvironmentService)
|
|
|
|
raw = {
|
|
"temperature": 15.5,
|
|
"conditions": "Cloudy",
|
|
"humidity": 72,
|
|
"location": "Rotterdam",
|
|
}
|
|
result = service._parse_weather(raw)
|
|
|
|
assert result is not None
|
|
assert result.temperature == 15.5
|
|
assert result.conditions == "Cloudy"
|
|
assert result.humidity == 72
|
|
|
|
def test_parse_weather_with_none(self):
|
|
"""Parse weather should return None for None input."""
|
|
from src.domains.tools.environment.service import EnvironmentService
|
|
service = EnvironmentService.__new__(EnvironmentService)
|
|
|
|
result = service._parse_weather(None)
|
|
assert result is None
|
|
|
|
def test_parse_forecast_with_list(self):
|
|
"""Parse forecast should handle list format."""
|
|
from src.domains.tools.environment.service import EnvironmentService
|
|
service = EnvironmentService.__new__(EnvironmentService)
|
|
|
|
raw = [
|
|
{"date": "2026-01-06", "high": 12, "low": 5, "conditions": "Cloudy"},
|
|
{"date": "2026-01-07", "high": 14, "low": 6, "conditions": "Sunny"},
|
|
]
|
|
result = service._parse_forecast(raw)
|
|
|
|
assert result is not None
|
|
assert len(result) == 2
|
|
assert result[0].date == "2026-01-06"
|
|
assert result[0].high == 12
|
|
|
|
def test_parse_forecast_with_dict(self):
|
|
"""Parse forecast should handle dict with days key."""
|
|
from src.domains.tools.environment.service import EnvironmentService
|
|
service = EnvironmentService.__new__(EnvironmentService)
|
|
|
|
raw = {
|
|
"days": [
|
|
{"date": "2026-01-06", "high": 12, "low": 5, "conditions": "Cloudy"},
|
|
]
|
|
}
|
|
result = service._parse_forecast(raw)
|
|
|
|
assert result is not None
|
|
assert len(result) == 1
|
|
|
|
def test_parse_sun_times_with_strings(self):
|
|
"""Parse sun times should handle ISO datetime strings."""
|
|
from src.domains.tools.environment.service import EnvironmentService
|
|
service = EnvironmentService.__new__(EnvironmentService)
|
|
|
|
raw = {
|
|
"sunrise": "2026-01-06T08:45:00",
|
|
"sunset": "2026-01-06T16:50:00",
|
|
}
|
|
result = service._parse_sun_times(raw)
|
|
|
|
assert result is not None
|
|
assert result.sunrise.hour == 8
|
|
assert result.sunrise.minute == 45
|
|
assert result.sunset.hour == 16
|
|
assert result.daylight_minutes == 485
|
|
|
|
def test_parse_air_quality_with_int(self):
|
|
"""Parse air quality should handle simple integer AQI."""
|
|
from src.domains.tools.environment.service import EnvironmentService
|
|
service = EnvironmentService.__new__(EnvironmentService)
|
|
|
|
result = service._parse_air_quality(42)
|
|
|
|
assert result is not None
|
|
assert result.aqi == 42
|
|
assert result.quality == "Good"
|
|
|
|
def test_parse_air_quality_with_dict(self):
|
|
"""Parse air quality should handle dict format."""
|
|
from src.domains.tools.environment.service import EnvironmentService
|
|
service = EnvironmentService.__new__(EnvironmentService)
|
|
|
|
raw = {
|
|
"aqi": 75,
|
|
"pm25": 8.5,
|
|
"pm10": 15,
|
|
}
|
|
result = service._parse_air_quality(raw)
|
|
|
|
assert result is not None
|
|
assert result.aqi == 75
|
|
assert result.quality == "Moderate"
|
|
assert result.pm25 == 8.5
|