Files
core/tests/components/simplepush/test_notify.py
T

200 lines
5.7 KiB
Python

"""Test Simplepush notifications."""
from collections.abc import Generator
from typing import Any
from unittest.mock import MagicMock, patch
import pytest
from simplepush import BadRequest, UnknownError
from homeassistant.components.notify import DOMAIN as NOTIFY_DOMAIN
from homeassistant.components.simplepush.const import CONF_DEVICE_KEY, CONF_SALT, DOMAIN
from homeassistant.const import CONF_NAME, CONF_PASSWORD
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
from homeassistant.setup import async_setup_component
from tests.common import MockConfigEntry
MOCK_CONFIG = {
CONF_DEVICE_KEY: "abc",
CONF_NAME: "simplepush",
}
SERVICE_NAME = "simplepush"
@pytest.fixture
def mock_send() -> Generator[MagicMock]:
"""Mock the simplepush send call."""
with patch("homeassistant.components.simplepush.notify.send") as mock:
yield mock
async def setup_config_entry(hass: HomeAssistant, data: dict[str, str]) -> None:
"""Set up the simplepush integration."""
entry = MockConfigEntry(domain=DOMAIN, data=data)
entry.add_to_hass(hass)
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert hass.services.has_service(NOTIFY_DOMAIN, SERVICE_NAME)
@pytest.mark.parametrize(
("service_data", "expected_attachments", "expected_event"),
[
pytest.param({}, None, None, id="message_only"),
pytest.param({"data": {"event": "event"}}, None, "event", id="event_in_data"),
pytest.param(
{"data": {"attachments": "image.jpg"}},
None,
None,
id="attachments_not_a_list",
),
pytest.param(
{"data": {"attachments": [{"image": "image.jpg"}]}},
["image.jpg"],
None,
id="image_attachment",
),
pytest.param(
{"data": {"attachments": [{"video": "video.mp4"}]}},
["video.mp4"],
None,
id="video_attachment",
),
pytest.param(
{
"data": {
"attachments": [{"video": "video.mp4", "thumbnail": "thumb.jpg"}]
}
},
[{"video": "video.mp4", "thumbnail": "thumb.jpg"}],
None,
id="video_attachment_with_thumbnail",
),
],
)
async def test_send_message(
hass: HomeAssistant,
mock_send: MagicMock,
service_data: dict[str, Any],
expected_attachments: list[Any] | None,
expected_event: str | None,
) -> None:
"""Test sending a message."""
await setup_config_entry(hass, MOCK_CONFIG)
await hass.services.async_call(
NOTIFY_DOMAIN,
SERVICE_NAME,
{"message": "Hello", **service_data},
blocking=True,
)
mock_send.assert_called_once_with(
key="abc",
title="Home Assistant",
message="Hello",
attachments=expected_attachments,
event=expected_event,
)
async def test_send_message_with_password(
hass: HomeAssistant, mock_send: MagicMock
) -> None:
"""Test sending a message with an encryption password."""
await setup_config_entry(
hass, {**MOCK_CONFIG, CONF_PASSWORD: "password", CONF_SALT: "salt"}
)
await hass.services.async_call(
NOTIFY_DOMAIN,
SERVICE_NAME,
{"message": "Hello"},
blocking=True,
)
mock_send.assert_called_once_with(
key="abc",
password="password",
salt="salt",
title="Home Assistant",
message="Hello",
attachments=None,
event=None,
)
async def test_send_message_with_invalid_attachment(
hass: HomeAssistant, mock_send: MagicMock, caplog: pytest.LogCaptureFixture
) -> None:
"""Test that an invalid attachment format sends nothing."""
await setup_config_entry(hass, MOCK_CONFIG)
await hass.services.async_call(
NOTIFY_DOMAIN,
SERVICE_NAME,
{"message": "Hello", "data": {"attachments": [{"file": "image.jpg"}]}},
blocking=True,
)
assert "Attachment format is incorrect" in caplog.text
mock_send.assert_not_called()
@pytest.mark.parametrize(
("side_effect", "expected_exception", "translation_key"),
[
pytest.param(
BadRequest,
ServiceValidationError,
"title_or_message_too_long",
id="bad_request",
),
pytest.param(
UnknownError,
HomeAssistantError,
"send_message_failed",
id="unknown_error",
),
],
)
async def test_send_message_error(
hass: HomeAssistant,
mock_send: MagicMock,
side_effect: type[Exception],
expected_exception: type[HomeAssistantError],
translation_key: str,
) -> None:
"""Test that a failing send raises the correct exception."""
await setup_config_entry(hass, MOCK_CONFIG)
mock_send.side_effect = side_effect
with pytest.raises(expected_exception) as exc_info:
await hass.services.async_call(
NOTIFY_DOMAIN,
SERVICE_NAME,
{"message": "Hello"},
blocking=True,
)
assert exc_info.value.translation_domain == DOMAIN
assert exc_info.value.translation_key == translation_key
async def test_no_discovery_info(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test setup of the legacy platform without discovery info."""
assert await async_setup_component(
hass,
NOTIFY_DOMAIN,
{NOTIFY_DOMAIN: {"platform": DOMAIN}},
)
await hass.async_block_till_done()
assert f"Failed to initialize notification service {DOMAIN}" in caplog.text
assert not hass.services.has_service(NOTIFY_DOMAIN, SERVICE_NAME)