diff --git a/homeassistant/helpers/selector.py b/homeassistant/helpers/selector.py index f9af2eb1d718..db8fe76b0d0a 100644 --- a/homeassistant/helpers/selector.py +++ b/homeassistant/helpers/selector.py @@ -136,6 +136,13 @@ def _validate_selector_reorder_config(config: Any) -> Any: return config +def _validate_media_selector_config(config: Any) -> Any: + """Validate media selectors with image_upload option.""" + if config.get("image_upload") and not config.get("accept"): + raise probatio.Invalid("image_upload can only be used when accept is not empty") + return config + + def make_selector_config_schema(schema_dict: dict | None = None) -> probatio.Schema: """Make selector config schema.""" if schema_dict is None: @@ -1358,6 +1365,7 @@ class MediaSelectorConfig(BaseSelectorConfig, total=False): accept: list[str] multiple: bool + image_upload: bool @SELECTORS.register("media") @@ -1366,11 +1374,15 @@ class MediaSelector(Selector[MediaSelectorConfig]): selector_type = "media" - CONFIG_SCHEMA = make_selector_config_schema( - { - probatio.Optional("accept"): [str], - probatio.Optional("multiple", default=False): cv.boolean, - } + CONFIG_SCHEMA = probatio.All( + make_selector_config_schema( + { + probatio.Optional("accept"): [str], + probatio.Optional("multiple", default=False): cv.boolean, + probatio.Optional("image_upload", default=False): cv.boolean, + } + ), + _validate_media_selector_config, ) DATA_SCHEMA = probatio.Schema( { diff --git a/tests/helpers/test_selector.py b/tests/helpers/test_selector.py index 188871d07e47..f002412ba497 100644 --- a/tests/helpers/test_selector.py +++ b/tests/helpers/test_selector.py @@ -1935,6 +1935,35 @@ def test_theme_selector_schema(schema, valid_selections, invalid_selections) -> }, ), ), + ( + { + "accept": ["image/*"], + "image_upload": True, + }, + ( + { + "media_content_id": "abc", + "media_content_type": "def", + }, + { + "media_content_id": "abc", + "media_content_type": "def", + "metadata": {}, + }, + ), + ( + None, + "abc", + {}, + { + # We do not allow entity_id when accept is set + "entity_id": "sensor.abc", + "media_content_id": "abc", + "media_content_type": "def", + "metadata": {}, + }, + ), + ), ], ) def test_media_selector_schema(schema, valid_selections, invalid_selections) -> None: @@ -1942,6 +1971,24 @@ def test_media_selector_schema(schema, valid_selections, invalid_selections) -> _test_selector("media", schema, valid_selections, invalid_selections) +@pytest.mark.parametrize( + "schema", + [ + # image_upload can only be used when accept is not empty + {"image_upload": True}, + {"image_upload": True, "accept": []}, + ], +) +def test_media_selector_schema_error( + schema: dict[str, bool | list[str]], +) -> None: + """Test media selector with invalid config.""" + with pytest.raises( + probatio.Invalid, match="image_upload can only be used when accept is not empty" + ): + selector.validate_selector({"media": schema}) + + @pytest.mark.parametrize( ("schema", "valid_selections", "invalid_selections"), [