Remove notify support for templates (#122820)

This commit is contained in:
Whitney Young 2024-09-08 08:31:58 -07:00 committed by GitHub
parent 6967c70580
commit 8d0dda6523
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 15 additions and 79 deletions

View file

@ -18,7 +18,6 @@ import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import EntityDescription
from homeassistant.helpers.entity_component import EntityComponent
from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.helpers.template import Template
from homeassistant.helpers.typing import ConfigType
from homeassistant.util import dt as dt_util
@ -39,7 +38,6 @@ from .legacy import ( # noqa: F401
async_reload,
async_reset_platform,
async_setup_legacy,
check_templates_warn,
)
from .repairs import migrate_notify_issue # noqa: F401
@ -90,22 +88,14 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
async def persistent_notification(service: ServiceCall) -> None:
"""Send notification via the built-in persistent_notify integration."""
message: Template = service.data[ATTR_MESSAGE]
check_templates_warn(hass, message)
title = None
title_tpl: Template | None
if title_tpl := service.data.get(ATTR_TITLE):
check_templates_warn(hass, title_tpl)
title = title_tpl.async_render(parse_result=False)
message: str = service.data[ATTR_MESSAGE]
title: str | None = service.data.get(ATTR_TITLE)
notification_id = None
if data := service.data.get(ATTR_DATA):
notification_id = data.get(pn.ATTR_NOTIFICATION_ID)
pn.async_create(
hass, message.async_render(parse_result=False), title, notification_id
)
pn.async_create(hass, message, title, notification_id)
hass.services.async_register(
DOMAIN,

View file

@ -30,8 +30,8 @@ SERVICE_PERSISTENT_NOTIFICATION = "persistent_notification"
NOTIFY_SERVICE_SCHEMA = vol.Schema(
{
vol.Required(ATTR_MESSAGE): cv.template,
vol.Optional(ATTR_TITLE): cv.template,
vol.Required(ATTR_MESSAGE): cv.string,
vol.Optional(ATTR_TITLE): cv.string,
vol.Optional(ATTR_TARGET): vol.All(cv.ensure_list, [cv.string]),
vol.Optional(ATTR_DATA): dict,
}

View file

@ -13,7 +13,6 @@ from homeassistant.core import HomeAssistant, ServiceCall, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import discovery
from homeassistant.helpers.service import async_set_service_schema
from homeassistant.helpers.template import Template
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.loader import async_get_integration, bind_hass
from homeassistant.setup import (
@ -155,19 +154,6 @@ def async_setup_legacy(
]
@callback
def check_templates_warn(hass: HomeAssistant, tpl: Template) -> None:
"""Warn user that passing templates to notify service is deprecated."""
if tpl.is_static or hass.data.get("notify_template_warned"):
return
hass.data["notify_template_warned"] = True
LOGGER.warning(
"Passing templates to notify service is deprecated and will be removed in"
" 2021.12. Automations and scripts handle templates automatically"
)
@bind_hass
async def async_reload(hass: HomeAssistant, integration_name: str) -> None:
"""Register notify services for an integration."""
@ -255,19 +241,17 @@ class BaseNotificationService:
async def _async_notify_message_service(self, service: ServiceCall) -> None:
"""Handle sending notification message service calls."""
kwargs = {}
message: Template = service.data[ATTR_MESSAGE]
title: Template | None
message: str = service.data[ATTR_MESSAGE]
title: str | None
if title := service.data.get(ATTR_TITLE):
check_templates_warn(self.hass, title)
kwargs[ATTR_TITLE] = title.async_render(parse_result=False)
kwargs[ATTR_TITLE] = title
if self.registered_targets.get(service.service) is not None:
kwargs[ATTR_TARGET] = [self.registered_targets[service.service]]
elif service.data.get(ATTR_TARGET) is not None:
kwargs[ATTR_TARGET] = service.data.get(ATTR_TARGET)
check_templates_warn(self.hass, message)
kwargs[ATTR_MESSAGE] = message.async_render(parse_result=False)
kwargs[ATTR_MESSAGE] = message
kwargs[ATTR_DATA] = service.data.get(ATTR_DATA)
await self.async_send_message(**kwargs)

View file

@ -165,8 +165,7 @@ async def test_login_flow_validates_mfa(hass: HomeAssistant) -> None:
assert notify_call.domain == "notify"
assert notify_call.service == "test-notify"
message = notify_call.data["message"]
message.hass = hass
assert MOCK_CODE in message.async_render()
assert MOCK_CODE in message
with patch("pyotp.HOTP.verify", return_value=False):
result = await hass.auth.login_flow.async_configure(
@ -224,8 +223,7 @@ async def test_login_flow_validates_mfa(hass: HomeAssistant) -> None:
assert notify_call.domain == "notify"
assert notify_call.service == "test-notify"
message = notify_call.data["message"]
message.hass = hass
assert MOCK_CODE in message.async_render()
assert MOCK_CODE in message
with patch("pyotp.HOTP.verify", return_value=True):
result = await hass.auth.login_flow.async_configure(
@ -264,8 +262,7 @@ async def test_setup_user_notify_service(hass: HomeAssistant) -> None:
assert notify_call.domain == "notify"
assert notify_call.service == "test1"
message = notify_call.data["message"]
message.hass = hass
assert MOCK_CODE in message.async_render()
assert MOCK_CODE in message
with patch("pyotp.HOTP.at", return_value=MOCK_CODE_2):
step = await flow.async_step_setup({"code": "invalid"})
@ -281,8 +278,7 @@ async def test_setup_user_notify_service(hass: HomeAssistant) -> None:
assert notify_call.domain == "notify"
assert notify_call.service == "test1"
message = notify_call.data["message"]
message.hass = hass
assert MOCK_CODE_2 in message.async_render()
assert MOCK_CODE_2 in message
with patch("pyotp.HOTP.verify", return_value=True):
step = await flow.async_step_setup({"code": MOCK_CODE_2})

View file

@ -19,7 +19,7 @@ from homeassistant.helpers.reload import async_setup_reload_service
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.setup import async_setup_component
from tests.common import MockPlatform, async_get_persistent_notifications, mock_platform
from tests.common import MockPlatform, mock_platform
class NotificationService(notify.BaseNotificationService):
@ -186,24 +186,6 @@ async def test_remove_targets(hass: HomeAssistant) -> None:
assert test.registered_targets == {"test_c": 1}
async def test_warn_template(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test warning when template used."""
assert await async_setup_component(hass, "notify", {})
await hass.services.async_call(
"notify",
"persistent_notification",
{"message": "{{ 1 + 1 }}", "title": "Test notif {{ 1 + 1 }}"},
blocking=True,
)
# We should only log it once
assert caplog.text.count("Passing templates to notify service is deprecated") == 1
notifications = async_get_persistent_notifications(hass)
assert len(notifications) == 1
async def test_invalid_platform(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture, tmp_path: Path
) -> None:
@ -550,27 +532,11 @@ async def test_sending_none_message(hass: HomeAssistant, tmp_path: Path) -> None
notify.DOMAIN, notify.SERVICE_NOTIFY, {notify.ATTR_MESSAGE: None}
)
assert (
str(exc.value)
== "template value is None for dictionary value @ data['message']"
str(exc.value) == "string value is None for dictionary value @ data['message']"
)
send_message_mock.assert_not_called()
async def test_sending_templated_message(hass: HomeAssistant, tmp_path: Path) -> None:
"""Send a templated message."""
send_message_mock = await help_setup_notify(hass, tmp_path)
hass.states.async_set("sensor.temperature", 10)
data = {
notify.ATTR_MESSAGE: "{{states.sensor.temperature.state}}",
notify.ATTR_TITLE: "{{ states.sensor.temperature.name }}",
}
await hass.services.async_call(notify.DOMAIN, notify.SERVICE_NOTIFY, data)
await hass.async_block_till_done()
send_message_mock.assert_called_once_with(
"10", {"title": "temperature", "data": None}
)
async def test_method_forwards_correct_data(
hass: HomeAssistant, tmp_path: Path
) -> None: