Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -656,11 +656,6 @@ omit =
homeassistant/components/plaato/*
homeassistant/components/plex/media_player.py
homeassistant/components/plex/sensor.py
homeassistant/components/plugwise/__init__.py
homeassistant/components/plugwise/binary_sensor.py
homeassistant/components/plugwise/climate.py
homeassistant/components/plugwise/sensor.py
homeassistant/components/plugwise/switch.py
homeassistant/components/plum_lightpad/light.py
homeassistant/components/pocketcasts/sensor.py
homeassistant/components/point/*
Expand Down
1 change: 0 additions & 1 deletion homeassistant/components/plugwise/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ async def async_step_user(self, user_input=None):
except Exception: # pylint: disable=broad-except
_LOGGER.exception("Unexpected exception")
errors["base"] = "unknown"

if not errors:
Comment thread
CoMPaTech marked this conversation as resolved.
await self.async_set_unique_id(api.gateway_id)
self._abort_if_unique_id_configured()
Expand Down
1 change: 1 addition & 0 deletions requirements_test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
asynctest==0.13.0
codecov==2.1.0
coverage==5.2.1
jsonpickle==1.4.1
mock-open==1.4.0
mypy==0.780
pre-commit==2.7.1
Expand Down
26 changes: 26 additions & 0 deletions tests/components/plugwise/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""Common initialisation for the Plugwise integration."""

from homeassistant.components.plugwise 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
167 changes: 167 additions & 0 deletions tests/components/plugwise/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
"""Setup mocks for the Plugwise integration tests."""

from functools import partial
import re

from Plugwise_Smile.Smile import Smile
import jsonpickle
import pytest

from tests.async_mock import AsyncMock, patch
from tests.common import load_fixture
from tests.test_util.aiohttp import AiohttpClientMocker


def _read_json(environment, call):
"""Undecode the json data."""
fixture = load_fixture(f"plugwise/{environment}/{call}.json")
return jsonpickle.decode(fixture)


@pytest.fixture(name="mock_smile")
def mock_smile():
"""Create a Mock Smile for testing exceptions."""
with patch(
"homeassistant.components.plugwise.config_flow.Smile",
) as smile_mock:
smile_mock.InvalidAuthentication = Smile.InvalidAuthentication
smile_mock.ConnectionFailedError = Smile.ConnectionFailedError
smile_mock.return_value.connect.return_value = True
yield smile_mock.return_value


@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=401)
aioclient_mock.put(re.compile(".*"), status=401)


@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=500)
aioclient_mock.put(re.compile(".*"), status=500)


@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.Smile") as smile_mock:
smile_mock.InvalidAuthentication = Smile.InvalidAuthentication
smile_mock.ConnectionFailedError = Smile.ConnectionFailedError
smile_mock.PlugwiseError = Smile.PlugwiseError
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."""
chosen_env = "adam_multiple_devices_per_zone"
with patch("homeassistant.components.plugwise.Smile") as smile_mock:
smile_mock.InvalidAuthentication = Smile.InvalidAuthentication
smile_mock.ConnectionFailedError = Smile.ConnectionFailedError
smile_mock.XMLDataMissingError = Smile.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.connect.side_effect = AsyncMock(return_value=True)
smile_mock.return_value.full_update_device.side_effect = AsyncMock(
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_relay_state.side_effect = AsyncMock(
return_value=True
)

smile_mock.return_value.get_all_devices.return_value = _read_json(
chosen_env, "get_all_devices"
)
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_anna")
def mock_smile_anna():
"""Create a Mock Anna environment for testing exceptions."""
chosen_env = "anna_heatpump"
with patch("homeassistant.components.plugwise.Smile") as smile_mock:
smile_mock.InvalidAuthentication = Smile.InvalidAuthentication
smile_mock.ConnectionFailedError = Smile.ConnectionFailedError
smile_mock.XMLDataMissingError = Smile.XMLDataMissingError

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.connect.side_effect = AsyncMock(return_value=True)
smile_mock.return_value.full_update_device.side_effect = AsyncMock(
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_relay_state.side_effect = AsyncMock(
return_value=True
)

smile_mock.return_value.get_all_devices.return_value = _read_json(
chosen_env, "get_all_devices"
)
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")
def mock_smile_p1():
"""Create a Mock P1 DSMR environment for testing exceptions."""
chosen_env = "p1v3_full_option"
with patch("homeassistant.components.plugwise.Smile") as smile_mock:
smile_mock.InvalidAuthentication = Smile.InvalidAuthentication
smile_mock.ConnectionFailedError = Smile.ConnectionFailedError
smile_mock.XMLDataMissingError = Smile.XMLDataMissingError

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.connect.side_effect = AsyncMock(return_value=True)
smile_mock.return_value.full_update_device.side_effect = AsyncMock(
return_value=True
)

smile_mock.return_value.get_all_devices.return_value = _read_json(
chosen_env, "get_all_devices"
)
smile_mock.return_value.get_device_data.side_effect = partial(
_get_device_data, chosen_env
)

yield smile_mock.return_value
37 changes: 37 additions & 0 deletions tests/components/plugwise/test_binary_sensor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""Tests for the Plugwise binary_sensor integration."""

from homeassistant.config_entries import ENTRY_STATE_LOADED
from homeassistant.const import STATE_OFF, STATE_ON

from tests.components.plugwise.common import async_init_integration


async def test_anna_climate_binary_sensor_entities(hass, mock_smile_anna):
"""Test creation of climate related binary_sensor entities."""
entry = await async_init_integration(hass, mock_smile_anna)
assert entry.state == ENTRY_STATE_LOADED

state = hass.states.get("binary_sensor.auxiliary_slave_boiler_state")
assert str(state.state) == STATE_OFF

state = hass.states.get("binary_sensor.auxiliary_dhw_state")
assert str(state.state) == STATE_OFF


async def test_anna_climate_binary_sensor_change(hass, mock_smile_anna):
"""Test change of climate related binary_sensor entities."""
entry = await async_init_integration(hass, mock_smile_anna)
assert entry.state == ENTRY_STATE_LOADED

hass.states.async_set("binary_sensor.auxiliary_dhw_state", STATE_ON, {})
await hass.async_block_till_done()

state = hass.states.get("binary_sensor.auxiliary_dhw_state")
assert str(state.state) == STATE_ON

await hass.helpers.entity_component.async_update_entity(
"binary_sensor.auxiliary_dhw_state"
)

state = hass.states.get("binary_sensor.auxiliary_dhw_state")
assert str(state.state) == STATE_OFF
Loading