diff --git a/homeassistant/components/crownstone/helpers.py b/homeassistant/components/crownstone/helpers.py index ad12c28d464..58b4dcdba47 100644 --- a/homeassistant/components/crownstone/helpers.py +++ b/homeassistant/components/crownstone/helpers.py @@ -31,8 +31,8 @@ def list_ports_as_str( port.serial_number, port.manufacturer, port.description, - f"{hex(port.vid)[2:]:0>4}".upper(), - f"{hex(port.pid)[2:]:0>4}".upper(), + f"{hex(port.vid)[2:]:0>4}".upper() if port.vid else None, + f"{hex(port.pid)[2:]:0>4}".upper() if port.pid else None, ) ) ports_as_string.append(MANUAL_PATH) diff --git a/tests/components/crownstone/test_config_flow.py b/tests/components/crownstone/test_config_flow.py index 7b05c8ba530..05fde6109e7 100644 --- a/tests/components/crownstone/test_config_flow.py +++ b/tests/components/crownstone/test_config_flow.py @@ -51,6 +51,16 @@ def usb_comports() -> MockFixture: yield comports_mock +@pytest.fixture(name="pyserial_comports_none_types") +def usb_comports_none_types() -> MockFixture: + """Mock pyserial comports.""" + with patch( + "serial.tools.list_ports.comports", + MagicMock(return_value=[get_mocked_com_port_none_types()]), + ) as comports_mock: + yield comports_mock + + @pytest.fixture(name="usb_path") def usb_path() -> MockFixture: """Mock usb serial path.""" @@ -104,6 +114,19 @@ def get_mocked_com_port(): return port +def get_mocked_com_port_none_types(): + """Mock of a serial port with NoneTypes.""" + port = ListPortInfo("/dev/ttyUSB1234") + port.device = "/dev/ttyUSB1234" + port.serial_number = None + port.manufacturer = None + port.description = "crownstone dongle - crownstone dongle" + port.vid = None + port.pid = None + + return port + + def create_mocked_entry_data_conf(email: str, password: str): """Set a result for the entry data for comparison.""" mock_data: dict[str, str | None] = {} @@ -262,7 +285,7 @@ async def test_successful_login_no_usb( async def test_successful_login_with_usb( crownstone_setup: MockFixture, - pyserial_comports: MockFixture, + pyserial_comports_none_types: MockFixture, usb_path: MockFixture, hass: HomeAssistant, ): @@ -282,17 +305,18 @@ async def test_successful_login_with_usb( # should show usb form assert result["type"] == data_entry_flow.RESULT_TYPE_FORM assert result["step_id"] == "usb_config" - assert pyserial_comports.call_count == 1 + assert pyserial_comports_none_types.call_count == 1 - # create a mocked port - port = get_mocked_com_port() + # create a mocked port which should be in + # the list returned from list_ports_as_str, from .helpers + port = get_mocked_com_port_none_types() port_select = usb.human_readable_device_name( port.device, port.serial_number, port.manufacturer, port.description, - f"{hex(port.vid)[2:]:0>4}".upper(), - f"{hex(port.pid)[2:]:0>4}".upper(), + port.vid, + port.pid, ) # select a port from the list @@ -301,7 +325,7 @@ async def test_successful_login_with_usb( ) assert result["type"] == data_entry_flow.RESULT_TYPE_FORM assert result["step_id"] == "usb_sphere_config" - assert pyserial_comports.call_count == 2 + assert pyserial_comports_none_types.call_count == 2 assert usb_path.call_count == 1 # select a sphere @@ -406,7 +430,8 @@ async def test_options_flow_setup_usb( assert result["step_id"] == "usb_config" assert pyserial_comports.call_count == 1 - # create a mocked port + # create a mocked port which should be in + # the list returned from list_ports_as_str, from .helpers port = get_mocked_com_port() port_select = usb.human_readable_device_name( port.device,