1
0
mirror of https://github.com/home-assistant/core.git synced 2025-12-24 21:06:19 +00:00

Fix entities/devices stuck in disabled state after config entry re-add (#151075)

This commit is contained in:
J. Nick Koston
2025-08-24 15:55:58 +02:00
committed by GitHub
parent 6c2ba15a73
commit bc6f261105
4 changed files with 198 additions and 1 deletions

View File

@@ -3368,6 +3368,98 @@ async def test_cleanup_startup(hass: HomeAssistant) -> None:
assert len(mock_call.mock_calls) == 1
async def test_deleted_device_clears_disabled_by_on_config_entry_removal(
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,
) -> None:
"""Test that disabled_by is cleared when config entry is removed."""
config_entry = MockConfigEntry(domain="test", entry_id="mock-id-1")
config_entry.add_to_hass(hass)
# Create a device disabled by the config entry
device = device_registry.async_get_or_create(
config_entry_id="mock-id-1",
identifiers={("test", "device_1")},
name="Test Device",
disabled_by=dr.DeviceEntryDisabler.CONFIG_ENTRY,
)
assert device.config_entries == {"mock-id-1"}
assert device.disabled_by is dr.DeviceEntryDisabler.CONFIG_ENTRY
# Remove the device (it moves to deleted_devices)
device_registry.async_remove_device(device.id)
assert len(device_registry.devices) == 0
assert len(device_registry.deleted_devices) == 1
deleted_device = device_registry.deleted_devices[device.id]
assert deleted_device.config_entries == {"mock-id-1"}
assert deleted_device.disabled_by is dr.DeviceEntryDisabler.CONFIG_ENTRY
assert deleted_device.orphaned_timestamp is None
# Clear the config entry
device_registry.async_clear_config_entry("mock-id-1")
# Verify disabled_by is cleared
deleted_device = device_registry.deleted_devices[device.id]
assert deleted_device.config_entries == set()
assert deleted_device.disabled_by is None # Should be cleared
assert deleted_device.orphaned_timestamp is not None
# Now re-add the config entry and device to verify it can be enabled
config_entry2 = MockConfigEntry(domain="test", entry_id="mock-id-2")
config_entry2.add_to_hass(hass)
# Re-create the device with same identifiers
device2 = device_registry.async_get_or_create(
config_entry_id="mock-id-2",
identifiers={("test", "device_1")},
name="Test Device",
)
assert device2.config_entries == {"mock-id-2"}
assert device2.disabled_by is None # Should not be disabled anymore
assert device2.id == device.id # Should keep the same device id
async def test_deleted_device_disabled_by_user_not_cleared(
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,
) -> None:
"""Test that disabled_by=USER is not cleared when config entry is removed."""
config_entry = MockConfigEntry(domain="test", entry_id="mock-id-1")
config_entry.add_to_hass(hass)
# Create a device disabled by the user
device = device_registry.async_get_or_create(
config_entry_id="mock-id-1",
identifiers={("test", "device_1")},
name="Test Device",
disabled_by=dr.DeviceEntryDisabler.USER,
)
assert device.config_entries == {"mock-id-1"}
assert device.disabled_by is dr.DeviceEntryDisabler.USER
# Remove the device (it moves to deleted_devices)
device_registry.async_remove_device(device.id)
assert len(device_registry.devices) == 0
assert len(device_registry.deleted_devices) == 1
deleted_device = device_registry.deleted_devices[device.id]
assert deleted_device.config_entries == {"mock-id-1"}
assert deleted_device.disabled_by is dr.DeviceEntryDisabler.USER
assert deleted_device.orphaned_timestamp is None
# Clear the config entry
device_registry.async_clear_config_entry("mock-id-1")
# Verify disabled_by is NOT cleared for USER disabled devices
deleted_device = device_registry.deleted_devices[device.id]
assert deleted_device.config_entries == set()
assert (
deleted_device.disabled_by is dr.DeviceEntryDisabler.USER
) # Should remain USER
assert deleted_device.orphaned_timestamp is not None
@pytest.mark.parametrize("load_registries", [False])
async def test_cleanup_entity_registry_change(
hass: HomeAssistant, mock_config_entry: MockConfigEntry