Update Improv BLE discovery notification when device name changes (#154352)

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
This commit is contained in:
J. Nick Koston
2025-10-13 10:14:51 -10:00
committed by GitHub
parent 663431fc80
commit 324aa09ebe
2 changed files with 75 additions and 3 deletions

View File

@@ -170,6 +170,12 @@ class ImprovBLEConfigFlow(ConfigFlow, domain=DOMAIN):
)
self._discovery_info = service_info
# Update title placeholders if name changed
name = service_info.name or service_info.address
if self.context.get("title_placeholders", {}).get("name") != name:
self.async_update_title_placeholders({"name": name})
try:
self._abort_if_provisioned()
except AbortFlow:

View File

@@ -8,7 +8,10 @@ from improv_ble_client import Error, State, errors as improv_ble_errors
import pytest
from homeassistant import config_entries
from homeassistant.components.bluetooth import BluetoothChange
from homeassistant.components.bluetooth import (
BluetoothChange,
BluetoothServiceInfoBleak,
)
from homeassistant.components.improv_ble.const import DOMAIN
from homeassistant.config_entries import SOURCE_IGNORE
from homeassistant.const import CONF_ADDRESS
@@ -22,8 +25,12 @@ from . import (
PROVISIONED_IMPROV_BLE_DISCOVERY_INFO,
)
from tests.common import MockConfigEntry
from tests.components.bluetooth import inject_bluetooth_service_info_bleak
from tests.common import MockConfigEntry, async_capture_events
from tests.components.bluetooth import (
generate_advertisement_data,
generate_ble_device,
inject_bluetooth_service_info_bleak,
)
IMPROV_BLE = "homeassistant.components.improv_ble"
@@ -803,3 +810,62 @@ async def test_provision_fails_invalid_data(
"Received invalid improv via BLE data '000000000000' from device with bluetooth address 'AA:BB:CC:DD:EE:F0'"
in caplog.text
)
async def test_bluetooth_name_update(hass: HomeAssistant) -> None:
"""Test that discovery notification title updates when device name changes."""
with patch(
f"{IMPROV_BLE}.config_flow.bluetooth.async_register_callback",
) as mock_async_register_callback:
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_BLUETOOTH},
data=IMPROV_BLE_DISCOVERY_INFO,
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "bluetooth_confirm"
# Get the flow to check initial title_placeholders
flow = hass.config_entries.flow.async_get(result["flow_id"])
assert flow["context"]["title_placeholders"] == {"name": "00123456"}
# Get the callback that was registered
callback = mock_async_register_callback.call_args.args[1]
# Create updated discovery info with a new name
updated_discovery_info = BluetoothServiceInfoBleak(
name="improvtest",
address="AA:BB:CC:DD:EE:F0",
rssi=-60,
manufacturer_data={},
service_uuids=[IMPROV_BLE_DISCOVERY_INFO.service_uuids[0]],
service_data=IMPROV_BLE_DISCOVERY_INFO.service_data,
source="local",
device=generate_ble_device(address="AA:BB:CC:DD:EE:F0", name="improvtest"),
advertisement=generate_advertisement_data(
service_uuids=IMPROV_BLE_DISCOVERY_INFO.service_uuids,
service_data=IMPROV_BLE_DISCOVERY_INFO.service_data,
),
time=0,
connectable=True,
tx_power=-127,
)
# Capture events to verify frontend notification
events = async_capture_events(hass, "data_entry_flow_progressed")
# Simulate receiving updated advertisement with new name
callback(updated_discovery_info, BluetoothChange.ADVERTISEMENT)
await hass.async_block_till_done()
# Verify title_placeholders were updated
flow = hass.config_entries.flow.async_get(result["flow_id"])
assert flow["context"]["title_placeholders"] == {"name": "improvtest"}
# Verify frontend was notified
assert len(events) == 1
assert events[0].data == {
"handler": DOMAIN,
"flow_id": result["flow_id"],
"refresh": True,
}