diff --git a/homeassistant/components/config/automation.py b/homeassistant/components/config/automation.py index 01e22297c0d..f1a2d9aab84 100644 --- a/homeassistant/components/config/automation.py +++ b/homeassistant/components/config/automation.py @@ -1,5 +1,4 @@ """Provide configuration end points for Automations.""" -from collections import OrderedDict import uuid from homeassistant.components.automation.config import ( @@ -52,7 +51,18 @@ class EditAutomationConfigView(EditIdBasedConfigView): def _write_value(self, hass, data, config_key, new_value): """Set value.""" - index = None + updated_value = {CONF_ID: config_key} + + # Iterate through some keys that we want to have ordered in the output + for key in ("alias", "description", "trigger", "condition", "action"): + if key in new_value: + updated_value[key] = new_value[key] + + # We cover all current fields above, but just in case we start + # supporting more fields in the future. + updated_value.update(new_value) + + updated = False for index, cur_value in enumerate(data): # When people copy paste their automations to the config file, # they sometimes forget to add IDs. Fix it here. @@ -60,23 +70,8 @@ class EditAutomationConfigView(EditIdBasedConfigView): cur_value[CONF_ID] = uuid.uuid4().hex elif cur_value[CONF_ID] == config_key: - break - else: - cur_value = OrderedDict() - cur_value[CONF_ID] = config_key - index = len(data) - data.append(cur_value) + data[index] = updated_value + updated = True - # Iterate through some keys that we want to have ordered in the output - updated_value = OrderedDict() - for key in ("id", "alias", "description", "trigger", "condition", "action"): - if key in cur_value: - updated_value[key] = cur_value[key] - if key in new_value: - updated_value[key] = new_value[key] - - # We cover all current fields above, but just in case we start - # supporting more fields in the future. - updated_value.update(cur_value) - updated_value.update(new_value) - data[index] = updated_value + if not updated: + data.append(updated_value) diff --git a/homeassistant/components/config/scene.py b/homeassistant/components/config/scene.py index 41b8dce0957..6523ff84158 100644 --- a/homeassistant/components/config/scene.py +++ b/homeassistant/components/config/scene.py @@ -47,8 +47,8 @@ class EditSceneConfigView(EditIdBasedConfigView): def _write_value(self, hass, data, config_key, new_value): """Set value.""" - # Iterate through some keys that we want to have ordered in the output updated_value = {CONF_ID: config_key} + # Iterate through some keys that we want to have ordered in the output for key in ("name", "entities"): if key in new_value: updated_value[key] = new_value[key] diff --git a/tests/components/config/test_automation.py b/tests/components/config/test_automation.py index 80ee38350aa..6f782fdbbff 100644 --- a/tests/components/config/test_automation.py +++ b/tests/components/config/test_automation.py @@ -80,6 +80,43 @@ async def test_update_device_config(hass, hass_client, setup_automation): assert written[0] == orig_data +@pytest.mark.parametrize("automation_config", ({},)) +async def test_update_remove_key_device_config(hass, hass_client, setup_automation): + """Test updating device config while removing a key.""" + with patch.object(config, "SECTIONS", ["automation"]): + await async_setup_component(hass, "config", {}) + + client = await hass_client() + + orig_data = [{"id": "sun", "key": "value"}, {"id": "moon", "key": "value"}] + + def mock_read(path): + """Mock reading data.""" + return orig_data + + written = [] + + def mock_write(path, data): + """Mock writing data.""" + written.append(data) + + with patch("homeassistant.components.config._read", mock_read), patch( + "homeassistant.components.config._write", mock_write + ), patch("homeassistant.config.async_hass_config_yaml", return_value={}): + resp = await client.post( + "/api/config/automation/config/moon", + data=json.dumps({"trigger": [], "action": [], "condition": []}), + ) + + assert resp.status == HTTPStatus.OK + result = await resp.json() + assert result == {"result": "ok"} + + assert list(orig_data[1]) == ["id", "trigger", "condition", "action"] + assert orig_data[1] == {"id": "moon", "trigger": [], "condition": [], "action": []} + assert written[0] == orig_data + + @pytest.mark.parametrize("automation_config", ({},)) async def test_bad_formatted_automations(hass, hass_client, setup_automation): """Test that we handle automations without ID."""