From 93a231fb19b9e34097691d03da01406efd4ad943 Mon Sep 17 00:00:00 2001 From: Markus Adrario Date: Sun, 26 Jan 2025 12:49:28 +0000 Subject: [PATCH] Homee cover-test (#136563) initial cover-test --- tests/components/homee/__init__.py | 12 ++ tests/components/homee/conftest.py | 21 ++-- tests/components/homee/fixtures/cover1.json | 101 ++++++++++++++++ tests/components/homee/fixtures/cover2.json | 101 ++++++++++++++++ tests/components/homee/fixtures/cover3.json | 101 ++++++++++++++++ tests/components/homee/fixtures/cover4.json | 101 ++++++++++++++++ tests/components/homee/test_cover.py | 124 ++++++++++++++++++++ 7 files changed, 551 insertions(+), 10 deletions(-) create mode 100644 tests/components/homee/fixtures/cover1.json create mode 100644 tests/components/homee/fixtures/cover2.json create mode 100644 tests/components/homee/fixtures/cover3.json create mode 100644 tests/components/homee/fixtures/cover4.json create mode 100644 tests/components/homee/test_cover.py diff --git a/tests/components/homee/__init__.py b/tests/components/homee/__init__.py index 03095aca7df..95fc6099269 100644 --- a/tests/components/homee/__init__.py +++ b/tests/components/homee/__init__.py @@ -1 +1,13 @@ """Tests for the homee component.""" + +from homeassistant.core import HomeAssistant + +from tests.common import MockConfigEntry + + +async def setup_integration(hass: HomeAssistant, config_entry: MockConfigEntry) -> None: + """Set up the component.""" + config_entry.add_to_hass(hass) + + await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() diff --git a/tests/components/homee/conftest.py b/tests/components/homee/conftest.py index a777f6b59a9..fb94ba0bbcc 100644 --- a/tests/components/homee/conftest.py +++ b/tests/components/homee/conftest.py @@ -17,6 +17,15 @@ TESTUSER = "testuser" TESTPASS = "testpass" +@pytest.fixture +def mock_setup_entry() -> Generator[AsyncMock]: + """Mock setting up a config entry.""" + with patch( + "homeassistant.components.homee.async_setup_entry", return_value=True + ) as mock_setup: + yield mock_setup + + @pytest.fixture def mock_config_entry() -> MockConfigEntry: """Return the default mocked config entry.""" @@ -32,15 +41,6 @@ def mock_config_entry() -> MockConfigEntry: ) -@pytest.fixture -def mock_setup_entry() -> Generator[AsyncMock]: - """Mock setting up a config entry.""" - with patch( - "homeassistant.components.homee.async_setup_entry", return_value=True - ) as mock_setup: - yield mock_setup - - @pytest.fixture def mock_homee() -> Generator[AsyncMock]: """Return a mock Homee instance.""" @@ -50,7 +50,7 @@ def mock_homee() -> Generator[AsyncMock]: ) as mocked_homee, patch( "homeassistant.components.homee.Homee", - autospec=True, + new=mocked_homee, ), ): homee = mocked_homee.return_value @@ -62,6 +62,7 @@ def mock_homee() -> Generator[AsyncMock]: homee.settings.uid = HOMEE_ID homee.settings.homee_name = HOMEE_NAME homee.reconnect_interval = 10 + homee.connected = True homee.get_access_token.return_value = "test_token" diff --git a/tests/components/homee/fixtures/cover1.json b/tests/components/homee/fixtures/cover1.json new file mode 100644 index 00000000000..8fedfb19d4f --- /dev/null +++ b/tests/components/homee/fixtures/cover1.json @@ -0,0 +1,101 @@ +{ + "id": 3, + "name": "Test%20Cover", + "profile": 2002, + "image": "default", + "favorite": 0, + "order": 4, + "protocol": 23, + "routing": 0, + "state": 1, + "state_changed": 1687175681, + "added": 1672086680, + "history": 1, + "cube_type": 14, + "note": "TestCoverDevice", + "services": 7, + "phonetic_name": "", + "owner": 2, + "security": 0, + "attributes": [ + { + "id": 1, + "node_id": 3, + "instance": 0, + "minimum": 0, + "maximum": 4, + "current_value": 1.0, + "target_value": 1.0, + "last_value": 4.0, + "unit": "n%2Fa", + "step_value": 1.0, + "editable": 1, + "type": 135, + "state": 1, + "last_changed": 1687175680, + "changed_by": 1, + "changed_by_id": 0, + "based_on": 1, + "data": "", + "name": "", + "options": { + "can_observe": [300], + "observes": [75], + "automations": ["toggle"] + } + }, + { + "id": 2, + "node_id": 3, + "instance": 0, + "minimum": 0, + "maximum": 100, + "current_value": 0.0, + "target_value": 0.0, + "last_value": 0.0, + "unit": "%25", + "step_value": 0.5, + "editable": 1, + "type": 15, + "state": 1, + "last_changed": 1687175680, + "changed_by": 1, + "changed_by_id": 0, + "based_on": 1, + "data": "", + "name": "", + "options": { + "automations": ["step"], + "history": { + "day": 35, + "week": 5, + "month": 1 + } + } + }, + { + "id": 3, + "node_id": 3, + "instance": 0, + "minimum": -45, + "maximum": 90, + "current_value": -45.0, + "target_value": 0.0, + "last_value": -45.0, + "unit": "%C2%B0", + "step_value": 1.0, + "editable": 1, + "type": 113, + "state": 1, + "last_changed": 1678284920, + "changed_by": 1, + "changed_by_id": 0, + "based_on": 1, + "data": "", + "name": "", + "options": { + "automations": ["step"] + } + } + ] +} diff --git a/tests/components/homee/fixtures/cover2.json b/tests/components/homee/fixtures/cover2.json new file mode 100644 index 00000000000..b53c3d49b62 --- /dev/null +++ b/tests/components/homee/fixtures/cover2.json @@ -0,0 +1,101 @@ +{ + "id": 1, + "name": "Test%20Cover", + "profile": 2002, + "image": "default", + "favorite": 0, + "order": 4, + "protocol": 23, + "routing": 0, + "state": 1, + "state_changed": 1687175681, + "added": 1672086680, + "history": 1, + "cube_type": 14, + "note": "TestCoverDevice", + "services": 7, + "phonetic_name": "", + "owner": 2, + "security": 0, + "attributes": [ + { + "id": 1, + "node_id": 1, + "instance": 0, + "minimum": 0, + "maximum": 4, + "current_value": 1.0, + "target_value": 1.0, + "last_value": 0.0, + "unit": "n%2Fa", + "step_value": 1.0, + "editable": 1, + "type": 135, + "state": 1, + "last_changed": 1687175680, + "changed_by": 1, + "changed_by_id": 0, + "based_on": 1, + "data": "", + "name": "", + "options": { + "can_observe": [300], + "observes": [75], + "automations": ["toggle"] + } + }, + { + "id": 2, + "node_id": 1, + "instance": 0, + "minimum": 0, + "maximum": 100, + "current_value": 100.0, + "target_value": 0.0, + "last_value": 0.0, + "unit": "%25", + "step_value": 0.5, + "editable": 1, + "type": 15, + "state": 1, + "last_changed": 1687175680, + "changed_by": 1, + "changed_by_id": 0, + "based_on": 1, + "data": "", + "name": "", + "options": { + "automations": ["step"], + "history": { + "day": 35, + "week": 5, + "month": 1 + } + } + }, + { + "id": 3, + "node_id": 1, + "instance": 0, + "minimum": -45, + "maximum": 90, + "current_value": 90.0, + "target_value": 0.0, + "last_value": -45.0, + "unit": "%C2%B0", + "step_value": 1.0, + "editable": 1, + "type": 113, + "state": 1, + "last_changed": 1678284920, + "changed_by": 1, + "changed_by_id": 0, + "based_on": 1, + "data": "", + "name": "", + "options": { + "automations": ["step"] + } + } + ] +} diff --git a/tests/components/homee/fixtures/cover3.json b/tests/components/homee/fixtures/cover3.json new file mode 100644 index 00000000000..0d3d5ea57e2 --- /dev/null +++ b/tests/components/homee/fixtures/cover3.json @@ -0,0 +1,101 @@ +{ + "id": 3, + "name": "Test%20Cover", + "profile": 2002, + "image": "default", + "favorite": 0, + "order": 4, + "protocol": 23, + "routing": 0, + "state": 1, + "state_changed": 1687175681, + "added": 1672086680, + "history": 1, + "cube_type": 14, + "note": "TestCoverDevice", + "services": 7, + "phonetic_name": "", + "owner": 2, + "security": 0, + "attributes": [ + { + "id": 1, + "node_id": 3, + "instance": 0, + "minimum": 0, + "maximum": 4, + "current_value": 3.0, + "target_value": 0.0, + "last_value": 1.0, + "unit": "n%2Fa", + "step_value": 1.0, + "editable": 1, + "type": 135, + "state": 1, + "last_changed": 1687175680, + "changed_by": 1, + "changed_by_id": 0, + "based_on": 1, + "data": "", + "name": "", + "options": { + "can_observe": [300], + "observes": [75], + "automations": ["toggle"] + } + }, + { + "id": 2, + "node_id": 3, + "instance": 0, + "minimum": 0, + "maximum": 100, + "current_value": 75.0, + "target_value": 0.0, + "last_value": 100.0, + "unit": "%25", + "step_value": 0.5, + "editable": 1, + "type": 15, + "state": 1, + "last_changed": 1687175680, + "changed_by": 1, + "changed_by_id": 0, + "based_on": 1, + "data": "", + "name": "", + "options": { + "automations": ["step"], + "history": { + "day": 35, + "week": 5, + "month": 1 + } + } + }, + { + "id": 3, + "node_id": 3, + "instance": 0, + "minimum": -45, + "maximum": 90, + "current_value": 56.0, + "target_value": 56.0, + "last_value": 0.0, + "unit": "%C2%B0", + "step_value": 1.0, + "editable": 1, + "type": 113, + "state": 1, + "last_changed": 1678284920, + "changed_by": 1, + "changed_by_id": 0, + "based_on": 1, + "data": "", + "name": "", + "options": { + "automations": ["step"] + } + } + ] +} diff --git a/tests/components/homee/fixtures/cover4.json b/tests/components/homee/fixtures/cover4.json new file mode 100644 index 00000000000..a3de555794a --- /dev/null +++ b/tests/components/homee/fixtures/cover4.json @@ -0,0 +1,101 @@ +{ + "id": 3, + "name": "Test%20Cover", + "profile": 2002, + "image": "default", + "favorite": 0, + "order": 4, + "protocol": 23, + "routing": 0, + "state": 1, + "state_changed": 1687175681, + "added": 1672086680, + "history": 1, + "cube_type": 14, + "note": "TestCoverDevice", + "services": 7, + "phonetic_name": "", + "owner": 2, + "security": 0, + "attributes": [ + { + "id": 1, + "node_id": 3, + "instance": 0, + "minimum": 0, + "maximum": 4, + "current_value": 4.0, + "target_value": 1.0, + "last_value": 0.0, + "unit": "n%2Fa", + "step_value": 1.0, + "editable": 1, + "type": 135, + "state": 1, + "last_changed": 1687175680, + "changed_by": 1, + "changed_by_id": 0, + "based_on": 1, + "data": "", + "name": "", + "options": { + "can_observe": [300], + "observes": [75], + "automations": ["toggle"] + } + }, + { + "id": 2, + "node_id": 3, + "instance": 0, + "minimum": 0, + "maximum": 100, + "current_value": 25.0, + "target_value": 100.0, + "last_value": 0.0, + "unit": "%25", + "step_value": 0.5, + "editable": 1, + "type": 15, + "state": 1, + "last_changed": 1687175680, + "changed_by": 1, + "changed_by_id": 0, + "based_on": 1, + "data": "", + "name": "", + "options": { + "automations": ["step"], + "history": { + "day": 35, + "week": 5, + "month": 1 + } + } + }, + { + "id": 3, + "node_id": 3, + "instance": 0, + "minimum": -45, + "maximum": 90, + "current_value": -11.0, + "target_value": 0.0, + "last_value": -45.0, + "unit": "%C2%B0", + "step_value": 1.0, + "editable": 1, + "type": 113, + "state": 1, + "last_changed": 1678284920, + "changed_by": 1, + "changed_by_id": 0, + "based_on": 1, + "data": "", + "name": "", + "options": { + "automations": ["step"] + } + } + ] +} diff --git a/tests/components/homee/test_cover.py b/tests/components/homee/test_cover.py new file mode 100644 index 00000000000..a7feaa10b66 --- /dev/null +++ b/tests/components/homee/test_cover.py @@ -0,0 +1,124 @@ +"""Test homee covers.""" + +from unittest.mock import AsyncMock, MagicMock + +from pyHomee import HomeeNode + +from homeassistant.components.cover import DOMAIN as COVER_DOMAIN, CoverState +from homeassistant.components.homee.const import DOMAIN +from homeassistant.const import ATTR_ENTITY_ID, SERVICE_CLOSE_COVER, SERVICE_OPEN_COVER +from homeassistant.core import HomeAssistant + +from . import setup_integration + +from tests.common import MockConfigEntry, load_json_object_fixture + + +async def test_cover_open( + hass: HomeAssistant, mock_homee: AsyncMock, mock_config_entry: MockConfigEntry +) -> None: + """Test an open cover.""" + # Cover open, tilt open. + cover_json = load_json_object_fixture("cover1.json", DOMAIN) + cover_node = HomeeNode(cover_json) + mock_homee.nodes = [cover_node] + + await setup_integration(hass, mock_config_entry) + + assert hass.states.get("cover.test_cover").state == CoverState.OPEN + + attributes = hass.states.get("cover.test_cover").attributes + assert attributes.get("supported_features") == 143 + assert attributes.get("current_position") == 100 + assert attributes.get("current_tilt_position") == 100 + + +async def test_cover_closed( + hass: HomeAssistant, mock_homee: MagicMock, mock_config_entry: MockConfigEntry +) -> None: + """Test a closed cover.""" + # Cover closed, tilt closed. + cover_json = load_json_object_fixture("cover2.json", DOMAIN) + cover_node = HomeeNode(cover_json) + mock_homee.nodes = [cover_node] + + await setup_integration(hass, mock_config_entry) + + assert hass.states.get("cover.test_cover").state == CoverState.CLOSED + attributes = hass.states.get("cover.test_cover").attributes + assert attributes.get("current_position") == 0 + assert attributes.get("current_tilt_position") == 0 + + +async def test_cover_opening( + hass: HomeAssistant, mock_homee: MagicMock, mock_config_entry: MockConfigEntry +) -> None: + """Test an opening cover.""" + # opening, 75% homee / 25% HA + cover_json = load_json_object_fixture("cover3.json", DOMAIN) + cover_node = HomeeNode(cover_json) + mock_homee.nodes = [cover_node] + + await setup_integration(hass, mock_config_entry) + + assert hass.states.get("cover.test_cover").state == CoverState.OPENING + attributes = hass.states.get("cover.test_cover").attributes + assert attributes.get("current_position") == 25 + assert attributes.get("current_tilt_position") == 25 + + +async def test_cover_closing( + hass: HomeAssistant, mock_homee: MagicMock, mock_config_entry: MockConfigEntry +) -> None: + """Test a closing cover.""" + # closing, 25% homee / 75% HA + cover_json = load_json_object_fixture("cover4.json", DOMAIN) + cover_node = HomeeNode(cover_json) + mock_homee.nodes = [cover_node] + + await setup_integration(hass, mock_config_entry) + + assert hass.states.get("cover.test_cover").state == CoverState.CLOSING + attributes = hass.states.get("cover.test_cover").attributes + assert attributes.get("current_position") == 75 + assert attributes.get("current_tilt_position") == 74 + + +async def test_open_cover( + hass: HomeAssistant, mock_homee: MagicMock, mock_config_entry: MockConfigEntry +) -> None: + """Test opening the cover.""" + # Cover closed, tilt closed. + cover_json = load_json_object_fixture("cover2.json", DOMAIN) + cover_node = HomeeNode(cover_json) + mock_homee.nodes = [cover_node] + + await setup_integration(hass, mock_config_entry) + + await hass.services.async_call( + COVER_DOMAIN, + SERVICE_OPEN_COVER, + {ATTR_ENTITY_ID: "cover.test_cover"}, + blocking=True, + ) + mock_homee.set_value.assert_called_once_with(cover_node.id, 1, 0) + + +async def test_close_cover( + hass: HomeAssistant, mock_homee: MagicMock, mock_config_entry: MockConfigEntry +) -> None: + """Test opening the cover.""" + # Cover open, tilt open. + cover_json = load_json_object_fixture("cover1.json", DOMAIN) + cover_node = HomeeNode(cover_json) + mock_homee.nodes = [cover_node] + + await setup_integration(hass, mock_config_entry) + + await hass.services.async_call( + COVER_DOMAIN, + SERVICE_CLOSE_COVER, + {ATTR_ENTITY_ID: "cover.test_cover"}, + blocking=True, + ) + mock_homee.set_value.assert_called_once_with(cover_node.id, 1, 1)