diff --git a/homeassistant/components/color_extractor/__init__.py b/homeassistant/components/color_extractor/__init__.py index 0fd9f8a1a2e45fc479eb0d1aa2edebb26d82f0bb..ddd2ae967e4a522fc20536c766965cf6e36e87da 100644 --- a/homeassistant/components/color_extractor/__init__.py +++ b/homeassistant/components/color_extractor/__init__.py @@ -27,12 +27,15 @@ import homeassistant.helpers.config_validation as cv _LOGGER = logging.getLogger(__name__) # Extend the existing light.turn_on service schema -SERVICE_SCHEMA = cv.make_entity_service_schema( - { - **LIGHT_TURN_ON_SCHEMA, - vol.Exclusive(ATTR_PATH, "color_extractor"): cv.isfile, - vol.Exclusive(ATTR_URL, "color_extractor"): cv.url, - } +SERVICE_SCHEMA = vol.All( + cv.has_at_least_one_key(ATTR_URL, ATTR_PATH), + cv.make_entity_service_schema( + { + **LIGHT_TURN_ON_SCHEMA, + vol.Exclusive(ATTR_PATH, "color_extractor"): cv.isfile, + vol.Exclusive(ATTR_URL, "color_extractor"): cv.url, + } + ), ) @@ -63,10 +66,6 @@ async def async_setup(hass, hass_config): """Decide which color_extractor method to call based on service.""" service_data = dict(service_call.data) - if ATTR_URL not in service_data and ATTR_PATH not in service_data: - _LOGGER.error("Missing either required %s or %s key", ATTR_URL, ATTR_PATH) - return - try: if ATTR_URL in service_data: image_type = "URL" @@ -110,7 +109,7 @@ async def async_setup(hass, hass_config): "External URL '%s' is not allowed, please add to 'allowlist_external_urls'", url, ) - return + return None _LOGGER.debug("Getting predominant RGB from image URL '%s'", url) @@ -123,7 +122,7 @@ async def async_setup(hass, hass_config): except (asyncio.TimeoutError, aiohttp.ClientError) as err: _LOGGER.error("Failed to get ColorThief image due to HTTPError: %s", err) - return + return None content = await response.content.read() @@ -140,7 +139,7 @@ async def async_setup(hass, hass_config): "File path '%s' is not allowed, please add to 'allowlist_external_dirs'", file_path, ) - return + return None _LOGGER.debug("Getting predominant RGB from file path '%s'", file_path) diff --git a/tests/components/color_extractor/test_service.py b/tests/components/color_extractor/test_service.py index 00b304cae548d50455acb8f5ae5c4332cd5b306d..31b623f1c76257623d8bf74c11a3d8541ae90acb 100644 --- a/tests/components/color_extractor/test_service.py +++ b/tests/components/color_extractor/test_service.py @@ -4,6 +4,7 @@ import io import aiohttp import pytest +from voluptuous.error import MultipleInvalid from homeassistant.components.color_extractor import ( ATTR_PATH, @@ -103,8 +104,11 @@ async def test_missing_url_and_path(hass): ATTR_ENTITY_ID: LIGHT_ENTITY, } - await hass.services.async_call(DOMAIN, SERVICE_TURN_ON, service_data, blocking=True) - await hass.async_block_till_done() + with pytest.raises(MultipleInvalid): + await hass.services.async_call( + DOMAIN, SERVICE_TURN_ON, service_data, blocking=True + ) + await hass.async_block_till_done() # check light is still off, unchanged due to bad parameters on service call state = hass.states.get(LIGHT_ENTITY)