Cleanup existing Plugwise tests and test fixtures (#66282)

* Cleanup existing Plugwise tests and test fixtures

* More cleanup
This commit is contained in:
Franck Nijhof 2022-02-10 20:41:30 +01:00 committed by GitHub
parent e5eba88ecc
commit bd920aa43d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 310 additions and 377 deletions

View file

@ -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

View file

@ -2,30 +2,49 @@
from __future__ import annotations from __future__ import annotations
from collections.abc import Generator from collections.abc import Generator
from functools import partial
from http import HTTPStatus
import json import json
import re from typing import Any
from unittest.mock import AsyncMock, MagicMock, Mock, patch from unittest.mock import AsyncMock, MagicMock, patch
from plugwise.exceptions import (
ConnectionFailedError,
InvalidAuthentication,
PlugwiseException,
XMLDataMissingError,
)
import pytest import pytest
from tests.common import load_fixture from homeassistant.components.plugwise.const import API, DOMAIN, PW_TYPE
from tests.test_util.aiohttp import AiohttpClientMocker 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.""" """Undecode the json data."""
fixture = load_fixture(f"plugwise/{environment}/{call}.json") fixture = load_fixture(f"plugwise/{environment}/{call}.json")
return json.loads(fixture) 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 @pytest.fixture
def mock_setup_entry() -> Generator[AsyncMock, None, None]: def mock_setup_entry() -> Generator[AsyncMock, None, None]:
"""Mock setting up a config entry.""" """Mock setting up a config entry."""
@ -49,179 +68,109 @@ def mock_smile_config_flow() -> Generator[None, MagicMock, None]:
yield smile yield smile
@pytest.fixture(name="mock_smile_unauth") @pytest.fixture
def mock_smile_unauth(aioclient_mock: AiohttpClientMocker) -> None: def mock_smile_adam() -> Generator[None, MagicMock, 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():
"""Create a Mock Adam environment for testing exceptions.""" """Create a Mock Adam environment for testing exceptions."""
chosen_env = "adam_multiple_devices_per_zone" 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" with patch(
smile_mock.return_value.heater_id = "90986d591dcd426cae3ec3e8111ff730" "homeassistant.components.plugwise.gateway.Smile", autospec=True
smile_mock.return_value.smile_version = "3.0.15" ) as smile_mock:
smile_mock.return_value.smile_type = "thermostat" smile = smile_mock.return_value
smile_mock.return_value.smile_hostname = "smile98765"
smile_mock.return_value.smile_name = "Adam"
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.connect.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
)
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") @pytest.fixture
def mock_smile_anna(): def mock_smile_anna() -> Generator[None, MagicMock, None]:
"""Create a Mock Anna environment for testing exceptions.""" """Create a Mock Anna environment for testing exceptions."""
chosen_env = "anna_heatpump" chosen_env = "anna_heatpump"
with patch("homeassistant.components.plugwise.gateway.Smile") as smile_mock: with patch(
smile_mock.InvalidAuthentication = InvalidAuthentication "homeassistant.components.plugwise.gateway.Smile", autospec=True
smile_mock.ConnectionFailedError = ConnectionFailedError ) as smile_mock:
smile_mock.XMLDataMissingError = XMLDataMissingError smile = smile_mock.return_value
smile_mock.return_value.gateway_id = "015ae9ea3f964e668e490fa39da3870b" smile.gateway_id = "015ae9ea3f964e668e490fa39da3870b"
smile_mock.return_value.heater_id = "1cbf783bb11e4a7c8a6843dee3a86927" smile.heater_id = "1cbf783bb11e4a7c8a6843dee3a86927"
smile_mock.return_value.smile_version = "4.0.15" smile.smile_version = "4.0.15"
smile_mock.return_value.smile_type = "thermostat" smile.smile_type = "thermostat"
smile_mock.return_value.smile_hostname = "smile98765" smile.smile_hostname = "smile98765"
smile_mock.return_value.smile_name = "Anna" 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.notifications = _read_json(chosen_env, "notifications")
smile_mock.return_value.single_master_thermostat.side_effect = Mock( smile.async_update.return_value = _read_json(chosen_env, "all_data")
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_mock.return_value.async_update.side_effect = AsyncMock( yield smile
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
@pytest.fixture(name="mock_smile_p1") @pytest.fixture
def mock_smile_p1(): def mock_smile_p1() -> Generator[None, MagicMock, None]:
"""Create a Mock P1 DSMR environment for testing exceptions.""" """Create a Mock P1 DSMR environment for testing exceptions."""
chosen_env = "p1v3_full_option" chosen_env = "p1v3_full_option"
with patch("homeassistant.components.plugwise.gateway.Smile") as smile_mock: with patch(
smile_mock.InvalidAuthentication = InvalidAuthentication "homeassistant.components.plugwise.gateway.Smile", autospec=True
smile_mock.ConnectionFailedError = ConnectionFailedError ) as smile_mock:
smile_mock.XMLDataMissingError = XMLDataMissingError smile = smile_mock.return_value
smile_mock.return_value.gateway_id = "e950c7d5e1ee407a858e2a8b5016c8b3" smile.gateway_id = "e950c7d5e1ee407a858e2a8b5016c8b3"
smile_mock.return_value.heater_id = None smile.heater_id = None
smile_mock.return_value.smile_version = "3.3.9" smile.smile_version = "3.3.9"
smile_mock.return_value.smile_type = "power" smile.smile_type = "power"
smile_mock.return_value.smile_hostname = "smile98765" smile.smile_hostname = "smile98765"
smile_mock.return_value.smile_name = "Smile P1" 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( yield smile
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
@pytest.fixture(name="mock_stretch") @pytest.fixture
def mock_stretch(): def mock_stretch() -> Generator[None, MagicMock, None]:
"""Create a Mock Stretch environment for testing exceptions.""" """Create a Mock Stretch environment for testing exceptions."""
chosen_env = "stretch_v31" chosen_env = "stretch_v31"
with patch("homeassistant.components.plugwise.gateway.Smile") as smile_mock: with patch(
smile_mock.InvalidAuthentication = InvalidAuthentication "homeassistant.components.plugwise.gateway.Smile", autospec=True
smile_mock.ConnectionFailedError = ConnectionFailedError ) as smile_mock:
smile_mock.XMLDataMissingError = XMLDataMissingError smile = smile_mock.return_value
smile_mock.return_value.gateway_id = "259882df3c05415b99c2d962534ce820" smile.gateway_id = "259882df3c05415b99c2d962534ce820"
smile_mock.return_value.heater_id = None smile.heater_id = None
smile_mock.return_value.smile_version = "3.1.11" smile.smile_version = "3.1.11"
smile_mock.return_value.smile_type = "stretch" smile.smile_type = "stretch"
smile_mock.return_value.smile_hostname = "stretch98765" smile.smile_hostname = "stretch98765"
smile_mock.return_value.smile_name = "Stretch" smile.smile_name = "Stretch"
smile_mock.return_value.connect.side_effect = AsyncMock(return_value=True) smile.connect.return_value = True
smile_mock.return_value.set_switch_state.side_effect = AsyncMock( smile.async_update.return_value = _read_json(chosen_env, "all_data")
return_value=True
)
smile_mock.return_value.get_device_data.side_effect = partial(
_get_device_data, chosen_env
)
smile_mock.return_value.async_update.side_effect = AsyncMock( yield smile
return_value=_read_json(chosen_env, "all_data")
)
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

View file

@ -1,32 +1,36 @@
"""Tests for the Plugwise binary_sensor integration.""" """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.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.""" """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") state = hass.states.get("binary_sensor.opentherm_secondary_boiler_state")
assert state
assert state.state == STATE_OFF assert state.state == STATE_OFF
state = hass.states.get("binary_sensor.opentherm_dhw_state") state = hass.states.get("binary_sensor.opentherm_dhw_state")
assert state
assert state.state == STATE_OFF 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.""" """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, {}) hass.states.async_set("binary_sensor.opentherm_dhw_state", STATE_ON, {})
await hass.async_block_till_done() await hass.async_block_till_done()
state = hass.states.get("binary_sensor.opentherm_dhw_state") state = hass.states.get("binary_sensor.opentherm_dhw_state")
assert state
assert state.state == STATE_ON assert state.state == STATE_ON
await hass.helpers.entity_component.async_update_entity( 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") state = hass.states.get("binary_sensor.opentherm_dhw_state")
assert state
assert state.state == STATE_OFF 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.""" """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") state = hass.states.get("binary_sensor.adam_plugwise_notification")
assert str(state.state) == STATE_ON assert state
assert "unreachable" in state.attributes.get("warning_msg")[0] 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("error_msg")
assert not state.attributes.get("other_msg") assert not state.attributes.get("other_msg")

View file

@ -1,5 +1,7 @@
"""Tests for the Plugwise Climate integration.""" """Tests for the Plugwise Climate integration."""
from unittest.mock import MagicMock
from plugwise.exceptions import PlugwiseException from plugwise.exceptions import PlugwiseException
import pytest import pytest
@ -9,55 +11,59 @@ from homeassistant.components.climate.const import (
HVAC_MODE_HEAT, HVAC_MODE_HEAT,
HVAC_MODE_OFF, HVAC_MODE_OFF,
) )
from homeassistant.config_entries import ConfigEntryState from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError 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.""" """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") 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 "preset_modes" in state.attributes
assert "no_frost" in attrs["preset_modes"] assert "no_frost" in state.attributes["preset_modes"]
assert "home" in attrs["preset_modes"] assert "home" in state.attributes["preset_modes"]
assert attrs["current_temperature"] == 20.9 assert state.attributes["current_temperature"] == 20.9
assert attrs["temperature"] == 21.5 assert state.attributes["preset_mode"] == "home"
assert state.attributes["supported_features"] == 17
assert attrs["preset_mode"] == "home" assert state.attributes["temperature"] == 21.5
assert attrs["supported_features"] == 17
state = hass.states.get("climate.zone_thermostat_jessie") 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 "preset_modes" in state.attributes
assert "no_frost" in attrs["preset_modes"] assert "no_frost" in state.attributes["preset_modes"]
assert "home" in attrs["preset_modes"] assert "home" in state.attributes["preset_modes"]
assert attrs["current_temperature"] == 17.2 assert state.attributes["current_temperature"] == 17.2
assert attrs["temperature"] == 15.0 assert state.attributes["preset_mode"] == "asleep"
assert state.attributes["temperature"] == 15.0
assert attrs["preset_mode"] == "asleep"
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.""" """Test exceptions of climate entities."""
mock_smile_adam.set_preset.side_effect = PlugwiseException mock_smile_adam.set_preset.side_effect = PlugwiseException
mock_smile_adam.set_schedule_state.side_effect = PlugwiseException mock_smile_adam.set_schedule_state.side_effect = PlugwiseException
mock_smile_adam.set_temperature.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): with pytest.raises(HomeAssistantError):
await hass.services.async_call( 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}, {"entity_id": "climate.zone_lisa_wk", "temperature": 25},
blocking=True, blocking=True,
) )
state = hass.states.get("climate.zone_lisa_wk")
attrs = state.attributes
assert attrs["temperature"] == 21.5
with pytest.raises(HomeAssistantError): with pytest.raises(HomeAssistantError):
await hass.services.async_call( 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"}, {"entity_id": "climate.zone_thermostat_jessie", "preset_mode": "home"},
blocking=True, blocking=True,
) )
state = hass.states.get("climate.zone_thermostat_jessie")
attrs = state.attributes
assert attrs["preset_mode"] == "asleep"
with pytest.raises(HomeAssistantError): with pytest.raises(HomeAssistantError):
await hass.services.async_call( await hass.services.async_call(
@ -91,15 +91,12 @@ async def test_adam_climate_adjust_negative_testing(hass, mock_smile_adam):
}, },
blocking=True, 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.""" """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( await hass.services.async_call(
"climate", "climate",
"set_temperature", "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.""" """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") state = hass.states.get("climate.anna")
attrs = state.attributes assert state
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.state == HVAC_MODE_HEAT assert state.state == HVAC_MODE_HEAT
assert attrs["hvac_action"] == "heating" assert state.attributes["hvac_modes"] == [
assert attrs["preset_mode"] == "home" 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.""" """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( await hass.services.async_call(
"climate", "climate",
"set_temperature", "set_temperature",

View file

@ -5,18 +5,20 @@ from aiohttp import ClientSession
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry
from tests.components.diagnostics import get_diagnostics_for_config_entry from tests.components.diagnostics import get_diagnostics_for_config_entry
from tests.components.plugwise.common import async_init_integration
async def test_diagnostics( async def test_diagnostics(
hass: HomeAssistant, hass: HomeAssistant,
hass_client: ClientSession, hass_client: ClientSession,
mock_smile_adam: MagicMock, mock_smile_adam: MagicMock,
): init_integration: MockConfigEntry,
) -> None:
"""Test diagnostics.""" """Test diagnostics."""
entry = await async_init_integration(hass, mock_smile_adam) assert await get_diagnostics_for_config_entry(
assert await get_diagnostics_for_config_entry(hass, hass_client, entry) == { hass, hass_client, init_integration
) == {
"gateway": { "gateway": {
"active_device": True, "active_device": True,
"cooling_present": None, "cooling_present": None,

View file

@ -1,65 +1,62 @@
"""Tests for the Plugwise Climate integration.""" """Tests for the Plugwise Climate integration."""
import asyncio 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.components.plugwise.const import DOMAIN
from homeassistant.config_entries import ConfigEntryState from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant
from tests.common import AsyncMock, MockConfigEntry from tests.common import MockConfigEntry
from tests.components.plugwise.common import async_init_integration
async def test_smile_unauthorized(hass, mock_smile_unauth): async def test_load_unload_config_entry(
"""Test failing unauthorization by Smile.""" hass: HomeAssistant,
entry = await async_init_integration(hass, mock_smile_unauth) mock_config_entry: MockConfigEntry,
assert entry.state is ConfigEntryState.SETUP_ERROR mock_smile_anna: MagicMock,
) -> None:
"""Test the Plugwise configuration entry loading/unloading."""
async def test_smile_error(hass, mock_smile_error): mock_config_entry.add_to_hass(hass)
"""Test server error handling by Smile.""" await hass.config_entries.async_setup(mock_config_entry.entry_id)
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)
await hass.async_block_till_done() 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): await hass.config_entries.async_unload(mock_config_entry.entry_id)
"""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.async_block_till_done() 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

View file

@ -1,26 +1,30 @@
"""Tests for the Plugwise Sensor integration.""" """Tests for the Plugwise Sensor integration."""
from homeassistant.config_entries import ConfigEntryState from unittest.mock import MagicMock
from tests.common import Mock from homeassistant.core import HomeAssistant
from tests.components.plugwise.common import async_init_integration
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.""" """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") state = hass.states.get("sensor.adam_outdoor_temperature")
assert state
assert float(state.state) == 7.81 assert float(state.state) == 7.81
state = hass.states.get("sensor.cv_pomp_electricity_consumed") state = hass.states.get("sensor.cv_pomp_electricity_consumed")
assert state
assert float(state.state) == 35.6 assert float(state.state) == 35.6
state = hass.states.get("sensor.onoff_water_temperature") state = hass.states.get("sensor.onoff_water_temperature")
assert state
assert float(state.state) == 70.0 assert float(state.state) == 70.0
state = hass.states.get("sensor.cv_pomp_electricity_consumed_interval") state = hass.states.get("sensor.cv_pomp_electricity_consumed_interval")
assert state
assert float(state.state) == 7.37 assert float(state.state) == 7.37
await hass.helpers.entity_component.async_update_entity( 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") state = hass.states.get("sensor.zone_lisa_wk_battery")
assert state
assert int(state.state) == 34 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.""" """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") state = hass.states.get("sensor.opentherm_outdoor_temperature")
assert state
assert float(state.state) == 3.0 assert float(state.state) == 3.0
state = hass.states.get("sensor.opentherm_water_temperature") state = hass.states.get("sensor.opentherm_water_temperature")
assert state
assert float(state.state) == 29.1 assert float(state.state) == 29.1
state = hass.states.get("sensor.anna_illuminance") state = hass.states.get("sensor.anna_illuminance")
assert state
assert float(state.state) == 86.0 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.""" """Test creation of climate related sensor entities as single master thermostat."""
mock_smile_anna.single_master_thermostat.side_effect = Mock(return_value=False) mock_smile_anna.single_master_thermostat.return_value = False
entry = await async_init_integration(hass, mock_smile_anna)
assert entry.state is ConfigEntryState.LOADED
state = hass.states.get("sensor.opentherm_outdoor_temperature") state = hass.states.get("sensor.opentherm_outdoor_temperature")
assert state
assert float(state.state) == 3.0 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.""" """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") state = hass.states.get("sensor.p1_net_electricity_point")
assert state
assert float(state.state) == -2816.0 assert float(state.state) == -2816.0
state = hass.states.get("sensor.p1_electricity_consumed_off_peak_cumulative") state = hass.states.get("sensor.p1_electricity_consumed_off_peak_cumulative")
assert state
assert float(state.state) == 551.09 assert float(state.state) == 551.09
state = hass.states.get("sensor.p1_electricity_produced_peak_point") state = hass.states.get("sensor.p1_electricity_produced_peak_point")
assert state
assert float(state.state) == 2816.0 assert float(state.state) == 2816.0
state = hass.states.get("sensor.p1_electricity_consumed_peak_cumulative") state = hass.states.get("sensor.p1_electricity_consumed_peak_cumulative")
assert state
assert float(state.state) == 442.932 assert float(state.state) == 442.932
state = hass.states.get("sensor.p1_gas_consumed_cumulative") state = hass.states.get("sensor.p1_gas_consumed_cumulative")
assert state
assert float(state.state) == 584.85 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.""" """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") state = hass.states.get("sensor.koelkast_92c4a_electricity_consumed")
assert state
assert float(state.state) == 50.5 assert float(state.state) == 50.5
state = hass.states.get("sensor.droger_52559_electricity_consumed_interval") state = hass.states.get("sensor.droger_52559_electricity_consumed_interval")
assert state
assert float(state.state) == 0.0 assert float(state.state) == 0.0

View file

@ -1,34 +1,36 @@
"""Tests for the Plugwise switch integration.""" """Tests for the Plugwise switch integration."""
from unittest.mock import MagicMock
from plugwise.exceptions import PlugwiseException from plugwise.exceptions import PlugwiseException
import pytest import pytest
from homeassistant.components.plugwise.const import DOMAIN from homeassistant.components.plugwise.const import DOMAIN
from homeassistant.components.switch import DOMAIN as SWITCH_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.exceptions import HomeAssistantError
from homeassistant.helpers import entity_registry as er from homeassistant.helpers import entity_registry as er
from tests.common import MockConfigEntry 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.""" """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") 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") 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.""" """Test exceptions of climate related switch entities."""
mock_smile_adam.set_switch_state.side_effect = PlugwiseException 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): with pytest.raises(HomeAssistantError):
await hass.services.async_call( 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.""" """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( await hass.services.async_call(
"switch", "switch",
"turn_off", "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.""" """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") 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") 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.""" """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( await hass.services.async_call(
"switch", "switch",
"turn_off", "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.""" """Test unique ID migration of -plugs to -relay."""
entry = MockConfigEntry( mock_config_entry.add_to_hass(hass)
domain=DOMAIN, data={"host": "1.1.1.1", "password": "test-password"}
)
entry.add_to_hass(hass)
registry = er.async_get(hass) registry = er.async_get(hass)
# Entry to migrate # Entry to migrate
@ -163,7 +163,7 @@ async def test_unique_id_migration_plug_relay(hass, mock_smile_adam):
SWITCH_DOMAIN, SWITCH_DOMAIN,
DOMAIN, DOMAIN,
"21f2b542c49845e6bb416884c55778d6-plug", "21f2b542c49845e6bb416884c55778d6-plug",
config_entry=entry, config_entry=mock_config_entry,
suggested_object_id="playstation_smart_plug", suggested_object_id="playstation_smart_plug",
disabled_by=None, disabled_by=None,
) )
@ -172,12 +172,12 @@ async def test_unique_id_migration_plug_relay(hass, mock_smile_adam):
SWITCH_DOMAIN, SWITCH_DOMAIN,
DOMAIN, DOMAIN,
"675416a629f343c495449970e2ca37b5-relay", "675416a629f343c495449970e2ca37b5-relay",
config_entry=entry, config_entry=mock_config_entry,
suggested_object_id="router", suggested_object_id="router",
disabled_by=None, 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() await hass.async_block_till_done()
assert hass.states.get("switch.playstation_smart_plug") is not None assert hass.states.get("switch.playstation_smart_plug") is not None