From b369616aadd276c2d42af471e6cbf0710efb0fed Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Mon, 4 Apr 2022 17:57:48 +0200 Subject: [PATCH] Remove deprecated YAML configuration from MJPEG Camera (#68980) --- homeassistant/components/mjpeg/camera.py | 53 +-------------- homeassistant/components/mjpeg/config_flow.py | 16 ----- tests/components/mjpeg/test_config_flow.py | 67 +------------------ tests/components/mjpeg/test_init.py | 61 +---------------- tests/helpers/test_aiohttp_client.py | 48 ++++++++----- 5 files changed, 36 insertions(+), 209 deletions(-) diff --git a/homeassistant/components/mjpeg/camera.py b/homeassistant/components/mjpeg/camera.py index 69588c1b670..91b2271aafa 100644 --- a/homeassistant/components/mjpeg/camera.py +++ b/homeassistant/components/mjpeg/camera.py @@ -10,13 +10,11 @@ from aiohttp import web import async_timeout import requests from requests.auth import HTTPBasicAuth, HTTPDigestAuth -import voluptuous as vol -from homeassistant.components.camera import PLATFORM_SCHEMA, Camera -from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry +from homeassistant.components.camera import Camera +from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( CONF_AUTHENTICATION, - CONF_NAME, CONF_PASSWORD, CONF_USERNAME, CONF_VERIFY_SSL, @@ -24,62 +22,15 @@ from homeassistant.const import ( HTTP_DIGEST_AUTHENTICATION, ) from homeassistant.core import HomeAssistant -from homeassistant.helpers import config_validation as cv from homeassistant.helpers.aiohttp_client import ( async_aiohttp_proxy_web, async_get_clientsession, ) from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from .const import CONF_MJPEG_URL, CONF_STILL_IMAGE_URL, DOMAIN, LOGGER -CONTENT_TYPE_HEADER = "Content-Type" - -DEFAULT_NAME = "Mjpeg Camera" -DEFAULT_VERIFY_SSL = True - -PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( - { - vol.Required(CONF_MJPEG_URL): cv.url, - vol.Optional(CONF_STILL_IMAGE_URL): cv.url, - vol.Optional(CONF_AUTHENTICATION, default=HTTP_BASIC_AUTHENTICATION): vol.In( - [HTTP_BASIC_AUTHENTICATION, HTTP_DIGEST_AUTHENTICATION] - ), - vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, - vol.Optional(CONF_PASSWORD, default=""): cv.string, - vol.Optional(CONF_USERNAME): cv.string, - vol.Optional(CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL): cv.boolean, - } -) - - -async def async_setup_platform( - hass: HomeAssistant, - config: ConfigType, - async_add_entities: AddEntitiesCallback, - discovery_info: DiscoveryInfoType | None = None, -) -> None: - """Set up the MJPEG IP camera from platform.""" - LOGGER.warning( - "Configuration of the MJPEG IP Camera platform in YAML is deprecated " - "and will be removed in Home Assistant 2022.5; Your existing " - "configuration has been imported into the UI automatically and can be " - "safely removed from your configuration.yaml file" - ) - - if discovery_info: - config = PLATFORM_SCHEMA(discovery_info) - - hass.async_create_task( - hass.config_entries.flow.async_init( - DOMAIN, - context={"source": SOURCE_IMPORT}, - data=config, - ) - ) - async def async_setup_entry( hass: HomeAssistant, diff --git a/homeassistant/components/mjpeg/config_flow.py b/homeassistant/components/mjpeg/config_flow.py index 2eecdd84d78..61c80bcde38 100644 --- a/homeassistant/components/mjpeg/config_flow.py +++ b/homeassistant/components/mjpeg/config_flow.py @@ -174,22 +174,6 @@ class MJPEGFlowHandler(ConfigFlow, domain=DOMAIN): errors=errors, ) - async def async_step_import(self, config: dict[str, Any]) -> FlowResult: - """Handle a flow initialized by importing a config.""" - self._async_abort_entries_match({CONF_MJPEG_URL: config[CONF_MJPEG_URL]}) - return self.async_create_entry( - title=config[CONF_NAME], - data={}, - options={ - CONF_AUTHENTICATION: config[CONF_AUTHENTICATION], - CONF_MJPEG_URL: config[CONF_MJPEG_URL], - CONF_PASSWORD: config[CONF_PASSWORD], - CONF_STILL_IMAGE_URL: config.get(CONF_STILL_IMAGE_URL), - CONF_USERNAME: config.get(CONF_USERNAME), - CONF_VERIFY_SSL: config[CONF_VERIFY_SSL], - }, - ) - class MJPEGOptionsFlowHandler(OptionsFlow): """Handle MJPEG IP Camera options.""" diff --git a/tests/components/mjpeg/test_config_flow.py b/tests/components/mjpeg/test_config_flow.py index 0678353cf6d..cdf56ab97c0 100644 --- a/tests/components/mjpeg/test_config_flow.py +++ b/tests/components/mjpeg/test_config_flow.py @@ -10,7 +10,7 @@ from homeassistant.components.mjpeg.const import ( CONF_STILL_IMAGE_URL, DOMAIN, ) -from homeassistant.config_entries import SOURCE_IMPORT, SOURCE_USER +from homeassistant.config_entries import SOURCE_USER from homeassistant.const import ( CONF_AUTHENTICATION, CONF_NAME, @@ -18,7 +18,6 @@ from homeassistant.const import ( CONF_USERNAME, CONF_VERIFY_SSL, HTTP_BASIC_AUTHENTICATION, - HTTP_DIGEST_AUTHENTICATION, ) from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import ( @@ -252,70 +251,6 @@ async def test_already_configured( assert result2.get("reason") == "already_configured" -async def test_import_flow( - hass: HomeAssistant, - mock_mjpeg_requests: Mocker, - mock_setup_entry: AsyncMock, -) -> None: - """Test the import configuration flow.""" - result = await hass.config_entries.flow.async_init( - DOMAIN, - context={"source": SOURCE_IMPORT}, - data={ - CONF_AUTHENTICATION: HTTP_DIGEST_AUTHENTICATION, - CONF_MJPEG_URL: "http://example.com/mjpeg", - CONF_NAME: "Imported Camera", - CONF_PASSWORD: "omgpuppies", - CONF_STILL_IMAGE_URL: "http://example.com/still", - CONF_USERNAME: "frenck", - CONF_VERIFY_SSL: False, - }, - ) - - assert result.get("type") == RESULT_TYPE_CREATE_ENTRY - assert result.get("title") == "Imported Camera" - assert result.get("data") == {} - assert result.get("options") == { - CONF_AUTHENTICATION: HTTP_DIGEST_AUTHENTICATION, - CONF_MJPEG_URL: "http://example.com/mjpeg", - CONF_PASSWORD: "omgpuppies", - CONF_STILL_IMAGE_URL: "http://example.com/still", - CONF_USERNAME: "frenck", - CONF_VERIFY_SSL: False, - } - - assert len(mock_setup_entry.mock_calls) == 1 - assert mock_mjpeg_requests.call_count == 0 - - -async def test_import_flow_already_configured( - hass: HomeAssistant, - mock_config_entry: MockConfigEntry, - mock_setup_entry: AsyncMock, -) -> None: - """Test the import configuration flow for an already configured entry.""" - mock_config_entry.add_to_hass(hass) - - result = await hass.config_entries.flow.async_init( - DOMAIN, - context={"source": SOURCE_IMPORT}, - data={ - CONF_AUTHENTICATION: HTTP_DIGEST_AUTHENTICATION, - CONF_MJPEG_URL: "https://example.com/mjpeg", - CONF_NAME: "Imported Camera", - CONF_PASSWORD: "omgpuppies", - CONF_STILL_IMAGE_URL: "https://example.com/still", - CONF_USERNAME: "frenck", - CONF_VERIFY_SSL: False, - }, - ) - - assert result.get("type") == RESULT_TYPE_ABORT - assert result.get("reason") == "already_configured" - - assert len(mock_setup_entry.mock_calls) == 0 - - async def test_options_flow( hass: HomeAssistant, mock_mjpeg_requests: Mocker, diff --git a/tests/components/mjpeg/test_init.py b/tests/components/mjpeg/test_init.py index 853e0feb687..e96749a98dd 100644 --- a/tests/components/mjpeg/test_init.py +++ b/tests/components/mjpeg/test_init.py @@ -1,25 +1,9 @@ """Tests for the MJPEG IP Camera integration.""" from unittest.mock import AsyncMock, MagicMock -import pytest - -from homeassistant.components.camera import DOMAIN as CAMERA_DOMAIN -from homeassistant.components.mjpeg.const import ( - CONF_MJPEG_URL, - CONF_STILL_IMAGE_URL, - DOMAIN, -) +from homeassistant.components.mjpeg.const import DOMAIN from homeassistant.config_entries import ConfigEntryState -from homeassistant.const import ( - CONF_AUTHENTICATION, - CONF_NAME, - CONF_PASSWORD, - CONF_USERNAME, - CONF_VERIFY_SSL, - HTTP_BASIC_AUTHENTICATION, -) from homeassistant.core import HomeAssistant -from homeassistant.setup import async_setup_component from tests.common import MockConfigEntry @@ -54,46 +38,3 @@ async def test_reload_config_entry( init_integration, options={"something": "else"} ) assert len(mock_reload_entry.mock_calls) == 1 - - -async def test_import_config( - hass: HomeAssistant, - mock_mjpeg_requests: MagicMock, - mock_setup_entry: AsyncMock, - caplog: pytest.LogCaptureFixture, -) -> None: - """Test MJPEG IP Camera being set up from config via import.""" - assert await async_setup_component( - hass, - CAMERA_DOMAIN, - { - CAMERA_DOMAIN: { - "platform": DOMAIN, - CONF_MJPEG_URL: "http://example.com/mjpeg", - CONF_NAME: "Random Camera", - CONF_PASSWORD: "supersecret", - CONF_STILL_IMAGE_URL: "http://example.com/still", - CONF_USERNAME: "frenck", - CONF_VERIFY_SSL: False, - } - }, - ) - await hass.async_block_till_done() - - config_entries = hass.config_entries.async_entries(DOMAIN) - assert len(config_entries) == 1 - - assert "the MJPEG IP Camera platform in YAML is deprecated" in caplog.text - - entry = config_entries[0] - assert entry.title == "Random Camera" - assert entry.unique_id is None - assert entry.data == {} - assert entry.options == { - CONF_AUTHENTICATION: HTTP_BASIC_AUTHENTICATION, - CONF_MJPEG_URL: "http://example.com/mjpeg", - CONF_PASSWORD: "supersecret", - CONF_STILL_IMAGE_URL: "http://example.com/still", - CONF_USERNAME: "frenck", - CONF_VERIFY_SSL: False, - } diff --git a/tests/helpers/test_aiohttp_client.py b/tests/helpers/test_aiohttp_client.py index bfd933a4afd..599b2c6984e 100644 --- a/tests/helpers/test_aiohttp_client.py +++ b/tests/helpers/test_aiohttp_client.py @@ -5,26 +5,42 @@ from unittest.mock import Mock, patch import aiohttp import pytest +from homeassistant.components.mjpeg.const import ( + CONF_MJPEG_URL, + CONF_STILL_IMAGE_URL, + DOMAIN as MJPEG_DOMAIN, +) +from homeassistant.const import ( + CONF_AUTHENTICATION, + CONF_PASSWORD, + CONF_USERNAME, + CONF_VERIFY_SSL, + HTTP_BASIC_AUTHENTICATION, +) from homeassistant.core import EVENT_HOMEASSISTANT_CLOSE import homeassistant.helpers.aiohttp_client as client -from homeassistant.setup import async_setup_component + +from tests.common import MockConfigEntry @pytest.fixture(name="camera_client") def camera_client_fixture(hass, hass_client): """Fixture to fetch camera streams.""" - assert hass.loop.run_until_complete( - async_setup_component( - hass, - "camera", - { - "camera": { - "name": "config_test", - "platform": "mjpeg", - "mjpeg_url": "http://example.com/mjpeg_stream", - } - }, - ) + mock_config_entry = MockConfigEntry( + title="MJPEG Camera", + domain=MJPEG_DOMAIN, + options={ + CONF_AUTHENTICATION: HTTP_BASIC_AUTHENTICATION, + CONF_MJPEG_URL: "http://example.com/mjpeg_stream", + CONF_PASSWORD: None, + CONF_STILL_IMAGE_URL: None, + CONF_USERNAME: None, + CONF_VERIFY_SSL: True, + }, + ) + mock_config_entry.add_to_hass(hass) + hass.loop.run_until_complete( + hass.config_entries.async_setup(mock_config_entry.entry_id) ) hass.loop.run_until_complete(hass.async_block_till_done()) @@ -175,7 +191,7 @@ async def test_async_aiohttp_proxy_stream(aioclient_mock, camera_client): """Test that it fetches the given url.""" aioclient_mock.get("http://example.com/mjpeg_stream", content=b"Frame1Frame2Frame3") - resp = await camera_client.get("/api/camera_proxy_stream/camera.config_test") + resp = await camera_client.get("/api/camera_proxy_stream/camera.mjpeg_camera") assert resp.status == 200 assert aioclient_mock.call_count == 1 @@ -187,7 +203,7 @@ async def test_async_aiohttp_proxy_stream_timeout(aioclient_mock, camera_client) """Test that it fetches the given url.""" aioclient_mock.get("http://example.com/mjpeg_stream", exc=asyncio.TimeoutError()) - resp = await camera_client.get("/api/camera_proxy_stream/camera.config_test") + resp = await camera_client.get("/api/camera_proxy_stream/camera.mjpeg_camera") assert resp.status == 504 @@ -195,7 +211,7 @@ async def test_async_aiohttp_proxy_stream_client_err(aioclient_mock, camera_clie """Test that it fetches the given url.""" aioclient_mock.get("http://example.com/mjpeg_stream", exc=aiohttp.ClientError()) - resp = await camera_client.get("/api/camera_proxy_stream/camera.config_test") + resp = await camera_client.get("/api/camera_proxy_stream/camera.mjpeg_camera") assert resp.status == 502