From 043f3e640c013c295719ac1c9d5bebe735c27912 Mon Sep 17 00:00:00 2001 From: Brett Adams Date: Sat, 23 Dec 2023 22:45:06 +1000 Subject: [PATCH] Rework entity description functions in Tessie (#106287) * use lamdba to return the library function * Rename mocks * lambda number * Lambda button * Add missing * Remove context manager --- homeassistant/components/tessie/button.py | 22 +++++++++++++-------- homeassistant/components/tessie/number.py | 8 ++++---- homeassistant/components/tessie/switch.py | 24 +++++++++++------------ tests/components/tessie/common.py | 17 +--------------- tests/components/tessie/test_button.py | 8 +++++--- tests/components/tessie/test_number.py | 15 +++++++------- tests/components/tessie/test_switch.py | 14 ++++++------- 7 files changed, 51 insertions(+), 57 deletions(-) diff --git a/homeassistant/components/tessie/button.py b/homeassistant/components/tessie/button.py index fb4449f5898..5d02d9fe8aa 100644 --- a/homeassistant/components/tessie/button.py +++ b/homeassistant/components/tessie/button.py @@ -33,21 +33,27 @@ class TessieButtonEntityDescription(ButtonEntityDescription): DESCRIPTIONS: tuple[TessieButtonEntityDescription, ...] = ( - TessieButtonEntityDescription(key="wake", func=wake, icon="mdi:sleep-off"), + TessieButtonEntityDescription(key="wake", func=lambda: wake, icon="mdi:sleep-off"), TessieButtonEntityDescription( - key="flash_lights", func=flash_lights, icon="mdi:flashlight" + key="flash_lights", func=lambda: flash_lights, icon="mdi:flashlight" ), TessieButtonEntityDescription(key="honk", func=honk, icon="mdi:bullhorn"), TessieButtonEntityDescription( - key="trigger_homelink", func=trigger_homelink, icon="mdi:garage" + key="trigger_homelink", func=lambda: trigger_homelink, icon="mdi:garage" ), TessieButtonEntityDescription( - key="enable_keyless_driving", func=enable_keyless_driving, icon="mdi:car-key" + key="enable_keyless_driving", + func=lambda: enable_keyless_driving, + icon="mdi:car-key", ), - TessieButtonEntityDescription(key="boombox", func=boombox, icon="mdi:volume-high"), - TessieButtonEntityDescription(key="frunk", func=open_front_trunk, icon="mdi:car"), TessieButtonEntityDescription( - key="trunk", func=open_close_rear_trunk, icon="mdi:car-back" + key="boombox", func=lambda: boombox, icon="mdi:volume-high" + ), + TessieButtonEntityDescription( + key="frunk", func=lambda: open_front_trunk, icon="mdi:car" + ), + TessieButtonEntityDescription( + key="trunk", func=lambda: open_close_rear_trunk, icon="mdi:car-back" ), ) @@ -81,4 +87,4 @@ class TessieButtonEntity(TessieEntity, ButtonEntity): async def async_press(self) -> None: """Press the button.""" - await self.run(self.entity_description.func) + await self.run(self.entity_description.func()) diff --git a/homeassistant/components/tessie/number.py b/homeassistant/components/tessie/number.py index 204260a7ab6..b7c0e145d7b 100644 --- a/homeassistant/components/tessie/number.py +++ b/homeassistant/components/tessie/number.py @@ -48,7 +48,7 @@ DESCRIPTIONS: tuple[TessieNumberEntityDescription, ...] = ( native_unit_of_measurement=UnitOfElectricCurrent.AMPERE, device_class=NumberDeviceClass.CURRENT, max_key="charge_state_charge_current_request_max", - func=set_charging_amps, + func=lambda: set_charging_amps, arg="amps", ), TessieNumberEntityDescription( @@ -60,7 +60,7 @@ DESCRIPTIONS: tuple[TessieNumberEntityDescription, ...] = ( device_class=NumberDeviceClass.BATTERY, min_key="charge_state_charge_limit_soc_min", max_key="charge_state_charge_limit_soc_max", - func=set_charge_limit, + func=lambda: set_charge_limit, arg="percent", ), TessieNumberEntityDescription( @@ -73,7 +73,7 @@ DESCRIPTIONS: tuple[TessieNumberEntityDescription, ...] = ( mode=NumberMode.BOX, min_key="vehicle_state_speed_limit_mode_min_limit_mph", max_key="vehicle_state_speed_limit_mode_max_limit_mph", - func=set_speed_limit, + func=lambda: set_speed_limit, arg="mph", ), ) @@ -132,6 +132,6 @@ class TessieNumberEntity(TessieEntity, NumberEntity): async def async_set_native_value(self, value: float) -> None: """Set new value.""" await self.run( - self.entity_description.func, **{self.entity_description.arg: value} + self.entity_description.func(), **{self.entity_description.arg: value} ) self.set((self.key, value)) diff --git a/homeassistant/components/tessie/switch.py b/homeassistant/components/tessie/switch.py index 179beafe290..2dd54cf7ed1 100644 --- a/homeassistant/components/tessie/switch.py +++ b/homeassistant/components/tessie/switch.py @@ -43,32 +43,32 @@ class TessieSwitchEntityDescription(SwitchEntityDescription): DESCRIPTIONS: tuple[TessieSwitchEntityDescription, ...] = ( TessieSwitchEntityDescription( key="charge_state_charge_enable_request", - on_func=start_charging, - off_func=stop_charging, + on_func=lambda: start_charging, + off_func=lambda: stop_charging, icon="mdi:ev-station", ), TessieSwitchEntityDescription( key="climate_state_defrost_mode", - on_func=start_defrost, - off_func=stop_defrost, + on_func=lambda: start_defrost, + off_func=lambda: stop_defrost, icon="mdi:snowflake", ), TessieSwitchEntityDescription( key="vehicle_state_sentry_mode", - on_func=enable_sentry_mode, - off_func=disable_sentry_mode, + on_func=lambda: enable_sentry_mode, + off_func=lambda: disable_sentry_mode, icon="mdi:shield-car", ), TessieSwitchEntityDescription( key="vehicle_state_valet_mode", - on_func=enable_valet_mode, - off_func=disable_valet_mode, + on_func=lambda: enable_valet_mode, + off_func=lambda: disable_valet_mode, icon="mdi:car-key", ), TessieSwitchEntityDescription( key="climate_state_steering_wheel_heater", - on_func=start_steering_wheel_heater, - off_func=stop_steering_wheel_heater, + on_func=lambda: start_steering_wheel_heater, + off_func=lambda: stop_steering_wheel_heater, icon="mdi:steering", ), ) @@ -112,10 +112,10 @@ class TessieSwitchEntity(TessieEntity, SwitchEntity): async def async_turn_on(self, **kwargs: Any) -> None: """Turn on the Switch.""" - await self.run(self.entity_description.on_func) + await self.run(self.entity_description.on_func()) self.set((self.entity_description.key, True)) async def async_turn_off(self, **kwargs: Any) -> None: """Turn off the Switch.""" - await self.run(self.entity_description.off_func) + await self.run(self.entity_description.off_func()) self.set((self.entity_description.key, False)) diff --git a/tests/components/tessie/common.py b/tests/components/tessie/common.py index c0f79d26a37..a26f4becf78 100644 --- a/tests/components/tessie/common.py +++ b/tests/components/tessie/common.py @@ -1,8 +1,7 @@ """Tessie common helpers for tests.""" -from contextlib import contextmanager from http import HTTPStatus -from unittest.mock import AsyncMock, patch +from unittest.mock import patch from aiohttp import ClientConnectionError, ClientResponseError from aiohttp.client import RequestInfo @@ -10,7 +9,6 @@ from aiohttp.client import RequestInfo from homeassistant.components.tessie.const import DOMAIN from homeassistant.const import CONF_ACCESS_TOKEN from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity import EntityDescription from tests.common import MockConfigEntry, load_json_object_fixture @@ -61,16 +59,3 @@ async def setup_platform(hass: HomeAssistant, side_effect=None): await hass.async_block_till_done() return mock_entry - - -@contextmanager -def patch_description( - key: str, attr: str, descriptions: tuple[EntityDescription] -) -> AsyncMock: - """Patch a description.""" - to_patch = next(filter(lambda x: x.key == key, descriptions)) - original = to_patch.func - mock = AsyncMock() - object.__setattr__(to_patch, attr, mock) - yield mock - object.__setattr__(to_patch, attr, original) diff --git a/tests/components/tessie/test_button.py b/tests/components/tessie/test_button.py index 6b20dd858a7..72e458cb5d6 100644 --- a/tests/components/tessie/test_button.py +++ b/tests/components/tessie/test_button.py @@ -1,11 +1,11 @@ """Test the Tessie button platform.""" +from unittest.mock import patch from homeassistant.components.button import DOMAIN as BUTTON_DOMAIN, SERVICE_PRESS -from homeassistant.components.tessie.button import DESCRIPTIONS from homeassistant.const import ATTR_ENTITY_ID from homeassistant.core import HomeAssistant -from .common import patch_description, setup_platform +from .common import setup_platform async def test_buttons(hass: HomeAssistant) -> None: @@ -14,7 +14,9 @@ async def test_buttons(hass: HomeAssistant) -> None: await setup_platform(hass) # Test wake button - with patch_description("wake", "func", DESCRIPTIONS) as mock_wake: + with patch( + "homeassistant.components.tessie.button.wake", + ) as mock_wake: await hass.services.async_call( BUTTON_DOMAIN, SERVICE_PRESS, diff --git a/tests/components/tessie/test_number.py b/tests/components/tessie/test_number.py index f4a407f80c4..116c9a2657d 100644 --- a/tests/components/tessie/test_number.py +++ b/tests/components/tessie/test_number.py @@ -1,12 +1,13 @@ """Test the Tessie number platform.""" +from unittest.mock import patch from homeassistant.components.number import DOMAIN as NUMBER_DOMAIN, SERVICE_SET_VALUE from homeassistant.components.tessie.number import DESCRIPTIONS from homeassistant.const import ATTR_ENTITY_ID from homeassistant.core import HomeAssistant -from .common import TEST_VEHICLE_STATE_ONLINE, patch_description, setup_platform +from .common import TEST_VEHICLE_STATE_ONLINE, setup_platform async def test_numbers(hass: HomeAssistant) -> None: @@ -33,8 +34,8 @@ async def test_numbers(hass: HomeAssistant) -> None: ) # Test number set value functions - with patch_description( - "charge_state_charge_current_request", "func", DESCRIPTIONS + with patch( + "homeassistant.components.tessie.number.set_charging_amps", ) as mock_set_charging_amps: await hass.services.async_call( NUMBER_DOMAIN, @@ -45,8 +46,8 @@ async def test_numbers(hass: HomeAssistant) -> None: assert hass.states.get("number.test_charge_current").state == "16.0" mock_set_charging_amps.assert_called_once() - with patch_description( - "charge_state_charge_limit_soc", "func", DESCRIPTIONS + with patch( + "homeassistant.components.tessie.number.set_charge_limit", ) as mock_set_charge_limit: await hass.services.async_call( NUMBER_DOMAIN, @@ -57,8 +58,8 @@ async def test_numbers(hass: HomeAssistant) -> None: assert hass.states.get("number.test_charge_limit").state == "80.0" mock_set_charge_limit.assert_called_once() - with patch_description( - "vehicle_state_speed_limit_mode_current_limit_mph", "func", DESCRIPTIONS + with patch( + "homeassistant.components.tessie.number.set_speed_limit", ) as mock_set_speed_limit: await hass.services.async_call( NUMBER_DOMAIN, diff --git a/tests/components/tessie/test_switch.py b/tests/components/tessie/test_switch.py index e19a7aed49e..5bc24d12e5c 100644 --- a/tests/components/tessie/test_switch.py +++ b/tests/components/tessie/test_switch.py @@ -30,9 +30,8 @@ async def test_switches(hass: HomeAssistant) -> None: ) with patch( - "homeassistant.components.tessie.entity.TessieEntity.run", - return_value=True, - ) as mock_run: + "homeassistant.components.tessie.switch.start_charging", + ) as mock_start_charging: # Test Switch On await hass.services.async_call( SWITCH_DOMAIN, @@ -40,9 +39,10 @@ async def test_switches(hass: HomeAssistant) -> None: {ATTR_ENTITY_ID: ["switch.test_charge"]}, blocking=True, ) - mock_run.assert_called_once() - mock_run.reset_mock() - + mock_start_charging.assert_called_once() + with patch( + "homeassistant.components.tessie.switch.stop_charging", + ) as mock_stop_charging: # Test Switch Off await hass.services.async_call( SWITCH_DOMAIN, @@ -50,4 +50,4 @@ async def test_switches(hass: HomeAssistant) -> None: {ATTR_ENTITY_ID: ["switch.test_charge"]}, blocking=True, ) - mock_run.assert_called_once() + mock_stop_charging.assert_called_once()