From c805baf88ce9a18809250b8c218431d4584dcb72 Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Wed, 27 Jan 2021 04:32:14 +0100 Subject: [PATCH] Refactor slack tests (#45561) * Refactor slack tests * Changes * Let service register for tests --- homeassistant/components/slack/__init__.py | 1 + tests/components/slack/test_notify.py | 128 +++++++++++++-------- 2 files changed, 82 insertions(+), 47 deletions(-) diff --git a/homeassistant/components/slack/__init__.py b/homeassistant/components/slack/__init__.py index a999c2375ff0..e3ae111f2ea8 100644 --- a/homeassistant/components/slack/__init__.py +++ b/homeassistant/components/slack/__init__.py @@ -1 +1,2 @@ """The slack component.""" +DOMAIN = "slack" diff --git a/tests/components/slack/test_notify.py b/tests/components/slack/test_notify.py index af3043651584..9fc6784a09e0 100644 --- a/tests/components/slack/test_notify.py +++ b/tests/components/slack/test_notify.py @@ -1,77 +1,111 @@ """Test slack notifications.""" +import copy import logging +from typing import List from unittest.mock import AsyncMock, Mock, patch from _pytest.logging import LogCaptureFixture import aiohttp from slack.errors import SlackApiError +from homeassistant.components import notify +from homeassistant.components.slack import DOMAIN from homeassistant.components.slack.notify import ( CONF_DEFAULT_CHANNEL, 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.setup import async_setup_component 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): - """Test async_get_service with exceptions.""" - config = { - CONF_API_KEY: "12345", - CONF_DEFAULT_CHANNEL: "channel", - } +def filter_log_records(caplog: LogCaptureFixture) -> List[logging.LogRecord]: + """Filter all unrelated log records.""" + return [ + rec for rec in caplog.records if rec.name.endswith(f"{DOMAIN}.{notify.DOMAIN}") + ] - 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 - mock_slack_service.return_value = service = Mock() - assert await async_get_service(hass, config) == service - mock_slack_service.assert_called_once_with( - hass, client, "channel", username=None, icon=None - ) +async def test_setup(hass: HomeAssistantType, caplog: LogCaptureFixture): + """Test setup slack notify.""" + config = DEFAULT_CONFIG + + 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) 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"}) - mock_slack_service.reset_mock() - mock_slack_service.return_value = service = Mock() + +async def test_setup_clientError(hass: HomeAssistantType, caplog: LogCaptureFixture): + """Test setup slack notify with aiohttp.ClientError exception.""" + 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] - assert await async_get_service(hass, config) == service - assert len(caplog.records) == 1 - record = caplog.records[0] + 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) == 1 + record = caplog_records_slack[0] assert record.levelno == logging.WARNING 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 - client.auth_test.side_effect = [err] - assert await async_get_service(hass, config) is None - assert len(caplog.records) == 1 - record = caplog.records[0] - assert record.levelno == level + +async def test_setup_slackApiError(hass: HomeAssistantType, caplog: LogCaptureFixture): + """Test setup slack notify with SlackApiError exception.""" + config = DEFAULT_CONFIG + + 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 = [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 - caplog.records.clear() - mock_slack_service.assert_not_called() - mock_slack_service.reset_mock() async def test_message_includes_default_emoji():