Skip to content

Commit

Permalink
Make legacy notify group tests independent of demo platform (home-ass…
Browse files Browse the repository at this point in the history
  • Loading branch information
jbouwh authored Apr 13, 2024
1 parent 27f6a7d commit 38c7b99
Showing 1 changed file with 139 additions and 75 deletions.
214 changes: 139 additions & 75 deletions tests/components/group/test_notify.py
Original file line number Diff line number Diff line change
@@ -1,58 +1,105 @@
"""The tests for the notify.group platform."""

from unittest.mock import MagicMock, patch
from collections.abc import Mapping
from pathlib import Path
from typing import Any
from unittest.mock import MagicMock, call, patch

from homeassistant import config as hass_config
from homeassistant.components import notify
import homeassistant.components.demo.notify as demo
from homeassistant.components.group import SERVICE_RELOAD
import homeassistant.components.group.notify as group
from homeassistant.core import HomeAssistant
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.setup import async_setup_component

from tests.common import get_fixture_path


async def test_send_message_with_data(hass: HomeAssistant) -> None:
"""Test sending a message with to a notify group."""
service1 = demo.DemoNotificationService(hass)
service2 = demo.DemoNotificationService(hass)
from tests.common import MockPlatform, get_fixture_path, mock_platform


class MockNotifyPlatform(MockPlatform):
"""Help to set up a legacy test notify platform."""

def __init__(self, async_get_service: Any) -> None:
"""Initialize platform."""
super().__init__()
self.async_get_service = async_get_service


def mock_notify_platform(
hass: HomeAssistant,
tmp_path: Path,
async_get_service: Any = None,
):
"""Specialize the mock platform for legacy notify service."""
loaded_platform = MockNotifyPlatform(async_get_service)
mock_platform(hass, "test.notify", loaded_platform)

return loaded_platform


async def help_setup_notify(
hass: HomeAssistant,
tmp_path: Path,
targets: dict[str, None] | None = None,
group_setup: list[dict[str, None]] | None = None,
) -> MagicMock:
"""Help set up a platform notify service."""
send_message_mock = MagicMock()

class _TestNotifyService(notify.BaseNotificationService):
def __init__(self, targets: dict[str, None] | None) -> None:
"""Initialize service."""
self._targets = targets
super().__init__()

@property
def targets(self) -> Mapping[str, Any] | None:
"""Return a dictionary of registered targets."""
return self._targets

def send_message(self, message: str, **kwargs: Any) -> None:
"""Send a message."""
send_message_mock(message, kwargs)

async def async_get_service(
hass: HomeAssistant,
config: ConfigType,
discovery_info: DiscoveryInfoType | None = None,
) -> notify.BaseNotificationService:
"""Get notify service for mocked platform."""
return _TestNotifyService(targets)

# Mock platform with service
mock_notify_platform(hass, tmp_path, async_get_service=async_get_service)
# Setup the platform
items: list[dict[str, Any]] = [{"platform": "test"}]
items.extend(group_setup or [])
await async_setup_component(hass, "notify", {"notify": items})
await hass.async_block_till_done()

service1.send_message = MagicMock(autospec=True)
service2.send_message = MagicMock(autospec=True)
# Return mock for assertion service calls
return send_message_mock

def mock_get_service(hass, config, discovery_info=None):
if config["name"] == "demo1":
return service1
return service2

async def test_send_message_with_data(hass: HomeAssistant, tmp_path: Path) -> None:
"""Test sending a message with to a notify group."""
send_message_mock = await help_setup_notify(
hass, tmp_path, {"service1": 1, "service2": 2}
)
assert await async_setup_component(
hass,
"group",
{},
)
await hass.async_block_till_done()

with patch.object(demo, "get_service", mock_get_service):
await async_setup_component(
hass,
notify.DOMAIN,
{
"notify": [
{"name": "demo1", "platform": "demo"},
{"name": "demo2", "platform": "demo"},
]
},
)
await hass.async_block_till_done()

service = await group.async_get_service(
hass,
{
"services": [
{"service": "demo1"},
{"service": "test_service1"},
{
"service": "demo2",
"service": "test_service2",
"data": {
"target": "unnamed device",
"data": {"test": "message", "default": "default"},
Expand All @@ -62,26 +109,35 @@ def mock_get_service(hass, config, discovery_info=None):
},
)

"""Test sending a message to a notify group."""
# Test sending a message to a notify group.
await service.async_send_message(
"Hello", title="Test notification", data={"hello": "world"}
)

await hass.async_block_till_done()
send_message_mock.assert_has_calls(
[
call(
"Hello",
{
"title": "Test notification",
"target": [1],
"data": {"hello": "world"},
},
),
call(
"Hello",
{
"title": "Test notification",
"target": [2],
"data": {"hello": "world", "test": "message", "default": "default"},
},
),
]
)
send_message_mock.reset_mock()

assert service1.send_message.mock_calls[0][1][0] == "Hello"
assert service1.send_message.mock_calls[0][2] == {
"title": "Test notification",
"data": {"hello": "world"},
}
assert service2.send_message.mock_calls[0][1][0] == "Hello"
assert service2.send_message.mock_calls[0][2] == {
"target": ["unnamed device"],
"title": "Test notification",
"data": {"hello": "world", "test": "message", "default": "default"},
}

"""Test sending a message which overrides service defaults to a notify group."""
# Test sending a message which overrides service defaults to a notify group
await service.async_send_message(
"Hello",
title="Test notification",
Expand All @@ -90,48 +146,56 @@ def mock_get_service(hass, config, discovery_info=None):

await hass.async_block_till_done()

assert service1.send_message.mock_calls[1][1][0] == "Hello"
assert service1.send_message.mock_calls[1][2] == {
"title": "Test notification",
"data": {"hello": "world", "default": "override"},
}
assert service2.send_message.mock_calls[1][1][0] == "Hello"
assert service2.send_message.mock_calls[1][2] == {
"target": ["unnamed device"],
"title": "Test notification",
"data": {"hello": "world", "test": "message", "default": "override"},
}
send_message_mock.assert_has_calls(
[
call(
"Hello",
{
"title": "Test notification",
"target": [1],
"data": {"hello": "world", "default": "override"},
},
),
call(
"Hello",
{
"title": "Test notification",
"target": [2],
"data": {
"hello": "world",
"test": "message",
"default": "override",
},
},
),
]
)


async def test_reload_notify(hass: HomeAssistant) -> None:
async def test_reload_notify(hass: HomeAssistant, tmp_path: Path) -> None:
"""Verify we can reload the notify service."""

assert await async_setup_component(
hass,
"group",
{},
)
await hass.async_block_till_done()

assert await async_setup_component(
await help_setup_notify(
hass,
notify.DOMAIN,
{
notify.DOMAIN: [
{"name": "demo1", "platform": "demo"},
{"name": "demo2", "platform": "demo"},
{
"name": "group_notify",
"platform": "group",
"services": [{"service": "demo1"}],
},
]
},
tmp_path,
{"service1": 1, "service2": 2},
[
{
"name": "group_notify",
"platform": "group",
"services": [{"service": "test_service1"}],
}
],
)
await hass.async_block_till_done()

assert hass.services.has_service(notify.DOMAIN, "demo1")
assert hass.services.has_service(notify.DOMAIN, "demo2")
assert hass.services.has_service(notify.DOMAIN, "test_service1")
assert hass.services.has_service(notify.DOMAIN, "test_service2")
assert hass.services.has_service(notify.DOMAIN, "group_notify")

yaml_path = get_fixture_path("configuration.yaml", "group")
Expand All @@ -145,7 +209,7 @@ async def test_reload_notify(hass: HomeAssistant) -> None:
)
await hass.async_block_till_done()

assert hass.services.has_service(notify.DOMAIN, "demo1")
assert hass.services.has_service(notify.DOMAIN, "demo2")
assert hass.services.has_service(notify.DOMAIN, "test_service1")
assert hass.services.has_service(notify.DOMAIN, "test_service2")
assert not hass.services.has_service(notify.DOMAIN, "group_notify")
assert hass.services.has_service(notify.DOMAIN, "new_group_notify")

0 comments on commit 38c7b99

Please sign in to comment.