async def test_restore_active_resume(hass): """Test entity restore logic when timer is active and end time is after startup.""" events = async_capture_events(hass, EVENT_TIMER_RESTARTED) assert not events utc_now = utcnow() finish = utc_now + timedelta(seconds=30) simulated_utc_now = utc_now + timedelta(seconds=15) stored_state = StoredState( State( "timer.test", STATUS_ACTIVE, { ATTR_DURATION: "0:00:30", ATTR_FINISHES_AT: finish.isoformat() }, ), None, utc_now, ) data = await RestoreStateData.async_get_instance(hass) await hass.async_block_till_done() await data.store.async_save([stored_state.as_dict()]) # Emulate a fresh load hass.data.pop(DATA_RESTORE_STATE_TASK) entity = Timer({ CONF_ID: "test", CONF_NAME: "test", CONF_DURATION: "0:01:00", CONF_RESTORE: True, }) entity.hass = hass entity.entity_id = "timer.test" # In patch make sure we ignore microseconds with patch( "homeassistant.components.timer.dt_util.utcnow", return_value=simulated_utc_now.replace(microsecond=999), ): await entity.async_added_to_hass() await hass.async_block_till_done() assert entity.state == STATUS_ACTIVE assert entity.extra_state_attributes[ATTR_DURATION] == "0:00:30" assert entity.extra_state_attributes[ATTR_REMAINING] == "0:00:15" assert entity.extra_state_attributes[ATTR_FINISHES_AT] == finish.isoformat( ) assert entity.extra_state_attributes[ATTR_RESTORE] assert len(events) == 1
async def test_restore_active_finished_outside_grace(hass): """Test entity restore logic: timer is active, ended while Home Assistant was stopped.""" events = async_capture_events(hass, EVENT_TIMER_FINISHED) assert not events utc_now = utcnow() finish = utc_now + timedelta(seconds=30) simulated_utc_now = utc_now + timedelta(seconds=46) stored_state = StoredState( State( "timer.test", STATUS_ACTIVE, { ATTR_DURATION: "0:00:30", ATTR_FINISHES_AT: finish.isoformat() }, ), None, utc_now, ) data = await RestoreStateData.async_get_instance(hass) await hass.async_block_till_done() await data.store.async_save([stored_state.as_dict()]) # Emulate a fresh load hass.data.pop(DATA_RESTORE_STATE_TASK) entity = Timer({ CONF_ID: "test", CONF_NAME: "test", CONF_DURATION: "0:01:00", CONF_RESTORE: True, }) entity.hass = hass entity.entity_id = "timer.test" with patch("homeassistant.components.timer.dt_util.utcnow", return_value=simulated_utc_now): await entity.async_added_to_hass() await hass.async_block_till_done() assert entity.state == STATUS_IDLE assert entity.extra_state_attributes[ATTR_DURATION] == "0:00:30" assert ATTR_REMAINING not in entity.extra_state_attributes assert ATTR_FINISHES_AT not in entity.extra_state_attributes assert entity.extra_state_attributes[ATTR_RESTORE] assert len(events) == 1
async def test_restore_paused(hass): """Test entity restore logic when timer is paused.""" utc_now = utcnow() stored_state = StoredState( State( "timer.test", STATUS_PAUSED, { ATTR_DURATION: "0:00:30", ATTR_REMAINING: "0:00:15" }, ), None, utc_now, ) data = await RestoreStateData.async_get_instance(hass) await hass.async_block_till_done() await data.store.async_save([stored_state.as_dict()]) # Emulate a fresh load hass.data.pop(DATA_RESTORE_STATE_TASK) entity = Timer({ CONF_ID: "test", CONF_NAME: "test", CONF_DURATION: "0:01:00", CONF_RESTORE: True, }) entity.hass = hass entity.entity_id = "timer.test" await entity.async_added_to_hass() await hass.async_block_till_done() assert entity.state == STATUS_PAUSED assert entity.extra_state_attributes[ATTR_DURATION] == "0:00:30" assert entity.extra_state_attributes[ATTR_REMAINING] == "0:00:15" assert ATTR_FINISHES_AT not in entity.extra_state_attributes assert entity.extra_state_attributes[ATTR_RESTORE]