Deprecate weather.get_forecast (#102534)

* Deprecate weather.get_forecast

* Rename forecast to get_forecasts

* raise issue for use of deprecated service

* Add fix_flow

* Add service translation/yaml
This commit is contained in:
Kevin Stillhammer 2023-11-19 20:44:02 +01:00 committed by GitHub
parent 41224f1674
commit 173f4760bc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 18726 additions and 76 deletions

View file

@ -18,7 +18,8 @@ from homeassistant.components.weather import (
ATTR_WEATHER_WIND_GUST_SPEED,
ATTR_WEATHER_WIND_SPEED,
DOMAIN as WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
LEGACY_SERVICE_GET_FORECAST,
SERVICE_GET_FORECASTS,
Forecast,
)
from homeassistant.const import ATTR_ATTRIBUTION, STATE_UNAVAILABLE, STATE_UNKNOWN
@ -92,6 +93,13 @@ async def test_template_state_text(hass: HomeAssistant, start_ha) -> None:
assert state.attributes.get(v_attr) == value
@pytest.mark.parametrize(
("service"),
[
SERVICE_GET_FORECASTS,
LEGACY_SERVICE_GET_FORECAST,
],
)
@pytest.mark.parametrize(("count", "domain"), [(1, WEATHER_DOMAIN)])
@pytest.mark.parametrize(
"config",
@ -114,7 +122,7 @@ async def test_template_state_text(hass: HomeAssistant, start_ha) -> None:
],
)
async def test_forecasts(
hass: HomeAssistant, start_ha, snapshot: SnapshotAssertion
hass: HomeAssistant, start_ha, snapshot: SnapshotAssertion, service: str
) -> None:
"""Test forecast service."""
for attr, _v_attr, value in [
@ -161,7 +169,7 @@ async def test_forecasts(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{"entity_id": "weather.forecast", "type": "daily"},
blocking=True,
return_response=True,
@ -169,7 +177,7 @@ async def test_forecasts(
assert response == snapshot
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{"entity_id": "weather.forecast", "type": "hourly"},
blocking=True,
return_response=True,
@ -177,7 +185,7 @@ async def test_forecasts(
assert response == snapshot
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{"entity_id": "weather.forecast", "type": "twice_daily"},
blocking=True,
return_response=True,
@ -204,7 +212,7 @@ async def test_forecasts(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{"entity_id": "weather.forecast", "type": "daily"},
blocking=True,
return_response=True,
@ -212,6 +220,13 @@ async def test_forecasts(
assert response == snapshot
@pytest.mark.parametrize(
("service", "expected"),
[
(SERVICE_GET_FORECASTS, {"weather.forecast": {"forecast": []}}),
(LEGACY_SERVICE_GET_FORECAST, {"forecast": []}),
],
)
@pytest.mark.parametrize(("count", "domain"), [(1, WEATHER_DOMAIN)])
@pytest.mark.parametrize(
"config",
@ -236,6 +251,8 @@ async def test_forecast_invalid(
hass: HomeAssistant,
start_ha,
caplog: pytest.LogCaptureFixture,
service: str,
expected: dict[str, Any],
) -> None:
"""Test invalid forecasts."""
for attr, _v_attr, value in [
@ -271,23 +288,30 @@ async def test_forecast_invalid(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{"entity_id": "weather.forecast", "type": "daily"},
blocking=True,
return_response=True,
)
assert response == {"forecast": []}
assert response == expected
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{"entity_id": "weather.forecast", "type": "hourly"},
blocking=True,
return_response=True,
)
assert response == {"forecast": []}
assert response == expected
assert "Only valid keys in Forecast are allowed" in caplog.text
@pytest.mark.parametrize(
("service", "expected"),
[
(SERVICE_GET_FORECASTS, {"weather.forecast": {"forecast": []}}),
(LEGACY_SERVICE_GET_FORECAST, {"forecast": []}),
],
)
@pytest.mark.parametrize(("count", "domain"), [(1, WEATHER_DOMAIN)])
@pytest.mark.parametrize(
"config",
@ -311,6 +335,8 @@ async def test_forecast_invalid_is_daytime_missing_in_twice_daily(
hass: HomeAssistant,
start_ha,
caplog: pytest.LogCaptureFixture,
service: str,
expected: dict[str, Any],
) -> None:
"""Test forecast service invalid when is_daytime missing in twice_daily forecast."""
for attr, _v_attr, value in [
@ -340,15 +366,22 @@ async def test_forecast_invalid_is_daytime_missing_in_twice_daily(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{"entity_id": "weather.forecast", "type": "twice_daily"},
blocking=True,
return_response=True,
)
assert response == {"forecast": []}
assert response == expected
assert "`is_daytime` is missing in twice_daily forecast" in caplog.text
@pytest.mark.parametrize(
("service", "expected"),
[
(SERVICE_GET_FORECASTS, {"weather.forecast": {"forecast": []}}),
(LEGACY_SERVICE_GET_FORECAST, {"forecast": []}),
],
)
@pytest.mark.parametrize(("count", "domain"), [(1, WEATHER_DOMAIN)])
@pytest.mark.parametrize(
"config",
@ -372,6 +405,8 @@ async def test_forecast_invalid_datetime_missing(
hass: HomeAssistant,
start_ha,
caplog: pytest.LogCaptureFixture,
service: str,
expected: dict[str, Any],
) -> None:
"""Test forecast service invalid when datetime missing."""
for attr, _v_attr, value in [
@ -401,15 +436,22 @@ async def test_forecast_invalid_datetime_missing(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{"entity_id": "weather.forecast", "type": "twice_daily"},
blocking=True,
return_response=True,
)
assert response == {"forecast": []}
assert response == expected
assert "`datetime` is required in forecasts" in caplog.text
@pytest.mark.parametrize(
("service"),
[
SERVICE_GET_FORECASTS,
LEGACY_SERVICE_GET_FORECAST,
],
)
@pytest.mark.parametrize(("count", "domain"), [(1, WEATHER_DOMAIN)])
@pytest.mark.parametrize(
"config",
@ -431,7 +473,7 @@ async def test_forecast_invalid_datetime_missing(
],
)
async def test_forecast_format_error(
hass: HomeAssistant, start_ha, caplog: pytest.LogCaptureFixture
hass: HomeAssistant, start_ha, caplog: pytest.LogCaptureFixture, service: str
) -> None:
"""Test forecast service invalid on incorrect format."""
for attr, _v_attr, value in [
@ -467,7 +509,7 @@ async def test_forecast_format_error(
await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{"entity_id": "weather.forecast", "type": "daily"},
blocking=True,
return_response=True,
@ -475,7 +517,7 @@ async def test_forecast_format_error(
assert "Forecasts is not a list, see Weather documentation" in caplog.text
await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{"entity_id": "weather.forecast", "type": "hourly"},
blocking=True,
return_response=True,
@ -638,6 +680,13 @@ async def test_trigger_action(
assert state.context is context
@pytest.mark.parametrize(
("service"),
[
SERVICE_GET_FORECASTS,
LEGACY_SERVICE_GET_FORECAST,
],
)
@pytest.mark.parametrize(("count", "domain"), [(1, "template")])
@pytest.mark.parametrize(
"config",
@ -694,6 +743,7 @@ async def test_trigger_weather_services(
start_ha,
entity_registry: er.EntityRegistry,
snapshot: SnapshotAssertion,
service: str,
) -> None:
"""Test trigger weather entity with services."""
state = hass.states.get("weather.test")
@ -756,7 +806,7 @@ async def test_trigger_weather_services(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": state.entity_id,
"type": "daily",
@ -768,7 +818,7 @@ async def test_trigger_weather_services(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": state.entity_id,
"type": "hourly",
@ -780,7 +830,7 @@ async def test_trigger_weather_services(
response = await hass.services.async_call(
WEATHER_DOMAIN,
SERVICE_GET_FORECAST,
service,
{
"entity_id": state.entity_id,
"type": "twice_daily",