"""The tests for the Scrape sensor platform.""" 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, ) 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 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", ) state = hass.states.get("sensor.ha_version") assert state.state == "Current Version: 2021.12.10" async def test_scrape_sensor_value_template(hass: HomeAssistant) -> None: """Test Scrape sensor with value template.""" await init_integration( hass, return_config( select=".current-version h1", name="HA version", template="{{ value.split(':')[1] }}", ), "test_scrape_sensor", ) state = hass.states.get("sensor.ha_version") assert state.state == "2021.12.10" 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( select=".current-temp h3", name="Current Temp", template="{{ value.split(':')[1] }}", uom="°C", device_class="temperature", state_class="measurement", ), "test_scrape_uom_and_classes", ) state = hass.states.get("sensor.current_temp") assert state.state == "22.1" assert state.attributes[CONF_UNIT_OF_MEASUREMENT] == TEMP_CELSIUS assert state.attributes[CONF_DEVICE_CLASS] == SensorDeviceClass.TEMPERATURE assert state.attributes[CONF_STATE_CLASS] == SensorStateClass.MEASUREMENT 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", ) state = hass.states.get("sensor.auth_page") assert state.state == "secret text" state2 = hass.states.get("sensor.auth_page2") assert state2.state == "secret text" 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", ) state = hass.states.get("sensor.ha_version") assert state is 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_entry.add_to_hass(hass) mocker = MockRestData("test_scrape_sensor") 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() state = hass.states.get("sensor.ha_version") assert state assert state.state == "Current Version: 2021.12.10" mocker.data = None await async_update_entity(hass, "sensor.ha_version") assert mocker.data is None assert state is not None assert state.state == "Current Version: 2021.12.10" 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", ) state = hass.states.get("sensor.ha_class") assert state.state == "['links']" state2 = hass.states.get("sensor.ha_template") assert state2.state == "Trying to get" 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] }}", } } mocker = MockRestData("test_scrape_sensor") with patch( "homeassistant.components.scrape.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"