From 6424c71daaba644c8f1c4c3edba5544c5c2b6510 Mon Sep 17 00:00:00 2001
From: epenet <6771947+epenet@users.noreply.github.com>
Date: Thu, 17 Nov 2022 09:39:46 +0100
Subject: [PATCH] Cleanup supported_features in demo (#82239)

* Cleanup supported_features in demo cover

* Improve other platforms

* Adjust media_player patch
---
 homeassistant/components/demo/cover.py        | 11 ++---------
 homeassistant/components/demo/fan.py          |  9 ++-------
 homeassistant/components/demo/humidifier.py   |  4 +---
 homeassistant/components/demo/light.py        |  9 ++-------
 homeassistant/components/demo/lock.py         |  8 +-------
 homeassistant/components/demo/media_player.py | 18 +++---------------
 homeassistant/components/demo/vacuum.py       | 18 +++++-------------
 homeassistant/components/demo/water_heater.py | 13 +++----------
 tests/components/media_player/test_init.py    |  6 +++---
 9 files changed, 22 insertions(+), 74 deletions(-)

diff --git a/homeassistant/components/demo/cover.py b/homeassistant/components/demo/cover.py
index 845bd9976a3..6f443329661 100644
--- a/homeassistant/components/demo/cover.py
+++ b/homeassistant/components/demo/cover.py
@@ -78,7 +78,7 @@ class DemoCover(CoverEntity):
         position: int | None = None,
         tilt_position: int | None = None,
         device_class: CoverDeviceClass | None = None,
-        supported_features: int | None = None,
+        supported_features: CoverEntityFeature | None = None,
     ) -> None:
         """Initialize the cover."""
         self.hass = hass
@@ -86,7 +86,7 @@ class DemoCover(CoverEntity):
         self._attr_name = name
         self._position = position
         self._attr_device_class = device_class
-        self._supported_features = supported_features
+        self._attr_supported_features = supported_features
         self._set_position: int | None = None
         self._set_tilt_position: int | None = None
         self._tilt_position = tilt_position
@@ -142,13 +142,6 @@ class DemoCover(CoverEntity):
         """Return if the cover is opening."""
         return self._is_opening
 
-    @property
-    def supported_features(self) -> int:
-        """Flag supported features."""
-        if self._supported_features is not None:
-            return self._supported_features
-        return super().supported_features
-
     async def async_close_cover(self, **kwargs: Any) -> None:
         """Close the cover."""
         if self._position == 0:
diff --git a/homeassistant/components/demo/fan.py b/homeassistant/components/demo/fan.py
index 8dcffa6e141..5c8cc849285 100644
--- a/homeassistant/components/demo/fan.py
+++ b/homeassistant/components/demo/fan.py
@@ -107,13 +107,13 @@ class BaseDemoFan(FanEntity):
         hass: HomeAssistant,
         unique_id: str,
         name: str,
-        supported_features: int,
+        supported_features: FanEntityFeature,
         preset_modes: list[str] | None,
     ) -> None:
         """Initialize the entity."""
         self.hass = hass
         self._unique_id = unique_id
-        self._supported_features = supported_features
+        self._attr_supported_features = supported_features
         self._percentage: int | None = None
         self._preset_modes = preset_modes
         self._preset_mode: str | None = None
@@ -140,11 +140,6 @@ class BaseDemoFan(FanEntity):
         """Oscillating."""
         return self._oscillating
 
-    @property
-    def supported_features(self) -> int:
-        """Flag supported features."""
-        return self._supported_features
-
 
 class DemoPercentageFan(BaseDemoFan, FanEntity):
     """A demonstration fan component that uses percentages."""
diff --git a/homeassistant/components/demo/humidifier.py b/homeassistant/components/demo/humidifier.py
index 571cfbe8db9..9b55583d12b 100644
--- a/homeassistant/components/demo/humidifier.py
+++ b/homeassistant/components/demo/humidifier.py
@@ -75,9 +75,7 @@ class DemoHumidifier(HumidifierEntity):
         self._attr_is_on = is_on
         self._attr_supported_features = SUPPORT_FLAGS
         if mode is not None:
-            self._attr_supported_features = (
-                self._attr_supported_features | HumidifierEntityFeature.MODES
-            )
+            self._attr_supported_features |= HumidifierEntityFeature.MODES
         self._attr_target_humidity = target_humidity
         self._attr_mode = mode
         self._attr_available_modes = available_modes
diff --git a/homeassistant/components/demo/light.py b/homeassistant/components/demo/light.py
index af8afe2c15d..c990e4ff8e0 100644
--- a/homeassistant/components/demo/light.py
+++ b/homeassistant/components/demo/light.py
@@ -129,7 +129,7 @@ class DemoLight(LightEntity):
         self._ct = ct or random.choice(LIGHT_TEMPS)
         self._effect = effect
         self._effect_list = effect_list
-        self._features = 0
+        self._attr_supported_features = 0
         self._hs_color = hs_color
         self._attr_name = name
         self._rgbw_color = rgbw_color
@@ -148,7 +148,7 @@ class DemoLight(LightEntity):
             supported_color_modes = SUPPORT_DEMO
         self._color_modes = supported_color_modes
         if self._effect_list is not None:
-            self._features |= LightEntityFeature.EFFECT
+            self._attr_supported_features |= LightEntityFeature.EFFECT
 
     @property
     def device_info(self) -> DeviceInfo:
@@ -218,11 +218,6 @@ class DemoLight(LightEntity):
         """Return true if light is on."""
         return self._state
 
-    @property
-    def supported_features(self) -> int:
-        """Flag supported features."""
-        return self._features
-
     @property
     def supported_color_modes(self) -> set[ColorMode]:
         """Flag supported color modes."""
diff --git a/homeassistant/components/demo/lock.py b/homeassistant/components/demo/lock.py
index d21d89f238b..546161b2d6f 100644
--- a/homeassistant/components/demo/lock.py
+++ b/homeassistant/components/demo/lock.py
@@ -60,6 +60,7 @@ class DemoLock(LockEntity):
     ) -> None:
         """Initialize the lock."""
         self._attr_name = name
+        self._attr_supported_features = 0
         if openable:
             self._attr_supported_features = LockEntityFeature.OPEN
         self._state = state
@@ -109,10 +110,3 @@ class DemoLock(LockEntity):
         """Open the door latch."""
         self._state = STATE_UNLOCKED
         self.async_write_ha_state()
-
-    @property
-    def supported_features(self) -> int:
-        """Flag supported features."""
-        if self._openable:
-            return LockEntityFeature.OPEN
-        return 0
diff --git a/homeassistant/components/demo/media_player.py b/homeassistant/components/demo/media_player.py
index 8bbe380d9ec..646485e8f42 100644
--- a/homeassistant/components/demo/media_player.py
+++ b/homeassistant/components/demo/media_player.py
@@ -186,6 +186,7 @@ class DemoYoutubePlayer(AbstractDemoPlayer):
     # We only implement the methods that we support
 
     _attr_media_content_type = MediaType.MOVIE
+    _attr_supported_features = YOUTUBE_PLAYER_SUPPORT
 
     def __init__(
         self, name: str, youtube_id: str, media_title: str, duration: int
@@ -223,11 +224,6 @@ class DemoYoutubePlayer(AbstractDemoPlayer):
         """Return the current running application."""
         return "YouTube"
 
-    @property
-    def supported_features(self) -> int:
-        """Flag media player features that are supported."""
-        return YOUTUBE_PLAYER_SUPPORT
-
     @property
     def media_position(self) -> int | None:
         """Position of current playing media in seconds."""
@@ -271,6 +267,7 @@ class DemoMusicPlayer(AbstractDemoPlayer):
     # We only implement the methods that we support
 
     _attr_media_content_type = MediaType.MUSIC
+    _attr_supported_features = MUSIC_PLAYER_SUPPORT
 
     tracks = [
         ("Technohead", "I Wanna Be A Hippy (Flamman & Abraxas Radio Mix)"),
@@ -347,11 +344,6 @@ class DemoMusicPlayer(AbstractDemoPlayer):
         """Return current repeat mode."""
         return self._repeat
 
-    @property
-    def supported_features(self) -> int:
-        """Flag media player features that are supported."""
-        return MUSIC_PLAYER_SUPPORT
-
     def media_previous_track(self) -> None:
         """Send previous track command."""
         if self._cur_track > 0:
@@ -395,6 +387,7 @@ class DemoTVShowPlayer(AbstractDemoPlayer):
     # We only implement the methods that we support
 
     _attr_media_content_type = MediaType.TVSHOW
+    _attr_supported_features = NETFLIX_PLAYER_SUPPORT
 
     def __init__(self) -> None:
         """Initialize the demo device."""
@@ -454,11 +447,6 @@ class DemoTVShowPlayer(AbstractDemoPlayer):
         """List of available sources."""
         return self._source_list
 
-    @property
-    def supported_features(self) -> int:
-        """Flag media player features that are supported."""
-        return NETFLIX_PLAYER_SUPPORT
-
     def media_previous_track(self) -> None:
         """Send previous track command."""
         if self._cur_episode > 1:
diff --git a/homeassistant/components/demo/vacuum.py b/homeassistant/components/demo/vacuum.py
index 015e6b8ca6f..5426c61fa52 100644
--- a/homeassistant/components/demo/vacuum.py
+++ b/homeassistant/components/demo/vacuum.py
@@ -106,10 +106,12 @@ class DemoVacuum(VacuumEntity):
 
     _attr_should_poll = False
 
-    def __init__(self, name: str, supported_features: int) -> None:
+    def __init__(
+        self, name: str, supported_features: VacuumEntityFeature | int
+    ) -> None:
         """Initialize the vacuum."""
         self._attr_name = name
-        self._supported_features = supported_features
+        self._attr_supported_features = supported_features
         self._state = False
         self._status = "Charging"
         self._fan_speed = FAN_SPEEDS[1]
@@ -146,11 +148,6 @@ class DemoVacuum(VacuumEntity):
         """Return device state attributes."""
         return {ATTR_CLEANED_AREA: round(self._cleaned_area, 2)}
 
-    @property
-    def supported_features(self) -> int:
-        """Flag supported features."""
-        return self._supported_features
-
     def turn_on(self, **kwargs: Any) -> None:
         """Turn the vacuum on."""
         if self.supported_features & VacuumEntityFeature.TURN_ON == 0:
@@ -251,21 +248,16 @@ class StateDemoVacuum(StateVacuumEntity):
     """Representation of a demo vacuum supporting states."""
 
     _attr_should_poll = False
+    _attr_supported_features = SUPPORT_STATE_SERVICES
 
     def __init__(self, name: str) -> None:
         """Initialize the vacuum."""
         self._attr_name = name
-        self._supported_features = SUPPORT_STATE_SERVICES
         self._state = STATE_DOCKED
         self._fan_speed = FAN_SPEEDS[1]
         self._cleaned_area: float = 0
         self._battery_level = 100
 
-    @property
-    def supported_features(self) -> int:
-        """Flag supported features."""
-        return self._supported_features
-
     @property
     def state(self) -> str:
         """Return the current state of the vacuum."""
diff --git a/homeassistant/components/demo/water_heater.py b/homeassistant/components/demo/water_heater.py
index 322abb0038b..1fc164d5046 100644
--- a/homeassistant/components/demo/water_heater.py
+++ b/homeassistant/components/demo/water_heater.py
@@ -61,18 +61,11 @@ class DemoWaterHeater(WaterHeaterEntity):
         """Initialize the water_heater device."""
         self._attr_name = name
         if target_temperature is not None:
-            self._attr_supported_features = (
-                self._attr_supported_features
-                | WaterHeaterEntityFeature.TARGET_TEMPERATURE
-            )
+            self._attr_supported_features |= WaterHeaterEntityFeature.TARGET_TEMPERATURE
         if away is not None:
-            self._attr_supported_features = (
-                self._attr_supported_features | WaterHeaterEntityFeature.AWAY_MODE
-            )
+            self._attr_supported_features |= WaterHeaterEntityFeature.AWAY_MODE
         if current_operation is not None:
-            self._attr_supported_features = (
-                self._attr_supported_features | WaterHeaterEntityFeature.OPERATION_MODE
-            )
+            self._attr_supported_features |= WaterHeaterEntityFeature.OPERATION_MODE
         self._attr_target_temperature = target_temperature
         self._attr_temperature_unit = unit_of_measurement
         self._attr_is_away_mode_on = away
diff --git a/tests/components/media_player/test_init.py b/tests/components/media_player/test_init.py
index 22206133fca..6c2ebda023a 100644
--- a/tests/components/media_player/test_init.py
+++ b/tests/components/media_player/test_init.py
@@ -136,7 +136,7 @@ async def test_media_browse(hass, hass_ws_client):
     client = await hass_ws_client(hass)
 
     with patch(
-        "homeassistant.components.demo.media_player.YOUTUBE_PLAYER_SUPPORT",
+        "homeassistant.components.demo.media_player.MediaPlayerEntity.supported_features",
         MediaPlayerEntityFeature.BROWSE_MEDIA,
     ), patch(
         "homeassistant.components.media_player.MediaPlayerEntity.async_browse_media",
@@ -179,7 +179,7 @@ async def test_media_browse(hass, hass_ws_client):
     assert mock_browse_media.mock_calls[0][1] == ("album", "abcd")
 
     with patch(
-        "homeassistant.components.demo.media_player.YOUTUBE_PLAYER_SUPPORT",
+        "homeassistant.components.demo.media_player.MediaPlayerEntity.supported_features",
         MediaPlayerEntityFeature.BROWSE_MEDIA,
     ), patch(
         "homeassistant.components.media_player.MediaPlayerEntity.async_browse_media",
@@ -210,7 +210,7 @@ async def test_group_members_available_when_off(hass):
 
     # Fake group support for DemoYoutubePlayer
     with patch(
-        "homeassistant.components.demo.media_player.YOUTUBE_PLAYER_SUPPORT",
+        "homeassistant.components.demo.media_player.MediaPlayerEntity.supported_features",
         MediaPlayerEntityFeature.GROUPING | MediaPlayerEntityFeature.TURN_OFF,
     ):
         await hass.services.async_call(