mirror of
https://github.com/home-assistant/core.git
synced 2026-08-23 14:43:52 +01:00
Improve error handling in websocket_update_device (#179709)
This commit is contained in:
@@ -178,8 +178,26 @@ def websocket_update_device(
|
||||
# Convert labels to a set
|
||||
msg["labels"] = set(msg["labels"])
|
||||
|
||||
device_id = msg["device_id"]
|
||||
|
||||
# A composite device id has no single underlying device to update; reject it.
|
||||
if (
|
||||
registry.async_get(
|
||||
device_id, include_main_devices=False, include_child_devices=False
|
||||
)
|
||||
is not None
|
||||
):
|
||||
connection.send_error(
|
||||
msg_id, websocket_api.ERR_NOT_ALLOWED, "Cannot update a composite device"
|
||||
)
|
||||
return
|
||||
if (
|
||||
device := registry.async_get(device_id, include_composite_devices=False)
|
||||
) is None:
|
||||
connection.send_error(msg_id, websocket_api.ERR_NOT_FOUND, "Device not found")
|
||||
return
|
||||
|
||||
entry: dr.AnyDeviceEntry | None
|
||||
device = registry.async_get(msg["device_id"], include_composite_devices=False)
|
||||
if isinstance(device, dr.ChildDeviceEntry):
|
||||
entry = registry.async_update_child_device(**msg)
|
||||
else:
|
||||
|
||||
@@ -388,6 +388,82 @@ async def test_update_device_labels(
|
||||
assert getattr(device, key) == value
|
||||
|
||||
|
||||
async def test_update_device_unknown_device(
|
||||
hass: HomeAssistant,
|
||||
client: MockHAClientWebSocket,
|
||||
) -> None:
|
||||
"""Test updating an unknown device returns an error."""
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"type": "config/device_registry/update",
|
||||
"device_id": "does_not_exist",
|
||||
"name_by_user": "Test Friendly Name",
|
||||
}
|
||||
)
|
||||
msg = await client.receive_json()
|
||||
|
||||
assert not msg["success"]
|
||||
assert msg["error"]["code"] == "not_found"
|
||||
assert msg["error"]["message"] == "Device not found"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("load_registries", [False])
|
||||
async def test_update_device_composite(
|
||||
hass: HomeAssistant,
|
||||
client: MockHAClientWebSocket,
|
||||
hass_storage: dict[str, Any],
|
||||
) -> None:
|
||||
"""Test updating a pre-migration composite device id is rejected."""
|
||||
entry_1 = MockConfigEntry()
|
||||
entry_1.add_to_hass(hass)
|
||||
entry_2 = MockConfigEntry()
|
||||
entry_2.add_to_hass(hass)
|
||||
|
||||
composite_id = "compositea000000000000000000000"
|
||||
hass_storage[dr.STORAGE_KEY] = {
|
||||
"version": 1,
|
||||
"minor_version": 12,
|
||||
"key": dr.STORAGE_KEY,
|
||||
"data": {
|
||||
"devices": [
|
||||
# Composite spanning two config entries; splitting it on load removes
|
||||
# the composite device, so composite_id no longer refers to a device
|
||||
_storage_device_v1_12(
|
||||
composite_id,
|
||||
[entry_1.entry_id, entry_2.entry_id],
|
||||
entry_1.entry_id,
|
||||
"a",
|
||||
),
|
||||
],
|
||||
"deleted_devices": [],
|
||||
},
|
||||
}
|
||||
|
||||
dr.async_setup(hass)
|
||||
await dr.async_load(hass)
|
||||
# pylint: disable-next=home-assistant-tests-registry-fixtures
|
||||
registry = dr.async_get(hass)
|
||||
assert registry.async_get(composite_id) is not None
|
||||
assert registry.async_get(composite_id, include_composite_devices=False) is None
|
||||
|
||||
await client.send_json_auto_id(
|
||||
{
|
||||
"type": "config/device_registry/update",
|
||||
"device_id": composite_id,
|
||||
"name_by_user": "Test Friendly Name",
|
||||
}
|
||||
)
|
||||
msg = await client.receive_json()
|
||||
|
||||
assert not msg["success"]
|
||||
assert msg["error"]["code"] == "not_allowed"
|
||||
assert msg["error"]["message"] == "Cannot update a composite device"
|
||||
|
||||
# The update was not fanned out to the underlying split devices
|
||||
for split in registry.async_get_devices_for_composite_device_id(composite_id):
|
||||
assert split.name_by_user is None
|
||||
|
||||
|
||||
_DEPRECATION_WARNING = (
|
||||
"The websocket command config/device_registry/remove_config_entry is "
|
||||
"deprecated and will be removed in Home Assistant 2027.9"
|
||||
|
||||
Reference in New Issue
Block a user