mirror of
https://github.com/home-assistant/core.git
synced 2025-07-28 07:37:34 +00:00
Add Homee general tests (#137128)
This commit is contained in:
parent
8d7e387b46
commit
1b11ac9123
@ -96,6 +96,55 @@
|
||||
"options": {
|
||||
"automations": ["step"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"node_id": 3,
|
||||
"instance": 0,
|
||||
"minimum": -50,
|
||||
"maximum": 125,
|
||||
"current_value": 20.3,
|
||||
"target_value": 20.3,
|
||||
"last_value": 20.3,
|
||||
"unit": "°C",
|
||||
"step_value": 1.0,
|
||||
"editable": 0,
|
||||
"type": 5,
|
||||
"state": 1,
|
||||
"last_changed": 1709982925,
|
||||
"changed_by": 1,
|
||||
"changed_by_id": 0,
|
||||
"based_on": 1,
|
||||
"data": "",
|
||||
"name": "",
|
||||
"options": {
|
||||
"history": {
|
||||
"day": 1,
|
||||
"week": 26,
|
||||
"month": 6
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"node_id": 3,
|
||||
"instance": 0,
|
||||
"minimum": 0,
|
||||
"maximum": 0,
|
||||
"current_value": 0.0,
|
||||
"target_value": 0.0,
|
||||
"last_value": 0.0,
|
||||
"unit": "text",
|
||||
"step_value": 1.0,
|
||||
"editable": 0,
|
||||
"type": 44,
|
||||
"state": 1,
|
||||
"last_changed": 0,
|
||||
"changed_by": 1,
|
||||
"changed_by_id": 0,
|
||||
"based_on": 1,
|
||||
"data": "4.54",
|
||||
"name": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -43,6 +43,27 @@
|
||||
"observes": [75],
|
||||
"automations": ["toggle"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"node_id": 3,
|
||||
"instance": 0,
|
||||
"minimum": 0,
|
||||
"maximum": 0,
|
||||
"current_value": 0.0,
|
||||
"target_value": 0.0,
|
||||
"last_value": 0.0,
|
||||
"unit": "text",
|
||||
"step_value": 1.0,
|
||||
"editable": 0,
|
||||
"type": 45,
|
||||
"state": 1,
|
||||
"last_changed": 0,
|
||||
"changed_by": 1,
|
||||
"changed_by_id": 0,
|
||||
"based_on": 1,
|
||||
"data": "1.45",
|
||||
"name": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -689,6 +689,55 @@
|
||||
'type': 113,
|
||||
'unit': '°',
|
||||
}),
|
||||
dict({
|
||||
'based_on': 1,
|
||||
'changed_by': 1,
|
||||
'changed_by_id': 0,
|
||||
'current_value': 20.3,
|
||||
'data': '',
|
||||
'editable': 0,
|
||||
'id': 4,
|
||||
'instance': 0,
|
||||
'last_changed': 1709982925,
|
||||
'last_value': 20.3,
|
||||
'maximum': 125,
|
||||
'minimum': -50,
|
||||
'name': '',
|
||||
'node_id': 3,
|
||||
'options': dict({
|
||||
'history': dict({
|
||||
'day': 1,
|
||||
'month': 6,
|
||||
'week': 26,
|
||||
}),
|
||||
}),
|
||||
'state': 1,
|
||||
'step_value': 1.0,
|
||||
'target_value': 20.3,
|
||||
'type': 5,
|
||||
'unit': '°C',
|
||||
}),
|
||||
dict({
|
||||
'based_on': 1,
|
||||
'changed_by': 1,
|
||||
'changed_by_id': 0,
|
||||
'current_value': 0.0,
|
||||
'data': '4.54',
|
||||
'editable': 0,
|
||||
'id': 5,
|
||||
'instance': 0,
|
||||
'last_changed': 0,
|
||||
'last_value': 0.0,
|
||||
'maximum': 0,
|
||||
'minimum': 0,
|
||||
'name': '',
|
||||
'node_id': 3,
|
||||
'state': 1,
|
||||
'step_value': 1.0,
|
||||
'target_value': 0.0,
|
||||
'type': 44,
|
||||
'unit': 'text',
|
||||
}),
|
||||
]),
|
||||
'cube_type': 14,
|
||||
'favorite': 0,
|
||||
|
71
tests/components/homee/snapshots/test_init.ambr
Normal file
71
tests/components/homee/snapshots/test_init.ambr
Normal file
@ -0,0 +1,71 @@
|
||||
# serializer version: 1
|
||||
# name: test_general_data
|
||||
DeviceRegistryEntrySnapshot({
|
||||
'area_id': None,
|
||||
'config_entries': <ANY>,
|
||||
'config_entries_subentries': <ANY>,
|
||||
'configuration_url': None,
|
||||
'connections': set({
|
||||
tuple(
|
||||
'mac',
|
||||
'00:05:55:11:ee:cc',
|
||||
),
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'entry_type': None,
|
||||
'hw_version': None,
|
||||
'id': <ANY>,
|
||||
'identifiers': set({
|
||||
tuple(
|
||||
'homee',
|
||||
'00055511EECC',
|
||||
),
|
||||
}),
|
||||
'is_new': False,
|
||||
'labels': set({
|
||||
}),
|
||||
'manufacturer': 'homee',
|
||||
'model': 'homee',
|
||||
'model_id': None,
|
||||
'name': 'TestHomee',
|
||||
'name_by_user': None,
|
||||
'primary_config_entry': <ANY>,
|
||||
'serial_number': None,
|
||||
'suggested_area': None,
|
||||
'sw_version': '1.2.3',
|
||||
'via_device_id': None,
|
||||
})
|
||||
# ---
|
||||
# name: test_general_data.1
|
||||
DeviceRegistryEntrySnapshot({
|
||||
'area_id': None,
|
||||
'config_entries': <ANY>,
|
||||
'config_entries_subentries': <ANY>,
|
||||
'configuration_url': None,
|
||||
'connections': set({
|
||||
}),
|
||||
'disabled_by': None,
|
||||
'entry_type': None,
|
||||
'hw_version': None,
|
||||
'id': <ANY>,
|
||||
'identifiers': set({
|
||||
tuple(
|
||||
'homee',
|
||||
'00055511EECC-3',
|
||||
),
|
||||
}),
|
||||
'is_new': False,
|
||||
'labels': set({
|
||||
}),
|
||||
'manufacturer': None,
|
||||
'model': 'shutter_position_switch',
|
||||
'model_id': None,
|
||||
'name': 'Test Cover',
|
||||
'name_by_user': None,
|
||||
'primary_config_entry': <ANY>,
|
||||
'serial_number': None,
|
||||
'suggested_area': None,
|
||||
'sw_version': '4.54',
|
||||
'via_device_id': <ANY>,
|
||||
})
|
||||
# ---
|
@ -13,6 +13,10 @@ from homeassistant.components.cover import (
|
||||
CoverEntityFeature,
|
||||
CoverState,
|
||||
)
|
||||
from homeassistant.components.homeassistant import (
|
||||
DOMAIN as HA_DOMAIN,
|
||||
SERVICE_UPDATE_ENTITY,
|
||||
)
|
||||
from homeassistant.components.homee.const import DOMAIN
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
@ -23,9 +27,11 @@ from homeassistant.const import (
|
||||
SERVICE_SET_COVER_POSITION,
|
||||
SERVICE_SET_COVER_TILT_POSITION,
|
||||
SERVICE_STOP_COVER,
|
||||
STATE_UNAVAILABLE,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from . import build_mock_node, setup_integration
|
||||
|
||||
@ -39,6 +45,7 @@ async def test_open_close_stop_cover(
|
||||
) -> None:
|
||||
"""Test opening the cover."""
|
||||
mock_homee.nodes = [build_mock_node("cover_with_position_slats.json")]
|
||||
mock_homee.get_node_by_id.return_value = mock_homee.nodes[0]
|
||||
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
@ -73,6 +80,7 @@ async def test_open_close_reverse_cover(
|
||||
) -> None:
|
||||
"""Test opening the cover."""
|
||||
mock_homee.nodes = [build_mock_node("cover_with_position_slats.json")]
|
||||
mock_homee.get_node_by_id.return_value = mock_homee.nodes[0]
|
||||
mock_homee.nodes[0].attributes[0].is_reversed = True
|
||||
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
@ -102,6 +110,7 @@ async def test_set_cover_position(
|
||||
) -> None:
|
||||
"""Test setting the cover position."""
|
||||
mock_homee.nodes = [build_mock_node("cover_with_position_slats.json")]
|
||||
mock_homee.get_node_by_id.return_value = mock_homee.nodes[0]
|
||||
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
@ -246,6 +255,7 @@ async def test_cover_positions(
|
||||
# Cover open, tilt open.
|
||||
# mock_homee.nodes = [cover]
|
||||
mock_homee.nodes = [build_mock_node("cover_with_position_slats.json")]
|
||||
mock_homee.get_node_by_id.return_value = mock_homee.nodes[0]
|
||||
cover = mock_homee.nodes[0]
|
||||
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
@ -348,3 +358,50 @@ async def test_send_error(
|
||||
|
||||
assert exc_info.value.translation_domain == DOMAIN
|
||||
assert exc_info.value.translation_key == "connection_closed"
|
||||
|
||||
|
||||
async def test_node_entity_connection_listener(
|
||||
hass: HomeAssistant,
|
||||
mock_homee: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test if loss of connection is sensed correctly."""
|
||||
mock_homee.nodes = [build_mock_node("cover_with_position_slats.json")]
|
||||
mock_homee.get_node_by_id.return_value = mock_homee.nodes[0]
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
states = hass.states.get("cover.test_cover")
|
||||
assert states.state != STATE_UNAVAILABLE
|
||||
|
||||
await mock_homee.add_connection_listener.call_args_list[1][0][0](False)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
states = hass.states.get("cover.test_cover")
|
||||
assert states.state == STATE_UNAVAILABLE
|
||||
|
||||
await mock_homee.add_connection_listener.call_args_list[1][0][0](True)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
states = hass.states.get("cover.test_cover")
|
||||
assert states.state != STATE_UNAVAILABLE
|
||||
|
||||
|
||||
async def test_node_entity_update_action(
|
||||
hass: HomeAssistant,
|
||||
mock_homee: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test the update_entity action for a HomeeEntity."""
|
||||
mock_homee.nodes = [build_mock_node("cover_with_position_slats.json")]
|
||||
mock_homee.get_node_by_id.return_value = mock_homee.nodes[0]
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
await async_setup_component(hass, HA_DOMAIN, {})
|
||||
|
||||
await hass.services.async_call(
|
||||
HA_DOMAIN,
|
||||
SERVICE_UPDATE_ENTITY,
|
||||
{ATTR_ENTITY_ID: "cover.test_cover"},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
mock_homee.update_node.assert_called_once_with(3)
|
||||
|
131
tests/components/homee/test_init.py
Normal file
131
tests/components/homee/test_init.py
Normal file
@ -0,0 +1,131 @@
|
||||
"""Test Homee initialization."""
|
||||
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from pyHomee import HomeeAuthFailedException, HomeeConnectionFailedException
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.homee.const import DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
|
||||
from . import build_mock_node, setup_integration
|
||||
from .conftest import HOMEE_ID
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"side_eff",
|
||||
[
|
||||
HomeeConnectionFailedException("connection timed out"),
|
||||
HomeeAuthFailedException("wrong username or password"),
|
||||
],
|
||||
)
|
||||
async def test_connection_errors(
|
||||
hass: HomeAssistant,
|
||||
mock_homee: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
side_eff: Exception,
|
||||
) -> None:
|
||||
"""Test if connection errors on startup are handled correctly."""
|
||||
mock_homee.get_access_token.side_effect = side_eff
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
|
||||
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
|
||||
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
|
||||
|
||||
|
||||
async def test_connection_listener(
|
||||
hass: HomeAssistant,
|
||||
mock_homee: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test if loss of connection is sensed correctly."""
|
||||
mock_homee.nodes = [build_mock_node("homee.json")]
|
||||
mock_homee.get_node_by_id.return_value = mock_homee.nodes[0]
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
await mock_homee.add_connection_listener.call_args_list[0][0][0](False)
|
||||
await hass.async_block_till_done()
|
||||
assert "Disconnected from Homee" in caplog.text
|
||||
await mock_homee.add_connection_listener.call_args_list[0][0][0](True)
|
||||
await hass.async_block_till_done()
|
||||
assert "Reconnected to Homee" in caplog.text
|
||||
|
||||
|
||||
async def test_general_data(
|
||||
hass: HomeAssistant,
|
||||
mock_homee: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
snapshot: SnapshotAssertion,
|
||||
) -> None:
|
||||
"""Test if data is set correctly."""
|
||||
mock_homee.nodes = [
|
||||
build_mock_node("cover_with_position_slats.json"),
|
||||
build_mock_node("homee.json"),
|
||||
]
|
||||
mock_homee.get_node_by_id = (
|
||||
lambda node_id: mock_homee.nodes[0] if node_id == 3 else mock_homee.nodes[1]
|
||||
)
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
# Verify hub and device created correctly using snapshots.
|
||||
hub = device_registry.async_get_device(identifiers={(DOMAIN, f"{HOMEE_ID}")})
|
||||
device = device_registry.async_get_device(identifiers={(DOMAIN, f"{HOMEE_ID}-3")})
|
||||
|
||||
assert hub == snapshot
|
||||
assert device == snapshot
|
||||
|
||||
|
||||
async def test_software_version(
|
||||
hass: HomeAssistant,
|
||||
mock_homee: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
) -> None:
|
||||
"""Test sw_version for device with only AttributeType.SOFTWARE_VERSION."""
|
||||
mock_homee.nodes = [build_mock_node("cover_without_position.json")]
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
device = device_registry.async_get_device(identifiers={(DOMAIN, f"{HOMEE_ID}-3")})
|
||||
assert device.sw_version == "1.45"
|
||||
|
||||
|
||||
async def test_invalid_profile(
|
||||
hass: HomeAssistant,
|
||||
mock_homee: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
) -> None:
|
||||
"""Test unknown value passed to get_name_for_enum."""
|
||||
mock_homee.nodes = [build_mock_node("cover_without_position.json")]
|
||||
# This is a profile, that does not exist in the enum.
|
||||
mock_homee.nodes[0].profile = 77
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
device = device_registry.async_get_device(identifiers={(DOMAIN, f"{HOMEE_ID}-3")})
|
||||
assert device.model is None
|
||||
|
||||
|
||||
async def test_unload_entry(
|
||||
hass: HomeAssistant,
|
||||
mock_homee: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test unloading of config entry."""
|
||||
mock_homee.nodes = [build_mock_node("cover_with_position_slats.json")]
|
||||
mock_homee.get_node_by_id.return_value = mock_homee.nodes[0]
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
|
||||
assert mock_config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
await hass.config_entries.async_unload(mock_config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert mock_config_entry.state is ConfigEntryState.NOT_LOADED
|
@ -5,6 +5,10 @@ from unittest.mock import MagicMock, patch
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.homeassistant import (
|
||||
DOMAIN as HA_DOMAIN,
|
||||
SERVICE_UPDATE_ENTITY,
|
||||
)
|
||||
from homeassistant.components.homee.const import (
|
||||
DOMAIN,
|
||||
OPEN_CLOSE_MAP,
|
||||
@ -13,9 +17,10 @@ from homeassistant.components.homee.const import (
|
||||
WINDOW_MAP_REVERSED,
|
||||
)
|
||||
from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.const import ATTR_ENTITY_ID, STATE_UNAVAILABLE, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er, issue_registry as ir
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from . import async_update_attribute_value, build_mock_node, setup_integration
|
||||
from .conftest import HOMEE_ID
|
||||
@ -168,6 +173,49 @@ async def test_sensor_deprecation_unused_entity(
|
||||
)
|
||||
|
||||
|
||||
async def test_entity_connection_listener(
|
||||
hass: HomeAssistant,
|
||||
mock_homee: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test if loss of connection is sensed correctly."""
|
||||
await setup_sensor(hass, mock_homee, mock_config_entry)
|
||||
|
||||
states = hass.states.get("sensor.test_multisensor_energy_1")
|
||||
assert states.state is not STATE_UNAVAILABLE
|
||||
|
||||
await mock_homee.add_connection_listener.call_args_list[2][0][0](False)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
states = hass.states.get("sensor.test_multisensor_energy_1")
|
||||
assert states.state is STATE_UNAVAILABLE
|
||||
|
||||
await mock_homee.add_connection_listener.call_args_list[2][0][0](True)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
states = hass.states.get("sensor.test_multisensor_energy_1")
|
||||
assert states.state is not STATE_UNAVAILABLE
|
||||
|
||||
|
||||
async def test_entity_update_action(
|
||||
hass: HomeAssistant,
|
||||
mock_homee: MagicMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test the update_entity action for a HomeeEntity."""
|
||||
await setup_sensor(hass, mock_homee, mock_config_entry)
|
||||
await async_setup_component(hass, HA_DOMAIN, {})
|
||||
|
||||
await hass.services.async_call(
|
||||
HA_DOMAIN,
|
||||
SERVICE_UPDATE_ENTITY,
|
||||
{ATTR_ENTITY_ID: "sensor.test_multisensor_temperature"},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
mock_homee.update_attribute.assert_called_once_with(1, 23)
|
||||
|
||||
|
||||
async def test_sensor_snapshot(
|
||||
hass: HomeAssistant,
|
||||
mock_homee: MagicMock,
|
||||
|
Loading…
x
Reference in New Issue
Block a user