Skip to content

Commit

Permalink
Mods
Browse files Browse the repository at this point in the history
  • Loading branch information
gjohansson-ST committed Aug 15, 2023
1 parent 330084a commit 9476f25
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 23 deletions.
48 changes: 25 additions & 23 deletions homeassistant/components/template/weather.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from __future__ import annotations

from functools import partial
from typing import Literal
from typing import Any, Literal

import voluptuous as vol

Expand Down Expand Up @@ -415,31 +415,33 @@ def _update_forecast(
def _validate_forecast(
self,
forecast_type: Literal["daily", "hourly", "twice_daily"],
result: list[Forecast] | TemplateError,
result: Any,
) -> list[Forecast] | None:
"""Validate the forecasts."""
if result is None or isinstance(result, TemplateError):
if result is None:
return None

if isinstance(result, list):
for forecast in result:
diff_result = (
set().union(forecast.keys()).difference(CHECK_FORECAST_KEYS)
if not isinstance(result, list):
raise vol.Invalid(
"Forecasts is not a list, see Weather documentation https://www.home-assistant.io/integrations/weather/"
)
for forecast in result:
if not isinstance(forecast, dict):
raise vol.Invalid(
"Forecast in list is not a dict, see Weather documentation https://www.home-assistant.io/integrations/weather/"
)
diff_result = set().union(forecast.keys()).difference(CHECK_FORECAST_KEYS)
if diff_result:
raise vol.Invalid(
"Only valid keys in Forecast are allowed, see Weather documentation https://www.home-assistant.io/integrations/weather/"
)
if forecast_type == "twice_daily" and "is_daytime" not in forecast.keys():
raise vol.Invalid(
"`is_daytime` is missing in twice_daily forecast, see Weather documentation https://www.home-assistant.io/integrations/weather/"
)
if "datetime" not in forecast.keys():
raise vol.Invalid(
"`datetime` is required in forecasts, see Weather documentation https://www.home-assistant.io/integrations/weather/"
)
if diff_result:
raise vol.Invalid(
"Only valid keys in Forecast are allowed, see Weather documentation https://www.home-assistant.io/integrations/weather/"
)
if (
forecast_type == "twice_daily"
and "is_daytime" not in forecast.keys()
):
raise vol.Invalid(
"`is_daytime` is missing in twice_daily forecast, see Weather documentation https://www.home-assistant.io/integrations/weather/"
)
if "datetime" not in forecast.keys():
raise vol.Invalid(
"`datetime` is required in forecasts, see Weather documentation https://www.home-assistant.io/integrations/weather/"
)
continue
continue
return result
73 changes: 73 additions & 0 deletions tests/components/template/test_weather.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,3 +420,76 @@ async def test_forecast_invalid_datetime_missing(
)
assert response == {"forecast": []}
assert "`datetime` is required in forecasts" in caplog.text


@pytest.mark.parametrize(("count", "domain"), [(1, WEATHER_DOMAIN)])
@pytest.mark.parametrize(
"config",
[
{
"weather": [
{
"platform": "template",
"name": "forecast",
"condition_template": "sunny",
"forecast_template": "{{ states.weather.forecast.attributes.forecast }}",
"forecast_daily_template": "{{ states.weather.forecast_daily.attributes.forecast }}",
"forecast_hourly_template": "{{ states.weather.forecast_hourly.attributes.forecast }}",
"temperature_template": "{{ states('sensor.temperature') | float }}",
"humidity_template": "{{ states('sensor.humidity') | int }}",
},
]
},
],
)
async def test_forecast_format_error(
hass: HomeAssistant, start_ha, caplog: pytest.LogCaptureFixture
) -> None:
"""Test forecast service invalid on incorrect format."""
for attr, _v_attr, value in [
("sensor.temperature", ATTR_WEATHER_TEMPERATURE, 22.3),
("sensor.humidity", ATTR_WEATHER_HUMIDITY, 60),
]:
hass.states.async_set(attr, value)
await hass.async_block_till_done()

hass.states.async_set(
"weather.forecast_daily",
"sunny",
{
ATTR_FORECAST: [
"cloudy",
"2023-02-17T14:00:00+00:00",
14.2,
1,
]
},
)
hass.states.async_set(
"weather.forecast_hourly",
"sunny",
{
ATTR_FORECAST: {
"condition": "cloudy",
"temperature": 14.2,
"is_daytime": True,
}
},
)

await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
{"entity_id": "weather.forecast", "type": "daily"},
blocking=True,
return_response=True,
)
assert "Forecasts is not a list, see Weather documentation" in caplog.text
await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
{"entity_id": "weather.forecast", "type": "hourly"},
blocking=True,
return_response=True,
)
assert "Forecast in list is not a dict, see Weather documentation" in caplog.text

0 comments on commit 9476f25

Please sign in to comment.