From 4c7828fd50a3b4017bf29659188ecc91c8152548 Mon Sep 17 00:00:00 2001 From: Robert Svensson Date: Wed, 24 Jul 2024 09:01:09 +0200 Subject: [PATCH] Improve deCONZ fan tests (#122493) * Improve fan tests * Use snapshots --- .../components/deconz/snapshots/test_fan.ambr | 54 +++++++++ tests/components/deconz/test_fan.py | 106 ++++++------------ 2 files changed, 89 insertions(+), 71 deletions(-) create mode 100644 tests/components/deconz/snapshots/test_fan.ambr diff --git a/tests/components/deconz/snapshots/test_fan.ambr b/tests/components/deconz/snapshots/test_fan.ambr new file mode 100644 index 00000000000..8b7dbba64e4 --- /dev/null +++ b/tests/components/deconz/snapshots/test_fan.ambr @@ -0,0 +1,54 @@ +# serializer version: 1 +# name: test_fans[light_payload0][fan.ceiling_fan-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'preset_modes': None, + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'fan', + 'entity_category': None, + 'entity_id': 'fan.ceiling_fan', + 'has_entity_name': False, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Ceiling fan', + 'platform': 'deconz', + 'previous_unique_id': None, + 'supported_features': , + 'translation_key': None, + 'unique_id': '00:22:a3:00:00:27:8b:81-01', + 'unit_of_measurement': None, + }) +# --- +# name: test_fans[light_payload0][fan.ceiling_fan-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'Ceiling fan', + 'percentage': 100, + 'percentage_step': 1.0, + 'preset_mode': None, + 'preset_modes': None, + 'supported_features': , + }), + 'context': , + 'entity_id': 'fan.ceiling_fan', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- diff --git a/tests/components/deconz/test_fan.py b/tests/components/deconz/test_fan.py index 0da48812ea3..cccf894c249 100644 --- a/tests/components/deconz/test_fan.py +++ b/tests/components/deconz/test_fan.py @@ -1,8 +1,10 @@ """deCONZ fan platform tests.""" from collections.abc import Callable +from unittest.mock import patch import pytest +from syrupy import SnapshotAssertion from homeassistant.components.fan import ( ATTR_PERCENTAGE, @@ -12,11 +14,19 @@ from homeassistant.components.fan import ( SERVICE_TURN_ON, ) from homeassistant.config_entries import ConfigEntry -from homeassistant.const import ATTR_ENTITY_ID, STATE_OFF, STATE_ON, STATE_UNAVAILABLE +from homeassistant.const import ( + ATTR_ENTITY_ID, + STATE_OFF, + STATE_ON, + STATE_UNAVAILABLE, + Platform, +) from homeassistant.core import HomeAssistant +from homeassistant.helpers import entity_registry as er from .conftest import WebsocketDataType +from tests.common import snapshot_platform from tests.test_util.aiohttp import AiohttpClientMocker @@ -44,33 +54,25 @@ from tests.test_util.aiohttp import AiohttpClientMocker ) async def test_fans( hass: HomeAssistant, + entity_registry: er.EntityRegistry, + snapshot: SnapshotAssertion, aioclient_mock: AiohttpClientMocker, - config_entry_setup: ConfigEntry, + config_entry_factory: ConfigEntry, mock_put_request: Callable[[str, str], AiohttpClientMocker], light_ws_data: WebsocketDataType, ) -> None: """Test that all supported fan entities are created.""" - assert len(hass.states.async_all()) == 2 # Light and fan - assert hass.states.get("fan.ceiling_fan").state == STATE_ON - assert hass.states.get("fan.ceiling_fan").attributes[ATTR_PERCENTAGE] == 100 + with patch("homeassistant.components.deconz.PLATFORMS", [Platform.FAN]): + config_entry = await config_entry_factory() + + await snapshot_platform(hass, entity_registry, snapshot, config_entry.entry_id) # Test states - await light_ws_data({"state": {"speed": 1}}) - assert hass.states.get("fan.ceiling_fan").state == STATE_ON - assert hass.states.get("fan.ceiling_fan").attributes[ATTR_PERCENTAGE] == 25 - - await light_ws_data({"state": {"speed": 2}}) - assert hass.states.get("fan.ceiling_fan").state == STATE_ON - assert hass.states.get("fan.ceiling_fan").attributes[ATTR_PERCENTAGE] == 50 - - await light_ws_data({"state": {"speed": 3}}) - assert hass.states.get("fan.ceiling_fan").state == STATE_ON - assert hass.states.get("fan.ceiling_fan").attributes[ATTR_PERCENTAGE] == 75 - - await light_ws_data({"state": {"speed": 4}}) - assert hass.states.get("fan.ceiling_fan").state == STATE_ON - assert hass.states.get("fan.ceiling_fan").attributes[ATTR_PERCENTAGE] == 100 + for speed, percent in (1, 25), (2, 50), (3, 75), (4, 100): + await light_ws_data({"state": {"speed": speed}}) + assert hass.states.get("fan.ceiling_fan").state == STATE_ON + assert hass.states.get("fan.ceiling_fan").attributes[ATTR_PERCENTAGE] == percent await light_ws_data({"state": {"speed": 0}}) assert hass.states.get("fan.ceiling_fan").state == STATE_OFF @@ -110,55 +112,17 @@ async def test_fans( ) assert aioclient_mock.mock_calls[3][2] == {"speed": 1} - # Service set fan percentage to 20% + # Service set fan percentage - await hass.services.async_call( - FAN_DOMAIN, - SERVICE_SET_PERCENTAGE, - {ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_PERCENTAGE: 20}, - blocking=True, - ) - assert aioclient_mock.mock_calls[4][2] == {"speed": 1} - - # Service set fan percentage to 40% - - await hass.services.async_call( - FAN_DOMAIN, - SERVICE_SET_PERCENTAGE, - {ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_PERCENTAGE: 40}, - blocking=True, - ) - assert aioclient_mock.mock_calls[5][2] == {"speed": 2} - - # Service set fan percentage to 60% - - await hass.services.async_call( - FAN_DOMAIN, - SERVICE_SET_PERCENTAGE, - {ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_PERCENTAGE: 60}, - blocking=True, - ) - assert aioclient_mock.mock_calls[6][2] == {"speed": 3} - - # Service set fan percentage to 80% - - await hass.services.async_call( - FAN_DOMAIN, - SERVICE_SET_PERCENTAGE, - {ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_PERCENTAGE: 80}, - blocking=True, - ) - assert aioclient_mock.mock_calls[7][2] == {"speed": 4} - - # Service set fan percentage to 0% does not equal off - - await hass.services.async_call( - FAN_DOMAIN, - SERVICE_SET_PERCENTAGE, - {ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_PERCENTAGE: 0}, - blocking=True, - ) - assert aioclient_mock.mock_calls[8][2] == {"speed": 0} + for percent, speed in (20, 1), (40, 2), (60, 3), (80, 4), (0, 0): + aioclient_mock.mock_calls.clear() + await hass.services.async_call( + FAN_DOMAIN, + SERVICE_SET_PERCENTAGE, + {ATTR_ENTITY_ID: "fan.ceiling_fan", ATTR_PERCENTAGE: percent}, + blocking=True, + ) + assert aioclient_mock.mock_calls[0][2] == {"speed": speed} # Events with an unsupported speed does not get converted @@ -166,13 +130,13 @@ async def test_fans( assert hass.states.get("fan.ceiling_fan").state == STATE_ON assert not hass.states.get("fan.ceiling_fan").attributes[ATTR_PERCENTAGE] - await hass.config_entries.async_unload(config_entry_setup.entry_id) + await hass.config_entries.async_unload(config_entry.entry_id) states = hass.states.async_all() - assert len(states) == 2 + assert len(states) == 1 for state in states: assert state.state == STATE_UNAVAILABLE - await hass.config_entries.async_remove(config_entry_setup.entry_id) + await hass.config_entries.async_remove(config_entry.entry_id) await hass.async_block_till_done() assert len(hass.states.async_all()) == 0