From 48d671ad5f57d1cfb1d5d78dfba3e520cb27126c Mon Sep 17 00:00:00 2001 From: Matthew Vance Date: Tue, 16 Dec 2025 23:27:06 -0800 Subject: [PATCH] Update py-improv-ble-client to 2.0.1 (#159233) --- .../components/improv_ble/config_flow.py | 3 +- .../components/improv_ble/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- .../components/improv_ble/test_config_flow.py | 115 ++++++++++++++---- 5 files changed, 93 insertions(+), 31 deletions(-) diff --git a/homeassistant/components/improv_ble/config_flow.py b/homeassistant/components/improv_ble/config_flow.py index 0df566066c1..ca74498f2a3 100644 --- a/homeassistant/components/improv_ble/config_flow.py +++ b/homeassistant/components/improv_ble/config_flow.py @@ -261,7 +261,8 @@ class ImprovBLEConfigFlow(ConfigFlow, domain=DOMAIN): if self._can_identify is None: try: - self._can_identify = await self._try_call(device.can_identify()) + await self._try_call(device.ensure_connected()) + self._can_identify = device.can_identify except AbortFlow as err: return self.async_abort(reason=err.reason) if self._can_identify: diff --git a/homeassistant/components/improv_ble/manifest.json b/homeassistant/components/improv_ble/manifest.json index 2815df5d7f5..144a8177c98 100644 --- a/homeassistant/components/improv_ble/manifest.json +++ b/homeassistant/components/improv_ble/manifest.json @@ -13,5 +13,5 @@ "documentation": "https://www.home-assistant.io/integrations/improv_ble", "integration_type": "device", "iot_class": "local_polling", - "requirements": ["py-improv-ble-client==1.0.3"] + "requirements": ["py-improv-ble-client==2.0.1"] } diff --git a/requirements_all.txt b/requirements_all.txt index 2c2865d6932..df0da555af2 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1810,7 +1810,7 @@ py-dactyl==2.0.4 py-dormakaba-dkey==1.0.6 # homeassistant.components.improv_ble -py-improv-ble-client==1.0.3 +py-improv-ble-client==2.0.1 # homeassistant.components.madvr py-madvr2==1.6.40 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 9a08e7ed291..609867b3de4 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1550,7 +1550,7 @@ py-dactyl==2.0.4 py-dormakaba-dkey==1.0.6 # homeassistant.components.improv_ble -py-improv-ble-client==1.0.3 +py-improv-ble-client==2.0.1 # homeassistant.components.madvr py-madvr2==1.6.40 diff --git a/tests/components/improv_ble/test_config_flow.py b/tests/components/improv_ble/test_config_flow.py index dca47035784..b493d982155 100644 --- a/tests/components/improv_ble/test_config_flow.py +++ b/tests/components/improv_ble/test_config_flow.py @@ -2,7 +2,7 @@ import asyncio from collections.abc import Callable -from unittest.mock import patch +from unittest.mock import PropertyMock, patch from bleak.exc import BleakError from improv_ble_client import ( @@ -294,8 +294,13 @@ async def test_bluetooth_rediscovery_after_successful_provision( assert result["step_id"] == "bluetooth_confirm" # Start provisioning - with patch( - f"{IMPROV_BLE}.config_flow.ImprovBLEClient.can_identify", return_value=False + with ( + patch( + f"{IMPROV_BLE}.config_flow.ImprovBLEClient.can_identify", + return_value=False, + new_callable=PropertyMock, + ), + patch(f"{IMPROV_BLE}.config_flow.ImprovBLEClient.ensure_connected"), ): result = await hass.config_entries.flow.async_configure( result["flow_id"], @@ -375,8 +380,13 @@ async def _test_common_success_with_identify( hass: HomeAssistant, result: FlowResult, address: str ) -> None: """Test bluetooth and user flow success paths.""" - with patch( - f"{IMPROV_BLE}.config_flow.ImprovBLEClient.can_identify", return_value=True + with ( + patch( + f"{IMPROV_BLE}.config_flow.ImprovBLEClient.can_identify", + return_value=True, + new_callable=PropertyMock, + ), + patch(f"{IMPROV_BLE}.config_flow.ImprovBLEClient.ensure_connected"), ): result = await hass.config_entries.flow.async_configure( result["flow_id"], @@ -420,8 +430,13 @@ async def _test_common_success_wo_identify( placeholders: dict[str, str] | None = None, ) -> None: """Test bluetooth and user flow success paths.""" - with patch( - f"{IMPROV_BLE}.config_flow.ImprovBLEClient.can_identify", return_value=False + with ( + patch( + f"{IMPROV_BLE}.config_flow.ImprovBLEClient.can_identify", + return_value=False, + new_callable=PropertyMock, + ), + patch(f"{IMPROV_BLE}.config_flow.ImprovBLEClient.ensure_connected"), ): result = await hass.config_entries.flow.async_configure( result["flow_id"], @@ -475,8 +490,13 @@ async def _test_common_success_wo_identify_w_authorize( hass: HomeAssistant, result: FlowResult, address: str ) -> None: """Test bluetooth and user flow success paths.""" - with patch( - f"{IMPROV_BLE}.config_flow.ImprovBLEClient.can_identify", return_value=False + with ( + patch( + f"{IMPROV_BLE}.config_flow.ImprovBLEClient.can_identify", + return_value=False, + new_callable=PropertyMock, + ), + patch(f"{IMPROV_BLE}.config_flow.ImprovBLEClient.ensure_connected"), ): result = await hass.config_entries.flow.async_configure( result["flow_id"], @@ -571,7 +591,7 @@ async def test_bluetooth_step_already_in_progress(hass: HomeAssistant) -> None: (improv_ble_errors.CharacteristicMissingError, "characteristic_missing"), ], ) -async def test_can_identify_fails(hass: HomeAssistant, exc, error) -> None: +async def test_ensure_connected_fails(hass: HomeAssistant, exc, error) -> None: """Test bluetooth flow with error.""" result = await hass.config_entries.flow.async_init( DOMAIN, @@ -588,7 +608,8 @@ async def test_can_identify_fails(hass: HomeAssistant, exc, error) -> None: assert result["errors"] is None with patch( - f"{IMPROV_BLE}.config_flow.ImprovBLEClient.can_identify", side_effect=exc + f"{IMPROV_BLE}.config_flow.ImprovBLEClient.ensure_connected", + side_effect=exc, ): result = await hass.config_entries.flow.async_configure( result["flow_id"], @@ -622,8 +643,13 @@ async def test_identify_fails(hass: HomeAssistant, exc, error) -> None: assert result["step_id"] == "bluetooth_confirm" assert result["errors"] is None - with patch( - f"{IMPROV_BLE}.config_flow.ImprovBLEClient.can_identify", return_value=True + with ( + patch( + f"{IMPROV_BLE}.config_flow.ImprovBLEClient.can_identify", + return_value=True, + new_callable=PropertyMock, + ), + patch(f"{IMPROV_BLE}.config_flow.ImprovBLEClient.ensure_connected"), ): result = await hass.config_entries.flow.async_configure( result["flow_id"], @@ -665,8 +691,13 @@ async def test_need_authorization_fails(hass: HomeAssistant, exc, error) -> None assert result["step_id"] == "bluetooth_confirm" assert result["errors"] is None - with patch( - f"{IMPROV_BLE}.config_flow.ImprovBLEClient.can_identify", return_value=False + with ( + patch( + f"{IMPROV_BLE}.config_flow.ImprovBLEClient.can_identify", + return_value=False, + new_callable=PropertyMock, + ), + patch(f"{IMPROV_BLE}.config_flow.ImprovBLEClient.ensure_connected"), ): result = await hass.config_entries.flow.async_configure( result["flow_id"], @@ -709,8 +740,13 @@ async def test_authorize_fails(hass: HomeAssistant, exc, error) -> None: assert result["step_id"] == "bluetooth_confirm" assert result["errors"] is None - with patch( - f"{IMPROV_BLE}.config_flow.ImprovBLEClient.can_identify", return_value=False + with ( + patch( + f"{IMPROV_BLE}.config_flow.ImprovBLEClient.can_identify", + return_value=False, + new_callable=PropertyMock, + ), + patch(f"{IMPROV_BLE}.config_flow.ImprovBLEClient.ensure_connected"), ): result = await hass.config_entries.flow.async_configure( result["flow_id"], @@ -752,8 +788,13 @@ async def _test_provision_error(hass: HomeAssistant, exc) -> str: assert result["step_id"] == "bluetooth_confirm" assert result["errors"] is None - with patch( - f"{IMPROV_BLE}.config_flow.ImprovBLEClient.can_identify", return_value=False + with ( + patch( + f"{IMPROV_BLE}.config_flow.ImprovBLEClient.can_identify", + return_value=False, + new_callable=PropertyMock, + ), + patch(f"{IMPROV_BLE}.config_flow.ImprovBLEClient.ensure_connected"), ): result = await hass.config_entries.flow.async_configure( result["flow_id"], @@ -878,8 +919,13 @@ async def test_flow_chaining_with_next_flow(hass: HomeAssistant) -> None: assert result["step_id"] == "bluetooth_confirm" # Start provisioning - with patch( - f"{IMPROV_BLE}.config_flow.ImprovBLEClient.can_identify", return_value=False + with ( + patch( + f"{IMPROV_BLE}.config_flow.ImprovBLEClient.can_identify", + return_value=False, + new_callable=PropertyMock, + ), + patch(f"{IMPROV_BLE}.config_flow.ImprovBLEClient.ensure_connected"), ): result = await hass.config_entries.flow.async_configure( result["flow_id"], @@ -946,8 +992,13 @@ async def test_flow_chaining_timeout(hass: HomeAssistant) -> None: assert result["step_id"] == "bluetooth_confirm" # Start provisioning - with patch( - f"{IMPROV_BLE}.config_flow.ImprovBLEClient.can_identify", return_value=False + with ( + patch( + f"{IMPROV_BLE}.config_flow.ImprovBLEClient.can_identify", + return_value=False, + new_callable=PropertyMock, + ), + patch(f"{IMPROV_BLE}.config_flow.ImprovBLEClient.ensure_connected"), ): result = await hass.config_entries.flow.async_configure( result["flow_id"], @@ -998,8 +1049,13 @@ async def test_flow_chaining_with_redirect_url(hass: HomeAssistant) -> None: assert result["step_id"] == "bluetooth_confirm" # Start provisioning - with patch( - f"{IMPROV_BLE}.config_flow.ImprovBLEClient.can_identify", return_value=False + with ( + patch( + f"{IMPROV_BLE}.config_flow.ImprovBLEClient.can_identify", + return_value=False, + new_callable=PropertyMock, + ), + patch(f"{IMPROV_BLE}.config_flow.ImprovBLEClient.ensure_connected"), ): result = await hass.config_entries.flow.async_configure( result["flow_id"], @@ -1069,8 +1125,13 @@ async def test_flow_chaining_future_already_done( assert result["step_id"] == "bluetooth_confirm" # Start provisioning - with patch( - f"{IMPROV_BLE}.config_flow.ImprovBLEClient.can_identify", return_value=False + with ( + patch( + f"{IMPROV_BLE}.config_flow.ImprovBLEClient.can_identify", + return_value=False, + new_callable=PropertyMock, + ), + patch(f"{IMPROV_BLE}.config_flow.ImprovBLEClient.ensure_connected"), ): result = await hass.config_entries.flow.async_configure( result["flow_id"],