From 10076e652353ac2959babb32fb790ac0630b218f Mon Sep 17 00:00:00 2001 From: Jan Bouwhuis <jbouwh@users.noreply.github.com> Date: Thu, 11 Apr 2024 12:04:08 +0200 Subject: [PATCH] Add notify entity component (#110950) * Add notify entity component * Device classes, restore state, icons * Add icons file * Add tests for kitchen_sink * Remove notify from no_entity_platforms in hassfest icons, translation link * ruff * Remove `data` feature * Only message support * Complete initial device classes * mypy pylint * Remove device_class implementation * format * Follow up comments * Remove _attr_supported_features * Use setup_test_component_platform * User helper at other places * last comment * Add entry unload test and non async test * Avoid default mutable object in constructor --- .../components/kitchen_sink/__init__.py | 3 +- .../components/kitchen_sink/notify.py | 54 ++++ homeassistant/components/notify/__init__.py | 92 ++++++- homeassistant/components/notify/const.py | 6 +- homeassistant/components/notify/icons.json | 8 +- homeassistant/components/notify/services.yaml | 10 + homeassistant/components/notify/strings.json | 15 ++ homeassistant/helpers/service.py | 2 + tests/components/kitchen_sink/test_notify.py | 66 +++++ tests/components/notify/conftest.py | 23 ++ tests/components/notify/test_init.py | 241 ++++++++++++++++-- 11 files changed, 494 insertions(+), 26 deletions(-) create mode 100644 homeassistant/components/kitchen_sink/notify.py create mode 100644 tests/components/kitchen_sink/test_notify.py create mode 100644 tests/components/notify/conftest.py diff --git a/homeassistant/components/kitchen_sink/__init__.py b/homeassistant/components/kitchen_sink/__init__.py index 6b6694c920d..94dfca77410 100644 --- a/homeassistant/components/kitchen_sink/__init__.py +++ b/homeassistant/components/kitchen_sink/__init__.py @@ -32,6 +32,7 @@ COMPONENTS_WITH_DEMO_PLATFORM = [ Platform.IMAGE, Platform.LAWN_MOWER, Platform.LOCK, + Platform.NOTIFY, Platform.SENSOR, Platform.SWITCH, Platform.WEATHER, @@ -70,7 +71,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b return True -def _create_issues(hass): +def _create_issues(hass: HomeAssistant) -> None: """Create some issue registry issues.""" async_create_issue( hass, diff --git a/homeassistant/components/kitchen_sink/notify.py b/homeassistant/components/kitchen_sink/notify.py new file mode 100644 index 00000000000..b0418411145 --- /dev/null +++ b/homeassistant/components/kitchen_sink/notify.py @@ -0,0 +1,54 @@ +"""Demo platform that offers a fake notify entity.""" + +from __future__ import annotations + +from homeassistant.components import persistent_notification +from homeassistant.components.notify import NotifyEntity +from homeassistant.config_entries import ConfigEntry +from homeassistant.core import HomeAssistant +from homeassistant.helpers.device_registry import DeviceInfo +from homeassistant.helpers.entity_platform import AddEntitiesCallback + +from . import DOMAIN + + +async def async_setup_entry( + hass: HomeAssistant, + config_entry: ConfigEntry, + async_add_entities: AddEntitiesCallback, +) -> None: + """Set up the demo notify entity platform.""" + async_add_entities( + [ + DemoNotify( + unique_id="just_notify_me", + device_name="MyBox", + entity_name="Personal notifier", + ), + ] + ) + + +class DemoNotify(NotifyEntity): + """Representation of a demo notify entity.""" + + _attr_has_entity_name = True + _attr_should_poll = False + + def __init__( + self, + unique_id: str, + device_name: str, + entity_name: str | None, + ) -> None: + """Initialize the Demo button entity.""" + self._attr_unique_id = unique_id + self._attr_device_info = DeviceInfo( + identifiers={(DOMAIN, unique_id)}, + name=device_name, + ) + self._attr_name = entity_name + + async def async_send_message(self, message: str) -> None: + """Send out a persistent notification.""" + persistent_notification.async_create(self.hass, message, "Demo notification") diff --git a/homeassistant/components/notify/__init__.py b/homeassistant/components/notify/__init__.py index e7390a49676..81b7d300acc 100644 --- a/homeassistant/components/notify/__init__.py +++ b/homeassistant/components/notify/__init__.py @@ -2,24 +2,36 @@ from __future__ import annotations +from datetime import timedelta +from functools import cached_property, partial +import logging +from typing import Any, final, override + import voluptuous as vol import homeassistant.components.persistent_notification as pn -from homeassistant.const import CONF_NAME, CONF_PLATFORM +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_NAME, CONF_PLATFORM, STATE_UNAVAILABLE from homeassistant.core import HomeAssistant, ServiceCall 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 from .const import ( # noqa: F401 ATTR_DATA, ATTR_MESSAGE, + ATTR_RECIPIENTS, ATTR_TARGET, ATTR_TITLE, DOMAIN, NOTIFY_SERVICE_SCHEMA, SERVICE_NOTIFY, SERVICE_PERSISTENT_NOTIFICATION, + SERVICE_SEND_MESSAGE, ) from .legacy import ( # noqa: F401 BaseNotificationService, @@ -29,9 +41,17 @@ from .legacy import ( # noqa: F401 check_templates_warn, ) +# mypy: disallow-any-generics + # Platform specific data ATTR_TITLE_DEFAULT = "Home Assistant" +ENTITY_ID_FORMAT = DOMAIN + ".{}" + +MIN_TIME_BETWEEN_SCANS = timedelta(seconds=10) + +_LOGGER = logging.getLogger(__name__) + PLATFORM_SCHEMA = vol.Schema( {vol.Required(CONF_PLATFORM): cv.string, vol.Optional(CONF_NAME): cv.string}, extra=vol.ALLOW_EXTRA, @@ -50,6 +70,13 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # legacy platforms to finish setting up. hass.async_create_task(setup, eager_start=True) + component = hass.data[DOMAIN] = EntityComponent[NotifyEntity](_LOGGER, DOMAIN, hass) + component.async_register_entity_service( + SERVICE_SEND_MESSAGE, + {vol.Required(ATTR_MESSAGE): cv.string}, + "_async_send_message", + ) + async def persistent_notification(service: ServiceCall) -> None: """Send notification via the built-in persistent_notify integration.""" message: Template = service.data[ATTR_MESSAGE] @@ -79,3 +106,66 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: ) return True + + +class NotifyEntityDescription(EntityDescription, frozen_or_thawed=True): + """A class that describes button entities.""" + + +async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: + """Set up a config entry.""" + component: EntityComponent[NotifyEntity] = hass.data[DOMAIN] + return await component.async_setup_entry(entry) + + +async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: + """Unload a config entry.""" + component: EntityComponent[NotifyEntity] = hass.data[DOMAIN] + return await component.async_unload_entry(entry) + + +class NotifyEntity(RestoreEntity): + """Representation of a notify entity.""" + + entity_description: NotifyEntityDescription + _attr_should_poll = False + _attr_device_class: None + _attr_state: None = None + __last_notified_isoformat: str | None = None + + @cached_property + @final + @override + def state(self) -> str | None: + """Return the entity state.""" + return self.__last_notified_isoformat + + def __set_state(self, state: str | None) -> None: + """Invalidate the cache of the cached property.""" + self.__dict__.pop("state", None) + self.__last_notified_isoformat = state + + async def async_internal_added_to_hass(self) -> None: + """Call when the notify entity is added to hass.""" + await super().async_internal_added_to_hass() + state = await self.async_get_last_state() + if state is not None and state.state not in (STATE_UNAVAILABLE, None): + self.__set_state(state.state) + + @final + async def _async_send_message(self, **kwargs: Any) -> None: + """Send a notification message (from e.g., service call). + + Should not be overridden, handle setting last notification timestamp. + """ + self.__set_state(dt_util.utcnow().isoformat()) + self.async_write_ha_state() + await self.async_send_message(**kwargs) + + def send_message(self, message: str) -> None: + """Send a message.""" + raise NotImplementedError + + async def async_send_message(self, message: str) -> None: + """Send a message.""" + await self.hass.async_add_executor_job(partial(self.send_message, message)) diff --git a/homeassistant/components/notify/const.py b/homeassistant/components/notify/const.py index b653b5d1cbf..6cd957e3afe 100644 --- a/homeassistant/components/notify/const.py +++ b/homeassistant/components/notify/const.py @@ -11,9 +11,12 @@ ATTR_DATA = "data" # Text to notify user of ATTR_MESSAGE = "message" -# Target of the notification (user, device, etc) +# Target of the (legacy) notification (user, device, etc) ATTR_TARGET = "target" +# Recipients for a notification +ATTR_RECIPIENTS = "recipients" + # Title of notification ATTR_TITLE = "title" @@ -22,6 +25,7 @@ DOMAIN = "notify" LOGGER = logging.getLogger(__package__) SERVICE_NOTIFY = "notify" +SERVICE_SEND_MESSAGE = "send_message" SERVICE_PERSISTENT_NOTIFICATION = "persistent_notification" NOTIFY_SERVICE_SCHEMA = vol.Schema( diff --git a/homeassistant/components/notify/icons.json b/homeassistant/components/notify/icons.json index 88577bc2356..ace8ee0c96b 100644 --- a/homeassistant/components/notify/icons.json +++ b/homeassistant/components/notify/icons.json @@ -1,6 +1,12 @@ { + "entity_component": { + "_": { + "default": "mdi:message" + } + }, "services": { "notify": "mdi:bell-ring", - "persistent_notification": "mdi:bell-badge" + "persistent_notification": "mdi:bell-badge", + "send_message": "mdi:message-arrow-right" } } diff --git a/homeassistant/components/notify/services.yaml b/homeassistant/components/notify/services.yaml index 8d053e3af58..ae2a0254761 100644 --- a/homeassistant/components/notify/services.yaml +++ b/homeassistant/components/notify/services.yaml @@ -20,6 +20,16 @@ notify: selector: object: +send_message: + target: + entity: + domain: notify + fields: + message: + required: true + selector: + text: + persistent_notification: fields: message: diff --git a/homeassistant/components/notify/strings.json b/homeassistant/components/notify/strings.json index cff7b265c37..b0dca501509 100644 --- a/homeassistant/components/notify/strings.json +++ b/homeassistant/components/notify/strings.json @@ -1,5 +1,10 @@ { "title": "Notifications", + "entity_component": { + "_": { + "name": "[%key:component::notify::title%]" + } + }, "services": { "notify": { "name": "Send a notification", @@ -23,6 +28,16 @@ } } }, + "send_message": { + "name": "Send a notification message", + "description": "Sends a notification message.", + "fields": { + "message": { + "name": "Message", + "description": "Your notification message." + } + } + }, "persistent_notification": { "name": "Send a persistent notification", "description": "Sends a notification that is visible in the **Notifications** panel.", diff --git a/homeassistant/helpers/service.py b/homeassistant/helpers/service.py index 9af02402bc0..31e0d3648db 100644 --- a/homeassistant/helpers/service.py +++ b/homeassistant/helpers/service.py @@ -93,6 +93,7 @@ def _base_components() -> dict[str, ModuleType]: light, lock, media_player, + notify, remote, siren, todo, @@ -112,6 +113,7 @@ def _base_components() -> dict[str, ModuleType]: "light": light, "lock": lock, "media_player": media_player, + "notify": notify, "remote": remote, "siren": siren, "todo": todo, diff --git a/tests/components/kitchen_sink/test_notify.py b/tests/components/kitchen_sink/test_notify.py new file mode 100644 index 00000000000..6d02bacb7be --- /dev/null +++ b/tests/components/kitchen_sink/test_notify.py @@ -0,0 +1,66 @@ +"""The tests for the demo button component.""" + +from collections.abc import AsyncGenerator +from unittest.mock import patch + +from freezegun.api import FrozenDateTimeFactory +import pytest + +from homeassistant.components.kitchen_sink import DOMAIN +from homeassistant.components.notify import ( + DOMAIN as NOTIFY_DOMAIN, + SERVICE_SEND_MESSAGE, +) +from homeassistant.components.notify.const import ATTR_MESSAGE +from homeassistant.const import ATTR_ENTITY_ID, STATE_UNKNOWN, Platform +from homeassistant.core import HomeAssistant +from homeassistant.setup import async_setup_component +from homeassistant.util import dt as dt_util + +ENTITY_DIRECT_MESSAGE = "notify.mybox_personal_notifier" + + +@pytest.fixture +async def notify_only() -> AsyncGenerator[None, None]: + """Enable only the button platform.""" + with patch( + "homeassistant.components.kitchen_sink.COMPONENTS_WITH_DEMO_PLATFORM", + [Platform.NOTIFY], + ): + yield + + +@pytest.fixture(autouse=True) +async def setup_comp(hass: HomeAssistant, notify_only: None): + """Set up demo component.""" + assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}}) + await hass.async_block_till_done() + + +def test_setup_params(hass: HomeAssistant) -> None: + """Test the initial parameters.""" + state = hass.states.get(ENTITY_DIRECT_MESSAGE) + assert state + assert state.state == STATE_UNKNOWN + + +async def test_send_message( + hass: HomeAssistant, freezer: FrozenDateTimeFactory +) -> None: + """Test pressing the button.""" + state = hass.states.get(ENTITY_DIRECT_MESSAGE) + assert state + assert state.state == STATE_UNKNOWN + + now = dt_util.parse_datetime("2021-01-09 12:00:00+00:00") + freezer.move_to(now) + await hass.services.async_call( + NOTIFY_DOMAIN, + SERVICE_SEND_MESSAGE, + {ATTR_ENTITY_ID: ENTITY_DIRECT_MESSAGE, ATTR_MESSAGE: "You have an update!"}, + blocking=True, + ) + + state = hass.states.get(ENTITY_DIRECT_MESSAGE) + assert state + assert state.state == now.isoformat() diff --git a/tests/components/notify/conftest.py b/tests/components/notify/conftest.py new file mode 100644 index 00000000000..23930132f7b --- /dev/null +++ b/tests/components/notify/conftest.py @@ -0,0 +1,23 @@ +"""Fixtures for Notify platform tests.""" + +from collections.abc import Generator + +import pytest + +from homeassistant.config_entries import ConfigFlow +from homeassistant.core import HomeAssistant + +from tests.common import mock_config_flow, mock_platform + + +class MockFlow(ConfigFlow): + """Test flow.""" + + +@pytest.fixture +def config_flow_fixture(hass: HomeAssistant) -> Generator[None, None, None]: + """Mock config flow.""" + mock_platform(hass, "test.config_flow") + + with mock_config_flow("test", MockFlow): + yield diff --git a/tests/components/notify/test_init.py b/tests/components/notify/test_init.py index 0b75a3c4691..26ed2ddc250 100644 --- a/tests/components/notify/test_init.py +++ b/tests/components/notify/test_init.py @@ -1,28 +1,216 @@ """The tests for notify services that change targets.""" import asyncio +import copy from pathlib import Path -from unittest.mock import Mock, patch +from typing import Any +from unittest.mock import MagicMock, Mock, patch import pytest import yaml from homeassistant import config as hass_config from homeassistant.components import notify -from homeassistant.const import SERVICE_RELOAD, Platform -from homeassistant.core import HomeAssistant +from homeassistant.components.notify import ( + DOMAIN, + SERVICE_SEND_MESSAGE, + NotifyEntity, + NotifyEntityDescription, +) +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import ( + SERVICE_RELOAD, + STATE_UNAVAILABLE, + STATE_UNKNOWN, + Platform, +) +from homeassistant.core import HomeAssistant, State from homeassistant.helpers.discovery import async_load_platform from homeassistant.helpers.reload import async_setup_reload_service from homeassistant.setup import async_setup_component -from tests.common import MockPlatform, async_get_persistent_notifications, mock_platform +from tests.common import ( + MockConfigEntry, + MockEntity, + MockModule, + MockPlatform, + async_get_persistent_notifications, + mock_integration, + mock_platform, + mock_restore_cache, + setup_test_component_platform, +) + +TEST_KWARGS = {"message": "Test message"} + + +class MockNotifyEntity(MockEntity, NotifyEntity): + """Mock Email notitier entity to use in tests.""" + + send_message_mock_calls = MagicMock() + + async def async_send_message(self, message: str) -> None: + """Send a notification message.""" + self.send_message_mock_calls(message=message) + + +class MockNotifyEntityNonAsync(MockEntity, NotifyEntity): + """Mock Email notitier entity to use in tests.""" + + send_message_mock_calls = MagicMock() + + def send_message(self, message: str) -> None: + """Send a notification message.""" + self.send_message_mock_calls(message=message) + + +async def help_async_setup_entry_init( + hass: HomeAssistant, config_entry: ConfigEntry +) -> bool: + """Set up test config entry.""" + await hass.config_entries.async_forward_entry_setup(config_entry, DOMAIN) + return True + + +async def help_async_unload_entry( + hass: HomeAssistant, config_entry: ConfigEntry +) -> bool: + """Unload test config emntry.""" + return await hass.config_entries.async_unload_platforms( + config_entry, [Platform.NOTIFY] + ) + + +@pytest.mark.parametrize( + "entity", + [ + MockNotifyEntityNonAsync(name="test", entity_id="notify.test"), + MockNotifyEntity(name="test", entity_id="notify.test"), + ], + ids=["non_async", "async"], +) +async def test_send_message_service( + hass: HomeAssistant, config_flow_fixture: None, entity: NotifyEntity +) -> None: + """Test send_message service.""" + + config_entry = MockConfigEntry(domain="test") + config_entry.add_to_hass(hass) + + mock_integration( + hass, + MockModule( + "test", + async_setup_entry=help_async_setup_entry_init, + async_unload_entry=help_async_unload_entry, + ), + ) + setup_test_component_platform(hass, DOMAIN, [entity], from_config_entry=True) + assert await hass.config_entries.async_setup(config_entry.entry_id) + + state = hass.states.get("notify.test") + assert state.state is STATE_UNKNOWN + + await hass.services.async_call( + DOMAIN, + SERVICE_SEND_MESSAGE, + copy.deepcopy(TEST_KWARGS) | {"entity_id": "notify.test"}, + blocking=True, + ) + await hass.async_block_till_done() + + entity.send_message_mock_calls.assert_called_once() + + # Test unloading the entry succeeds + assert await hass.config_entries.async_unload(config_entry.entry_id) + + +@pytest.mark.parametrize( + ("state", "init_state"), + [ + ("2021-01-01T23:59:59+00:00", "2021-01-01T23:59:59+00:00"), + (STATE_UNAVAILABLE, STATE_UNKNOWN), + ], +) +async def test_restore_state( + hass: HomeAssistant, config_flow_fixture: None, state: str, init_state: str +) -> None: + """Test we restore state integration.""" + mock_restore_cache(hass, (State("notify.test", state),)) + + mock_integration( + hass, + MockModule( + "test", + async_setup_entry=help_async_setup_entry_init, + ), + ) + + entity = MockNotifyEntity(name="test", entity_id="notify.test") + setup_test_component_platform(hass, DOMAIN, [entity], from_config_entry=True) + + config_entry = MockConfigEntry(domain="test") + config_entry.add_to_hass(hass) + assert await hass.config_entries.async_setup(config_entry.entry_id) + + state = hass.states.get("notify.test") + assert state is not None + assert state.state is init_state + + +async def test_name(hass: HomeAssistant, config_flow_fixture: None) -> None: + """Test notify name.""" + + mock_platform(hass, "test.config_flow") + mock_integration( + hass, + MockModule( + "test", + async_setup_entry=help_async_setup_entry_init, + ), + ) + + # Unnamed notify entity -> no name + entity1 = NotifyEntity() + entity1.entity_id = "notify.test1" + + # Unnamed notify entity and has_entity_name True -> unnamed + entity2 = NotifyEntity() + entity2.entity_id = "notify.test3" + entity2._attr_has_entity_name = True + + # Named notify entity and has_entity_name True -> named + entity3 = NotifyEntity() + entity3.entity_id = "notify.test4" + entity3.entity_description = NotifyEntityDescription("test", has_entity_name=True) + + setup_test_component_platform( + hass, DOMAIN, [entity1, entity2, entity3], from_config_entry=True + ) + + config_entry = MockConfigEntry(domain="test") + config_entry.add_to_hass(hass) + assert await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + state = hass.states.get(entity1.entity_id) + assert state + assert state.attributes == {} + + state = hass.states.get(entity2.entity_id) + assert state + assert state.attributes == {} + + state = hass.states.get(entity3.entity_id) + assert state + assert state.attributes == {} class MockNotifyPlatform(MockPlatform): - """Help to set up test notify service.""" + """Help to set up a legacy test notify service.""" - def __init__(self, async_get_service=None, get_service=None): - """Return the notify service.""" + def __init__(self, async_get_service: Any = None, get_service: Any = None) -> None: + """Return a legacy notify service.""" super().__init__() if get_service: self.get_service = get_service @@ -31,9 +219,13 @@ class MockNotifyPlatform(MockPlatform): def mock_notify_platform( - hass, tmp_path, integration="notify", async_get_service=None, get_service=None + hass: HomeAssistant, + tmp_path: Path, + integration: str = "notify", + async_get_service: Any = None, + get_service: Any = None, ): - """Specialize the mock platform for notify.""" + """Specialize the mock platform for legacy notify service.""" loaded_platform = MockNotifyPlatform(async_get_service, get_service) mock_platform(hass, f"{integration}.notify", loaded_platform) @@ -41,7 +233,7 @@ def mock_notify_platform( async def test_same_targets(hass: HomeAssistant) -> None: - """Test not changing the targets in a notify service.""" + """Test not changing the targets in a legacy notify service.""" test = NotificationService(hass) await test.async_setup(hass, "notify", "test") await test.async_register_services() @@ -56,7 +248,7 @@ async def test_same_targets(hass: HomeAssistant) -> None: async def test_change_targets(hass: HomeAssistant) -> None: - """Test changing the targets in a notify service.""" + """Test changing the targets in a legacy notify service.""" test = NotificationService(hass) await test.async_setup(hass, "notify", "test") await test.async_register_services() @@ -73,7 +265,7 @@ async def test_change_targets(hass: HomeAssistant) -> None: async def test_add_targets(hass: HomeAssistant) -> None: - """Test adding the targets in a notify service.""" + """Test adding the targets in a legacy notify service.""" test = NotificationService(hass) await test.async_setup(hass, "notify", "test") await test.async_register_services() @@ -90,7 +282,7 @@ async def test_add_targets(hass: HomeAssistant) -> None: async def test_remove_targets(hass: HomeAssistant) -> None: - """Test removing targets from the targets in a notify service.""" + """Test removing targets from the targets in a legacy notify service.""" test = NotificationService(hass) await test.async_setup(hass, "notify", "test") await test.async_register_services() @@ -107,17 +299,22 @@ async def test_remove_targets(hass: HomeAssistant) -> None: class NotificationService(notify.BaseNotificationService): - """A test class for notification services.""" - - def __init__(self, hass, target_list={"a": 1, "b": 2}, name="notify"): + """A test class for legacy notification services.""" + + def __init__( + self, + hass: HomeAssistant, + target_list: dict[str, Any] | None = None, + name="notify", + ) -> None: """Initialize the service.""" - async def _async_make_reloadable(hass): + async def _async_make_reloadable(hass: HomeAssistant) -> None: """Initialize the reload service.""" await async_setup_reload_service(hass, name, [notify.DOMAIN]) self.hass = hass - self.target_list = target_list + self.target_list = target_list or {"a": 1, "b": 2} hass.async_create_task(_async_make_reloadable(hass)) @property @@ -229,7 +426,7 @@ async def test_platform_setup_with_error( async def test_reload_with_notify_builtin_platform_reload( hass: HomeAssistant, caplog: pytest.LogCaptureFixture, tmp_path: Path ) -> None: - """Test reload using the notify platform reload method.""" + """Test reload using the legacy notify platform reload method.""" async def async_get_service(hass, config, discovery_info=None): """Get notify service for mocked platform.""" @@ -271,7 +468,7 @@ async def test_setup_platform_and_reload( return NotificationService(hass, targetlist, "testnotify") async def async_get_service2(hass, config, discovery_info=None): - """Get notify service for mocked platform.""" + """Get legacy notify service for mocked platform.""" get_service_called(config, discovery_info) targetlist = {"c": 3, "d": 4} return NotificationService(hass, targetlist, "testnotify2") @@ -351,7 +548,7 @@ async def test_setup_platform_and_reload( async def test_setup_platform_before_notify_setup( hass: HomeAssistant, caplog: pytest.LogCaptureFixture, tmp_path: Path ) -> None: - """Test trying to setup a platform before notify is setup.""" + """Test trying to setup a platform before legacy notify service is setup.""" get_service_called = Mock() async def async_get_service(hass, config, discovery_info=None): @@ -401,7 +598,7 @@ async def test_setup_platform_before_notify_setup( async def test_setup_platform_after_notify_setup( hass: HomeAssistant, caplog: pytest.LogCaptureFixture, tmp_path: Path ) -> None: - """Test trying to setup a platform after notify is setup.""" + """Test trying to setup a platform after legacy notify service is set up.""" get_service_called = Mock() async def async_get_service(hass, config, discovery_info=None): -- GitLab