diff --git a/tests/ha/test_lifecycle.py b/tests/ha/test_lifecycle.py index 01fa9f7..e865a86 100644 --- a/tests/ha/test_lifecycle.py +++ b/tests/ha/test_lifecycle.py @@ -149,6 +149,45 @@ async def test_scheduled_sample_saves_and_unload_stops_polling(hass, entry, inpu assert coordinator.learners["sensor.room"].count == 1 +async def test_reloads_leave_one_relay_listener_and_one_polling_coordinator(hass, entry, inputs, freezer): + coordinators = [await setup(hass, entry)] + for _ in range(3): + assert await hass.config_entries.async_reload(entry.entry_id) + await hass.async_block_till_done() + coordinators.append(hass.data[DOMAIN][entry.entry_id]) + *old, current = coordinators + assert len({id(c) for c in coordinators}) == 4 + # A relay change reaches only the current coordinator. + hass.states.async_set("switch.boiler", "on") + await hass.async_block_till_done() + assert [state for _, state in current._relay_events] == ["on"] + assert not any(c._relay_events for c in old) + # Only the current coordinator polls; the replaced ones neither learn nor publish. + status_id = er.async_get(hass).async_get_entity_id("sensor", DOMAIN, f"{entry.entry_id}_status") + updates = [] + hass.bus.async_listen("state_changed", lambda event: updates.append(event.data["entity_id"])) + before = [(c.learners["sensor.room"].count, c.data) for c in old] + future = dt_util.utcnow() + timedelta(minutes=5, seconds=1) + freezer.move_to(future) + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + assert [(c.learners["sensor.room"].count, c.data) for c in old] == before + assert updates.count(status_id) <= 1 + assert hass.states.get(status_id).state == current.data["status"] + # After unload, a relay change is recorded nowhere and nothing is published. + assert await hass.config_entries.async_unload(entry.entry_id) + await hass.async_block_till_done() + events = list(current._relay_events) + updates.clear() + hass.states.async_set("switch.boiler", "off") + future += timedelta(minutes=5) + freezer.move_to(future) + async_fire_time_changed(hass, future) + await hass.async_block_till_done() + assert list(current._relay_events) == events + assert status_id not in updates + + @pytest.mark.parametrize("payload", ["broken", {"learners": []}, {"learners": {"sensor.room": {"theta": []}}}]) async def test_corrupt_saved_payload_starts_learning(hass, entry, inputs, hass_storage, payload): hass_storage[f"{DOMAIN}.{entry.entry_id}"] = {"version": 1, "data": payload}