From 400741006b75f0e91010f6b3a236fa07cb4c86bd Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 28 Aug 2020 09:44:51 -0500 Subject: [PATCH] Add the ability to reload generic platforms from yaml (#39289) --- homeassistant/components/generic/__init__.py | 3 + homeassistant/components/generic/camera.py | 6 ++ .../components/generic/services.yaml | 2 + tests/components/generic/test_camera.py | 64 ++++++++++++++++++- tests/fixtures/generic/configuration.yaml | 6 ++ 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 homeassistant/components/generic/services.yaml create mode 100644 tests/fixtures/generic/configuration.yaml diff --git a/homeassistant/components/generic/__init__.py b/homeassistant/components/generic/__init__.py index 28f79fc91e6..feb51d0177d 100644 --- a/homeassistant/components/generic/__init__.py +++ b/homeassistant/components/generic/__init__.py @@ -1 +1,4 @@ """The generic component.""" + +DOMAIN = "generic" +PLATFORMS = ["camera"] diff --git a/homeassistant/components/generic/camera.py b/homeassistant/components/generic/camera.py index 91f5322ae81..a7ef367a95d 100644 --- a/homeassistant/components/generic/camera.py +++ b/homeassistant/components/generic/camera.py @@ -26,6 +26,9 @@ from homeassistant.const import ( from homeassistant.exceptions import TemplateError from homeassistant.helpers import config_validation as cv from homeassistant.helpers.aiohttp_client import async_get_clientsession +from homeassistant.helpers.reload import async_setup_reload_service + +from . import DOMAIN, PLATFORMS _LOGGER = logging.getLogger(__name__) @@ -59,6 +62,9 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): """Set up a generic IP Camera.""" + + await async_setup_reload_service(hass, DOMAIN, PLATFORMS) + async_add_entities([GenericCamera(hass, config)]) diff --git a/homeassistant/components/generic/services.yaml b/homeassistant/components/generic/services.yaml new file mode 100644 index 00000000000..afde1990cef --- /dev/null +++ b/homeassistant/components/generic/services.yaml @@ -0,0 +1,2 @@ +reload: + description: Reload all generic entities. diff --git a/tests/components/generic/test_camera.py b/tests/components/generic/test_camera.py index fffa5db6be5..c3400d8f57c 100644 --- a/tests/components/generic/test_camera.py +++ b/tests/components/generic/test_camera.py @@ -1,8 +1,15 @@ """The tests for generic camera component.""" import asyncio +from os import path +from homeassistant import config as hass_config +from homeassistant.components.generic import DOMAIN from homeassistant.components.websocket_api.const import TYPE_RESULT -from homeassistant.const import HTTP_INTERNAL_SERVER_ERROR, HTTP_NOT_FOUND +from homeassistant.const import ( + HTTP_INTERNAL_SERVER_ERROR, + HTTP_NOT_FOUND, + SERVICE_RELOAD, +) from homeassistant.setup import async_setup_component from tests.async_mock import patch @@ -292,3 +299,58 @@ async def test_camera_content_type(aioclient_mock, hass, hass_client): assert resp_2.content_type == "image/jpeg" body = await resp_2.text() assert body == svg_image + + +async def test_reloading(aioclient_mock, hass, hass_client): + """Test we can cleanly reload.""" + aioclient_mock.get("http://example.com", text="hello world") + + await async_setup_component( + hass, + "camera", + { + "camera": { + "name": "config_test", + "platform": "generic", + "still_image_url": "http://example.com", + "username": "user", + "password": "pass", + } + }, + ) + await hass.async_block_till_done() + + client = await hass_client() + + resp = await client.get("/api/camera_proxy/camera.config_test") + + assert resp.status == 200 + assert aioclient_mock.call_count == 1 + body = await resp.text() + assert body == "hello world" + + yaml_path = path.join( + _get_fixtures_base_path(), "fixtures", "generic/configuration.yaml", + ) + with patch.object(hass_config, "YAML_CONFIG_FILE", yaml_path): + await hass.services.async_call( + DOMAIN, SERVICE_RELOAD, {}, blocking=True, + ) + await hass.async_block_till_done() + + assert len(hass.states.async_all()) == 1 + + resp = await client.get("/api/camera_proxy/camera.config_test") + + assert resp.status == 404 + + resp = await client.get("/api/camera_proxy/camera.reload") + + assert resp.status == 200 + assert aioclient_mock.call_count == 2 + body = await resp.text() + assert body == "hello world" + + +def _get_fixtures_base_path(): + return path.dirname(path.dirname(path.dirname(__file__))) diff --git a/tests/fixtures/generic/configuration.yaml b/tests/fixtures/generic/configuration.yaml new file mode 100644 index 00000000000..7ed443a3fb1 --- /dev/null +++ b/tests/fixtures/generic/configuration.yaml @@ -0,0 +1,6 @@ +camera: + - platform: generic + name: reload + still_image_url: "http://example.com" + username: user + password: pass