diff --git a/homeassistant/components/input_select/__init__.py b/homeassistant/components/input_select/__init__.py index 83d6684a366..5d0e356b8ee 100644 --- a/homeassistant/components/input_select/__init__.py +++ b/homeassistant/components/input_select/__init__.py @@ -56,7 +56,7 @@ def _unique(options: Any) -> Any: raise HomeAssistantError("Duplicate options are not allowed") from exc -CREATE_FIELDS = { +STORAGE_FIELDS = { vol.Required(CONF_NAME): vol.All(str, vol.Length(min=1)), vol.Required(CONF_OPTIONS): vol.All( cv.ensure_list, vol.Length(min=1), _unique, [cv.string] @@ -64,14 +64,6 @@ CREATE_FIELDS = { vol.Optional(CONF_INITIAL): cv.string, vol.Optional(CONF_ICON): cv.icon, } -UPDATE_FIELDS = { - vol.Optional(CONF_NAME): cv.string, - vol.Optional(CONF_OPTIONS): vol.All( - cv.ensure_list, vol.Length(min=1), _unique, [cv.string] - ), - vol.Optional(CONF_INITIAL): cv.string, - vol.Optional(CONF_ICON): cv.icon, -} def _remove_duplicates(options: list[str], name: str | None) -> list[str]: @@ -172,7 +164,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: await storage_collection.async_load() collection.StorageCollectionWebsocket( - storage_collection, DOMAIN, DOMAIN, CREATE_FIELDS, UPDATE_FIELDS + storage_collection, DOMAIN, DOMAIN, STORAGE_FIELDS, STORAGE_FIELDS ).async_setup(hass) async def reload_service_handler(service_call: ServiceCall) -> None: @@ -238,12 +230,11 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: class InputSelectStorageCollection(collection.StorageCollection): """Input storage based collection.""" - CREATE_SCHEMA = vol.Schema(vol.All(CREATE_FIELDS, _cv_input_select)) - UPDATE_SCHEMA = vol.Schema(UPDATE_FIELDS) + CREATE_UPDATE_SCHEMA = vol.Schema(vol.All(STORAGE_FIELDS, _cv_input_select)) async def _process_create_data(self, data: dict[str, Any]) -> dict[str, Any]: """Validate the config is valid.""" - return cast(dict[str, Any], self.CREATE_SCHEMA(data)) + return cast(dict[str, Any], self.CREATE_UPDATE_SCHEMA(data)) @callback def _get_suggested_id(self, info: dict[str, Any]) -> str: @@ -254,8 +245,8 @@ class InputSelectStorageCollection(collection.StorageCollection): self, data: dict[str, Any], update_data: dict[str, Any] ) -> dict[str, Any]: """Return a new updated data object.""" - update_data = self.UPDATE_SCHEMA(update_data) - return _cv_input_select({**data, **update_data}) + update_data = self.CREATE_UPDATE_SCHEMA(update_data) + return {CONF_ID: data[CONF_ID]} | update_data class InputSelect(SelectEntity, RestoreEntity): diff --git a/tests/components/input_select/test_init.py b/tests/components/input_select/test_init.py index d65140dcbf9..1a1618d7805 100644 --- a/tests/components/input_select/test_init.py +++ b/tests/components/input_select/test_init.py @@ -628,13 +628,11 @@ async def test_ws_delete(hass, hass_ws_client, storage_setup): async def test_update(hass, hass_ws_client, storage_setup): """Test updating options updates the state.""" - items = [ - { - "id": "from_storage", - "name": "from storage", - "options": ["yaml update 1", "yaml update 2"], - } - ] + settings = { + "name": "from storage", + "options": ["yaml update 1", "yaml update 2"], + } + items = [{"id": "from_storage"} | settings] assert await storage_setup(items) input_id = "from_storage" @@ -647,28 +645,36 @@ async def test_update(hass, hass_ws_client, storage_setup): client = await hass_ws_client(hass) + updated_settings = settings | { + "options": ["new option", "newer option"], + CONF_INITIAL: "newer option", + } await client.send_json( { "id": 6, "type": f"{DOMAIN}/update", f"{DOMAIN}_id": f"{input_id}", - "options": ["new option", "newer option"], - CONF_INITIAL: "newer option", + **updated_settings, } ) resp = await client.receive_json() assert resp["success"] + assert resp["result"] == {"id": "from_storage"} | updated_settings state = hass.states.get(input_entity_id) assert state.attributes[ATTR_OPTIONS] == ["new option", "newer option"] # Should fail because the initial state is now invalid + updated_settings = settings | { + "options": ["new option", "no newer option"], + CONF_INITIAL: "newer option", + } await client.send_json( { "id": 7, "type": f"{DOMAIN}/update", f"{DOMAIN}_id": f"{input_id}", - "options": ["new option", "no newer option"], + **updated_settings, } ) resp = await client.receive_json() @@ -678,13 +684,11 @@ async def test_update(hass, hass_ws_client, storage_setup): async def test_update_duplicates(hass, hass_ws_client, storage_setup, caplog): """Test updating options updates the state.""" - items = [ - { - "id": "from_storage", - "name": "from storage", - "options": ["yaml update 1", "yaml update 2"], - } - ] + settings = { + "name": "from storage", + "options": ["yaml update 1", "yaml update 2"], + } + items = [{"id": "from_storage"} | settings] assert await storage_setup(items) input_id = "from_storage" @@ -697,13 +701,16 @@ async def test_update_duplicates(hass, hass_ws_client, storage_setup, caplog): client = await hass_ws_client(hass) + updated_settings = settings | { + "options": ["new option", "newer option", "newer option"], + CONF_INITIAL: "newer option", + } await client.send_json( { "id": 6, "type": f"{DOMAIN}/update", f"{DOMAIN}_id": f"{input_id}", - "options": ["new option", "newer option", "newer option"], - CONF_INITIAL: "newer option", + **updated_settings, } ) resp = await client.receive_json()