Refactor slack tests (#45561)

* Refactor slack tests

* Changes

* Let service register for tests
This commit is contained in:
Marc Mueller 2021-01-27 04:32:14 +01:00 committed by GitHub
parent 25f411ef6e
commit c805baf88c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 82 additions and 47 deletions

View File

@ -1 +1,2 @@
"""The slack component.""" """The slack component."""
DOMAIN = "slack"

View File

@ -1,77 +1,111 @@
"""Test slack notifications.""" """Test slack notifications."""
import copy
import logging import logging
from typing import List
from unittest.mock import AsyncMock, Mock, patch from unittest.mock import AsyncMock, Mock, patch
from _pytest.logging import LogCaptureFixture from _pytest.logging import LogCaptureFixture
import aiohttp import aiohttp
from slack.errors import SlackApiError from slack.errors import SlackApiError
from homeassistant.components import notify
from homeassistant.components.slack import DOMAIN
from homeassistant.components.slack.notify import ( from homeassistant.components.slack.notify import (
CONF_DEFAULT_CHANNEL, CONF_DEFAULT_CHANNEL,
SlackNotificationService, SlackNotificationService,
async_get_service,
) )
from homeassistant.const import CONF_API_KEY, CONF_ICON, CONF_USERNAME from homeassistant.const import (
CONF_API_KEY,
CONF_ICON,
CONF_NAME,
CONF_PLATFORM,
CONF_USERNAME,
)
from homeassistant.helpers.typing import HomeAssistantType from homeassistant.helpers.typing import HomeAssistantType
from homeassistant.setup import async_setup_component
MODULE_PATH = "homeassistant.components.slack.notify" MODULE_PATH = "homeassistant.components.slack.notify"
SERVICE_NAME = f"notify_{DOMAIN}"
DEFAULT_CONFIG = {
notify.DOMAIN: [
{
CONF_PLATFORM: DOMAIN,
CONF_NAME: SERVICE_NAME,
CONF_API_KEY: "12345",
CONF_DEFAULT_CHANNEL: "channel",
}
]
}
async def test_get_service(hass: HomeAssistantType, caplog: LogCaptureFixture): def filter_log_records(caplog: LogCaptureFixture) -> List[logging.LogRecord]:
"""Test async_get_service with exceptions.""" """Filter all unrelated log records."""
config = { return [
CONF_API_KEY: "12345", rec for rec in caplog.records if rec.name.endswith(f"{DOMAIN}.{notify.DOMAIN}")
CONF_DEFAULT_CHANNEL: "channel", ]
}
with patch(MODULE_PATH + ".aiohttp_client") as mock_session, patch(
MODULE_PATH + ".WebClient"
) as mock_client, patch(
MODULE_PATH + ".SlackNotificationService"
) as mock_slack_service:
mock_session.async_get_clientsession.return_value = session = Mock()
mock_client.return_value = client = AsyncMock()
# Normal setup async def test_setup(hass: HomeAssistantType, caplog: LogCaptureFixture):
mock_slack_service.return_value = service = Mock() """Test setup slack notify."""
assert await async_get_service(hass, config) == service config = DEFAULT_CONFIG
mock_slack_service.assert_called_once_with(
hass, client, "channel", username=None, icon=None with patch(
) MODULE_PATH + ".aiohttp_client",
**{"async_get_clientsession.return_value": (session := Mock())},
), patch(
MODULE_PATH + ".WebClient",
return_value=(client := AsyncMock()),
) as mock_client:
await async_setup_component(hass, notify.DOMAIN, config)
await hass.async_block_till_done()
assert hass.services.has_service(notify.DOMAIN, SERVICE_NAME)
caplog_records_slack = filter_log_records(caplog)
assert len(caplog_records_slack) == 0
mock_client.assert_called_with(token="12345", run_async=True, session=session) mock_client.assert_called_with(token="12345", run_async=True, session=session)
client.auth_test.assert_called_once_with() client.auth_test.assert_called_once_with()
mock_slack_service.assert_called_once_with(
hass, client, "channel", username=None, icon=None
)
mock_slack_service.reset_mock()
# aiohttp.ClientError
config.update({CONF_USERNAME: "user", CONF_ICON: "icon"}) async def test_setup_clientError(hass: HomeAssistantType, caplog: LogCaptureFixture):
mock_slack_service.reset_mock() """Test setup slack notify with aiohttp.ClientError exception."""
mock_slack_service.return_value = service = Mock() config = copy.deepcopy(DEFAULT_CONFIG)
config[notify.DOMAIN][0].update({CONF_USERNAME: "user", CONF_ICON: "icon"})
with patch(
MODULE_PATH + ".aiohttp_client",
**{"async_get_clientsession.return_value": Mock()},
), patch(MODULE_PATH + ".WebClient", return_value=(client := AsyncMock())):
client.auth_test.side_effect = [aiohttp.ClientError] client.auth_test.side_effect = [aiohttp.ClientError]
assert await async_get_service(hass, config) == service await async_setup_component(hass, notify.DOMAIN, config)
assert len(caplog.records) == 1 await hass.async_block_till_done()
record = caplog.records[0] assert hass.services.has_service(notify.DOMAIN, SERVICE_NAME)
caplog_records_slack = filter_log_records(caplog)
assert len(caplog_records_slack) == 1
record = caplog_records_slack[0]
assert record.levelno == logging.WARNING assert record.levelno == logging.WARNING
assert aiohttp.ClientError.__qualname__ in record.message assert aiohttp.ClientError.__qualname__ in record.message
caplog.records.clear()
mock_slack_service.assert_called_once_with(
hass, client, "channel", username="user", icon="icon"
)
mock_slack_service.reset_mock()
# SlackApiError
err, level = SlackApiError("msg", "resp"), logging.ERROR async def test_setup_slackApiError(hass: HomeAssistantType, caplog: LogCaptureFixture):
client.auth_test.side_effect = [err] """Test setup slack notify with SlackApiError exception."""
assert await async_get_service(hass, config) is None config = DEFAULT_CONFIG
assert len(caplog.records) == 1
record = caplog.records[0] with patch(
assert record.levelno == level MODULE_PATH + ".aiohttp_client",
**{"async_get_clientsession.return_value": Mock()},
), patch(MODULE_PATH + ".WebClient", return_value=(client := AsyncMock())):
client.auth_test.side_effect = [err := SlackApiError("msg", "resp")]
await async_setup_component(hass, notify.DOMAIN, config)
await hass.async_block_till_done()
assert hass.services.has_service(notify.DOMAIN, SERVICE_NAME) is False
caplog_records_slack = filter_log_records(caplog)
assert len(caplog_records_slack) == 1
record = caplog_records_slack[0]
assert record.levelno == logging.ERROR
assert err.__class__.__qualname__ in record.message assert err.__class__.__qualname__ in record.message
caplog.records.clear()
mock_slack_service.assert_not_called()
mock_slack_service.reset_mock()
async def test_message_includes_default_emoji(): async def test_message_includes_default_emoji():