From 1288085b31eb5bf15fb0e8f777b4101b168ec616 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 1 Jul 2022 12:10:40 -0500 Subject: [PATCH] Revert scrape changes to 2022.6.6 (#74305) --- CODEOWNERS | 4 +- homeassistant/components/scrape/__init__.py | 63 ------ homeassistant/components/scrape/manifest.json | 3 +- homeassistant/components/scrape/sensor.py | 104 ++++----- homeassistant/generated/config_flows.py | 1 - tests/components/scrape/__init__.py | 40 +--- tests/components/scrape/test_config_flow.py | 194 ---------------- tests/components/scrape/test_init.py | 89 -------- tests/components/scrape/test_sensor.py | 209 ++++++++---------- 9 files changed, 137 insertions(+), 570 deletions(-) delete mode 100644 tests/components/scrape/test_config_flow.py delete mode 100644 tests/components/scrape/test_init.py diff --git a/CODEOWNERS b/CODEOWNERS index 9845f5f7e5d..0c3f73db76d 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -893,8 +893,8 @@ build.json @home-assistant/supervisor /homeassistant/components/scene/ @home-assistant/core /tests/components/scene/ @home-assistant/core /homeassistant/components/schluter/ @prairieapps -/homeassistant/components/scrape/ @fabaff @gjohansson-ST -/tests/components/scrape/ @fabaff @gjohansson-ST +/homeassistant/components/scrape/ @fabaff +/tests/components/scrape/ @fabaff /homeassistant/components/screenlogic/ @dieselrabbit @bdraco /tests/components/screenlogic/ @dieselrabbit @bdraco /homeassistant/components/script/ @home-assistant/core diff --git a/homeassistant/components/scrape/__init__.py b/homeassistant/components/scrape/__init__.py index 684be76b80d..f9222c126b5 100644 --- a/homeassistant/components/scrape/__init__.py +++ b/homeassistant/components/scrape/__init__.py @@ -1,64 +1 @@ """The scrape component.""" -from __future__ import annotations - -import httpx - -from homeassistant.components.rest.data import RestData -from homeassistant.config_entries import ConfigEntry -from homeassistant.const import ( - CONF_AUTHENTICATION, - CONF_HEADERS, - CONF_PASSWORD, - CONF_RESOURCE, - CONF_USERNAME, - CONF_VERIFY_SSL, - HTTP_DIGEST_AUTHENTICATION, -) -from homeassistant.core import HomeAssistant -from homeassistant.exceptions import ConfigEntryNotReady - -from .const import DOMAIN, PLATFORMS - - -async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: - """Set up Scrape from a config entry.""" - - resource: str = entry.options[CONF_RESOURCE] - method: str = "GET" - payload: str | None = None - headers: str | None = entry.options.get(CONF_HEADERS) - verify_ssl: bool = entry.options[CONF_VERIFY_SSL] - username: str | None = entry.options.get(CONF_USERNAME) - password: str | None = entry.options.get(CONF_PASSWORD) - - auth: httpx.DigestAuth | tuple[str, str] | None = None - if username and password: - if entry.options.get(CONF_AUTHENTICATION) == HTTP_DIGEST_AUTHENTICATION: - auth = httpx.DigestAuth(username, password) - else: - auth = (username, password) - - rest = RestData(hass, method, resource, auth, headers, None, payload, verify_ssl) - await rest.async_update() - - if rest.data is None: - raise ConfigEntryNotReady - - hass.data.setdefault(DOMAIN, {})[entry.entry_id] = rest - - entry.async_on_unload(entry.add_update_listener(async_update_listener)) - - hass.config_entries.async_setup_platforms(entry, PLATFORMS) - - return True - - -async def async_update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None: - """Update listener for options.""" - await hass.config_entries.async_reload(entry.entry_id) - - -async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: - """Unload Scrape config entry.""" - - return await hass.config_entries.async_unload_platforms(entry, PLATFORMS) diff --git a/homeassistant/components/scrape/manifest.json b/homeassistant/components/scrape/manifest.json index 631af2e6051..b1ccbb354a9 100644 --- a/homeassistant/components/scrape/manifest.json +++ b/homeassistant/components/scrape/manifest.json @@ -4,7 +4,6 @@ "documentation": "https://www.home-assistant.io/integrations/scrape", "requirements": ["beautifulsoup4==4.11.1", "lxml==4.8.0"], "after_dependencies": ["rest"], - "codeowners": ["@fabaff", "@gjohansson-ST"], - "config_flow": true, + "codeowners": ["@fabaff"], "iot_class": "cloud_polling" } diff --git a/homeassistant/components/scrape/sensor.py b/homeassistant/components/scrape/sensor.py index b6b8828ca73..e15f7c5ba97 100644 --- a/homeassistant/components/scrape/sensor.py +++ b/homeassistant/components/scrape/sensor.py @@ -1,11 +1,11 @@ """Support for getting data from websites with scraping.""" from __future__ import annotations -from datetime import timedelta import logging from typing import Any from bs4 import BeautifulSoup +import httpx import voluptuous as vol from homeassistant.components.rest.data import RestData @@ -16,16 +16,13 @@ from homeassistant.components.sensor import ( STATE_CLASSES_SCHEMA, SensorEntity, ) -from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry from homeassistant.const import ( - CONF_ATTRIBUTE, CONF_AUTHENTICATION, CONF_DEVICE_CLASS, CONF_HEADERS, CONF_NAME, CONF_PASSWORD, CONF_RESOURCE, - CONF_SCAN_INTERVAL, CONF_UNIT_OF_MEASUREMENT, CONF_USERNAME, CONF_VALUE_TEMPLATE, @@ -34,25 +31,26 @@ from homeassistant.const import ( HTTP_DIGEST_AUTHENTICATION, ) from homeassistant.core import HomeAssistant +from homeassistant.exceptions import PlatformNotReady import homeassistant.helpers.config_validation as cv -from homeassistant.helpers.device_registry import DeviceEntryType -from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.template import Template from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType -from .const import CONF_INDEX, CONF_SELECT, DEFAULT_NAME, DEFAULT_VERIFY_SSL, DOMAIN - _LOGGER = logging.getLogger(__name__) -SCAN_INTERVAL = timedelta(minutes=10) -ICON = "mdi:web" +CONF_ATTR = "attribute" +CONF_SELECT = "select" +CONF_INDEX = "index" + +DEFAULT_NAME = "Web scrape" +DEFAULT_VERIFY_SSL = True PLATFORM_SCHEMA = PARENT_PLATFORM_SCHEMA.extend( { vol.Required(CONF_RESOURCE): cv.string, vol.Required(CONF_SELECT): cv.string, - vol.Optional(CONF_ATTRIBUTE): cv.string, + vol.Optional(CONF_ATTR): cv.string, vol.Optional(CONF_INDEX, default=0): cv.positive_int, vol.Optional(CONF_AUTHENTICATION): vol.In( [HTTP_BASIC_AUTHENTICATION, HTTP_DIGEST_AUTHENTICATION] @@ -64,7 +62,7 @@ PLATFORM_SCHEMA = PARENT_PLATFORM_SCHEMA.extend( vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA, vol.Optional(CONF_STATE_CLASS): STATE_CLASSES_SCHEMA, vol.Optional(CONF_USERNAME): cv.string, - vol.Optional(CONF_VALUE_TEMPLATE): cv.string, + vol.Optional(CONF_VALUE_TEMPLATE): cv.template, vol.Optional(CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL): cv.boolean, } ) @@ -77,47 +75,37 @@ async def async_setup_platform( discovery_info: DiscoveryInfoType | None = None, ) -> None: """Set up the Web scrape sensor.""" - _LOGGER.warning( - # Config flow added in Home Assistant Core 2022.7, remove import flow in 2022.9 - "Loading Scrape via platform setup has been deprecated in Home Assistant 2022.7 " - "Your configuration has been automatically imported and you can " - "remove it from your configuration.yaml" - ) + name: str = config[CONF_NAME] + resource: str = config[CONF_RESOURCE] + method: str = "GET" + payload: str | None = None + headers: str | None = config.get(CONF_HEADERS) + verify_ssl: bool = config[CONF_VERIFY_SSL] + select: str | None = config.get(CONF_SELECT) + attr: str | None = config.get(CONF_ATTR) + index: int = config[CONF_INDEX] + unit: str | None = config.get(CONF_UNIT_OF_MEASUREMENT) + device_class: str | None = config.get(CONF_DEVICE_CLASS) + state_class: str | None = config.get(CONF_STATE_CLASS) + username: str | None = config.get(CONF_USERNAME) + password: str | None = config.get(CONF_PASSWORD) + value_template: Template | None = config.get(CONF_VALUE_TEMPLATE) - if config.get(CONF_VALUE_TEMPLATE): - template: Template = Template(config[CONF_VALUE_TEMPLATE]) - template.ensure_valid() - config[CONF_VALUE_TEMPLATE] = template.template - - hass.async_create_task( - hass.config_entries.flow.async_init( - DOMAIN, - context={"source": SOURCE_IMPORT}, - data={k: v for k, v in config.items() if k != CONF_SCAN_INTERVAL}, - ) - ) - - -async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback -) -> None: - """Set up the Scrape sensor entry.""" - name: str = entry.options[CONF_NAME] - resource: str = entry.options[CONF_RESOURCE] - select: str | None = entry.options.get(CONF_SELECT) - attr: str | None = entry.options.get(CONF_ATTRIBUTE) - index: int = int(entry.options[CONF_INDEX]) - unit: str | None = entry.options.get(CONF_UNIT_OF_MEASUREMENT) - device_class: str | None = entry.options.get(CONF_DEVICE_CLASS) - state_class: str | None = entry.options.get(CONF_STATE_CLASS) - value_template: str | None = entry.options.get(CONF_VALUE_TEMPLATE) - entry_id: str = entry.entry_id - - val_template: Template | None = None if value_template is not None: - val_template = Template(value_template, hass) + value_template.hass = hass - rest = hass.data[DOMAIN][entry.entry_id] + auth: httpx.DigestAuth | tuple[str, str] | None = None + if username and password: + if config.get(CONF_AUTHENTICATION) == HTTP_DIGEST_AUTHENTICATION: + auth = httpx.DigestAuth(username, password) + else: + auth = (username, password) + + rest = RestData(hass, method, resource, auth, headers, None, payload, verify_ssl) + await rest.async_update() + + if rest.data is None: + raise PlatformNotReady async_add_entities( [ @@ -127,12 +115,10 @@ async def async_setup_entry( select, attr, index, - val_template, + value_template, unit, device_class, state_class, - entry_id, - resource, ) ], True, @@ -142,8 +128,6 @@ async def async_setup_entry( class ScrapeSensor(SensorEntity): """Representation of a web scrape sensor.""" - _attr_icon = ICON - def __init__( self, rest: RestData, @@ -155,8 +139,6 @@ class ScrapeSensor(SensorEntity): unit: str | None, device_class: str | None, state_class: str | None, - entry_id: str, - resource: str, ) -> None: """Initialize a web scrape sensor.""" self.rest = rest @@ -169,14 +151,6 @@ class ScrapeSensor(SensorEntity): self._attr_native_unit_of_measurement = unit self._attr_device_class = device_class self._attr_state_class = state_class - self._attr_unique_id = entry_id - self._attr_device_info = DeviceInfo( - entry_type=DeviceEntryType.SERVICE, - identifiers={(DOMAIN, entry_id)}, - manufacturer="Scrape", - name=name, - configuration_url=resource, - ) def _extract_value(self) -> Any: """Parse the html extraction in the executor.""" diff --git a/homeassistant/generated/config_flows.py b/homeassistant/generated/config_flows.py index 0b985f6e161..eba8bfe10c4 100644 --- a/homeassistant/generated/config_flows.py +++ b/homeassistant/generated/config_flows.py @@ -301,7 +301,6 @@ FLOWS = { "ruckus_unleashed", "sabnzbd", "samsungtv", - "scrape", "screenlogic", "season", "sense", diff --git a/tests/components/scrape/__init__.py b/tests/components/scrape/__init__.py index 37abb061e75..0ba9266a79d 100644 --- a/tests/components/scrape/__init__.py +++ b/tests/components/scrape/__init__.py @@ -2,42 +2,6 @@ from __future__ import annotations from typing import Any -from unittest.mock import patch - -from homeassistant.components.scrape.const import DOMAIN -from homeassistant.config_entries import SOURCE_USER -from homeassistant.core import HomeAssistant - -from tests.common import MockConfigEntry - - -async def init_integration( - hass: HomeAssistant, - config: dict[str, Any], - data: str, - entry_id: str = "1", - source: str = SOURCE_USER, -) -> MockConfigEntry: - """Set up the Scrape integration in Home Assistant.""" - - config_entry = MockConfigEntry( - domain=DOMAIN, - source=source, - data={}, - options=config, - entry_id=entry_id, - ) - - config_entry.add_to_hass(hass) - mocker = MockRestData(data) - with patch( - "homeassistant.components.scrape.RestData", - return_value=mocker, - ): - await hass.config_entries.async_setup(config_entry.entry_id) - await hass.async_block_till_done() - - return config_entry def return_config( @@ -61,8 +25,6 @@ def return_config( "resource": "https://www.home-assistant.io", "select": select, "name": name, - "index": 0, - "verify_ssl": True, } if attribute: config["attribute"] = attribute @@ -76,7 +38,7 @@ def return_config( config["device_class"] = device_class if state_class: config["state_class"] = state_class - if username: + if authentication: config["authentication"] = authentication config["username"] = username config["password"] = password diff --git a/tests/components/scrape/test_config_flow.py b/tests/components/scrape/test_config_flow.py deleted file mode 100644 index 287004b1dd3..00000000000 --- a/tests/components/scrape/test_config_flow.py +++ /dev/null @@ -1,194 +0,0 @@ -"""Test the Scrape config flow.""" -from __future__ import annotations - -from unittest.mock import patch - -from homeassistant import config_entries -from homeassistant.components.scrape.const import CONF_INDEX, CONF_SELECT, DOMAIN -from homeassistant.const import ( - CONF_NAME, - CONF_RESOURCE, - CONF_VALUE_TEMPLATE, - CONF_VERIFY_SSL, -) -from homeassistant.core import HomeAssistant -from homeassistant.data_entry_flow import ( - RESULT_TYPE_ABORT, - RESULT_TYPE_CREATE_ENTRY, - RESULT_TYPE_FORM, -) - -from . import MockRestData - -from tests.common import MockConfigEntry - - -async def test_form(hass: HomeAssistant) -> None: - """Test we get the form.""" - - result = await hass.config_entries.flow.async_init( - DOMAIN, context={"source": config_entries.SOURCE_USER} - ) - assert result["type"] == RESULT_TYPE_FORM - - with patch( - "homeassistant.components.scrape.sensor.RestData", - return_value=MockRestData("test_scrape_sensor"), - ), patch( - "homeassistant.components.scrape.async_setup_entry", - return_value=True, - ) as mock_setup_entry: - result2 = await hass.config_entries.flow.async_configure( - result["flow_id"], - { - CONF_RESOURCE: "https://www.home-assistant.io", - CONF_NAME: "Release", - CONF_SELECT: ".current-version h1", - CONF_VALUE_TEMPLATE: "{{ value.split(':')[1] }}", - }, - ) - await hass.async_block_till_done() - - assert result2["type"] == RESULT_TYPE_CREATE_ENTRY - assert result2["title"] == "Release" - assert result2["options"] == { - "resource": "https://www.home-assistant.io", - "name": "Release", - "select": ".current-version h1", - "value_template": "{{ value.split(':')[1] }}", - "index": 0.0, - "verify_ssl": True, - } - assert len(mock_setup_entry.mock_calls) == 1 - - -async def test_import_flow_success(hass: HomeAssistant) -> None: - """Test a successful import of yaml.""" - - with patch( - "homeassistant.components.scrape.sensor.RestData", - return_value=MockRestData("test_scrape_sensor"), - ), patch( - "homeassistant.components.scrape.async_setup_entry", - return_value=True, - ) as mock_setup_entry: - result2 = await hass.config_entries.flow.async_init( - DOMAIN, - context={"source": config_entries.SOURCE_IMPORT}, - data={ - CONF_RESOURCE: "https://www.home-assistant.io", - CONF_NAME: "Release", - CONF_SELECT: ".current-version h1", - CONF_VALUE_TEMPLATE: "{{ value.split(':')[1] }}", - CONF_INDEX: 0, - CONF_VERIFY_SSL: True, - }, - ) - await hass.async_block_till_done() - - assert result2["type"] == RESULT_TYPE_CREATE_ENTRY - assert result2["title"] == "Release" - assert result2["options"] == { - "resource": "https://www.home-assistant.io", - "name": "Release", - "select": ".current-version h1", - "value_template": "{{ value.split(':')[1] }}", - "index": 0, - "verify_ssl": True, - } - assert len(mock_setup_entry.mock_calls) == 1 - - -async def test_import_flow_already_exist(hass: HomeAssistant) -> None: - """Test import of yaml already exist.""" - - MockConfigEntry( - domain=DOMAIN, - data={}, - options={ - "resource": "https://www.home-assistant.io", - "name": "Release", - "select": ".current-version h1", - "value_template": "{{ value.split(':')[1] }}", - "index": 0, - "verify_ssl": True, - }, - ).add_to_hass(hass) - - with patch( - "homeassistant.components.scrape.sensor.RestData", - return_value=MockRestData("test_scrape_sensor"), - ), patch( - "homeassistant.components.scrape.async_setup_entry", - return_value=True, - ): - result3 = await hass.config_entries.flow.async_init( - DOMAIN, - context={"source": config_entries.SOURCE_IMPORT}, - data={ - CONF_RESOURCE: "https://www.home-assistant.io", - CONF_NAME: "Release", - CONF_SELECT: ".current-version h1", - CONF_VALUE_TEMPLATE: "{{ value.split(':')[1] }}", - CONF_INDEX: 0, - CONF_VERIFY_SSL: True, - }, - ) - await hass.async_block_till_done() - - assert result3["type"] == RESULT_TYPE_ABORT - assert result3["reason"] == "already_configured" - - -async def test_options_form(hass: HomeAssistant) -> None: - """Test we get the form in options.""" - - entry = MockConfigEntry( - domain=DOMAIN, - data={}, - options={ - "resource": "https://www.home-assistant.io", - "name": "Release", - "select": ".current-version h1", - "value_template": "{{ value.split(':')[1] }}", - "index": 0, - "verify_ssl": True, - }, - entry_id="1", - ) - entry.add_to_hass(hass) - - with patch( - "homeassistant.components.scrape.RestData", - return_value=MockRestData("test_scrape_sensor"), - ): - assert await hass.config_entries.async_setup(entry.entry_id) - await hass.async_block_till_done() - - result = await hass.config_entries.options.async_init(entry.entry_id) - - with patch( - "homeassistant.components.scrape.RestData", - return_value=MockRestData("test_scrape_sensor"), - ): - result2 = await hass.config_entries.options.async_configure( - result["flow_id"], - user_input={ - "value_template": "{{ value.split(':')[1] }}", - "index": 1.0, - "verify_ssl": True, - }, - ) - - assert result2["type"] == RESULT_TYPE_CREATE_ENTRY - assert result2["data"] == { - "resource": "https://www.home-assistant.io", - "name": "Release", - "select": ".current-version h1", - "value_template": "{{ value.split(':')[1] }}", - "index": 1.0, - "verify_ssl": True, - } - entry_check = hass.config_entries.async_get_entry("1") - assert entry_check.state == config_entries.ConfigEntryState.LOADED - assert entry_check.update_listeners is not None diff --git a/tests/components/scrape/test_init.py b/tests/components/scrape/test_init.py deleted file mode 100644 index 021790e65c3..00000000000 --- a/tests/components/scrape/test_init.py +++ /dev/null @@ -1,89 +0,0 @@ -"""Test Scrape component setup process.""" -from __future__ import annotations - -from unittest.mock import patch - -from homeassistant.components.scrape.const import DOMAIN -from homeassistant.config_entries import ConfigEntryState -from homeassistant.core import HomeAssistant - -from . import MockRestData - -from tests.common import MockConfigEntry - -TEST_CONFIG = { - "resource": "https://www.home-assistant.io", - "name": "Release", - "select": ".current-version h1", - "value_template": "{{ value.split(':')[1] }}", - "index": 0, - "verify_ssl": True, -} - - -async def test_setup_entry(hass: HomeAssistant) -> None: - """Test setup entry.""" - entry = MockConfigEntry( - domain=DOMAIN, - data={}, - options=TEST_CONFIG, - title="Release", - ) - entry.add_to_hass(hass) - - with patch( - "homeassistant.components.scrape.RestData", - return_value=MockRestData("test_scrape_sensor"), - ): - await hass.config_entries.async_setup(entry.entry_id) - await hass.async_block_till_done() - - state = hass.states.get("sensor.release") - assert state - - -async def test_setup_entry_no_data_fails(hass: HomeAssistant) -> None: - """Test setup entry no data fails.""" - entry = MockConfigEntry( - domain=DOMAIN, data={}, options=TEST_CONFIG, title="Release", entry_id="1" - ) - entry.add_to_hass(hass) - - with patch( - "homeassistant.components.scrape.RestData", - return_value=MockRestData("test_scrape_sensor_no_data"), - ): - await hass.config_entries.async_setup(entry.entry_id) - await hass.async_block_till_done() - - state = hass.states.get("sensor.ha_version") - assert state is None - entry = hass.config_entries.async_get_entry("1") - assert entry.state == ConfigEntryState.SETUP_RETRY - - -async def test_remove_entry(hass: HomeAssistant) -> None: - """Test remove entry.""" - entry = MockConfigEntry( - domain=DOMAIN, - data={}, - options=TEST_CONFIG, - title="Release", - ) - entry.add_to_hass(hass) - - with patch( - "homeassistant.components.scrape.RestData", - return_value=MockRestData("test_scrape_sensor"), - ): - await hass.config_entries.async_setup(entry.entry_id) - await hass.async_block_till_done() - - state = hass.states.get("sensor.release") - assert state - - await hass.config_entries.async_remove(entry.entry_id) - await hass.async_block_till_done() - - state = hass.states.get("sensor.release") - assert not state diff --git a/tests/components/scrape/test_sensor.py b/tests/components/scrape/test_sensor.py index cd4e27e88a2..aaf156208ef 100644 --- a/tests/components/scrape/test_sensor.py +++ b/tests/components/scrape/test_sensor.py @@ -3,15 +3,10 @@ from __future__ import annotations from unittest.mock import patch -import pytest - from homeassistant.components.sensor import SensorDeviceClass, SensorStateClass from homeassistant.components.sensor.const import CONF_STATE_CLASS -from homeassistant.config_entries import SOURCE_USER from homeassistant.const import ( CONF_DEVICE_CLASS, - CONF_NAME, - CONF_RESOURCE, CONF_UNIT_OF_MEASUREMENT, STATE_UNKNOWN, TEMP_CELSIUS, @@ -20,20 +15,22 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_component import async_update_entity from homeassistant.setup import async_setup_component -from . import MockRestData, init_integration, return_config - -from tests.common import MockConfigEntry +from . import MockRestData, return_config DOMAIN = "scrape" async def test_scrape_sensor(hass: HomeAssistant) -> None: """Test Scrape sensor minimal.""" - await init_integration( - hass, - return_config(select=".current-version h1", name="HA version"), - "test_scrape_sensor", - ) + config = {"sensor": return_config(select=".current-version h1", name="HA version")} + + mocker = MockRestData("test_scrape_sensor") + with patch( + "homeassistant.components.scrape.sensor.RestData", + return_value=mocker, + ): + assert await async_setup_component(hass, "sensor", config) + await hass.async_block_till_done() state = hass.states.get("sensor.ha_version") assert state.state == "Current Version: 2021.12.10" @@ -41,15 +38,21 @@ async def test_scrape_sensor(hass: HomeAssistant) -> None: async def test_scrape_sensor_value_template(hass: HomeAssistant) -> None: """Test Scrape sensor with value template.""" - await init_integration( - hass, - return_config( + config = { + "sensor": return_config( select=".current-version h1", name="HA version", template="{{ value.split(':')[1] }}", - ), - "test_scrape_sensor", - ) + ) + } + + mocker = MockRestData("test_scrape_sensor") + with patch( + "homeassistant.components.scrape.sensor.RestData", + return_value=mocker, + ): + assert await async_setup_component(hass, "sensor", config) + await hass.async_block_till_done() state = hass.states.get("sensor.ha_version") assert state.state == "2021.12.10" @@ -57,18 +60,24 @@ async def test_scrape_sensor_value_template(hass: HomeAssistant) -> None: async def test_scrape_uom_and_classes(hass: HomeAssistant) -> None: """Test Scrape sensor for unit of measurement, device class and state class.""" - await init_integration( - hass, - return_config( + config = { + "sensor": return_config( select=".current-temp h3", name="Current Temp", template="{{ value.split(':')[1] }}", uom="°C", device_class="temperature", state_class="measurement", - ), - "test_scrape_uom_and_classes", - ) + ) + } + + mocker = MockRestData("test_scrape_uom_and_classes") + with patch( + "homeassistant.components.scrape.sensor.RestData", + return_value=mocker, + ): + assert await async_setup_component(hass, "sensor", config) + await hass.async_block_till_done() state = hass.states.get("sensor.current_temp") assert state.state == "22.1" @@ -79,28 +88,31 @@ async def test_scrape_uom_and_classes(hass: HomeAssistant) -> None: async def test_scrape_sensor_authentication(hass: HomeAssistant) -> None: """Test Scrape sensor with authentication.""" - await init_integration( - hass, - return_config( - select=".return", - name="Auth page", - username="user@secret.com", - password="12345678", - authentication="digest", - ), - "test_scrape_sensor_authentication", - ) - await init_integration( - hass, - return_config( - select=".return", - name="Auth page2", - username="user@secret.com", - password="12345678", - ), - "test_scrape_sensor_authentication", - entry_id="2", - ) + config = { + "sensor": [ + return_config( + select=".return", + name="Auth page", + username="user@secret.com", + password="12345678", + authentication="digest", + ), + return_config( + select=".return", + name="Auth page2", + username="user@secret.com", + password="12345678", + ), + ] + } + + mocker = MockRestData("test_scrape_sensor_authentication") + with patch( + "homeassistant.components.scrape.sensor.RestData", + return_value=mocker, + ): + assert await async_setup_component(hass, "sensor", config) + await hass.async_block_till_done() state = hass.states.get("sensor.auth_page") assert state.state == "secret text" @@ -110,11 +122,15 @@ async def test_scrape_sensor_authentication(hass: HomeAssistant) -> None: async def test_scrape_sensor_no_data(hass: HomeAssistant) -> None: """Test Scrape sensor fails on no data.""" - await init_integration( - hass, - return_config(select=".current-version h1", name="HA version"), - "test_scrape_sensor_no_data", - ) + config = {"sensor": return_config(select=".current-version h1", name="HA version")} + + mocker = MockRestData("test_scrape_sensor_no_data") + with patch( + "homeassistant.components.scrape.sensor.RestData", + return_value=mocker, + ): + assert await async_setup_component(hass, "sensor", config) + await hass.async_block_till_done() state = hass.states.get("sensor.ha_version") assert state is None @@ -122,21 +138,14 @@ async def test_scrape_sensor_no_data(hass: HomeAssistant) -> None: async def test_scrape_sensor_no_data_refresh(hass: HomeAssistant) -> None: """Test Scrape sensor no data on refresh.""" - config_entry = MockConfigEntry( - domain=DOMAIN, - source=SOURCE_USER, - data={}, - options=return_config(select=".current-version h1", name="HA version"), - entry_id="1", - ) + config = {"sensor": return_config(select=".current-version h1", name="HA version")} - config_entry.add_to_hass(hass) mocker = MockRestData("test_scrape_sensor") with patch( - "homeassistant.components.scrape.RestData", + "homeassistant.components.scrape.sensor.RestData", return_value=mocker, ): - await hass.config_entries.async_setup(config_entry.entry_id) + assert await async_setup_component(hass, "sensor", config) await hass.async_block_till_done() state = hass.states.get("sensor.ha_version") @@ -153,17 +162,20 @@ async def test_scrape_sensor_no_data_refresh(hass: HomeAssistant) -> None: async def test_scrape_sensor_attribute_and_tag(hass: HomeAssistant) -> None: """Test Scrape sensor with attribute and tag.""" - await init_integration( - hass, - return_config(select="div", name="HA class", index=1, attribute="class"), - "test_scrape_sensor", - ) - await init_integration( - hass, - return_config(select="template", name="HA template"), - "test_scrape_sensor", - entry_id="2", - ) + config = { + "sensor": [ + return_config(select="div", name="HA class", index=1, attribute="class"), + return_config(select="template", name="HA template"), + ] + } + + mocker = MockRestData("test_scrape_sensor") + with patch( + "homeassistant.components.scrape.sensor.RestData", + return_value=mocker, + ): + assert await async_setup_component(hass, "sensor", config) + await hass.async_block_till_done() state = hass.states.get("sensor.ha_class") assert state.state == "['links']" @@ -173,55 +185,22 @@ async def test_scrape_sensor_attribute_and_tag(hass: HomeAssistant) -> None: async def test_scrape_sensor_errors(hass: HomeAssistant) -> None: """Test Scrape sensor handle errors.""" - await init_integration( - hass, - return_config(select="div", name="HA class", index=5, attribute="class"), - "test_scrape_sensor", - ) - await init_integration( - hass, - return_config(select="div", name="HA class2", attribute="classes"), - "test_scrape_sensor", - entry_id="2", - ) - - state = hass.states.get("sensor.ha_class") - assert state.state == STATE_UNKNOWN - state2 = hass.states.get("sensor.ha_class2") - assert state2.state == STATE_UNKNOWN - - -async def test_import(hass: HomeAssistant, caplog: pytest.LogCaptureFixture) -> None: - """Test the Scrape sensor import.""" config = { - "sensor": { - "platform": "scrape", - "resource": "https://www.home-assistant.io", - "select": ".current-version h1", - "name": "HA Version", - "index": 0, - "verify_ssl": True, - "value_template": "{{ value.split(':')[1] }}", - } + "sensor": [ + return_config(select="div", name="HA class", index=5, attribute="class"), + return_config(select="div", name="HA class2", attribute="classes"), + ] } mocker = MockRestData("test_scrape_sensor") with patch( - "homeassistant.components.scrape.RestData", + "homeassistant.components.scrape.sensor.RestData", return_value=mocker, ): assert await async_setup_component(hass, "sensor", config) await hass.async_block_till_done() - assert ( - "Loading Scrape via platform setup has been deprecated in Home Assistant" - in caplog.text - ) - - assert hass.config_entries.async_entries(DOMAIN) - options = hass.config_entries.async_entries(DOMAIN)[0].options - assert options[CONF_NAME] == "HA Version" - assert options[CONF_RESOURCE] == "https://www.home-assistant.io" - - state = hass.states.get("sensor.ha_version") - assert state.state == "2021.12.10" + state = hass.states.get("sensor.ha_class") + assert state.state == STATE_UNKNOWN + state2 = hass.states.get("sensor.ha_class2") + assert state2.state == STATE_UNKNOWN