Files
Home_assistant/backend/tests/test_openmeteo_helpers.py
T
2026-06-16 04:38:23 +00:00

114 lines
4.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from unittest.mock import patch
from app.homelab.openmeteo import (
PRECIP_PROB_HINT,
RECOMMENDED_SYNC_DOMAINS,
RECOMMENDED_SYNC_VARIABLES,
SYNC_HINT,
_coverage_sufficient,
_field_coverage,
_hourly_start_index,
_local_needs_sync_hint,
build_weather_dashboard,
format_weather_snapshot,
weather_query_relevant,
)
def test_hourly_start_index_from_current():
times = ["2026-06-14T00:00", "2026-06-14T01:00", "2026-06-14T18:00", "2026-06-14T19:00"]
assert _hourly_start_index(times, "2026-06-14T18:15") == 2
def test_coverage_sufficient():
assert _coverage_sufficient({"current": ["temperature_2m"], "hourly": ["temperature_2m"]}) is False
assert _coverage_sufficient(
{
"current": ["temperature_2m", "weather_code", "wind_speed_10m"],
"hourly": ["temperature_2m", "weather_code"],
}
) is True
def test_field_coverage_partial():
raw = {
"current": {"time": "2026-06-14T18:15", "temperature_2m": 20.6, "weather_code": 2},
"hourly": {
"time": ["2026-06-14T18:00", "2026-06-14T19:00"],
"temperature_2m": [20.0, 19.5],
"precipitation": [0.0, 0.0],
"weather_code": [2, 3],
},
"daily": {
"time": ["2026-06-14", "2026-06-15"],
"temperature_2m_max": [21.0, 18.0],
"temperature_2m_min": [12.0, 10.0],
"weather_code": [2, 3],
},
}
coverage = _field_coverage(raw)
assert "temperature_2m" in coverage["current"]
assert "weather_code" in coverage["hourly"]
assert "temperature_2m_max" in coverage["daily"]
def test_local_needs_sync_hint():
assert _local_needs_sync_hint({"current": ["temperature_2m"], "hourly": ["temperature_2m"]}) is True
assert _local_needs_sync_hint(
{"current": ["temperature_2m", "weather_code"], "hourly": ["temperature_2m", "weather_code"]}
) is False
def test_weather_query_relevant():
assert weather_query_relevant("какая погода завтра")
assert not weather_query_relevant("напиши код на python")
def test_format_weather_snapshot_includes_tomorrow():
snap = {
"ok": True,
"location": "СПб",
"current": {"temperature_c": 20, "conditions": "ясно"},
"hourly": [],
"daily": [
{"label": "Сегодня", "temperature_min_c": 10, "temperature_max_c": 20, "conditions": "ясно"},
{"label": "Завтра", "temperature_min_c": 12, "temperature_max_c": 18, "conditions": "дождь"},
],
}
text = format_weather_snapshot(snap)
assert "Завтра:" in text
assert "None" not in text
def test_build_weather_dashboard_includes_daily():
fake_weather = {
"ok": True,
"location": "Test",
"data_source": "local",
"local_field_coverage": {"current": ["temperature_2m", "weather_code"], "hourly": ["temperature_2m"], "daily": []},
"field_coverage": {"current": ["temperature_2m"], "hourly": ["temperature_2m"], "daily": []},
"sync_hint": PRECIP_PROB_HINT,
"merged_fields": [],
"current": {"temperature_c": 10, "conditions": "ясно"},
"hourly": [],
"daily": [{"label": "Завтра", "temperature_min_c": 5, "temperature_max_c": 12, "conditions": "дождь"}],
}
with patch("app.homelab.openmeteo.OpenMeteoClient") as mock_cls:
client = mock_cls.return_value
client.fetch_forecast.return_value = fake_weather
client.rain_summary.return_value = "ok"
client.daily_summary.return_value = "Завтра: 512°C"
client.cache_status.return_value = {"source": "local", "has_data": True, "cached": True, "ttl_sec": 300}
client.location_name = "Test"
client.lat = 1.0
client.lon = 2.0
client.base_url = "http://local"
client.cache_ttl = 300
client.forecast_days = 7
result = build_weather_dashboard(days_ahead=7)
assert result["daily_summary"] == "Завтра: 512°C"
assert result["recommended_sync"]["domains"] == RECOMMENDED_SYNC_DOMAINS
assert result["recommended_sync"]["variables"] == RECOMMENDED_SYNC_VARIABLES
assert SYNC_HINT # constant exists