From b84e93f462ae0b69deaeaaba69e6ad3ce67a4caf Mon Sep 17 00:00:00 2001 From: Petar Petrov Date: Tue, 20 May 2025 08:25:44 +0300 Subject: [PATCH] Sort usb ports in Z-Wave flow so unknown devices are last (#145211) * Sort usb ports in Z-Wave flow so unknown devices are last * tweak * Apply suggestions from code review Co-authored-by: Martin Hjelmare --------- Co-authored-by: Martin Hjelmare --- .../components/zwave_js/config_flow.py | 9 +++++- tests/components/zwave_js/test_config_flow.py | 30 ++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/zwave_js/config_flow.py b/homeassistant/components/zwave_js/config_flow.py index e442fb59cfc..324011a3009 100644 --- a/homeassistant/components/zwave_js/config_flow.py +++ b/homeassistant/components/zwave_js/config_flow.py @@ -149,7 +149,14 @@ def get_usb_ports() -> dict[str, str]: pid, ) port_descriptions[dev_path] = human_name - return port_descriptions + + # Sort the dictionary by description, putting "n/a" last + return dict( + sorted( + port_descriptions.items(), + key=lambda x: x[1].lower().startswith("n/a"), + ) + ) async def async_get_usb_ports(hass: HomeAssistant) -> dict[str, str]: diff --git a/tests/components/zwave_js/test_config_flow.py b/tests/components/zwave_js/test_config_flow.py index 7a2788a7b75..68489b304d2 100644 --- a/tests/components/zwave_js/test_config_flow.py +++ b/tests/components/zwave_js/test_config_flow.py @@ -17,7 +17,7 @@ from zwave_js_server.exceptions import FailedCommand from zwave_js_server.version import VersionInfo from homeassistant import config_entries, data_entry_flow -from homeassistant.components.zwave_js.config_flow import TITLE +from homeassistant.components.zwave_js.config_flow import TITLE, get_usb_ports from homeassistant.components.zwave_js.const import ADDON_SLUG, CONF_USB_PATH, DOMAIN from homeassistant.components.zwave_js.helpers import SERVER_VERSION_TIMEOUT from homeassistant.core import HomeAssistant @@ -4661,3 +4661,31 @@ async def test_configure_addon_usb_ports_failure( ) assert result["type"] is FlowResultType.ABORT assert result["reason"] == "usb_ports_failed" + + +async def test_get_usb_ports_sorting(hass: HomeAssistant) -> None: + """Test that get_usb_ports sorts ports with 'n/a' descriptions last.""" + mock_ports = [ + ListPortInfo("/dev/ttyUSB0"), + ListPortInfo("/dev/ttyUSB1"), + ListPortInfo("/dev/ttyUSB2"), + ListPortInfo("/dev/ttyUSB3"), + ] + mock_ports[0].description = "n/a" + mock_ports[1].description = "Device A" + mock_ports[2].description = "N/A" + mock_ports[3].description = "Device B" + + with patch("serial.tools.list_ports.comports", return_value=mock_ports): + result = get_usb_ports() + + descriptions = list(result.values()) + + # Verify that descriptions containing "n/a" are at the end + + assert descriptions == [ + "Device A - /dev/ttyUSB1, s/n: n/a", + "Device B - /dev/ttyUSB3, s/n: n/a", + "n/a - /dev/ttyUSB0, s/n: n/a", + "N/A - /dev/ttyUSB2, s/n: n/a", + ]