From f0ca27fd083b69961c256cd368dd687513b93b1b Mon Sep 17 00:00:00 2001 From: RoboMagus <68224306+RoboMagus@users.noreply.github.com> Date: Thu, 28 Sep 2023 16:28:38 +0200 Subject: [PATCH] Add reload to rest_command integration (#100511) * Add YAML reload to rest_command integration * Add rest_command reload tests * Fix test coverage * Remove unnecessary call to keys Co-authored-by: J. Nick Koston * Perform cleanup on reload with empty config * Fix mypy * Fix ruff * Update homeassistant/components/rest_command/__init__.py * Update __init__.py --------- Co-authored-by: J. Nick Koston Co-authored-by: Erik Montnemery --- .../components/rest_command/__init__.py | 23 ++++++++++++++ tests/components/rest_command/test_init.py | 31 ++++++++++++++++++- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/rest_command/__init__.py b/homeassistant/components/rest_command/__init__.py index 1007ee1d2de..dcf790748ec 100644 --- a/homeassistant/components/rest_command/__init__.py +++ b/homeassistant/components/rest_command/__init__.py @@ -16,10 +16,12 @@ from homeassistant.const import ( CONF_URL, CONF_USERNAME, CONF_VERIFY_SSL, + SERVICE_RELOAD, ) from homeassistant.core import HomeAssistant, ServiceCall, callback from homeassistant.helpers.aiohttp_client import async_get_clientsession import homeassistant.helpers.config_validation as cv +from homeassistant.helpers.reload import async_integration_yaml_config from homeassistant.helpers.typing import ConfigType DOMAIN = "rest_command" @@ -58,6 +60,23 @@ CONFIG_SCHEMA = vol.Schema( async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up the REST command component.""" + async def reload_service_handler(service: ServiceCall) -> None: + """Remove all rest_commands and load new ones from config.""" + conf = await async_integration_yaml_config(hass, DOMAIN) + + # conf will be None if the configuration can't be parsed + if conf is None: + return + + existing = hass.services.async_services().get(DOMAIN, {}) + for existing_service in existing: + if existing_service == SERVICE_RELOAD: + continue + hass.services.async_remove(DOMAIN, existing_service) + + for name, command_config in conf[DOMAIN].items(): + async_register_rest_command(name, command_config) + @callback def async_register_rest_command(name, command_config): """Create service for rest command.""" @@ -156,4 +175,8 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: for name, command_config in config[DOMAIN].items(): async_register_rest_command(name, command_config) + hass.services.async_register( + DOMAIN, SERVICE_RELOAD, reload_service_handler, schema=vol.Schema({}) + ) + return True diff --git a/tests/components/rest_command/test_init.py b/tests/components/rest_command/test_init.py index 7cf94dcf846..c43fe84ea8f 100644 --- a/tests/components/rest_command/test_init.py +++ b/tests/components/rest_command/test_init.py @@ -1,11 +1,16 @@ """The tests for the rest command platform.""" import asyncio from http import HTTPStatus +from unittest.mock import patch import aiohttp import homeassistant.components.rest_command as rc -from homeassistant.const import CONTENT_TYPE_JSON, CONTENT_TYPE_TEXT_PLAIN +from homeassistant.const import ( + CONTENT_TYPE_JSON, + CONTENT_TYPE_TEXT_PLAIN, + SERVICE_RELOAD, +) from homeassistant.setup import setup_component from tests.common import assert_setup_component, get_test_home_assistant @@ -43,6 +48,30 @@ class TestRestCommandSetup: assert self.hass.services.has_service(rc.DOMAIN, "test_get") + def test_reload(self): + """Verify we can reload rest_command integration.""" + + with assert_setup_component(1): + setup_component(self.hass, rc.DOMAIN, self.config) + + assert self.hass.services.has_service(rc.DOMAIN, "test_get") + assert not self.hass.services.has_service(rc.DOMAIN, "new_test") + + new_config = { + rc.DOMAIN: { + "new_test": {"url": "https://example.org", "method": "get"}, + } + } + with patch( + "homeassistant.config.load_yaml_config_file", + autospec=True, + return_value=new_config, + ): + self.hass.services.call(rc.DOMAIN, SERVICE_RELOAD, blocking=True) + + assert self.hass.services.has_service(rc.DOMAIN, "new_test") + assert not self.hass.services.has_service(rc.DOMAIN, "get_test") + class TestRestCommandComponent: """Test the rest command component."""