async def test_restoring_invalid_entity_id(hass, hass_storage): """Test restoring invalid entity IDs.""" entity = RestoreEntity() entity.hass = hass entity.entity_id = "test.invalid__entity_id" now = dt_util.utcnow().isoformat() hass_storage[STORAGE_KEY] = { "version": 1, "key": STORAGE_KEY, "data": [{ "state": { "entity_id": "test.invalid__entity_id", "state": "off", "attributes": {}, "last_changed": now, "last_updated": now, "context": { "id": "3c2243ff5f30447eb12e7348cfd5b8ff", "user_id": None, }, }, "last_seen": dt_util.utcnow().isoformat(), }], } state = await entity.async_get_last_state() assert state is None
async def test_restoring_invalid_entity_id(hass, hass_storage): """Test restoring invalid entity IDs.""" entity = RestoreEntity() entity.hass = hass entity.entity_id = 'test.invalid__entity_id' now = dt_util.utcnow().isoformat() hass_storage[STORAGE_KEY] = { 'version': 1, 'key': STORAGE_KEY, 'data': [{ 'state': { 'entity_id': 'test.invalid__entity_id', 'state': 'off', 'attributes': {}, 'last_changed': now, 'last_updated': now, 'context': { 'id': '3c2243ff5f30447eb12e7348cfd5b8ff', 'user_id': None } }, 'last_seen': dt_util.utcnow().isoformat() }] } state = await entity.async_get_last_state() assert state is None
async def test_state_saved_on_remove(hass): """Test that we save entity state on removal.""" entity = RestoreEntity() entity.hass = hass entity.entity_id = "input_boolean.b0" await entity.async_internal_added_to_hass() now = dt_util.utcnow() hass.states.async_set("input_boolean.b0", "on", {"complicated": { "value": {1, 2, now} }}) data = await RestoreStateData.async_get_instance(hass) # No last states should currently be saved assert not data.last_states await entity.async_remove() # We should store the input boolean state when it is removed state = data.last_states["input_boolean.b0"].state assert state.state == "on" assert isinstance(state.attributes["complicated"]["value"], list) assert set( state.attributes["complicated"]["value"]) == {1, 2, now.isoformat()}
async def test_caching_data(hass): """Test that we cache data.""" now = dt_util.utcnow() stored_states = [ StoredState(State("input_boolean.b0", "on"), None, now), StoredState(State("input_boolean.b1", "on"), None, now), StoredState(State("input_boolean.b2", "on"), None, now), ] data = await RestoreStateData.async_get_instance(hass) await hass.async_block_till_done() await data.store.async_save([state.as_dict() for state in stored_states]) # Emulate a fresh load hass.data.pop(DATA_RESTORE_STATE_TASK) entity = RestoreEntity() entity.hass = hass entity.entity_id = "input_boolean.b1" # Mock that only b1 is present this run with patch("homeassistant.helpers.restore_state.Store.async_save" ) as mock_write_data: state = await entity.async_get_last_state() await hass.async_block_till_done() assert state is not None assert state.entity_id == "input_boolean.b1" assert state.state == "on" assert mock_write_data.called
async def test_caching_data(hass): """Test that we cache data.""" now = dt_util.utcnow() stored_states = [ StoredState(State('input_boolean.b0', 'on'), now), StoredState(State('input_boolean.b1', 'on'), now), StoredState(State('input_boolean.b2', 'on'), now), ] data = await RestoreStateData.async_get_instance(hass) await data.store.async_save([state.as_dict() for state in stored_states]) # Emulate a fresh load hass.data[DATA_RESTORE_STATE_TASK] = None entity = RestoreEntity() entity.hass = hass entity.entity_id = 'input_boolean.b1' # Mock that only b1 is present this run with patch('homeassistant.helpers.restore_state.Store.async_save' ) as mock_write_data: state = await entity.async_get_last_state() assert state is not None assert state.entity_id == 'input_boolean.b1' assert state.state == 'on' assert mock_write_data.called
async def test_load_error(hass): """Test that we cache data.""" entity = RestoreEntity() entity.hass = hass entity.entity_id = 'input_boolean.b1' with patch('homeassistant.helpers.storage.Store.async_load', return_value=mock_coro(exception=HomeAssistantError)): state = await entity.async_get_last_state() assert state is None
async def test_load_error(hass): """Test that we cache data.""" entity = RestoreEntity() entity.hass = hass entity.entity_id = "input_boolean.b1" with patch( "homeassistant.helpers.storage.Store.async_load", side_effect=HomeAssistantError, ): state = await entity.async_get_last_state() assert state is None
async def test_save_persistent_states(hass): """Test that we cancel the currently running job, save the data, and verify the perdiodic job continues.""" data = await RestoreStateData.async_get_instance(hass) await hass.async_block_till_done() await data.store.async_save([]) # Emulate a fresh load hass.data.pop(DATA_RESTORE_STATE_TASK) entity = RestoreEntity() entity.hass = hass entity.entity_id = "input_boolean.b1" with patch("homeassistant.helpers.restore_state.Store.async_save" ) as mock_write_data: await entity.async_get_last_state() await hass.async_block_till_done() # Startup Save assert mock_write_data.called with patch("homeassistant.helpers.restore_state.Store.async_save" ) as mock_write_data: async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=10)) await hass.async_block_till_done() # Not quite the first interval assert not mock_write_data.called with patch("homeassistant.helpers.restore_state.Store.async_save" ) as mock_write_data: await RestoreStateData.async_save_persistent_states(hass) await hass.async_block_till_done() assert mock_write_data.called with patch("homeassistant.helpers.restore_state.Store.async_save" ) as mock_write_data: async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=20)) await hass.async_block_till_done() # Verify still saving assert mock_write_data.called with patch("homeassistant.helpers.restore_state.Store.async_save" ) as mock_write_data: hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP) await hass.async_block_till_done() # Verify normal shutdown assert mock_write_data.called
async def test_hass_starting(hass): """Test that we cache data.""" hass.state = CoreState.starting now = dt_util.utcnow() stored_states = [ StoredState(State("input_boolean.b0", "on"), None, now), StoredState(State("input_boolean.b1", "on"), None, now), StoredState(State("input_boolean.b2", "on"), None, now), ] data = await RestoreStateData.async_get_instance(hass) await hass.async_block_till_done() await data.store.async_save([state.as_dict() for state in stored_states]) # Emulate a fresh load hass.state = CoreState.not_running hass.data.pop(DATA_RESTORE_STATE_TASK) entity = RestoreEntity() entity.hass = hass entity.entity_id = "input_boolean.b1" # Mock that only b1 is present this run states = [State("input_boolean.b1", "on")] with patch("homeassistant.helpers.restore_state.Store.async_save" ) as mock_write_data, patch.object(hass.states, "async_all", return_value=states): state = await entity.async_get_last_state() await hass.async_block_till_done() assert state is not None assert state.entity_id == "input_boolean.b1" assert state.state == "on" # Assert that no data was written yet, since hass is still starting. assert not mock_write_data.called # Finish hass startup with patch("homeassistant.helpers.restore_state.Store.async_save" ) as mock_write_data: hass.bus.async_fire(EVENT_HOMEASSISTANT_START) await hass.async_block_till_done() # Assert that this session states were written assert mock_write_data.called
async def test_state_saved_on_remove(hass): """Test that we save entity state on removal.""" entity = RestoreEntity() entity.hass = hass entity.entity_id = 'input_boolean.b0' await entity.async_internal_added_to_hass() hass.states.async_set('input_boolean.b0', 'on') data = await RestoreStateData.async_get_instance(hass) # No last states should currently be saved assert not data.last_states await entity.async_remove() # We should store the input boolean state when it is removed assert data.last_states['input_boolean.b0'].state.state == 'on'
async def test_periodic_write(hass): """Test that we write periodiclly but not after stop.""" data = await RestoreStateData.async_get_instance(hass) await hass.async_block_till_done() await data.store.async_save([]) # Emulate a fresh load hass.data[DATA_RESTORE_STATE_TASK] = None entity = RestoreEntity() entity.hass = hass entity.entity_id = "input_boolean.b1" with patch( "homeassistant.helpers.restore_state.Store.async_save" ) as mock_write_data: await entity.async_get_last_state() await hass.async_block_till_done() assert mock_write_data.called with patch( "homeassistant.helpers.restore_state.Store.async_save" ) as mock_write_data: async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=15)) await hass.async_block_till_done() assert mock_write_data.called with patch( "homeassistant.helpers.restore_state.Store.async_save" ) as mock_write_data: hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP) await hass.async_block_till_done() assert mock_write_data.called with patch( "homeassistant.helpers.restore_state.Store.async_save" ) as mock_write_data: async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=30)) await hass.async_block_till_done() assert not mock_write_data.called