From 13385912d13e178590dc0653df2737c14690383b Mon Sep 17 00:00:00 2001 From: Thomas55555 <59625598+Thomas55555@users.noreply.github.com> Date: Fri, 24 May 2024 10:54:19 +0200 Subject: [PATCH] Refactor Husqvarna Automower (#117938) --- .../components/husqvarna_automower/const.py | 1 + .../components/husqvarna_automower/number.py | 29 ++-- .../components/husqvarna_automower/sensor.py | 2 +- .../components/husqvarna_automower/switch.py | 11 +- .../husqvarna_automower/conftest.py | 29 ++-- .../snapshots/test_binary_sensor.ambr | 152 +----------------- .../snapshots/test_number.ambr | 16 +- .../snapshots/test_sensor.ambr | 52 +++--- .../snapshots/test_switch.ambr | 12 +- .../husqvarna_automower/test_binary_sensor.py | 4 +- .../test_device_tracker.py | 2 +- .../husqvarna_automower/test_lawn_mower.py | 11 +- .../husqvarna_automower/test_number.py | 26 ++- .../husqvarna_automower/test_select.py | 10 +- .../husqvarna_automower/test_sensor.py | 4 +- .../husqvarna_automower/test_switch.py | 15 +- 16 files changed, 120 insertions(+), 256 deletions(-) diff --git a/homeassistant/components/husqvarna_automower/const.py b/homeassistant/components/husqvarna_automower/const.py index 5e38b354957..1ea0511d721 100644 --- a/homeassistant/components/husqvarna_automower/const.py +++ b/homeassistant/components/husqvarna_automower/const.py @@ -1,6 +1,7 @@ """The constants for the Husqvarna Automower integration.""" DOMAIN = "husqvarna_automower" +EXECUTION_TIME_DELAY = 5 NAME = "Husqvarna Automower" OAUTH2_AUTHORIZE = "https://api.authentication.husqvarnagroup.dev/v1/oauth2/authorize" OAUTH2_TOKEN = "https://api.authentication.husqvarnagroup.dev/v1/oauth2/token" diff --git a/homeassistant/components/husqvarna_automower/number.py b/homeassistant/components/husqvarna_automower/number.py index 2b3cf3fb7a8..5e4ba48c230 100644 --- a/homeassistant/components/husqvarna_automower/number.py +++ b/homeassistant/components/husqvarna_automower/number.py @@ -12,13 +12,13 @@ from aioautomower.session import AutomowerSession from homeassistant.components.number import NumberEntity, NumberEntityDescription from homeassistant.config_entries import ConfigEntry -from homeassistant.const import PERCENTAGE, EntityCategory +from homeassistant.const import PERCENTAGE, EntityCategory, Platform from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import entity_registry as er from homeassistant.helpers.entity_platform import AddEntitiesCallback -from .const import DOMAIN +from .const import DOMAIN, EXECUTION_TIME_DELAY from .coordinator import AutomowerDataUpdateCoordinator from .entity import AutomowerControlEntity @@ -52,10 +52,6 @@ async def async_set_work_area_cutting_height( await coordinator.api.commands.set_cutting_height_workarea( mower_id, int(cheight), work_area_id ) - # As there are no updates from the websocket regarding work area changes, - # we need to wait 5s and then poll the API. - await asyncio.sleep(5) - await coordinator.async_request_refresh() async def async_set_cutting_height( @@ -189,6 +185,7 @@ class AutomowerWorkAreaNumberEntity(AutomowerControlEntity, NumberEntity): ) -> None: """Set up AutomowerNumberEntity.""" super().__init__(mower_id, coordinator) + self.coordinator = coordinator self.entity_description = description self.work_area_id = work_area_id self._attr_unique_id = f"{mower_id}_{work_area_id}_{description.key}" @@ -221,6 +218,11 @@ class AutomowerWorkAreaNumberEntity(AutomowerControlEntity, NumberEntity): raise HomeAssistantError( f"Command couldn't be sent to the command queue: {exception}" ) from exception + else: + # As there are no updates from the websocket regarding work area changes, + # we need to wait 5s and then poll the API. + await asyncio.sleep(EXECUTION_TIME_DELAY) + await self.coordinator.async_request_refresh() @callback @@ -238,10 +240,13 @@ def async_remove_entities( for work_area_id in _work_areas: uid = f"{mower_id}_{work_area_id}_cutting_height_work_area" active_work_areas.add(uid) - for entity_entry in er.async_entries_for_config_entry( - entity_reg, config_entry.entry_id + for entity_entry in er.async_entries_for_config_entry( + entity_reg, config_entry.entry_id + ): + if ( + entity_entry.domain == Platform.NUMBER + and (split := entity_entry.unique_id.split("_"))[0] == mower_id + and split[-1] == "area" + and entity_entry.unique_id not in active_work_areas ): - if entity_entry.unique_id.split("_")[0] == mower_id: - if entity_entry.unique_id.endswith("cutting_height_work_area"): - if entity_entry.unique_id not in active_work_areas: - entity_reg.async_remove(entity_entry.entity_id) + entity_reg.async_remove(entity_entry.entity_id) diff --git a/homeassistant/components/husqvarna_automower/sensor.py b/homeassistant/components/husqvarna_automower/sensor.py index 6840708ed42..0ece16f8e83 100644 --- a/homeassistant/components/husqvarna_automower/sensor.py +++ b/homeassistant/components/husqvarna_automower/sensor.py @@ -1,4 +1,4 @@ -"""Creates a the sensor entities for the mower.""" +"""Creates the sensor entities for the mower.""" from collections.abc import Callable from dataclasses import dataclass diff --git a/homeassistant/components/husqvarna_automower/switch.py b/homeassistant/components/husqvarna_automower/switch.py index 9e7dab80533..4964c50eee5 100644 --- a/homeassistant/components/husqvarna_automower/switch.py +++ b/homeassistant/components/husqvarna_automower/switch.py @@ -15,12 +15,13 @@ from aioautomower.model import ( from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry +from homeassistant.const import Platform from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import entity_registry as er from homeassistant.helpers.entity_platform import AddEntitiesCallback -from .const import DOMAIN +from .const import DOMAIN, EXECUTION_TIME_DELAY from .coordinator import AutomowerDataUpdateCoordinator from .entity import AutomowerControlEntity @@ -40,7 +41,6 @@ ERROR_STATES = [ MowerStates.STOPPED, MowerStates.OFF, ] -EXECUTION_TIME = 5 async def async_setup_entry( @@ -172,7 +172,7 @@ class AutomowerStayOutZoneSwitchEntity(AutomowerControlEntity, SwitchEntity): else: # As there are no updates from the websocket regarding stay out zone changes, # we need to wait until the command is executed and then poll the API. - await asyncio.sleep(EXECUTION_TIME) + await asyncio.sleep(EXECUTION_TIME_DELAY) await self.coordinator.async_request_refresh() async def async_turn_on(self, **kwargs: Any) -> None: @@ -188,7 +188,7 @@ class AutomowerStayOutZoneSwitchEntity(AutomowerControlEntity, SwitchEntity): else: # As there are no updates from the websocket regarding stay out zone changes, # we need to wait until the command is executed and then poll the API. - await asyncio.sleep(EXECUTION_TIME) + await asyncio.sleep(EXECUTION_TIME_DELAY) await self.coordinator.async_request_refresh() @@ -211,7 +211,8 @@ def async_remove_entities( entity_reg, config_entry.entry_id ): if ( - (split := entity_entry.unique_id.split("_"))[0] == mower_id + entity_entry.domain == Platform.SWITCH + and (split := entity_entry.unique_id.split("_"))[0] == mower_id and split[-1] == "zones" and entity_entry.unique_id not in active_zones ): diff --git a/tests/components/husqvarna_automower/conftest.py b/tests/components/husqvarna_automower/conftest.py index a2359c64905..6c6eb0430d3 100644 --- a/tests/components/husqvarna_automower/conftest.py +++ b/tests/components/husqvarna_automower/conftest.py @@ -4,6 +4,7 @@ from collections.abc import Generator import time from unittest.mock import AsyncMock, patch +from aioautomower.session import AutomowerSession, _MowerCommands from aioautomower.utils import mower_list_to_dictionary_dataclass from aiohttp import ClientWebSocketResponse import pytest @@ -82,20 +83,18 @@ async def setup_credentials(hass: HomeAssistant) -> None: @pytest.fixture def mock_automower_client() -> Generator[AsyncMock, None, None]: """Mock a Husqvarna Automower client.""" + + mower_dict = mower_list_to_dictionary_dataclass( + load_json_value_fixture("mower.json", DOMAIN) + ) + + mock = AsyncMock(spec=AutomowerSession) + mock.auth = AsyncMock(side_effect=ClientWebSocketResponse) + mock.commands = AsyncMock(spec_set=_MowerCommands) + mock.get_status.return_value = mower_dict + with patch( "homeassistant.components.husqvarna_automower.AutomowerSession", - autospec=True, - ) as mock_client: - client = mock_client.return_value - client.get_status.return_value = mower_list_to_dictionary_dataclass( - load_json_value_fixture("mower.json", DOMAIN) - ) - - async def websocket_connect() -> ClientWebSocketResponse: - """Mock listen.""" - return ClientWebSocketResponse - - client.auth = AsyncMock(side_effect=websocket_connect) - client.commands = AsyncMock() - - yield client + return_value=mock, + ): + yield mock diff --git a/tests/components/husqvarna_automower/snapshots/test_binary_sensor.ambr b/tests/components/husqvarna_automower/snapshots/test_binary_sensor.ambr index d677f504390..aaa9c59679f 100644 --- a/tests/components/husqvarna_automower/snapshots/test_binary_sensor.ambr +++ b/tests/components/husqvarna_automower/snapshots/test_binary_sensor.ambr @@ -1,5 +1,5 @@ # serializer version: 1 -# name: test_sensor[binary_sensor.test_mower_1_charging-entry] +# name: test_binary_sensor_snapshot[binary_sensor.test_mower_1_charging-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -32,7 +32,7 @@ 'unit_of_measurement': None, }) # --- -# name: test_sensor[binary_sensor.test_mower_1_charging-state] +# name: test_binary_sensor_snapshot[binary_sensor.test_mower_1_charging-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'device_class': 'battery_charging', @@ -41,11 +41,12 @@ 'context': , 'entity_id': 'binary_sensor.test_mower_1_charging', 'last_changed': , + 'last_reported': , 'last_updated': , 'state': 'off', }) # --- -# name: test_sensor[binary_sensor.test_mower_1_leaving_dock-entry] +# name: test_binary_sensor_snapshot[binary_sensor.test_mower_1_leaving_dock-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -78,7 +79,7 @@ 'unit_of_measurement': None, }) # --- -# name: test_sensor[binary_sensor.test_mower_1_leaving_dock-state] +# name: test_binary_sensor_snapshot[binary_sensor.test_mower_1_leaving_dock-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'friendly_name': 'Test Mower 1 Leaving dock', @@ -86,11 +87,12 @@ 'context': , 'entity_id': 'binary_sensor.test_mower_1_leaving_dock', 'last_changed': , + 'last_reported': , 'last_updated': , 'state': 'off', }) # --- -# name: test_sensor[binary_sensor.test_mower_1_returning_to_dock-entry] +# name: test_binary_sensor_snapshot[binary_sensor.test_mower_1_returning_to_dock-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -123,145 +125,7 @@ 'unit_of_measurement': None, }) # --- -# name: test_sensor[binary_sensor.test_mower_1_returning_to_dock-state] - StateSnapshot({ - 'attributes': ReadOnlyDict({ - 'friendly_name': 'Test Mower 1 Returning to dock', - }), - 'context': , - 'entity_id': 'binary_sensor.test_mower_1_returning_to_dock', - 'last_changed': , - 'last_updated': , - 'state': 'off', - }) -# --- -# name: test_snapshot_binary_sensor[binary_sensor.test_mower_1_charging-entry] - EntityRegistryEntrySnapshot({ - 'aliases': set({ - }), - 'area_id': None, - 'capabilities': None, - 'config_entry_id': , - 'device_class': None, - 'device_id': , - 'disabled_by': None, - 'domain': 'binary_sensor', - 'entity_category': None, - 'entity_id': 'binary_sensor.test_mower_1_charging', - 'has_entity_name': True, - 'hidden_by': None, - 'icon': None, - 'id': , - 'labels': set({ - }), - 'name': None, - 'options': dict({ - }), - 'original_device_class': , - 'original_icon': None, - 'original_name': 'Charging', - 'platform': 'husqvarna_automower', - 'previous_unique_id': None, - 'supported_features': 0, - 'translation_key': None, - 'unique_id': 'c7233734-b219-4287-a173-08e3643f89f0_battery_charging', - 'unit_of_measurement': None, - }) -# --- -# name: test_snapshot_binary_sensor[binary_sensor.test_mower_1_charging-state] - StateSnapshot({ - 'attributes': ReadOnlyDict({ - 'device_class': 'battery_charging', - 'friendly_name': 'Test Mower 1 Charging', - }), - 'context': , - 'entity_id': 'binary_sensor.test_mower_1_charging', - 'last_changed': , - 'last_reported': , - 'last_updated': , - 'state': 'off', - }) -# --- -# name: test_snapshot_binary_sensor[binary_sensor.test_mower_1_leaving_dock-entry] - EntityRegistryEntrySnapshot({ - 'aliases': set({ - }), - 'area_id': None, - 'capabilities': None, - 'config_entry_id': , - 'device_class': None, - 'device_id': , - 'disabled_by': None, - 'domain': 'binary_sensor', - 'entity_category': None, - 'entity_id': 'binary_sensor.test_mower_1_leaving_dock', - 'has_entity_name': True, - 'hidden_by': None, - 'icon': None, - 'id': , - 'labels': set({ - }), - 'name': None, - 'options': dict({ - }), - 'original_device_class': None, - 'original_icon': None, - 'original_name': 'Leaving dock', - 'platform': 'husqvarna_automower', - 'previous_unique_id': None, - 'supported_features': 0, - 'translation_key': 'leaving_dock', - 'unique_id': 'c7233734-b219-4287-a173-08e3643f89f0_leaving_dock', - 'unit_of_measurement': None, - }) -# --- -# name: test_snapshot_binary_sensor[binary_sensor.test_mower_1_leaving_dock-state] - StateSnapshot({ - 'attributes': ReadOnlyDict({ - 'friendly_name': 'Test Mower 1 Leaving dock', - }), - 'context': , - 'entity_id': 'binary_sensor.test_mower_1_leaving_dock', - 'last_changed': , - 'last_reported': , - 'last_updated': , - 'state': 'off', - }) -# --- -# name: test_snapshot_binary_sensor[binary_sensor.test_mower_1_returning_to_dock-entry] - EntityRegistryEntrySnapshot({ - 'aliases': set({ - }), - 'area_id': None, - 'capabilities': None, - 'config_entry_id': , - 'device_class': None, - 'device_id': , - 'disabled_by': None, - 'domain': 'binary_sensor', - 'entity_category': None, - 'entity_id': 'binary_sensor.test_mower_1_returning_to_dock', - 'has_entity_name': True, - 'hidden_by': None, - 'icon': None, - 'id': , - 'labels': set({ - }), - 'name': None, - 'options': dict({ - }), - 'original_device_class': None, - 'original_icon': None, - 'original_name': 'Returning to dock', - 'platform': 'husqvarna_automower', - 'previous_unique_id': None, - 'supported_features': 0, - 'translation_key': 'returning_to_dock', - 'unique_id': 'c7233734-b219-4287-a173-08e3643f89f0_returning_to_dock', - 'unit_of_measurement': None, - }) -# --- -# name: test_snapshot_binary_sensor[binary_sensor.test_mower_1_returning_to_dock-state] +# name: test_binary_sensor_snapshot[binary_sensor.test_mower_1_returning_to_dock-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'friendly_name': 'Test Mower 1 Returning to dock', diff --git a/tests/components/husqvarna_automower/snapshots/test_number.ambr b/tests/components/husqvarna_automower/snapshots/test_number.ambr index 4ce5476a555..de8b397f01c 100644 --- a/tests/components/husqvarna_automower/snapshots/test_number.ambr +++ b/tests/components/husqvarna_automower/snapshots/test_number.ambr @@ -1,5 +1,5 @@ # serializer version: 1 -# name: test_snapshot_number[number.test_mower_1_back_lawn_cutting_height-entry] +# name: test_number_snapshot[number.test_mower_1_back_lawn_cutting_height-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -37,7 +37,7 @@ 'unit_of_measurement': '%', }) # --- -# name: test_snapshot_number[number.test_mower_1_back_lawn_cutting_height-state] +# name: test_number_snapshot[number.test_mower_1_back_lawn_cutting_height-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'friendly_name': 'Test Mower 1 Back lawn cutting height', @@ -55,7 +55,7 @@ 'state': '25', }) # --- -# name: test_snapshot_number[number.test_mower_1_cutting_height-entry] +# name: test_number_snapshot[number.test_mower_1_cutting_height-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -93,7 +93,7 @@ 'unit_of_measurement': None, }) # --- -# name: test_snapshot_number[number.test_mower_1_cutting_height-state] +# name: test_number_snapshot[number.test_mower_1_cutting_height-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'friendly_name': 'Test Mower 1 Cutting height', @@ -110,7 +110,7 @@ 'state': '4', }) # --- -# name: test_snapshot_number[number.test_mower_1_front_lawn_cutting_height-entry] +# name: test_number_snapshot[number.test_mower_1_front_lawn_cutting_height-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -148,7 +148,7 @@ 'unit_of_measurement': '%', }) # --- -# name: test_snapshot_number[number.test_mower_1_front_lawn_cutting_height-state] +# name: test_number_snapshot[number.test_mower_1_front_lawn_cutting_height-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'friendly_name': 'Test Mower 1 Front lawn cutting height', @@ -166,7 +166,7 @@ 'state': '50', }) # --- -# name: test_snapshot_number[number.test_mower_1_my_lawn_cutting_height-entry] +# name: test_number_snapshot[number.test_mower_1_my_lawn_cutting_height-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -204,7 +204,7 @@ 'unit_of_measurement': '%', }) # --- -# name: test_snapshot_number[number.test_mower_1_my_lawn_cutting_height-state] +# name: test_number_snapshot[number.test_mower_1_my_lawn_cutting_height-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'friendly_name': 'Test Mower 1 My lawn cutting height ', diff --git a/tests/components/husqvarna_automower/snapshots/test_sensor.ambr b/tests/components/husqvarna_automower/snapshots/test_sensor.ambr index 7d4533afe72..c43a7d4841a 100644 --- a/tests/components/husqvarna_automower/snapshots/test_sensor.ambr +++ b/tests/components/husqvarna_automower/snapshots/test_sensor.ambr @@ -1,5 +1,5 @@ # serializer version: 1 -# name: test_sensor[sensor.test_mower_1_battery-entry] +# name: test_sensor_snapshot[sensor.test_mower_1_battery-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -34,7 +34,7 @@ 'unit_of_measurement': '%', }) # --- -# name: test_sensor[sensor.test_mower_1_battery-state] +# name: test_sensor_snapshot[sensor.test_mower_1_battery-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'device_class': 'battery', @@ -50,7 +50,7 @@ 'state': '100', }) # --- -# name: test_sensor[sensor.test_mower_1_cutting_blade_usage_time-entry] +# name: test_sensor_snapshot[sensor.test_mower_1_cutting_blade_usage_time-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -88,7 +88,7 @@ 'unit_of_measurement': , }) # --- -# name: test_sensor[sensor.test_mower_1_cutting_blade_usage_time-state] +# name: test_sensor_snapshot[sensor.test_mower_1_cutting_blade_usage_time-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'device_class': 'duration', @@ -104,7 +104,7 @@ 'state': '0.034', }) # --- -# name: test_sensor[sensor.test_mower_1_error-entry] +# name: test_sensor_snapshot[sensor.test_mower_1_error-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -283,7 +283,7 @@ 'unit_of_measurement': None, }) # --- -# name: test_sensor[sensor.test_mower_1_error-state] +# name: test_sensor_snapshot[sensor.test_mower_1_error-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'device_class': 'enum', @@ -442,7 +442,7 @@ 'state': 'no_error', }) # --- -# name: test_sensor[sensor.test_mower_1_mode-entry] +# name: test_sensor_snapshot[sensor.test_mower_1_mode-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -483,7 +483,7 @@ 'unit_of_measurement': None, }) # --- -# name: test_sensor[sensor.test_mower_1_mode-state] +# name: test_sensor_snapshot[sensor.test_mower_1_mode-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'device_class': 'enum', @@ -504,7 +504,7 @@ 'state': 'main_area', }) # --- -# name: test_sensor[sensor.test_mower_1_next_start-entry] +# name: test_sensor_snapshot[sensor.test_mower_1_next_start-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -537,7 +537,7 @@ 'unit_of_measurement': None, }) # --- -# name: test_sensor[sensor.test_mower_1_next_start-state] +# name: test_sensor_snapshot[sensor.test_mower_1_next_start-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'device_class': 'timestamp', @@ -551,7 +551,7 @@ 'state': '2023-06-05T19:00:00+00:00', }) # --- -# name: test_sensor[sensor.test_mower_1_number_of_charging_cycles-entry] +# name: test_sensor_snapshot[sensor.test_mower_1_number_of_charging_cycles-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -586,7 +586,7 @@ 'unit_of_measurement': None, }) # --- -# name: test_sensor[sensor.test_mower_1_number_of_charging_cycles-state] +# name: test_sensor_snapshot[sensor.test_mower_1_number_of_charging_cycles-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'friendly_name': 'Test Mower 1 Number of charging cycles', @@ -600,7 +600,7 @@ 'state': '1380', }) # --- -# name: test_sensor[sensor.test_mower_1_number_of_collisions-entry] +# name: test_sensor_snapshot[sensor.test_mower_1_number_of_collisions-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -635,7 +635,7 @@ 'unit_of_measurement': None, }) # --- -# name: test_sensor[sensor.test_mower_1_number_of_collisions-state] +# name: test_sensor_snapshot[sensor.test_mower_1_number_of_collisions-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'friendly_name': 'Test Mower 1 Number of collisions', @@ -649,7 +649,7 @@ 'state': '11396', }) # --- -# name: test_sensor[sensor.test_mower_1_restricted_reason-entry] +# name: test_sensor_snapshot[sensor.test_mower_1_restricted_reason-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -695,7 +695,7 @@ 'unit_of_measurement': None, }) # --- -# name: test_sensor[sensor.test_mower_1_restricted_reason-state] +# name: test_sensor_snapshot[sensor.test_mower_1_restricted_reason-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'device_class': 'enum', @@ -721,7 +721,7 @@ 'state': 'week_schedule', }) # --- -# name: test_sensor[sensor.test_mower_1_total_charging_time-entry] +# name: test_sensor_snapshot[sensor.test_mower_1_total_charging_time-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -759,7 +759,7 @@ 'unit_of_measurement': , }) # --- -# name: test_sensor[sensor.test_mower_1_total_charging_time-state] +# name: test_sensor_snapshot[sensor.test_mower_1_total_charging_time-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'device_class': 'duration', @@ -775,7 +775,7 @@ 'state': '1204.000', }) # --- -# name: test_sensor[sensor.test_mower_1_total_cutting_time-entry] +# name: test_sensor_snapshot[sensor.test_mower_1_total_cutting_time-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -813,7 +813,7 @@ 'unit_of_measurement': , }) # --- -# name: test_sensor[sensor.test_mower_1_total_cutting_time-state] +# name: test_sensor_snapshot[sensor.test_mower_1_total_cutting_time-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'device_class': 'duration', @@ -829,7 +829,7 @@ 'state': '1165.000', }) # --- -# name: test_sensor[sensor.test_mower_1_total_drive_distance-entry] +# name: test_sensor_snapshot[sensor.test_mower_1_total_drive_distance-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -867,7 +867,7 @@ 'unit_of_measurement': , }) # --- -# name: test_sensor[sensor.test_mower_1_total_drive_distance-state] +# name: test_sensor_snapshot[sensor.test_mower_1_total_drive_distance-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'device_class': 'distance', @@ -883,7 +883,7 @@ 'state': '1780.272', }) # --- -# name: test_sensor[sensor.test_mower_1_total_running_time-entry] +# name: test_sensor_snapshot[sensor.test_mower_1_total_running_time-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -921,7 +921,7 @@ 'unit_of_measurement': , }) # --- -# name: test_sensor[sensor.test_mower_1_total_running_time-state] +# name: test_sensor_snapshot[sensor.test_mower_1_total_running_time-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'device_class': 'duration', @@ -937,7 +937,7 @@ 'state': '1268.000', }) # --- -# name: test_sensor[sensor.test_mower_1_total_searching_time-entry] +# name: test_sensor_snapshot[sensor.test_mower_1_total_searching_time-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -975,7 +975,7 @@ 'unit_of_measurement': , }) # --- -# name: test_sensor[sensor.test_mower_1_total_searching_time-state] +# name: test_sensor_snapshot[sensor.test_mower_1_total_searching_time-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'device_class': 'duration', diff --git a/tests/components/husqvarna_automower/snapshots/test_switch.ambr b/tests/components/husqvarna_automower/snapshots/test_switch.ambr index 214273ababe..f52462496ff 100644 --- a/tests/components/husqvarna_automower/snapshots/test_switch.ambr +++ b/tests/components/husqvarna_automower/snapshots/test_switch.ambr @@ -1,5 +1,5 @@ # serializer version: 1 -# name: test_switch[switch.test_mower_1_avoid_danger_zone-entry] +# name: test_switch_snapshot[switch.test_mower_1_avoid_danger_zone-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -32,7 +32,7 @@ 'unit_of_measurement': None, }) # --- -# name: test_switch[switch.test_mower_1_avoid_danger_zone-state] +# name: test_switch_snapshot[switch.test_mower_1_avoid_danger_zone-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'friendly_name': 'Test Mower 1 Avoid Danger Zone', @@ -45,7 +45,7 @@ 'state': 'off', }) # --- -# name: test_switch[switch.test_mower_1_avoid_springflowers-entry] +# name: test_switch_snapshot[switch.test_mower_1_avoid_springflowers-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -78,7 +78,7 @@ 'unit_of_measurement': None, }) # --- -# name: test_switch[switch.test_mower_1_avoid_springflowers-state] +# name: test_switch_snapshot[switch.test_mower_1_avoid_springflowers-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'friendly_name': 'Test Mower 1 Avoid Springflowers', @@ -91,7 +91,7 @@ 'state': 'on', }) # --- -# name: test_switch[switch.test_mower_1_enable_schedule-entry] +# name: test_switch_snapshot[switch.test_mower_1_enable_schedule-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ }), @@ -124,7 +124,7 @@ 'unit_of_measurement': None, }) # --- -# name: test_switch[switch.test_mower_1_enable_schedule-state] +# name: test_switch_snapshot[switch.test_mower_1_enable_schedule-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'friendly_name': 'Test Mower 1 Enable schedule', diff --git a/tests/components/husqvarna_automower/test_binary_sensor.py b/tests/components/husqvarna_automower/test_binary_sensor.py index 5500b547853..29e626f99cb 100644 --- a/tests/components/husqvarna_automower/test_binary_sensor.py +++ b/tests/components/husqvarna_automower/test_binary_sensor.py @@ -59,14 +59,14 @@ async def test_binary_sensor_states( assert state.state == "on" -async def test_snapshot_binary_sensor( +async def test_binary_sensor_snapshot( hass: HomeAssistant, entity_registry: er.EntityRegistry, mock_automower_client: AsyncMock, mock_config_entry: MockConfigEntry, snapshot: SnapshotAssertion, ) -> None: - """Test states of the binary sensors.""" + """Snapshot test states of the binary sensors.""" with patch( "homeassistant.components.husqvarna_automower.PLATFORMS", [Platform.BINARY_SENSOR], diff --git a/tests/components/husqvarna_automower/test_device_tracker.py b/tests/components/husqvarna_automower/test_device_tracker.py index 015be201ccc..91f5e40b154 100644 --- a/tests/components/husqvarna_automower/test_device_tracker.py +++ b/tests/components/husqvarna_automower/test_device_tracker.py @@ -20,7 +20,7 @@ async def test_device_tracker_snapshot( mock_config_entry: MockConfigEntry, snapshot: SnapshotAssertion, ) -> None: - """Test device tracker with a snapshot.""" + """Snapshot test of the device tracker.""" with patch( "homeassistant.components.husqvarna_automower.PLATFORMS", [Platform.DEVICE_TRACKER], diff --git a/tests/components/husqvarna_automower/test_lawn_mower.py b/tests/components/husqvarna_automower/test_lawn_mower.py index 58e7c65bf92..f01f4afd401 100644 --- a/tests/components/husqvarna_automower/test_lawn_mower.py +++ b/tests/components/husqvarna_automower/test_lawn_mower.py @@ -70,19 +70,16 @@ async def test_lawn_mower_commands( ) -> None: """Test lawn_mower commands.""" await setup_integration(hass, mock_config_entry) - getattr( mock_automower_client.commands, aioautomower_command ).side_effect = ApiException("Test error") - - with pytest.raises(HomeAssistantError) as exc_info: + with pytest.raises( + HomeAssistantError, + match="Command couldn't be sent to the command queue: Test error", + ): await hass.services.async_call( domain="lawn_mower", service=service, service_data={"entity_id": "lawn_mower.test_mower_1"}, blocking=True, ) - assert ( - str(exc_info.value) - == "Command couldn't be sent to the command queue: Test error" - ) diff --git a/tests/components/husqvarna_automower/test_number.py b/tests/components/husqvarna_automower/test_number.py index 1b3751af28f..0547d6a9b2e 100644 --- a/tests/components/husqvarna_automower/test_number.py +++ b/tests/components/husqvarna_automower/test_number.py @@ -36,10 +36,13 @@ async def test_number_commands( blocking=True, ) mocked_method = mock_automower_client.commands.set_cutting_height - assert len(mocked_method.mock_calls) == 1 + mocked_method.assert_called_once_with(TEST_MOWER_ID, 3) mocked_method.side_effect = ApiException("Test error") - with pytest.raises(HomeAssistantError) as exc_info: + with pytest.raises( + HomeAssistantError, + match="Command couldn't be sent to the command queue: Test error", + ): await hass.services.async_call( domain="number", service="set_value", @@ -47,10 +50,6 @@ async def test_number_commands( service_data={"value": "3"}, blocking=True, ) - assert ( - str(exc_info.value) - == "Command couldn't be sent to the command queue: Test error" - ) assert len(mocked_method.mock_calls) == 2 @@ -78,13 +77,16 @@ async def test_number_workarea_commands( service_data={"value": "75"}, blocking=True, ) - assert len(mocked_method.mock_calls) == 1 + mocked_method.assert_called_once_with(TEST_MOWER_ID, 75, 123456) state = hass.states.get(entity_id) assert state.state is not None assert state.state == "75" mocked_method.side_effect = ApiException("Test error") - with pytest.raises(HomeAssistantError) as exc_info: + with pytest.raises( + HomeAssistantError, + match="Command couldn't be sent to the command queue: Test error", + ): await hass.services.async_call( domain="number", service="set_value", @@ -92,10 +94,6 @@ async def test_number_workarea_commands( service_data={"value": "75"}, blocking=True, ) - assert ( - str(exc_info.value) - == "Command couldn't be sent to the command queue: Test error" - ) assert len(mocked_method.mock_calls) == 2 @@ -125,14 +123,14 @@ async def test_workarea_deleted( @pytest.mark.usefixtures("entity_registry_enabled_by_default") -async def test_snapshot_number( +async def test_number_snapshot( hass: HomeAssistant, entity_registry: er.EntityRegistry, mock_automower_client: AsyncMock, mock_config_entry: MockConfigEntry, snapshot: SnapshotAssertion, ) -> None: - """Test states of the number entity.""" + """Snapshot tests of the number entities.""" with patch( "homeassistant.components.husqvarna_automower.PLATFORMS", [Platform.NUMBER], diff --git a/tests/components/husqvarna_automower/test_select.py b/tests/components/husqvarna_automower/test_select.py index 5ddb32828aa..fea2ca08742 100644 --- a/tests/components/husqvarna_automower/test_select.py +++ b/tests/components/husqvarna_automower/test_select.py @@ -82,10 +82,14 @@ async def test_select_commands( blocking=True, ) mocked_method = mock_automower_client.commands.set_headlight_mode + mocked_method.assert_called_once_with(TEST_MOWER_ID, service.upper()) assert len(mocked_method.mock_calls) == 1 mocked_method.side_effect = ApiException("Test error") - with pytest.raises(HomeAssistantError) as exc_info: + with pytest.raises( + HomeAssistantError, + match="Command couldn't be sent to the command queue: Test error", + ): await hass.services.async_call( domain="select", service="select_option", @@ -95,8 +99,4 @@ async def test_select_commands( }, blocking=True, ) - assert ( - str(exc_info.value) - == "Command couldn't be sent to the command queue: Test error" - ) assert len(mocked_method.mock_calls) == 2 diff --git a/tests/components/husqvarna_automower/test_sensor.py b/tests/components/husqvarna_automower/test_sensor.py index 2c0661f82cb..9eea901c93c 100644 --- a/tests/components/husqvarna_automower/test_sensor.py +++ b/tests/components/husqvarna_automower/test_sensor.py @@ -144,14 +144,14 @@ async def test_error_sensor( assert state.state == expected_state -async def test_sensor( +async def test_sensor_snapshot( hass: HomeAssistant, entity_registry: er.EntityRegistry, mock_automower_client: AsyncMock, mock_config_entry: MockConfigEntry, snapshot: SnapshotAssertion, ) -> None: - """Test states of the sensors.""" + """Snapshot test of the sensors.""" with patch( "homeassistant.components.husqvarna_automower.PLATFORMS", [Platform.SENSOR], diff --git a/tests/components/husqvarna_automower/test_switch.py b/tests/components/husqvarna_automower/test_switch.py index f8875ae2716..a6e91e35544 100644 --- a/tests/components/husqvarna_automower/test_switch.py +++ b/tests/components/husqvarna_automower/test_switch.py @@ -79,20 +79,19 @@ async def test_switch_commands( blocking=True, ) mocked_method = getattr(mock_automower_client.commands, aioautomower_command) - assert len(mocked_method.mock_calls) == 1 + mocked_method.assert_called_once_with(TEST_MOWER_ID) mocked_method.side_effect = ApiException("Test error") - with pytest.raises(HomeAssistantError) as exc_info: + with pytest.raises( + HomeAssistantError, + match="Command couldn't be sent to the command queue: Test error", + ): await hass.services.async_call( domain="switch", service=service, service_data={"entity_id": "switch.test_mower_1_enable_schedule"}, blocking=True, ) - assert ( - str(exc_info.value) - == "Command couldn't be sent to the command queue: Test error" - ) assert len(mocked_method.mock_calls) == 2 @@ -172,14 +171,14 @@ async def test_zones_deleted( ) == (current_entries - 1) -async def test_switch( +async def test_switch_snapshot( hass: HomeAssistant, entity_registry: er.EntityRegistry, mock_automower_client: AsyncMock, mock_config_entry: MockConfigEntry, snapshot: SnapshotAssertion, ) -> None: - """Test states of the switch.""" + """Snapshot tests of the switches.""" with patch( "homeassistant.components.husqvarna_automower.PLATFORMS", [Platform.SWITCH],