From d3aef2b4940def3642bb39af53c53caf2b1af348 Mon Sep 17 00:00:00 2001 From: Luke Date: Wed, 24 Jul 2024 16:26:06 +0000 Subject: [PATCH 1/4] Fix tests and change some objects --- custom_components/bermuda/__init__.py | 11 ++-- custom_components/bermuda/config_flow.py | 7 +-- tests/conftest.py | 32 +++++++++++ tests/test_config_flow.py | 30 ++-------- tests/test_init.py | 31 ++++------ tests/test_switch.py | 72 +++++++++++------------- 6 files changed, 90 insertions(+), 93 deletions(-) diff --git a/custom_components/bermuda/__init__.py b/custom_components/bermuda/__init__.py index 9ffefe8..907752f 100644 --- a/custom_components/bermuda/__init__.py +++ b/custom_components/bermuda/__init__.py @@ -8,7 +8,6 @@ from __future__ import annotations from homeassistant.config_entries import ConfigEntry -from homeassistant.core import Config from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.helpers import config_validation as cv @@ -35,11 +34,11 @@ CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN) -async def async_setup( - hass: HomeAssistant, config: Config -): # pylint: disable=unused-argument; - """Setting up this integration using YAML is not supported.""" - return True +# async def async_setup( +# hass: HomeAssistant, config: Config +# ): # pylint: disable=unused-argument; +# """Setting up this integration using YAML is not supported.""" +# return True async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): diff --git a/custom_components/bermuda/config_flow.py b/custom_components/bermuda/config_flow.py index a763aea..0ba2e10 100644 --- a/custom_components/bermuda/config_flow.py +++ b/custom_components/bermuda/config_flow.py @@ -7,6 +7,7 @@ from homeassistant.components.bluetooth import MONOTONIC_TIME from homeassistant.components.bluetooth import BluetoothServiceInfoBleak from homeassistant.config_entries import ConfigEntry +from homeassistant.config_entries import OptionsFlowWithConfigEntry from homeassistant.core import callback from homeassistant.data_entry_flow import FlowResult from homeassistant.helpers.selector import selector @@ -105,14 +106,12 @@ def async_get_options_flow(config_entry): # ) -class BermudaOptionsFlowHandler(config_entries.OptionsFlow): +class BermudaOptionsFlowHandler(OptionsFlowWithConfigEntry): """Config flow options handler for bermuda.""" def __init__(self, config_entry: ConfigEntry): """Initialize HACS options flow.""" - super().__init__() - self.config_entry = config_entry - self.options = dict(config_entry.options) + super().__init__(config_entry) self.coordinator: BermudaDataUpdateCoordinator self.devices: dict[str, BermudaDevice] diff --git a/tests/conftest.py b/tests/conftest.py index 34933c4..53439ef 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -5,6 +5,15 @@ from unittest.mock import patch import pytest +from homeassistant.core import HomeAssistant +from homeassistant.setup import async_setup_component +from pytest_homeassistant_custom_component.common import MockConfigEntry + +from custom_components.bermuda.const import DOMAIN +from custom_components.bermuda.const import NAME + +# from .const import MOCK_OPTIONS +from .const import MOCK_CONFIG # from custom_components.bermuda import BermudaDataUpdateCoordinator @@ -72,3 +81,26 @@ def error_get_data_fixture(): # """Simulate a discovered advertisement for config_flow""" # with patch("custom_components.bermuda.bluetooth.async_discovered_service_info"): # return SERVICE_INFOS + + +@pytest.fixture() +async def mock_bermuda_entry(hass: HomeAssistant): + """This creates a mock config entry""" + config_entry = MockConfigEntry( + domain=DOMAIN, data=MOCK_CONFIG, entry_id="test", title=NAME + ) + config_entry.add_to_hass(hass) + await hass.async_block_till_done() + return config_entry + + +@pytest.fixture() +async def setup_bermuda_entry(hass: HomeAssistant): + """This setups a entry so that it can be used.""" + config_entry = MockConfigEntry( + domain=DOMAIN, data=MOCK_CONFIG, entry_id="test", title=NAME + ) + config_entry.add_to_hass(hass) + await async_setup_component(hass, DOMAIN, {}) + assert DOMAIN in hass.data and config_entry.entry_id in hass.data[DOMAIN] + return config_entry diff --git a/tests/test_config_flow.py b/tests/test_config_flow.py index 025781c..01d5818 100644 --- a/tests/test_config_flow.py +++ b/tests/test_config_flow.py @@ -2,11 +2,9 @@ from __future__ import annotations -from unittest.mock import patch - -import pytest from homeassistant import config_entries from homeassistant import data_entry_flow +from homeassistant.core import HomeAssistant # from homeassistant.core import HomeAssistant # noqa: F401 from homeassistant.data_entry_flow import FlowResultType @@ -19,21 +17,9 @@ from .const import MOCK_CONFIG from .const import MOCK_OPTIONS_GLOBALS - # This fixture bypasses the actual setup of the integration # since we only want to test the config flow. We test the # actual functionality of the integration in other test modules. -@pytest.fixture(autouse=True) -def bypass_setup_fixture(): - """Prevent setup.""" - with patch( - "custom_components.bermuda.async_setup", - return_value=True, - ), patch( - "custom_components.bermuda.async_setup_entry", - return_value=True, - ): - yield # Here we simiulate a successful config flow from the backend. @@ -88,16 +74,10 @@ async def test_failed_config_flow(hass, error_on_get_data): # Our config flow also has an options flow, so we must test it as well. -async def test_options_flow(hass): +async def test_options_flow(hass: HomeAssistant, setup_bermuda_entry: MockConfigEntry): """Test an options flow.""" - # Create a new MockConfigEntry and add to HASS (we're bypassing config - # flow entirely) - entry = MockConfigEntry(domain=DOMAIN, data=MOCK_CONFIG, entry_id="test") - entry.add_to_hass(hass) - - # Initialize an options flow - await hass.config_entries.async_setup(entry.entry_id) - result = await hass.config_entries.options.async_init(entry.entry_id) + # Go through options flow + result = await hass.config_entries.options.async_init(setup_bermuda_entry.entry_id) # Verify that the first options step is a user form assert result["type"] == FlowResultType.MENU @@ -122,4 +102,4 @@ async def test_options_flow(hass): assert result["title"] == NAME # Verify that the options were updated - assert entry.options == MOCK_OPTIONS_GLOBALS + assert setup_bermuda_entry.options == MOCK_OPTIONS_GLOBALS diff --git a/tests/test_init.py b/tests/test_init.py index 0c4ba90..6d0542e 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -2,12 +2,11 @@ from __future__ import annotations +from homeassistant.core import HomeAssistant + # from homeassistant.exceptions import ConfigEntryNotReady from pytest_homeassistant_custom_component.common import MockConfigEntry -from custom_components.bermuda import async_reload_entry -from custom_components.bermuda import async_setup_entry -from custom_components.bermuda import async_unload_entry from custom_components.bermuda.const import DOMAIN from custom_components.bermuda.coordinator import BermudaDataUpdateCoordinator @@ -21,32 +20,24 @@ # Home Assistant using the pytest_homeassistant_custom_component plugin. # Assertions allow you to verify that the return value of whatever is on the left # side of the assertion matches with the right side. -async def test_setup_unload_and_reload_entry(hass, bypass_get_data): +async def test_setup_unload_and_reload_entry( + hass: HomeAssistant, bypass_get_data, setup_bermuda_entry: MockConfigEntry +): """Test entry setup and unload.""" - # Create a mock entry so we don't have to go through config flow - config_entry = MockConfigEntry(domain=DOMAIN, data=MOCK_CONFIG, entry_id="test") - - # Set up the entry and assert that the values - # set during setup are where we expect - # them to be. Because we have patched - # the BermudaDataUpdateCoordinator.async_get_data - # call, no code from custom_components/bermuda/api.py actually runs. - assert await async_setup_entry(hass, config_entry) - assert DOMAIN in hass.data and config_entry.entry_id in hass.data[DOMAIN] assert isinstance( - hass.data[DOMAIN][config_entry.entry_id], BermudaDataUpdateCoordinator + hass.data[DOMAIN][setup_bermuda_entry.entry_id], BermudaDataUpdateCoordinator ) # Reload the entry and assert that the data from above is still there - assert await async_reload_entry(hass, config_entry) is None - assert DOMAIN in hass.data and config_entry.entry_id in hass.data[DOMAIN] + assert await hass.config_entries.async_reload(setup_bermuda_entry.entry_id) + assert DOMAIN in hass.data and setup_bermuda_entry.entry_id in hass.data[DOMAIN] assert isinstance( - hass.data[DOMAIN][config_entry.entry_id], BermudaDataUpdateCoordinator + hass.data[DOMAIN][setup_bermuda_entry.entry_id], BermudaDataUpdateCoordinator ) # Unload the entry and verify that the data has been removed - assert await async_unload_entry(hass, config_entry) - assert config_entry.entry_id not in hass.data[DOMAIN] + assert await hass.config_entries.async_unload(setup_bermuda_entry.entry_id) + assert setup_bermuda_entry.entry_id not in hass.data[DOMAIN] async def test_setup_entry_exception(hass, error_on_get_data): diff --git a/tests/test_switch.py b/tests/test_switch.py index 9c18ab9..6d126f8 100644 --- a/tests/test_switch.py +++ b/tests/test_switch.py @@ -5,14 +5,10 @@ # from homeassistant.components.switch import SERVICE_TURN_OFF # from homeassistant.components.switch import SERVICE_TURN_ON # from homeassistant.const import ATTR_ENTITY_ID -from pytest_homeassistant_custom_component.common import MockConfigEntry -from custom_components.bermuda import async_setup_entry # from custom_components.bermuda.const import DEFAULT_NAME -from custom_components.bermuda.const import DOMAIN -from .const import MOCK_CONFIG # from unittest.mock import call # from unittest.mock import patch @@ -20,37 +16,37 @@ # from custom_components.bermuda.const import SWITCH - -async def test_switch_services(hass): - """Test switch services.""" - # Create a mock entry so we don't have to go through config flow - config_entry = MockConfigEntry(domain=DOMAIN, data=MOCK_CONFIG, entry_id="test") - assert await async_setup_entry(hass, config_entry) - await hass.async_block_till_done() - - # Functions/objects can be patched directly - # in test code as well and can be used to test - # additional things, like whether a function - # was called or what arguments it was called with - # with patch( - # "custom_components.bermuda.BermudaDataUpdateCoordinator.async_set_title" - # ) as title_func: - # await hass.services.async_call( - # SWITCH, - # SERVICE_TURN_OFF, - # service_data={ATTR_ENTITY_ID: f"{SWITCH}.{DEFAULT_NAME}_{SWITCH}"}, - # blocking=True, - # ) - # assert title_func.called - # assert title_func.call_args == call("foo") - - # title_func.reset_mock() - - # await hass.services.async_call( - # SWITCH, - # SERVICE_TURN_ON, - # service_data={ATTR_ENTITY_ID: f"{SWITCH}.{DEFAULT_NAME}_{SWITCH}"}, - # blocking=True, - # ) - # assert title_func.called - # assert title_func.call_args == call("bar") +# Not currently used - commenting out +# async def test_switch_services(hass: HomeAssistant): +# """Test switch services.""" +# # Create a mock entry so we don't have to go through config flow +# config_entry = MockConfigEntry(domain=DOMAIN, data=MOCK_CONFIG, entry_id="test") +# assert await async_setup_entry(hass, config_entry) +# await hass.async_block_till_done() + +# Functions/objects can be patched directly +# in test code as well and can be used to test +# additional things, like whether a function +# was called or what arguments it was called with +# with patch( +# "custom_components.bermuda.BermudaDataUpdateCoordinator.async_set_title" +# ) as title_func: +# await hass.services.async_call( +# SWITCH, +# SERVICE_TURN_OFF, +# service_data={ATTR_ENTITY_ID: f"{SWITCH}.{DEFAULT_NAME}_{SWITCH}"}, +# blocking=True, +# ) +# assert title_func.called +# assert title_func.call_args == call("foo") + +# title_func.reset_mock() + +# await hass.services.async_call( +# SWITCH, +# SERVICE_TURN_ON, +# service_data={ATTR_ENTITY_ID: f"{SWITCH}.{DEFAULT_NAME}_{SWITCH}"}, +# blocking=True, +# ) +# assert title_func.called +# assert title_func.call_args == call("bar") From 4c1e2239ab39ced6ae484f97970bdb10e30693a5 Mon Sep 17 00:00:00 2001 From: Luke Date: Sat, 27 Jul 2024 20:14:04 +0000 Subject: [PATCH 2/4] lint --- custom_components/bermuda/__init__.py | 6 +++--- custom_components/bermuda/config_flow.py | 3 +-- tests/conftest.py | 8 ++------ 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/custom_components/bermuda/__init__.py b/custom_components/bermuda/__init__.py index f5992dd..9140c61 100644 --- a/custom_components/bermuda/__init__.py +++ b/custom_components/bermuda/__init__.py @@ -7,10 +7,10 @@ from __future__ import annotations -from homeassistant.config_entries import ConfigEntry -from homeassistant.core import HomeAssistant from typing import TYPE_CHECKING +from homeassistant.config_entries import ConfigEntry +from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.helpers import config_validation as cv @@ -22,7 +22,7 @@ if TYPE_CHECKING: from homeassistant.config_entries import ConfigEntry - from homeassistant.core import Config, HomeAssistant + from homeassistant.core import HomeAssistant # from .const import _LOGGER_SPAM_LESS diff --git a/custom_components/bermuda/config_flow.py b/custom_components/bermuda/config_flow.py index 5187de3..4d9acf1 100644 --- a/custom_components/bermuda/config_flow.py +++ b/custom_components/bermuda/config_flow.py @@ -6,9 +6,8 @@ import voluptuous as vol from homeassistant import config_entries -from homeassistant.config_entries import ConfigEntry -from homeassistant.config_entries import OptionsFlowWithConfigEntry from homeassistant.components.bluetooth import MONOTONIC_TIME, BluetoothServiceInfoBleak +from homeassistant.config_entries import ConfigEntry, OptionsFlowWithConfigEntry from homeassistant.core import callback from homeassistant.helpers.selector import selector diff --git a/tests/conftest.py b/tests/conftest.py index fd6afdf..e3e0e43 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -87,9 +87,7 @@ def error_get_data_fixture(): @pytest.fixture() async def mock_bermuda_entry(hass: HomeAssistant): """This creates a mock config entry""" - config_entry = MockConfigEntry( - domain=DOMAIN, data=MOCK_CONFIG, entry_id="test", title=NAME - ) + config_entry = MockConfigEntry(domain=DOMAIN, data=MOCK_CONFIG, entry_id="test", title=NAME) config_entry.add_to_hass(hass) await hass.async_block_till_done() return config_entry @@ -98,9 +96,7 @@ async def mock_bermuda_entry(hass: HomeAssistant): @pytest.fixture() async def setup_bermuda_entry(hass: HomeAssistant): """This setups a entry so that it can be used.""" - config_entry = MockConfigEntry( - domain=DOMAIN, data=MOCK_CONFIG, entry_id="test", title=NAME - ) + config_entry = MockConfigEntry(domain=DOMAIN, data=MOCK_CONFIG, entry_id="test", title=NAME) config_entry.add_to_hass(hass) await async_setup_component(hass, DOMAIN, {}) assert DOMAIN in hass.data and config_entry.entry_id in hass.data[DOMAIN] From 20fd243198ec13843d98e82ae3e480780b9b4cba Mon Sep 17 00:00:00 2001 From: Luke Date: Sat, 27 Jul 2024 20:20:05 +0000 Subject: [PATCH 3/4] fix linting for real --- tests/test_init.py | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/tests/test_init.py b/tests/test_init.py index a73e013..c762cfd 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -24,22 +24,12 @@ async def test_setup_unload_and_reload_entry( hass: HomeAssistant, bypass_get_data, setup_bermuda_entry: MockConfigEntry ): """Test entry setup and unload.""" - # Create a mock entry so we don't have to go through config flow - config_entry = MockConfigEntry(domain=DOMAIN, data=MOCK_CONFIG, entry_id="test") - - # Set up the entry and assert that the values - # set during setup are where we expect - # them to be. Because we have patched - # the BermudaDataUpdateCoordinator.async_get_data - # call, no code from custom_components/bermuda/api.py actually runs. - assert await async_setup_entry(hass, config_entry) - assert DOMAIN in hass.data and config_entry.entry_id in hass.data[DOMAIN] - assert isinstance(hass.data[DOMAIN][config_entry.entry_id], BermudaDataUpdateCoordinator) + assert isinstance(hass.data[DOMAIN][setup_bermuda_entry.entry_id], BermudaDataUpdateCoordinator) # Reload the entry and assert that the data from above is still there - assert await async_reload_entry(hass, config_entry) is None - assert DOMAIN in hass.data and config_entry.entry_id in hass.data[DOMAIN] - assert isinstance(hass.data[DOMAIN][config_entry.entry_id], BermudaDataUpdateCoordinator) + assert await hass.config_entries.async_reload(setup_bermuda_entry.entry_id) + assert DOMAIN in hass.data and setup_bermuda_entry.entry_id in hass.data[DOMAIN] + assert isinstance(hass.data[DOMAIN][setup_bermuda_entry.entry_id], BermudaDataUpdateCoordinator) # Unload the entry and verify that the data has been removed assert await hass.config_entries.async_unload(setup_bermuda_entry.entry_id) From d3cdf0bdb502a0bf31317e3e5138b97d6ef43bf6 Mon Sep 17 00:00:00 2001 From: Luke Date: Thu, 1 Aug 2024 00:42:36 +0000 Subject: [PATCH 4/4] Remove comment --- tests/test_config_flow.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/test_config_flow.py b/tests/test_config_flow.py index e0e490e..8e300d9 100644 --- a/tests/test_config_flow.py +++ b/tests/test_config_flow.py @@ -17,10 +17,6 @@ from .const import MOCK_CONFIG from .const import MOCK_OPTIONS_GLOBALS -# This fixture bypasses the actual setup of the integration -# since we only want to test the config flow. We test the -# actual functionality of the integration in other test modules. - # Here we simiulate a successful config flow from the backend. # Note that we use the `bypass_get_data` fixture here because