From 8d1a70391e6bb05e35ce18b36159820643a55ebb Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Tue, 6 Dec 2022 14:18:21 -0500 Subject: [PATCH] Improve zwave_js test coverage (#83372) * Improve zwave_js test coverage * review comments and clean up test --- homeassistant/components/zwave_js/number.py | 20 +++---- tests/components/zwave_js/test_api.py | 20 +++++++ tests/components/zwave_js/test_cover.py | 25 ++++++++ tests/components/zwave_js/test_number.py | 66 +++++++++++++++++++++ 4 files changed, 119 insertions(+), 12 deletions(-) diff --git a/homeassistant/components/zwave_js/number.py b/homeassistant/components/zwave_js/number.py index 7f7f5d65bb8..a6a219fa7c6 100644 --- a/homeassistant/components/zwave_js/number.py +++ b/homeassistant/components/zwave_js/number.py @@ -71,30 +71,26 @@ class ZwaveNumberEntity(ZWaveBaseEntity, NumberEntity): @property def native_min_value(self) -> float: """Return the minimum value.""" - if self.info.primary_value.metadata.min is None: - return 0 - return float(self.info.primary_value.metadata.min) + min_ = self.info.primary_value.metadata.min + return float(0 if min_ is None else min_) @property def native_max_value(self) -> float: """Return the maximum value.""" - if self.info.primary_value.metadata.max is None: - return 255 - return float(self.info.primary_value.metadata.max) + max_ = self.info.primary_value.metadata.max + return float(255 if max_ is None else max_) @property def native_value(self) -> float | None: """Return the entity value.""" - if self.info.primary_value.value is None: - return None - return float(self.info.primary_value.value) + value = self.info.primary_value.value + return None if value is None else float(value) @property def native_unit_of_measurement(self) -> str | None: """Return the unit of measurement of this entity, if any.""" - if self.info.primary_value.metadata.unit is None: - return None - return str(self.info.primary_value.metadata.unit) + unit = self.info.primary_value.metadata.unit + return None if unit is None else str(unit) async def async_set_native_value(self, value: float) -> None: """Set new value.""" diff --git a/tests/components/zwave_js/test_api.py b/tests/components/zwave_js/test_api.py index caea283e25c..4ea0669f0cb 100644 --- a/tests/components/zwave_js/test_api.py +++ b/tests/components/zwave_js/test_api.py @@ -87,6 +87,26 @@ def get_device(hass, node): return dev_reg.async_get_device({device_id}) +async def test_no_driver( + hass, client, multisensor_6, controller_state, integration, hass_ws_client +): + """Test driver missing results in error.""" + entry = integration + ws_client = await hass_ws_client(hass) + client.driver = None + + # Try API call with entry ID + await ws_client.send_json( + { + ID: 1, + TYPE: "zwave_js/network_status", + ENTRY_ID: entry.entry_id, + } + ) + msg = await ws_client.receive_json() + assert not msg["success"] + + async def test_network_status( hass, multisensor_6, controller_state, integration, hass_ws_client ): diff --git a/tests/components/zwave_js/test_cover.py b/tests/components/zwave_js/test_cover.py index 0ca2e36d853..d2c8fc32a73 100644 --- a/tests/components/zwave_js/test_cover.py +++ b/tests/components/zwave_js/test_cover.py @@ -267,6 +267,31 @@ async def test_fibaro_FGR222_shutter_cover( } assert args["value"] == 0 + # Test some tilt + event = Event( + type="value updated", + data={ + "source": "node", + "event": "value updated", + "nodeId": 42, + "args": { + "commandClassName": "Manufacturer Proprietary", + "commandClass": 145, + "endpoint": 0, + "property": "fibaro", + "propertyKey": "venetianBlindsTilt", + "newValue": 99, + "prevValue": 0, + "propertyName": "fibaro", + "propertyKeyName": "venetianBlindsTilt", + }, + }, + ) + fibaro_fgr222_shutter.receive_event(event) + state = hass.states.get(FIBARO_SHUTTER_COVER_ENTITY) + assert state + assert state.attributes[ATTR_CURRENT_TILT_POSITION] == 100 + async def test_aeotec_nano_shutter_cover( hass, client, aeotec_nano_shutter, integration diff --git a/tests/components/zwave_js/test_number.py b/tests/components/zwave_js/test_number.py index e36bd081b18..ff551ce554b 100644 --- a/tests/components/zwave_js/test_number.py +++ b/tests/components/zwave_js/test_number.py @@ -1,11 +1,17 @@ """Test the Z-Wave JS number platform.""" +from unittest.mock import patch + +import pytest from zwave_js_server.event import Event from homeassistant.const import STATE_UNKNOWN +from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import entity_registry as er from .common import BASIC_NUMBER_ENTITY +from tests.common import MockConfigEntry + NUMBER_ENTITY = "number.thermostat_hvac_valve_control" VOLUME_NUMBER_ENTITY = "number.indoor_siren_6_default_volume_2" @@ -63,6 +69,66 @@ async def test_number(hass, client, aeotec_radiator_thermostat, integration): assert state.state == "99.0" +@pytest.fixture(name="no_target_value") +def mock_client_fixture(): + """Mock no target_value.""" + + with patch( + "homeassistant.components.zwave_js.number.ZwaveNumberEntity.get_zwave_value", + return_value=None, + ): + yield + + +async def test_number_no_target_value( + hass, client, no_target_value, aeotec_radiator_thermostat, integration +): + """Test the number entity with no target value.""" + # Test turn on setting value fails + with pytest.raises(HomeAssistantError): + await hass.services.async_call( + "number", + "set_value", + {"entity_id": NUMBER_ENTITY, "value": 30}, + blocking=True, + ) + + +async def test_number_writeable(hass, client, aeotec_radiator_thermostat): + """Test the number entity where current value is writeable.""" + aeotec_radiator_thermostat.values["4-38-0-currentValue"].metadata.data[ + "writeable" + ] = True + aeotec_radiator_thermostat.values.pop("4-38-0-targetValue") + + # set up config entry + entry = MockConfigEntry(domain="zwave_js", data={"url": "ws://test.org"}) + entry.add_to_hass(hass) + await hass.config_entries.async_setup(entry.entry_id) + await hass.async_block_till_done() + + # Test turn on setting value + await hass.services.async_call( + "number", + "set_value", + {"entity_id": NUMBER_ENTITY, "value": 30}, + blocking=True, + ) + + assert len(client.async_send_command.call_args_list) == 1 + args = client.async_send_command.call_args[0][0] + assert args["command"] == "node.set_value" + assert args["nodeId"] == 4 + assert args["valueId"] == { + "commandClass": 38, + "endpoint": 0, + "property": "currentValue", + } + assert args["value"] == 30.0 + + client.async_send_command.reset_mock() + + async def test_volume_number(hass, client, aeotec_zw164_siren, integration): """Test the volume number entity.""" node = aeotec_zw164_siren