From 390daf1723c395535f87cfae2f6cba5ecc58892a Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Tue, 28 Feb 2023 16:12:49 +0100 Subject: [PATCH] Sort unit lists sent to frontend (#88898) --- .../components/number/websocket_api.py | 7 +++-- .../components/sensor/websocket_api.py | 7 +++-- .../components/weather/websocket_api.py | 5 +++- tests/components/number/test_websocket_api.py | 15 ++++------ tests/components/sensor/test_websocket_api.py | 30 +++++++++++-------- .../components/weather/test_websocket_api.py | 12 ++++---- 6 files changed, 41 insertions(+), 35 deletions(-) diff --git a/homeassistant/components/number/websocket_api.py b/homeassistant/components/number/websocket_api.py index eca280d7d43..1ca61fd158f 100644 --- a/homeassistant/components/number/websocket_api.py +++ b/homeassistant/components/number/websocket_api.py @@ -29,7 +29,10 @@ def ws_device_class_units( ) -> None: """Return supported units for a device class.""" device_class = msg["device_class"] - convertible_units = set() + convertible_units = [] if device_class in UNIT_CONVERTERS and device_class in DEVICE_CLASS_UNITS: - convertible_units = DEVICE_CLASS_UNITS[device_class] + convertible_units = sorted( + DEVICE_CLASS_UNITS[device_class], + key=lambda s: str.casefold(str(s)), + ) connection.send_result(msg["id"], {"units": convertible_units}) diff --git a/homeassistant/components/sensor/websocket_api.py b/homeassistant/components/sensor/websocket_api.py index 10699b8c1c6..2457bfcabe3 100644 --- a/homeassistant/components/sensor/websocket_api.py +++ b/homeassistant/components/sensor/websocket_api.py @@ -29,7 +29,10 @@ def ws_device_class_units( ) -> None: """Return supported units for a device class.""" device_class = msg["device_class"] - convertible_units = set() + convertible_units = [] if device_class in UNIT_CONVERTERS and device_class in DEVICE_CLASS_UNITS: - convertible_units = DEVICE_CLASS_UNITS[device_class] + convertible_units = sorted( + DEVICE_CLASS_UNITS[device_class], + key=lambda s: str.casefold(str(s)), + ) connection.send_result(msg["id"], {"units": convertible_units}) diff --git a/homeassistant/components/weather/websocket_api.py b/homeassistant/components/weather/websocket_api.py index 793efeeed7e..51f129fc4a2 100644 --- a/homeassistant/components/weather/websocket_api.py +++ b/homeassistant/components/weather/websocket_api.py @@ -27,4 +27,7 @@ def ws_convertible_units( hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any] ) -> None: """Return supported units for a device class.""" - connection.send_result(msg["id"], {"units": VALID_UNITS}) + sorted_units = { + key: sorted(units, key=str.casefold) for key, units in VALID_UNITS.items() + } + connection.send_result(msg["id"], {"units": sorted_units}) diff --git a/tests/components/number/test_websocket_api.py b/tests/components/number/test_websocket_api.py index 4f487a6326a..194f24dc9da 100644 --- a/tests/components/number/test_websocket_api.py +++ b/tests/components/number/test_websocket_api.py @@ -1,6 +1,4 @@ """Test the number websocket API.""" -from pytest_unordered import unordered - from homeassistant.components.number.const import DOMAIN from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component @@ -17,21 +15,19 @@ async def test_device_class_units( client = await hass_ws_client(hass) # Device class with units which number allows customizing & converting - await client.send_json( + await client.send_json_auto_id( { - "id": 1, "type": "number/device_class_convertible_units", "device_class": "temperature", } ) msg = await client.receive_json() assert msg["success"] - assert msg["result"] == {"units": unordered(["°F", "°C", "K"])} + assert msg["result"] == {"units": ["K", "°C", "°F"]} # Device class with units which number doesn't allow customizing & converting - await client.send_json( + await client.send_json_auto_id( { - "id": 2, "type": "number/device_class_convertible_units", "device_class": "energy", } @@ -41,13 +37,12 @@ async def test_device_class_units( assert msg["result"] == {"units": []} # Unknown device class - await client.send_json( + await client.send_json_auto_id( { - "id": 3, "type": "number/device_class_convertible_units", "device_class": "kebabsås", } ) msg = await client.receive_json() assert msg["success"] - assert msg["result"] == {"units": unordered([])} + assert msg["result"] == {"units": []} diff --git a/tests/components/sensor/test_websocket_api.py b/tests/components/sensor/test_websocket_api.py index 91eff6e277b..17b8a2ab5cb 100644 --- a/tests/components/sensor/test_websocket_api.py +++ b/tests/components/sensor/test_websocket_api.py @@ -1,6 +1,4 @@ """Test the sensor websocket API.""" -from pytest_unordered import unordered - from homeassistant.components.sensor.const import DOMAIN from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component @@ -17,9 +15,8 @@ async def test_device_class_units( client = await hass_ws_client(hass) # Device class with units which sensor allows customizing & converting - await client.send_json( + await client.send_json_auto_id( { - "id": 1, "type": "sensor/device_class_convertible_units", "device_class": "speed", } @@ -27,15 +24,23 @@ async def test_device_class_units( msg = await client.receive_json() assert msg["success"] assert msg["result"] == { - "units": unordered( - ["km/h", "kn", "mph", "in/h", "in/d", "ft/s", "mm/d", "mm/h", "m/s"] - ) + "units": ["ft/s", "in/d", "in/h", "km/h", "kn", "m/s", "mm/d", "mm/h", "mph"] } - # Device class with units which sensor doesn't allow customizing & converting - await client.send_json( + # Device class with units which include `None` + await client.send_json_auto_id( + { + "type": "sensor/device_class_convertible_units", + "device_class": "power_factor", + } + ) + msg = await client.receive_json() + assert msg["success"] + assert msg["result"] == {"units": ["%", None]} + + # Device class with units which sensor doesn't allow customizing & converting + await client.send_json_auto_id( { - "id": 2, "type": "sensor/device_class_convertible_units", "device_class": "pm1", } @@ -45,13 +50,12 @@ async def test_device_class_units( assert msg["result"] == {"units": []} # Unknown device class - await client.send_json( + await client.send_json_auto_id( { - "id": 3, "type": "sensor/device_class_convertible_units", "device_class": "kebabsås", } ) msg = await client.receive_json() assert msg["success"] - assert msg["result"] == {"units": unordered([])} + assert msg["result"] == {"units": []} diff --git a/tests/components/weather/test_websocket_api.py b/tests/components/weather/test_websocket_api.py index 3995bd2a54b..1112d7713ed 100644 --- a/tests/components/weather/test_websocket_api.py +++ b/tests/components/weather/test_websocket_api.py @@ -1,6 +1,4 @@ """Test the weather websocket API.""" -from pytest_unordered import unordered - from homeassistant.components.weather.const import DOMAIN from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component @@ -22,10 +20,10 @@ async def test_device_class_units(hass: HomeAssistant, hass_ws_client) -> None: assert msg["success"] assert msg["result"] == { "units": { - "precipitation_unit": unordered(["mm", "in"]), - "pressure_unit": unordered(["mbar", "mmHg", "inHg", "hPa"]), - "temperature_unit": unordered(["°F", "°C"]), - "visibility_unit": unordered(["km", "mi"]), - "wind_speed_unit": unordered(["mph", "km/h", "kn", "m/s", "ft/s"]), + "precipitation_unit": ["in", "mm"], + "pressure_unit": ["hPa", "inHg", "mbar", "mmHg"], + "temperature_unit": ["°C", "°F"], + "visibility_unit": ["km", "mi"], + "wind_speed_unit": ["ft/s", "km/h", "kn", "m/s", "mph"], } }