From f68ed8b7a0c2d5c8d33ac733181499b3ce236a73 Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Wed, 14 Jun 2023 21:03:07 +0200 Subject: [PATCH] Always setup demo platforms with device support from config entry (#94601) * Always setup demo platforms with device support from config entry * Update tests depending on the demo integration --- homeassistant/components/demo/switch.py | 24 ++++--------- homeassistant/components/demo/text.py | 33 ++++++------------ homeassistant/components/demo/time.py | 22 +++--------- homeassistant/components/demo/update.py | 34 ++++++------------- tests/components/demo/test_switch.py | 16 +++++++-- tests/components/demo/test_text.py | 21 ++++++++++-- tests/components/demo/test_time.py | 16 +++++++-- tests/components/demo/test_update.py | 13 ++++++- .../google_assistant/test_smart_home.py | 2 ++ 9 files changed, 94 insertions(+), 87 deletions(-) diff --git a/homeassistant/components/demo/switch.py b/homeassistant/components/demo/switch.py index 2ad400ff3f7..080488642e7 100644 --- a/homeassistant/components/demo/switch.py +++ b/homeassistant/components/demo/switch.py @@ -5,22 +5,19 @@ from typing import Any from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity from homeassistant.config_entries import ConfigEntry -from homeassistant.const import DEVICE_DEFAULT_NAME from homeassistant.core import HomeAssistant from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from . import DOMAIN -async def async_setup_platform( +async def async_setup_entry( hass: HomeAssistant, - config: ConfigType, + config_entry: ConfigEntry, async_add_entities: AddEntitiesCallback, - discovery_info: DiscoveryInfoType | None = None, ) -> None: - """Set up the demo switches.""" + """Set up the demo switch platform.""" async_add_entities( [ DemoSwitch("switch1", "Decorative Lights", True, None, True), @@ -36,24 +33,16 @@ async def async_setup_platform( ) -async def async_setup_entry( - hass: HomeAssistant, - config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, -) -> None: - """Set up the Demo config entry.""" - await async_setup_platform(hass, {}, async_add_entities) - - class DemoSwitch(SwitchEntity): """Representation of a demo switch.""" + _attr_has_entity_name = True _attr_should_poll = False def __init__( self, unique_id: str, - name: str, + device_name: str, state: bool, icon: str | None, assumed: bool, @@ -64,11 +53,10 @@ class DemoSwitch(SwitchEntity): self._attr_device_class = device_class self._attr_icon = icon self._attr_is_on = state - self._attr_name = name or DEVICE_DEFAULT_NAME self._attr_unique_id = unique_id self._attr_device_info = DeviceInfo( identifiers={(DOMAIN, unique_id)}, - name=self.name, + name=device_name, ) def turn_on(self, **kwargs: Any) -> None: diff --git a/homeassistant/components/demo/text.py b/homeassistant/components/demo/text.py index efce1af5c37..ff50e508354 100644 --- a/homeassistant/components/demo/text.py +++ b/homeassistant/components/demo/text.py @@ -3,40 +3,37 @@ from __future__ import annotations from homeassistant.components.text import TextEntity, TextMode from homeassistant.config_entries import ConfigEntry -from homeassistant.const import DEVICE_DEFAULT_NAME from homeassistant.core import HomeAssistant from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from . import DOMAIN -async def async_setup_platform( +async def async_setup_entry( hass: HomeAssistant, - config: ConfigType, + config_entry: ConfigEntry, async_add_entities: AddEntitiesCallback, - discovery_info: DiscoveryInfoType | None = None, ) -> None: - """Set up the demo Text entity.""" + """Set up the Demo text platform.""" async_add_entities( [ DemoText( unique_id="text", - name="Text", + device_name="Text", icon=None, native_value="Hello world", ), DemoText( unique_id="password", - name="Password", + device_name="Password", icon="mdi:text", native_value="Hello world", mode=TextMode.PASSWORD, ), DemoText( unique_id="text_1_to_5_char", - name="Text with 1 to 5 characters", + device_name="Text with 1 to 5 characters", icon="mdi:text", native_value="Hello", native_min=1, @@ -44,7 +41,7 @@ async def async_setup_platform( ), DemoText( unique_id="text_lowercase", - name="Text with only lower case characters", + device_name="Text with only lower case characters", icon="mdi:text", native_value="world", pattern=r"[a-z]+", @@ -53,24 +50,16 @@ async def async_setup_platform( ) -async def async_setup_entry( - hass: HomeAssistant, - config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, -) -> None: - """Set up the Demo config entry.""" - await async_setup_platform(hass, {}, async_add_entities) - - class DemoText(TextEntity): """Representation of a demo text entity.""" + _attr_has_entity_name = True _attr_should_poll = False def __init__( self, unique_id: str, - name: str, + device_name: str, icon: str | None, native_value: str | None, mode: TextMode = TextMode.TEXT, @@ -80,7 +69,7 @@ class DemoText(TextEntity): ) -> None: """Initialize the Demo text entity.""" self._attr_unique_id = unique_id - self._attr_name = name or DEVICE_DEFAULT_NAME + self._attr_name = None self._attr_native_value = native_value self._attr_icon = icon self._attr_mode = mode @@ -92,7 +81,7 @@ class DemoText(TextEntity): self._attr_pattern = pattern self._attr_device_info = DeviceInfo( identifiers={(DOMAIN, unique_id)}, - name=name, + name=device_name, ) async def async_set_value(self, value: str) -> None: diff --git a/homeassistant/components/demo/time.py b/homeassistant/components/demo/time.py index aafd425a024..d5e34779927 100644 --- a/homeassistant/components/demo/time.py +++ b/homeassistant/components/demo/time.py @@ -5,43 +5,32 @@ from datetime import time from homeassistant.components.time import TimeEntity from homeassistant.config_entries import ConfigEntry -from homeassistant.const import DEVICE_DEFAULT_NAME from homeassistant.core import HomeAssistant from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from . import DOMAIN -async def async_setup_platform( - hass: HomeAssistant, - config: ConfigType, - async_add_entities: AddEntitiesCallback, - discovery_info: DiscoveryInfoType | None = None, -) -> None: - """Set up the Demo time entity.""" - async_add_entities([DemoTime("time", "Time", time(12, 0, 0), "mdi:clock", False)]) - - async def async_setup_entry( hass: HomeAssistant, config_entry: ConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: - """Set up the Demo config entry.""" - await async_setup_platform(hass, {}, async_add_entities) + """Set up the demo time platform.""" + async_add_entities([DemoTime("time", "Time", time(12, 0, 0), "mdi:clock", False)]) class DemoTime(TimeEntity): """Representation of a Demo time entity.""" + _attr_has_entity_name = True _attr_should_poll = False def __init__( self, unique_id: str, - name: str, + device_name: str, state: time, icon: str, assumed_state: bool, @@ -49,12 +38,11 @@ class DemoTime(TimeEntity): """Initialize the Demo time entity.""" self._attr_assumed_state = assumed_state self._attr_icon = icon - self._attr_name = name or DEVICE_DEFAULT_NAME self._attr_native_value = state self._attr_unique_id = unique_id self._attr_device_info = DeviceInfo( - identifiers={(DOMAIN, unique_id)}, name=self.name + identifiers={(DOMAIN, unique_id)}, name=device_name ) async def async_set_value(self, value: time) -> None: diff --git a/homeassistant/components/demo/update.py b/homeassistant/components/demo/update.py index 15e67ffa0a8..f89f5a160e2 100644 --- a/homeassistant/components/demo/update.py +++ b/homeassistant/components/demo/update.py @@ -10,29 +10,26 @@ from homeassistant.components.update import ( UpdateEntityFeature, ) from homeassistant.config_entries import ConfigEntry -from homeassistant.const import DEVICE_DEFAULT_NAME from homeassistant.core import HomeAssistant from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from . import DOMAIN FAKE_INSTALL_SLEEP_TIME = 0.5 -async def async_setup_platform( +async def async_setup_entry( hass: HomeAssistant, - config: ConfigType, + config_entry: ConfigEntry, async_add_entities: AddEntitiesCallback, - discovery_info: DiscoveryInfoType | None = None, ) -> None: - """Set up demo update entities.""" + """Set up demo update platform.""" async_add_entities( [ DemoUpdate( unique_id="update_no_install", - name="Demo Update No Install", + device_name="Demo Update No Install", title="Awesomesoft Inc.", installed_version="1.0.0", latest_version="1.0.1", @@ -42,14 +39,14 @@ async def async_setup_platform( ), DemoUpdate( unique_id="update_2_date", - name="Demo No Update", + device_name="Demo No Update", title="AdGuard Home", installed_version="1.0.0", latest_version="1.0.0", ), DemoUpdate( unique_id="update_addon", - name="Demo add-on", + device_name="Demo add-on", title="AdGuard Home", installed_version="1.0.0", latest_version="1.0.1", @@ -58,7 +55,7 @@ async def async_setup_platform( ), DemoUpdate( unique_id="update_light_bulb", - name="Demo Living Room Bulb Update", + device_name="Demo Living Room Bulb Update", title="Philips Lamps Firmware", installed_version="1.93.3", latest_version="1.94.2", @@ -68,7 +65,7 @@ async def async_setup_platform( ), DemoUpdate( unique_id="update_support_progress", - name="Demo Update with Progress", + device_name="Demo Update with Progress", title="Philips Lamps Firmware", installed_version="1.93.3", latest_version="1.94.2", @@ -82,15 +79,6 @@ async def async_setup_platform( ) -async def async_setup_entry( - hass: HomeAssistant, - config_entry: ConfigEntry, - async_add_entities: AddEntitiesCallback, -) -> None: - """Set up the Demo config entry.""" - await async_setup_platform(hass, {}, async_add_entities) - - async def _fake_install() -> None: """Fake install an update.""" await asyncio.sleep(FAKE_INSTALL_SLEEP_TIME) @@ -99,13 +87,14 @@ async def _fake_install() -> None: class DemoUpdate(UpdateEntity): """Representation of a demo update entity.""" + _attr_has_entity_name = True _attr_should_poll = False def __init__( self, *, unique_id: str, - name: str, + device_name: str, title: str | None, installed_version: str | None, latest_version: str | None, @@ -120,14 +109,13 @@ class DemoUpdate(UpdateEntity): self._attr_installed_version = installed_version self._attr_device_class = device_class self._attr_latest_version = latest_version - self._attr_name = name or DEVICE_DEFAULT_NAME self._attr_release_summary = release_summary self._attr_release_url = release_url self._attr_title = title self._attr_unique_id = unique_id self._attr_device_info = DeviceInfo( identifiers={(DOMAIN, unique_id)}, - name=name, + name=device_name, ) if support_install: self._attr_supported_features |= ( diff --git a/tests/components/demo/test_switch.py b/tests/components/demo/test_switch.py index 74fa8082d5f..95963ba0cbd 100644 --- a/tests/components/demo/test_switch.py +++ b/tests/components/demo/test_switch.py @@ -1,4 +1,6 @@ """The tests for the demo switch component.""" +from unittest.mock import patch + import pytest from homeassistant.components.demo import DOMAIN @@ -7,15 +9,25 @@ from homeassistant.components.switch import ( SERVICE_TURN_OFF, SERVICE_TURN_ON, ) -from homeassistant.const import ATTR_ENTITY_ID, STATE_OFF, STATE_ON +from homeassistant.const import ATTR_ENTITY_ID, STATE_OFF, STATE_ON, Platform from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component SWITCH_ENTITY_IDS = ["switch.decorative_lights", "switch.ac"] +@pytest.fixture +async def switch_only() -> None: + """Enable only the switch platform.""" + with patch( + "homeassistant.components.demo.COMPONENTS_WITH_CONFIG_ENTRY_DEMO_PLATFORM", + [Platform.SWITCH], + ): + yield + + @pytest.fixture(autouse=True) -async def setup_comp(hass, disable_platforms): +async def setup_comp(hass, switch_only): """Set up demo component.""" assert await async_setup_component( hass, SWITCH_DOMAIN, {SWITCH_DOMAIN: {"platform": DOMAIN}} diff --git a/tests/components/demo/test_text.py b/tests/components/demo/test_text.py index 17680d6f606..2b8d8d122a3 100644 --- a/tests/components/demo/test_text.py +++ b/tests/components/demo/test_text.py @@ -1,4 +1,6 @@ """The tests for the demo text component.""" +from unittest.mock import patch + import pytest from homeassistant.components.text import ( @@ -9,15 +11,30 @@ from homeassistant.components.text import ( DOMAIN, SERVICE_SET_VALUE, ) -from homeassistant.const import ATTR_ENTITY_ID, ATTR_MODE, MAX_LENGTH_STATE_STATE +from homeassistant.const import ( + ATTR_ENTITY_ID, + ATTR_MODE, + MAX_LENGTH_STATE_STATE, + Platform, +) from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component ENTITY_TEXT = "text.text" +@pytest.fixture +async def text_only() -> None: + """Enable only the text platform.""" + with patch( + "homeassistant.components.demo.COMPONENTS_WITH_CONFIG_ENTRY_DEMO_PLATFORM", + [Platform.TEXT], + ): + yield + + @pytest.fixture(autouse=True) -async def setup_demo_text(hass, disable_platforms): +async def setup_demo_text(hass, text_only): """Initialize setup demo text.""" assert await async_setup_component(hass, DOMAIN, {"text": {"platform": "demo"}}) await hass.async_block_till_done() diff --git a/tests/components/demo/test_time.py b/tests/components/demo/test_time.py index abd0faef884..efa62c1436b 100644 --- a/tests/components/demo/test_time.py +++ b/tests/components/demo/test_time.py @@ -1,16 +1,28 @@ """The tests for the demo time component.""" +from unittest.mock import patch + import pytest from homeassistant.components.time import ATTR_TIME, DOMAIN, SERVICE_SET_VALUE -from homeassistant.const import ATTR_ENTITY_ID +from homeassistant.const import ATTR_ENTITY_ID, Platform from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component ENTITY_TIME = "time.time" +@pytest.fixture +async def time_only() -> None: + """Enable only the time platform.""" + with patch( + "homeassistant.components.demo.COMPONENTS_WITH_CONFIG_ENTRY_DEMO_PLATFORM", + [Platform.TIME], + ): + yield + + @pytest.fixture(autouse=True) -async def setup_demo_datetime(hass: HomeAssistant, disable_platforms) -> None: +async def setup_demo_datetime(hass: HomeAssistant, time_only) -> None: """Initialize setup demo time.""" assert await async_setup_component(hass, DOMAIN, {"time": {"platform": "demo"}}) await hass.async_block_till_done() diff --git a/tests/components/demo/test_update.py b/tests/components/demo/test_update.py index f53cceafd23..a645c45019c 100644 --- a/tests/components/demo/test_update.py +++ b/tests/components/demo/test_update.py @@ -20,14 +20,25 @@ from homeassistant.const import ( ATTR_ENTITY_PICTURE, STATE_OFF, STATE_ON, + Platform, ) from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.event import async_track_state_change_event from homeassistant.setup import async_setup_component +@pytest.fixture +async def update_only() -> None: + """Enable only the update platform.""" + with patch( + "homeassistant.components.demo.COMPONENTS_WITH_CONFIG_ENTRY_DEMO_PLATFORM", + [Platform.UPDATE], + ): + yield + + @pytest.fixture(autouse=True) -async def setup_demo_update(hass: HomeAssistant, disable_platforms) -> None: +async def setup_demo_update(hass: HomeAssistant, update_only) -> None: """Initialize setup demo update entity.""" assert await async_setup_component(hass, DOMAIN, {"update": {"platform": "demo"}}) await hass.async_block_till_done() diff --git a/tests/components/google_assistant/test_smart_home.py b/tests/components/google_assistant/test_smart_home.py index c27ea76c00a..4fab32ac932 100644 --- a/tests/components/google_assistant/test_smart_home.py +++ b/tests/components/google_assistant/test_smart_home.py @@ -1054,6 +1054,8 @@ async def test_device_class_switch( ) sensor.hass = hass sensor.entity_id = "switch.demo_sensor" + sensor._attr_device_info = None + sensor._attr_name = "Demo Sensor" sensor.async_write_ha_state() result = await sh.async_handle_message(