diff --git a/tests/components/plugwise/common.py b/tests/components/plugwise/common.py deleted file mode 100644 index 379929ce2f1..00000000000 --- a/tests/components/plugwise/common.py +++ /dev/null @@ -1,26 +0,0 @@ -"""Common initialisation for the Plugwise integration.""" - -from homeassistant.components.plugwise.const import DOMAIN -from homeassistant.core import HomeAssistant - -from tests.common import MockConfigEntry -from tests.test_util.aiohttp import AiohttpClientMocker - - -async def async_init_integration( - hass: HomeAssistant, - aioclient_mock: AiohttpClientMocker, - skip_setup: bool = False, -): - """Initialize the Smile integration.""" - - entry = MockConfigEntry( - domain=DOMAIN, data={"host": "1.1.1.1", "password": "test-password"} - ) - entry.add_to_hass(hass) - - if not skip_setup: - await hass.config_entries.async_setup(entry.entry_id) - await hass.async_block_till_done() - - return entry diff --git a/tests/components/plugwise/conftest.py b/tests/components/plugwise/conftest.py index fa49967437d..012734315f6 100644 --- a/tests/components/plugwise/conftest.py +++ b/tests/components/plugwise/conftest.py @@ -2,30 +2,49 @@ from __future__ import annotations from collections.abc import Generator -from functools import partial -from http import HTTPStatus import json -import re -from unittest.mock import AsyncMock, MagicMock, Mock, patch +from typing import Any +from unittest.mock import AsyncMock, MagicMock, patch -from plugwise.exceptions import ( - ConnectionFailedError, - InvalidAuthentication, - PlugwiseException, - XMLDataMissingError, -) import pytest -from tests.common import load_fixture -from tests.test_util.aiohttp import AiohttpClientMocker +from homeassistant.components.plugwise.const import API, DOMAIN, PW_TYPE +from homeassistant.const import ( + CONF_HOST, + CONF_MAC, + CONF_PASSWORD, + CONF_PORT, + CONF_USERNAME, +) +from homeassistant.core import HomeAssistant + +from tests.common import MockConfigEntry, load_fixture -def _read_json(environment, call): +def _read_json(environment: str, call: str) -> dict[str, Any]: """Undecode the json data.""" fixture = load_fixture(f"plugwise/{environment}/{call}.json") return json.loads(fixture) +@pytest.fixture +def mock_config_entry() -> MockConfigEntry: + """Return the default mocked config entry.""" + return MockConfigEntry( + title="My Plugwise", + domain=DOMAIN, + data={ + CONF_HOST: "127.0.0.1", + CONF_MAC: "AA:BB:CC:DD:EE:FF", + CONF_PASSWORD: "test-password", + CONF_PORT: 80, + CONF_USERNAME: "smile", + PW_TYPE: API, + }, + unique_id="smile98765", + ) + + @pytest.fixture def mock_setup_entry() -> Generator[AsyncMock, None, None]: """Mock setting up a config entry.""" @@ -49,179 +68,109 @@ def mock_smile_config_flow() -> Generator[None, MagicMock, None]: yield smile -@pytest.fixture(name="mock_smile_unauth") -def mock_smile_unauth(aioclient_mock: AiohttpClientMocker) -> None: - """Mock the Plugwise Smile unauthorized for Home Assistant.""" - aioclient_mock.get(re.compile(".*"), status=HTTPStatus.UNAUTHORIZED) - aioclient_mock.put(re.compile(".*"), status=HTTPStatus.UNAUTHORIZED) - - -@pytest.fixture(name="mock_smile_error") -def mock_smile_error(aioclient_mock: AiohttpClientMocker) -> None: - """Mock the Plugwise Smile server failure for Home Assistant.""" - aioclient_mock.get(re.compile(".*"), status=HTTPStatus.INTERNAL_SERVER_ERROR) - aioclient_mock.put(re.compile(".*"), status=HTTPStatus.INTERNAL_SERVER_ERROR) - - -@pytest.fixture(name="mock_smile_notconnect") -def mock_smile_notconnect(): - """Mock the Plugwise Smile general connection failure for Home Assistant.""" - with patch("homeassistant.components.plugwise.gateway.Smile") as smile_mock: - smile_mock.InvalidAuthentication = InvalidAuthentication - smile_mock.ConnectionFailedError = ConnectionFailedError - smile_mock.PlugwiseException = PlugwiseException - smile_mock.return_value.connect.side_effect = AsyncMock(return_value=False) - yield smile_mock.return_value - - -def _get_device_data(chosen_env, device_id): - """Mock return data for specific devices.""" - return _read_json(chosen_env, "get_device_data/" + device_id) - - -@pytest.fixture(name="mock_smile_adam") -def mock_smile_adam(): +@pytest.fixture +def mock_smile_adam() -> Generator[None, MagicMock, None]: """Create a Mock Adam environment for testing exceptions.""" chosen_env = "adam_multiple_devices_per_zone" - with patch("homeassistant.components.plugwise.gateway.Smile") as smile_mock: - smile_mock.InvalidAuthentication = InvalidAuthentication - smile_mock.ConnectionFailedError = ConnectionFailedError - smile_mock.XMLDataMissingError = XMLDataMissingError - smile_mock.return_value.gateway_id = "fe799307f1624099878210aa0b9f1475" - smile_mock.return_value.heater_id = "90986d591dcd426cae3ec3e8111ff730" - smile_mock.return_value.smile_version = "3.0.15" - smile_mock.return_value.smile_type = "thermostat" - smile_mock.return_value.smile_hostname = "smile98765" - smile_mock.return_value.smile_name = "Adam" + with patch( + "homeassistant.components.plugwise.gateway.Smile", autospec=True + ) as smile_mock: + smile = smile_mock.return_value - smile_mock.return_value.notifications = _read_json(chosen_env, "notifications") + smile.gateway_id = "fe799307f1624099878210aa0b9f1475" + smile.heater_id = "90986d591dcd426cae3ec3e8111ff730" + smile.smile_version = "3.0.15" + smile.smile_type = "thermostat" + smile.smile_hostname = "smile98765" + smile.smile_name = "Adam" - smile_mock.return_value.connect.side_effect = AsyncMock(return_value=True) - smile_mock.return_value.single_master_thermostat.side_effect = Mock( - return_value=False - ) - smile_mock.return_value.set_schedule_state.side_effect = AsyncMock( - return_value=True - ) - smile_mock.return_value.set_preset.side_effect = AsyncMock(return_value=True) - smile_mock.return_value.set_temperature.side_effect = AsyncMock( - return_value=True - ) - smile_mock.return_value.async_update.side_effect = AsyncMock( - return_value=_read_json(chosen_env, "all_data") - ) - smile_mock.return_value.set_switch_state.side_effect = AsyncMock( - return_value=True - ) + smile.connect.return_value = True - yield smile_mock.return_value + smile.notifications = _read_json(chosen_env, "notifications") + smile.async_update.return_value = _read_json(chosen_env, "all_data") + + yield smile -@pytest.fixture(name="mock_smile_anna") -def mock_smile_anna(): +@pytest.fixture +def mock_smile_anna() -> Generator[None, MagicMock, None]: """Create a Mock Anna environment for testing exceptions.""" chosen_env = "anna_heatpump" - with patch("homeassistant.components.plugwise.gateway.Smile") as smile_mock: - smile_mock.InvalidAuthentication = InvalidAuthentication - smile_mock.ConnectionFailedError = ConnectionFailedError - smile_mock.XMLDataMissingError = XMLDataMissingError + with patch( + "homeassistant.components.plugwise.gateway.Smile", autospec=True + ) as smile_mock: + smile = smile_mock.return_value - smile_mock.return_value.gateway_id = "015ae9ea3f964e668e490fa39da3870b" - smile_mock.return_value.heater_id = "1cbf783bb11e4a7c8a6843dee3a86927" - smile_mock.return_value.smile_version = "4.0.15" - smile_mock.return_value.smile_type = "thermostat" - smile_mock.return_value.smile_hostname = "smile98765" - smile_mock.return_value.smile_name = "Anna" + smile.gateway_id = "015ae9ea3f964e668e490fa39da3870b" + smile.heater_id = "1cbf783bb11e4a7c8a6843dee3a86927" + smile.smile_version = "4.0.15" + smile.smile_type = "thermostat" + smile.smile_hostname = "smile98765" + smile.smile_name = "Anna" - smile_mock.return_value.notifications = _read_json(chosen_env, "notifications") + smile.connect.return_value = True - smile_mock.return_value.connect.side_effect = AsyncMock(return_value=True) - smile_mock.return_value.single_master_thermostat.side_effect = Mock( - return_value=True - ) - smile_mock.return_value.set_schedule_state.side_effect = AsyncMock( - return_value=True - ) - smile_mock.return_value.set_preset.side_effect = AsyncMock(return_value=True) - smile_mock.return_value.set_temperature.side_effect = AsyncMock( - return_value=True - ) - smile_mock.return_value.set_switch_state.side_effect = AsyncMock( - return_value=True - ) + smile.notifications = _read_json(chosen_env, "notifications") + smile.async_update.return_value = _read_json(chosen_env, "all_data") - smile_mock.return_value.async_update.side_effect = AsyncMock( - return_value=_read_json(chosen_env, "all_data") - ) - smile_mock.return_value.get_device_data.side_effect = partial( - _get_device_data, chosen_env - ) - - yield smile_mock.return_value + yield smile -@pytest.fixture(name="mock_smile_p1") -def mock_smile_p1(): +@pytest.fixture +def mock_smile_p1() -> Generator[None, MagicMock, None]: """Create a Mock P1 DSMR environment for testing exceptions.""" chosen_env = "p1v3_full_option" - with patch("homeassistant.components.plugwise.gateway.Smile") as smile_mock: - smile_mock.InvalidAuthentication = InvalidAuthentication - smile_mock.ConnectionFailedError = ConnectionFailedError - smile_mock.XMLDataMissingError = XMLDataMissingError + with patch( + "homeassistant.components.plugwise.gateway.Smile", autospec=True + ) as smile_mock: + smile = smile_mock.return_value - smile_mock.return_value.gateway_id = "e950c7d5e1ee407a858e2a8b5016c8b3" - smile_mock.return_value.heater_id = None - smile_mock.return_value.smile_version = "3.3.9" - smile_mock.return_value.smile_type = "power" - smile_mock.return_value.smile_hostname = "smile98765" - smile_mock.return_value.smile_name = "Smile P1" + smile.gateway_id = "e950c7d5e1ee407a858e2a8b5016c8b3" + smile.heater_id = None + smile.smile_version = "3.3.9" + smile.smile_type = "power" + smile.smile_hostname = "smile98765" + smile.smile_name = "Smile P1" - smile_mock.return_value.notifications = _read_json(chosen_env, "notifications") + smile.connect.return_value = True - smile_mock.return_value.connect.side_effect = AsyncMock(return_value=True) + smile.notifications = _read_json(chosen_env, "notifications") + smile.async_update.return_value = _read_json(chosen_env, "all_data") - smile_mock.return_value.single_master_thermostat.side_effect = Mock( - return_value=None - ) - - smile_mock.return_value.get_device_data.side_effect = partial( - _get_device_data, chosen_env - ) - - smile_mock.return_value.async_update.side_effect = AsyncMock( - return_value=_read_json(chosen_env, "all_data") - ) - - yield smile_mock.return_value + yield smile -@pytest.fixture(name="mock_stretch") -def mock_stretch(): +@pytest.fixture +def mock_stretch() -> Generator[None, MagicMock, None]: """Create a Mock Stretch environment for testing exceptions.""" chosen_env = "stretch_v31" - with patch("homeassistant.components.plugwise.gateway.Smile") as smile_mock: - smile_mock.InvalidAuthentication = InvalidAuthentication - smile_mock.ConnectionFailedError = ConnectionFailedError - smile_mock.XMLDataMissingError = XMLDataMissingError + with patch( + "homeassistant.components.plugwise.gateway.Smile", autospec=True + ) as smile_mock: + smile = smile_mock.return_value - smile_mock.return_value.gateway_id = "259882df3c05415b99c2d962534ce820" - smile_mock.return_value.heater_id = None - smile_mock.return_value.smile_version = "3.1.11" - smile_mock.return_value.smile_type = "stretch" - smile_mock.return_value.smile_hostname = "stretch98765" - smile_mock.return_value.smile_name = "Stretch" + smile.gateway_id = "259882df3c05415b99c2d962534ce820" + smile.heater_id = None + smile.smile_version = "3.1.11" + smile.smile_type = "stretch" + smile.smile_hostname = "stretch98765" + smile.smile_name = "Stretch" - smile_mock.return_value.connect.side_effect = AsyncMock(return_value=True) - smile_mock.return_value.set_switch_state.side_effect = AsyncMock( - return_value=True - ) - smile_mock.return_value.get_device_data.side_effect = partial( - _get_device_data, chosen_env - ) + smile.connect.return_value = True + smile.async_update.return_value = _read_json(chosen_env, "all_data") - smile_mock.return_value.async_update.side_effect = AsyncMock( - return_value=_read_json(chosen_env, "all_data") - ) + yield smile - yield smile_mock.return_value + +@pytest.fixture +async def init_integration( + hass: HomeAssistant, mock_config_entry: MockConfigEntry +) -> MockConfigEntry: + """Set up the Plugwise integration for testing.""" + mock_config_entry.add_to_hass(hass) + + await hass.config_entries.async_setup(mock_config_entry.entry_id) + await hass.async_block_till_done() + + return mock_config_entry diff --git a/tests/components/plugwise/test_binary_sensor.py b/tests/components/plugwise/test_binary_sensor.py index b2356036eb9..4bcecf83157 100644 --- a/tests/components/plugwise/test_binary_sensor.py +++ b/tests/components/plugwise/test_binary_sensor.py @@ -1,32 +1,36 @@ """Tests for the Plugwise binary_sensor integration.""" -from homeassistant.config_entries import ConfigEntryState +from unittest.mock import MagicMock + from homeassistant.const import STATE_OFF, STATE_ON +from homeassistant.core import HomeAssistant -from tests.components.plugwise.common import async_init_integration +from tests.common import MockConfigEntry -async def test_anna_climate_binary_sensor_entities(hass, mock_smile_anna): +async def test_anna_climate_binary_sensor_entities( + hass: HomeAssistant, mock_smile_anna: MagicMock, init_integration: MockConfigEntry +) -> None: """Test creation of climate related binary_sensor entities.""" - entry = await async_init_integration(hass, mock_smile_anna) - assert entry.state is ConfigEntryState.LOADED state = hass.states.get("binary_sensor.opentherm_secondary_boiler_state") + assert state assert state.state == STATE_OFF state = hass.states.get("binary_sensor.opentherm_dhw_state") + assert state assert state.state == STATE_OFF -async def test_anna_climate_binary_sensor_change(hass, mock_smile_anna): +async def test_anna_climate_binary_sensor_change( + hass: HomeAssistant, mock_smile_anna: MagicMock, init_integration: MockConfigEntry +) -> None: """Test change of climate related binary_sensor entities.""" - entry = await async_init_integration(hass, mock_smile_anna) - assert entry.state is ConfigEntryState.LOADED - hass.states.async_set("binary_sensor.opentherm_dhw_state", STATE_ON, {}) await hass.async_block_till_done() state = hass.states.get("binary_sensor.opentherm_dhw_state") + assert state assert state.state == STATE_ON await hass.helpers.entity_component.async_update_entity( @@ -34,16 +38,18 @@ async def test_anna_climate_binary_sensor_change(hass, mock_smile_anna): ) state = hass.states.get("binary_sensor.opentherm_dhw_state") + assert state assert state.state == STATE_OFF -async def test_adam_climate_binary_sensor_change(hass, mock_smile_adam): +async def test_adam_climate_binary_sensor_change( + hass: HomeAssistant, mock_smile_adam: MagicMock, init_integration: MockConfigEntry +) -> None: """Test change of climate related binary_sensor entities.""" - entry = await async_init_integration(hass, mock_smile_adam) - assert entry.state is ConfigEntryState.LOADED - state = hass.states.get("binary_sensor.adam_plugwise_notification") - assert str(state.state) == STATE_ON - assert "unreachable" in state.attributes.get("warning_msg")[0] + assert state + assert state.state == STATE_ON + assert "warning_msg" in state.attributes + assert "unreachable" in state.attributes["warning_msg"][0] assert not state.attributes.get("error_msg") assert not state.attributes.get("other_msg") diff --git a/tests/components/plugwise/test_climate.py b/tests/components/plugwise/test_climate.py index 5c9df093487..6f9a258bb38 100644 --- a/tests/components/plugwise/test_climate.py +++ b/tests/components/plugwise/test_climate.py @@ -1,5 +1,7 @@ """Tests for the Plugwise Climate integration.""" +from unittest.mock import MagicMock + from plugwise.exceptions import PlugwiseException import pytest @@ -9,55 +11,59 @@ from homeassistant.components.climate.const import ( HVAC_MODE_HEAT, HVAC_MODE_OFF, ) -from homeassistant.config_entries import ConfigEntryState +from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from tests.components.plugwise.common import async_init_integration +from tests.common import MockConfigEntry -async def test_adam_climate_entity_attributes(hass, mock_smile_adam): +async def test_adam_climate_entity_attributes( + hass: HomeAssistant, mock_smile_adam: MagicMock, init_integration: MockConfigEntry +) -> None: """Test creation of adam climate device environment.""" - entry = await async_init_integration(hass, mock_smile_adam) - assert entry.state is ConfigEntryState.LOADED - state = hass.states.get("climate.zone_lisa_wk") - attrs = state.attributes - assert attrs["hvac_modes"] == [HVAC_MODE_HEAT, HVAC_MODE_OFF, HVAC_MODE_AUTO] + assert state + assert state.attributes["hvac_modes"] == [ + HVAC_MODE_HEAT, + HVAC_MODE_OFF, + HVAC_MODE_AUTO, + ] - assert "preset_modes" in attrs - assert "no_frost" in attrs["preset_modes"] - assert "home" in attrs["preset_modes"] + assert "preset_modes" in state.attributes + assert "no_frost" in state.attributes["preset_modes"] + assert "home" in state.attributes["preset_modes"] - assert attrs["current_temperature"] == 20.9 - assert attrs["temperature"] == 21.5 - - assert attrs["preset_mode"] == "home" - - assert attrs["supported_features"] == 17 + assert state.attributes["current_temperature"] == 20.9 + assert state.attributes["preset_mode"] == "home" + assert state.attributes["supported_features"] == 17 + assert state.attributes["temperature"] == 21.5 state = hass.states.get("climate.zone_thermostat_jessie") - attrs = state.attributes + assert state - assert attrs["hvac_modes"] == [HVAC_MODE_HEAT, HVAC_MODE_OFF, HVAC_MODE_AUTO] + assert state.attributes["hvac_modes"] == [ + HVAC_MODE_HEAT, + HVAC_MODE_OFF, + HVAC_MODE_AUTO, + ] - assert "preset_modes" in attrs - assert "no_frost" in attrs["preset_modes"] - assert "home" in attrs["preset_modes"] + assert "preset_modes" in state.attributes + assert "no_frost" in state.attributes["preset_modes"] + assert "home" in state.attributes["preset_modes"] - assert attrs["current_temperature"] == 17.2 - assert attrs["temperature"] == 15.0 - - assert attrs["preset_mode"] == "asleep" + assert state.attributes["current_temperature"] == 17.2 + assert state.attributes["preset_mode"] == "asleep" + assert state.attributes["temperature"] == 15.0 -async def test_adam_climate_adjust_negative_testing(hass, mock_smile_adam): +async def test_adam_climate_adjust_negative_testing( + hass: HomeAssistant, mock_smile_adam: MagicMock, init_integration: MockConfigEntry +) -> None: """Test exceptions of climate entities.""" mock_smile_adam.set_preset.side_effect = PlugwiseException mock_smile_adam.set_schedule_state.side_effect = PlugwiseException mock_smile_adam.set_temperature.side_effect = PlugwiseException - entry = await async_init_integration(hass, mock_smile_adam) - assert entry.state is ConfigEntryState.LOADED with pytest.raises(HomeAssistantError): await hass.services.async_call( @@ -66,9 +72,6 @@ async def test_adam_climate_adjust_negative_testing(hass, mock_smile_adam): {"entity_id": "climate.zone_lisa_wk", "temperature": 25}, blocking=True, ) - state = hass.states.get("climate.zone_lisa_wk") - attrs = state.attributes - assert attrs["temperature"] == 21.5 with pytest.raises(HomeAssistantError): await hass.services.async_call( @@ -77,9 +80,6 @@ async def test_adam_climate_adjust_negative_testing(hass, mock_smile_adam): {"entity_id": "climate.zone_thermostat_jessie", "preset_mode": "home"}, blocking=True, ) - state = hass.states.get("climate.zone_thermostat_jessie") - attrs = state.attributes - assert attrs["preset_mode"] == "asleep" with pytest.raises(HomeAssistantError): await hass.services.async_call( @@ -91,15 +91,12 @@ async def test_adam_climate_adjust_negative_testing(hass, mock_smile_adam): }, blocking=True, ) - state = hass.states.get("climate.zone_thermostat_jessie") - attrs = state.attributes -async def test_adam_climate_entity_climate_changes(hass, mock_smile_adam): +async def test_adam_climate_entity_climate_changes( + hass: HomeAssistant, mock_smile_adam: MagicMock, init_integration: MockConfigEntry +) -> None: """Test handling of user requests in adam climate device environment.""" - entry = await async_init_integration(hass, mock_smile_adam) - assert entry.state is ConfigEntryState.LOADED - await hass.services.async_call( "climate", "set_temperature", @@ -149,36 +146,32 @@ async def test_adam_climate_entity_climate_changes(hass, mock_smile_adam): ) -async def test_anna_climate_entity_attributes(hass, mock_smile_anna): +async def test_anna_climate_entity_attributes( + hass: HomeAssistant, mock_smile_anna: MagicMock, init_integration: MockConfigEntry +) -> None: """Test creation of anna climate device environment.""" - entry = await async_init_integration(hass, mock_smile_anna) - assert entry.state is ConfigEntryState.LOADED - state = hass.states.get("climate.anna") - attrs = state.attributes - - assert "hvac_modes" in attrs - assert attrs["hvac_modes"] == [HVAC_MODE_HEAT, HVAC_MODE_OFF, HVAC_MODE_COOL] - - assert "preset_modes" in attrs - assert "no_frost" in attrs["preset_modes"] - assert "home" in attrs["preset_modes"] - - assert attrs["current_temperature"] == 19.3 - assert attrs["temperature"] == 21.0 - + assert state assert state.state == HVAC_MODE_HEAT - assert attrs["hvac_action"] == "heating" - assert attrs["preset_mode"] == "home" + assert state.attributes["hvac_modes"] == [ + HVAC_MODE_HEAT, + HVAC_MODE_OFF, + HVAC_MODE_COOL, + ] + assert "no_frost" in state.attributes["preset_modes"] + assert "home" in state.attributes["preset_modes"] - assert attrs["supported_features"] == 17 + assert state.attributes["current_temperature"] == 19.3 + assert state.attributes["hvac_action"] == "heating" + assert state.attributes["preset_mode"] == "home" + assert state.attributes["supported_features"] == 17 + assert state.attributes["temperature"] == 21.0 -async def test_anna_climate_entity_climate_changes(hass, mock_smile_anna): +async def test_anna_climate_entity_climate_changes( + hass: HomeAssistant, mock_smile_anna: MagicMock, init_integration: MockConfigEntry +) -> None: """Test handling of user requests in anna climate device environment.""" - entry = await async_init_integration(hass, mock_smile_anna) - assert entry.state is ConfigEntryState.LOADED - await hass.services.async_call( "climate", "set_temperature", diff --git a/tests/components/plugwise/test_diagnostics.py b/tests/components/plugwise/test_diagnostics.py index fdc4ee87920..673e77f1630 100644 --- a/tests/components/plugwise/test_diagnostics.py +++ b/tests/components/plugwise/test_diagnostics.py @@ -5,18 +5,20 @@ from aiohttp import ClientSession from homeassistant.core import HomeAssistant +from tests.common import MockConfigEntry from tests.components.diagnostics import get_diagnostics_for_config_entry -from tests.components.plugwise.common import async_init_integration async def test_diagnostics( hass: HomeAssistant, hass_client: ClientSession, mock_smile_adam: MagicMock, -): + init_integration: MockConfigEntry, +) -> None: """Test diagnostics.""" - entry = await async_init_integration(hass, mock_smile_adam) - assert await get_diagnostics_for_config_entry(hass, hass_client, entry) == { + assert await get_diagnostics_for_config_entry( + hass, hass_client, init_integration + ) == { "gateway": { "active_device": True, "cooling_present": None, diff --git a/tests/components/plugwise/test_init.py b/tests/components/plugwise/test_init.py index d0d810804e2..d63b81bd0d3 100644 --- a/tests/components/plugwise/test_init.py +++ b/tests/components/plugwise/test_init.py @@ -1,65 +1,62 @@ """Tests for the Plugwise Climate integration.""" - import asyncio +from unittest.mock import MagicMock -from plugwise.exceptions import XMLDataMissingError +from plugwise.exceptions import ( + ConnectionFailedError, + PlugwiseException, + XMLDataMissingError, +) +import pytest from homeassistant.components.plugwise.const import DOMAIN from homeassistant.config_entries import ConfigEntryState +from homeassistant.core import HomeAssistant -from tests.common import AsyncMock, MockConfigEntry -from tests.components.plugwise.common import async_init_integration +from tests.common import MockConfigEntry -async def test_smile_unauthorized(hass, mock_smile_unauth): - """Test failing unauthorization by Smile.""" - entry = await async_init_integration(hass, mock_smile_unauth) - assert entry.state is ConfigEntryState.SETUP_ERROR - - -async def test_smile_error(hass, mock_smile_error): - """Test server error handling by Smile.""" - entry = await async_init_integration(hass, mock_smile_error) - assert entry.state is ConfigEntryState.SETUP_RETRY - - -async def test_smile_notconnect(hass, mock_smile_notconnect): - """Connection failure error handling by Smile.""" - mock_smile_notconnect.connect.return_value = False - entry = await async_init_integration(hass, mock_smile_notconnect) - assert entry.state is ConfigEntryState.SETUP_RETRY - - -async def test_smile_timeout(hass, mock_smile_notconnect): - """Timeout error handling by Smile.""" - mock_smile_notconnect.connect.side_effect = asyncio.TimeoutError - entry = await async_init_integration(hass, mock_smile_notconnect) - assert entry.state is ConfigEntryState.SETUP_RETRY - - -async def test_smile_adam_xmlerror(hass, mock_smile_adam): - """Detect malformed XML by Smile in Adam environment.""" - mock_smile_adam.async_update.side_effect = XMLDataMissingError - entry = await async_init_integration(hass, mock_smile_adam) - assert entry.state is ConfigEntryState.SETUP_RETRY - - -async def test_unload_entry(hass, mock_smile_adam): - """Test being able to unload an entry.""" - entry = await async_init_integration(hass, mock_smile_adam) - - mock_smile_adam.async_reset = AsyncMock(return_value=True) - await hass.config_entries.async_unload(entry.entry_id) +async def test_load_unload_config_entry( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + mock_smile_anna: MagicMock, +) -> None: + """Test the Plugwise configuration entry loading/unloading.""" + mock_config_entry.add_to_hass(hass) + await hass.config_entries.async_setup(mock_config_entry.entry_id) await hass.async_block_till_done() - assert entry.state is ConfigEntryState.NOT_LOADED - assert not hass.data[DOMAIN] + assert mock_config_entry.state is ConfigEntryState.LOADED + assert len(mock_smile_anna.connect.mock_calls) == 1 -async def test_async_setup_entry_fail(hass): - """Test async_setup_entry.""" - entry = MockConfigEntry(domain=DOMAIN, data={}) - - entry.add_to_hass(hass) - await hass.config_entries.async_setup(entry.entry_id) + await hass.config_entries.async_unload(mock_config_entry.entry_id) await hass.async_block_till_done() - assert entry.state is ConfigEntryState.SETUP_ERROR + + assert not hass.data.get(DOMAIN) + assert mock_config_entry.state is ConfigEntryState.NOT_LOADED + + +@pytest.mark.parametrize( + "side_effect", + [ + (ConnectionFailedError), + (PlugwiseException), + (XMLDataMissingError), + (asyncio.TimeoutError), + ], +) +async def test_config_entry_not_ready( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + mock_smile_anna: MagicMock, + side_effect: Exception, +) -> None: + """Test the Plugwise configuration entry not ready.""" + mock_smile_anna.connect.side_effect = side_effect + + mock_config_entry.add_to_hass(hass) + await hass.config_entries.async_setup(mock_config_entry.entry_id) + await hass.async_block_till_done() + + assert len(mock_smile_anna.connect.mock_calls) == 1 + assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY diff --git a/tests/components/plugwise/test_sensor.py b/tests/components/plugwise/test_sensor.py index 47cbea1a8bc..6f5309d3810 100644 --- a/tests/components/plugwise/test_sensor.py +++ b/tests/components/plugwise/test_sensor.py @@ -1,26 +1,30 @@ """Tests for the Plugwise Sensor integration.""" -from homeassistant.config_entries import ConfigEntryState +from unittest.mock import MagicMock -from tests.common import Mock -from tests.components.plugwise.common import async_init_integration +from homeassistant.core import HomeAssistant + +from tests.common import MockConfigEntry -async def test_adam_climate_sensor_entities(hass, mock_smile_adam): +async def test_adam_climate_sensor_entities( + hass: HomeAssistant, mock_smile_adam: MagicMock, init_integration: MockConfigEntry +) -> None: """Test creation of climate related sensor entities.""" - entry = await async_init_integration(hass, mock_smile_adam) - assert entry.state is ConfigEntryState.LOADED - state = hass.states.get("sensor.adam_outdoor_temperature") + assert state assert float(state.state) == 7.81 state = hass.states.get("sensor.cv_pomp_electricity_consumed") + assert state assert float(state.state) == 35.6 state = hass.states.get("sensor.onoff_water_temperature") + assert state assert float(state.state) == 70.0 state = hass.states.get("sensor.cv_pomp_electricity_consumed_interval") + assert state assert float(state.state) == 7.37 await hass.helpers.entity_component.async_update_entity( @@ -28,62 +32,70 @@ async def test_adam_climate_sensor_entities(hass, mock_smile_adam): ) state = hass.states.get("sensor.zone_lisa_wk_battery") + assert state assert int(state.state) == 34 -async def test_anna_as_smt_climate_sensor_entities(hass, mock_smile_anna): +async def test_anna_as_smt_climate_sensor_entities( + hass: HomeAssistant, mock_smile_anna: MagicMock, init_integration: MockConfigEntry +) -> None: """Test creation of climate related sensor entities.""" - entry = await async_init_integration(hass, mock_smile_anna) - assert entry.state is ConfigEntryState.LOADED - state = hass.states.get("sensor.opentherm_outdoor_temperature") + assert state assert float(state.state) == 3.0 state = hass.states.get("sensor.opentherm_water_temperature") + assert state assert float(state.state) == 29.1 state = hass.states.get("sensor.anna_illuminance") + assert state assert float(state.state) == 86.0 -async def test_anna_climate_sensor_entities(hass, mock_smile_anna): +async def test_anna_climate_sensor_entities( + hass: HomeAssistant, mock_smile_anna: MagicMock, init_integration: MockConfigEntry +) -> None: """Test creation of climate related sensor entities as single master thermostat.""" - mock_smile_anna.single_master_thermostat.side_effect = Mock(return_value=False) - entry = await async_init_integration(hass, mock_smile_anna) - assert entry.state is ConfigEntryState.LOADED - + mock_smile_anna.single_master_thermostat.return_value = False state = hass.states.get("sensor.opentherm_outdoor_temperature") + assert state assert float(state.state) == 3.0 -async def test_p1_dsmr_sensor_entities(hass, mock_smile_p1): +async def test_p1_dsmr_sensor_entities( + hass: HomeAssistant, mock_smile_p1: MagicMock, init_integration: MockConfigEntry +) -> None: """Test creation of power related sensor entities.""" - entry = await async_init_integration(hass, mock_smile_p1) - assert entry.state is ConfigEntryState.LOADED - state = hass.states.get("sensor.p1_net_electricity_point") + assert state assert float(state.state) == -2816.0 state = hass.states.get("sensor.p1_electricity_consumed_off_peak_cumulative") + assert state assert float(state.state) == 551.09 state = hass.states.get("sensor.p1_electricity_produced_peak_point") + assert state assert float(state.state) == 2816.0 state = hass.states.get("sensor.p1_electricity_consumed_peak_cumulative") + assert state assert float(state.state) == 442.932 state = hass.states.get("sensor.p1_gas_consumed_cumulative") + assert state assert float(state.state) == 584.85 -async def test_stretch_sensor_entities(hass, mock_stretch): +async def test_stretch_sensor_entities( + hass: HomeAssistant, mock_stretch: MagicMock, init_integration: MockConfigEntry +) -> None: """Test creation of power related sensor entities.""" - entry = await async_init_integration(hass, mock_stretch) - assert entry.state is ConfigEntryState.LOADED - state = hass.states.get("sensor.koelkast_92c4a_electricity_consumed") + assert state assert float(state.state) == 50.5 state = hass.states.get("sensor.droger_52559_electricity_consumed_interval") + assert state assert float(state.state) == 0.0 diff --git a/tests/components/plugwise/test_switch.py b/tests/components/plugwise/test_switch.py index 4785a222f69..74e19e987d7 100644 --- a/tests/components/plugwise/test_switch.py +++ b/tests/components/plugwise/test_switch.py @@ -1,34 +1,36 @@ """Tests for the Plugwise switch integration.""" +from unittest.mock import MagicMock + from plugwise.exceptions import PlugwiseException import pytest from homeassistant.components.plugwise.const import DOMAIN from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN -from homeassistant.config_entries import ConfigEntryState +from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import entity_registry as er from tests.common import MockConfigEntry -from tests.components.plugwise.common import async_init_integration -async def test_adam_climate_switch_entities(hass, mock_smile_adam): +async def test_adam_climate_switch_entities( + hass: HomeAssistant, mock_smile_adam: MagicMock, init_integration: MockConfigEntry +) -> None: """Test creation of climate related switch entities.""" - entry = await async_init_integration(hass, mock_smile_adam) - assert entry.state is ConfigEntryState.LOADED - state = hass.states.get("switch.cv_pomp_relay") - assert str(state.state) == "on" + assert state + assert state.state == "on" state = hass.states.get("switch.fibaro_hc2_relay") - assert str(state.state) == "on" + assert state + assert state.state == "on" -async def test_adam_climate_switch_negative_testing(hass, mock_smile_adam): +async def test_adam_climate_switch_negative_testing( + hass: HomeAssistant, mock_smile_adam: MagicMock, init_integration: MockConfigEntry +): """Test exceptions of climate related switch entities.""" mock_smile_adam.set_switch_state.side_effect = PlugwiseException - entry = await async_init_integration(hass, mock_smile_adam) - assert entry.state is ConfigEntryState.LOADED with pytest.raises(HomeAssistantError): await hass.services.async_call( @@ -57,11 +59,10 @@ async def test_adam_climate_switch_negative_testing(hass, mock_smile_adam): ) -async def test_adam_climate_switch_changes(hass, mock_smile_adam): +async def test_adam_climate_switch_changes( + hass: HomeAssistant, mock_smile_adam: MagicMock, init_integration: MockConfigEntry +) -> None: """Test changing of climate related switch entities.""" - entry = await async_init_integration(hass, mock_smile_adam) - assert entry.state is ConfigEntryState.LOADED - await hass.services.async_call( "switch", "turn_off", @@ -99,23 +100,23 @@ async def test_adam_climate_switch_changes(hass, mock_smile_adam): ) -async def test_stretch_switch_entities(hass, mock_stretch): +async def test_stretch_switch_entities( + hass: HomeAssistant, mock_stretch: MagicMock, init_integration: MockConfigEntry +) -> None: """Test creation of climate related switch entities.""" - entry = await async_init_integration(hass, mock_stretch) - assert entry.state is ConfigEntryState.LOADED - state = hass.states.get("switch.koelkast_92c4a_relay") - assert str(state.state) == "on" + assert state + assert state.state == "on" state = hass.states.get("switch.droger_52559_relay") - assert str(state.state) == "on" + assert state + assert state.state == "on" -async def test_stretch_switch_changes(hass, mock_stretch): +async def test_stretch_switch_changes( + hass: HomeAssistant, mock_stretch: MagicMock, init_integration: MockConfigEntry +) -> None: """Test changing of power related switch entities.""" - entry = await async_init_integration(hass, mock_stretch) - assert entry.state is ConfigEntryState.LOADED - await hass.services.async_call( "switch", "turn_off", @@ -150,12 +151,11 @@ async def test_stretch_switch_changes(hass, mock_stretch): ) -async def test_unique_id_migration_plug_relay(hass, mock_smile_adam): +async def test_unique_id_migration_plug_relay( + hass: HomeAssistant, mock_smile_adam: MagicMock, mock_config_entry: MockConfigEntry +) -> None: """Test unique ID migration of -plugs to -relay.""" - entry = MockConfigEntry( - domain=DOMAIN, data={"host": "1.1.1.1", "password": "test-password"} - ) - entry.add_to_hass(hass) + mock_config_entry.add_to_hass(hass) registry = er.async_get(hass) # Entry to migrate @@ -163,7 +163,7 @@ async def test_unique_id_migration_plug_relay(hass, mock_smile_adam): SWITCH_DOMAIN, DOMAIN, "21f2b542c49845e6bb416884c55778d6-plug", - config_entry=entry, + config_entry=mock_config_entry, suggested_object_id="playstation_smart_plug", disabled_by=None, ) @@ -172,12 +172,12 @@ async def test_unique_id_migration_plug_relay(hass, mock_smile_adam): SWITCH_DOMAIN, DOMAIN, "675416a629f343c495449970e2ca37b5-relay", - config_entry=entry, + config_entry=mock_config_entry, suggested_object_id="router", disabled_by=None, ) - await hass.config_entries.async_setup(entry.entry_id) + await hass.config_entries.async_setup(mock_config_entry.entry_id) await hass.async_block_till_done() assert hass.states.get("switch.playstation_smart_plug") is not None