diff --git a/tests/components/roku/__init__.py b/tests/components/roku/__init__.py index fe3ef215524..8f7e01a1ed5 100644 --- a/tests/components/roku/__init__.py +++ b/tests/components/roku/__init__.py @@ -2,8 +2,13 @@ from ipaddress import ip_address +from rokuecp import Device as RokuDevice + from homeassistant.components import ssdp, zeroconf from homeassistant.components.ssdp import ATTR_UPNP_FRIENDLY_NAME, ATTR_UPNP_SERIAL +from homeassistant.core import HomeAssistant + +from tests.common import MockConfigEntry NAME = "Roku 3" NAME_ROKUTV = '58" Onn Roku TV' @@ -36,3 +41,16 @@ MOCK_HOMEKIT_DISCOVERY_INFO = zeroconf.ZeroconfServiceInfo( }, type="mock_type", ) + + +async def setup_integration( + hass: HomeAssistant, config_entry: MockConfigEntry, device: RokuDevice +) -> None: + """Fixture for setting up the component.""" + config_entry.add_to_hass(hass) + hass.config_entries.async_update_entry( + config_entry, unique_id=device.info.serial_number + ) + + await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() diff --git a/tests/components/roku/conftest.py b/tests/components/roku/conftest.py index 7ac332a1a6c..12787e1cdd2 100644 --- a/tests/components/roku/conftest.py +++ b/tests/components/roku/conftest.py @@ -1,7 +1,6 @@ """Fixtures for Roku integration tests.""" from collections.abc import Generator -import json from unittest.mock import MagicMock, patch import pytest @@ -11,7 +10,7 @@ from homeassistant.components.roku.const import DOMAIN from homeassistant.const import CONF_HOST from homeassistant.core import HomeAssistant -from tests.common import MockConfigEntry, load_fixture +from tests.common import MockConfigEntry, load_json_object_fixture def app_icon_url(*args, **kwargs): @@ -43,11 +42,11 @@ async def mock_device( request: pytest.FixtureRequest, ) -> RokuDevice: """Return the mocked roku device.""" - fixture: str = "roku/roku3.json" + fixture: str = "roku3" if hasattr(request, "param") and request.param: fixture = request.param - return RokuDevice(json.loads(load_fixture(fixture))) + return RokuDevice(load_json_object_fixture(f"{fixture}.json", DOMAIN)) @pytest.fixture diff --git a/tests/components/roku/snapshots/test_binary_sensor.ambr b/tests/components/roku/snapshots/test_binary_sensor.ambr new file mode 100644 index 00000000000..3a6107ff973 --- /dev/null +++ b/tests/components/roku/snapshots/test_binary_sensor.ambr @@ -0,0 +1,369 @@ +# serializer version: 1 +# name: test_entities[roku3][binary_sensor.my_roku_3_headphones_connected-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': None, + 'entity_id': 'binary_sensor.my_roku_3_headphones_connected', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Headphones connected', + 'platform': 'roku', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'headphones_connected', + 'unique_id': '1GU48T017973_headphones_connected', + 'unit_of_measurement': None, + }) +# --- +# name: test_entities[roku3][binary_sensor.my_roku_3_headphones_connected-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'My Roku 3 Headphones connected', + }), + 'context': , + 'entity_id': 'binary_sensor.my_roku_3_headphones_connected', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'off', + }) +# --- +# name: test_entities[roku3][binary_sensor.my_roku_3_supports_airplay-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.my_roku_3_supports_airplay', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Supports AirPlay', + 'platform': 'roku', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'supports_airplay', + 'unique_id': '1GU48T017973_supports_airplay', + 'unit_of_measurement': None, + }) +# --- +# name: test_entities[roku3][binary_sensor.my_roku_3_supports_airplay-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'My Roku 3 Supports AirPlay', + }), + 'context': , + 'entity_id': 'binary_sensor.my_roku_3_supports_airplay', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'off', + }) +# --- +# name: test_entities[roku3][binary_sensor.my_roku_3_supports_ethernet-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.my_roku_3_supports_ethernet', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Supports ethernet', + 'platform': 'roku', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'supports_ethernet', + 'unique_id': '1GU48T017973_supports_ethernet', + 'unit_of_measurement': None, + }) +# --- +# name: test_entities[roku3][binary_sensor.my_roku_3_supports_ethernet-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'My Roku 3 Supports ethernet', + }), + 'context': , + 'entity_id': 'binary_sensor.my_roku_3_supports_ethernet', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entities[roku3][binary_sensor.my_roku_3_supports_find_remote-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.my_roku_3_supports_find_remote', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Supports find remote', + 'platform': 'roku', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'supports_find_remote', + 'unique_id': '1GU48T017973_supports_find_remote', + 'unit_of_measurement': None, + }) +# --- +# name: test_entities[roku3][binary_sensor.my_roku_3_supports_find_remote-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'My Roku 3 Supports find remote', + }), + 'context': , + 'entity_id': 'binary_sensor.my_roku_3_supports_find_remote', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'off', + }) +# --- +# name: test_entities[rokutv-7820x][binary_sensor.58_onn_roku_tv_headphones_connected-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': None, + 'entity_id': 'binary_sensor.58_onn_roku_tv_headphones_connected', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Headphones connected', + 'platform': 'roku', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'headphones_connected', + 'unique_id': 'YN00H5555555_headphones_connected', + 'unit_of_measurement': None, + }) +# --- +# name: test_entities[rokutv-7820x][binary_sensor.58_onn_roku_tv_headphones_connected-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': '58" Onn Roku TV Headphones connected', + }), + 'context': , + 'entity_id': 'binary_sensor.58_onn_roku_tv_headphones_connected', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'off', + }) +# --- +# name: test_entities[rokutv-7820x][binary_sensor.58_onn_roku_tv_supports_airplay-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.58_onn_roku_tv_supports_airplay', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Supports AirPlay', + 'platform': 'roku', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'supports_airplay', + 'unique_id': 'YN00H5555555_supports_airplay', + 'unit_of_measurement': None, + }) +# --- +# name: test_entities[rokutv-7820x][binary_sensor.58_onn_roku_tv_supports_airplay-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': '58" Onn Roku TV Supports AirPlay', + }), + 'context': , + 'entity_id': 'binary_sensor.58_onn_roku_tv_supports_airplay', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entities[rokutv-7820x][binary_sensor.58_onn_roku_tv_supports_ethernet-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.58_onn_roku_tv_supports_ethernet', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Supports ethernet', + 'platform': 'roku', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'supports_ethernet', + 'unique_id': 'YN00H5555555_supports_ethernet', + 'unit_of_measurement': None, + }) +# --- +# name: test_entities[rokutv-7820x][binary_sensor.58_onn_roku_tv_supports_ethernet-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': '58" Onn Roku TV Supports ethernet', + }), + 'context': , + 'entity_id': 'binary_sensor.58_onn_roku_tv_supports_ethernet', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entities[rokutv-7820x][binary_sensor.58_onn_roku_tv_supports_find_remote-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'binary_sensor', + 'entity_category': , + 'entity_id': 'binary_sensor.58_onn_roku_tv_supports_find_remote', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Supports find remote', + 'platform': 'roku', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'supports_find_remote', + 'unique_id': 'YN00H5555555_supports_find_remote', + 'unit_of_measurement': None, + }) +# --- +# name: test_entities[rokutv-7820x][binary_sensor.58_onn_roku_tv_supports_find_remote-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': '58" Onn Roku TV Supports find remote', + }), + 'context': , + 'entity_id': 'binary_sensor.58_onn_roku_tv_supports_find_remote', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- diff --git a/tests/components/roku/snapshots/test_media_player.ambr b/tests/components/roku/snapshots/test_media_player.ambr new file mode 100644 index 00000000000..8ec76b9637f --- /dev/null +++ b/tests/components/roku/snapshots/test_media_player.ambr @@ -0,0 +1,538 @@ +# serializer version: 1 +# name: test_entities[roku3-app][media_player.my_roku_3-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'source_list': list([ + 'Home', + 'Amazon Video on Demand', + 'Free FrameChannel Service', + 'MLB.TV®', + 'Mediafly', + 'Netflix', + 'Pandora', + "Pluto TV - It's Free TV", + 'Roku Channel Store', + ]), + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'media_player', + 'entity_category': None, + 'entity_id': 'media_player.my_roku_3', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'roku', + 'previous_unique_id': None, + 'supported_features': , + 'translation_key': None, + 'unique_id': '1GU48T017973', + 'unit_of_measurement': None, + }) +# --- +# name: test_entities[roku3-app][media_player.my_roku_3-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'app_id': '12', + 'app_name': 'Netflix', + 'device_class': 'receiver', + 'entity_picture': '/api/media_player_proxy/media_player.my_roku_3?token=ed44071fe209b5b8ee2390ef473fa7540ff125ff441441dbb0026f7cec87e224&cache=2cab7007c60e13ef', + 'friendly_name': 'My Roku 3', + 'media_content_type': , + 'source': 'Netflix', + 'source_list': list([ + 'Home', + 'Amazon Video on Demand', + 'Free FrameChannel Service', + 'MLB.TV®', + 'Mediafly', + 'Netflix', + 'Pandora', + "Pluto TV - It's Free TV", + 'Roku Channel Store', + ]), + 'supported_features': , + }), + 'context': , + 'entity_id': 'media_player.my_roku_3', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- +# name: test_entities[roku3-idle][media_player.my_roku_3-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'source_list': list([ + 'Home', + 'Amazon Video on Demand', + 'Free FrameChannel Service', + 'MLB.TV®', + 'Mediafly', + 'Netflix', + 'Pandora', + "Pluto TV - It's Free TV", + 'Roku Channel Store', + ]), + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'media_player', + 'entity_category': None, + 'entity_id': 'media_player.my_roku_3', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'roku', + 'previous_unique_id': None, + 'supported_features': , + 'translation_key': None, + 'unique_id': '1GU48T017973', + 'unit_of_measurement': None, + }) +# --- +# name: test_entities[roku3-idle][media_player.my_roku_3-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'app_name': 'Roku', + 'device_class': 'receiver', + 'friendly_name': 'My Roku 3', + 'source': 'Roku', + 'source_list': list([ + 'Home', + 'Amazon Video on Demand', + 'Free FrameChannel Service', + 'MLB.TV®', + 'Mediafly', + 'Netflix', + 'Pandora', + "Pluto TV - It's Free TV", + 'Roku Channel Store', + ]), + 'supported_features': , + }), + 'context': , + 'entity_id': 'media_player.my_roku_3', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'standby', + }) +# --- +# name: test_entities[roku3-media-paused][media_player.my_roku_3-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'source_list': list([ + 'Home', + 'Amazon Video on Demand', + 'Free FrameChannel Service', + 'MLB.TV®', + 'Mediafly', + 'Netflix', + 'Pandora', + "Pluto TV - It's Free TV", + 'Roku Channel Store', + ]), + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'media_player', + 'entity_category': None, + 'entity_id': 'media_player.my_roku_3', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'roku', + 'previous_unique_id': None, + 'supported_features': , + 'translation_key': None, + 'unique_id': '1GU48T017973', + 'unit_of_measurement': None, + }) +# --- +# name: test_entities[roku3-media-paused][media_player.my_roku_3-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'app_id': '74519', + 'app_name': "Pluto TV - It's Free TV", + 'device_class': 'receiver', + 'entity_picture': '/api/media_player_proxy/media_player.my_roku_3?token=fc68bc359dd5eb6b27813cfa435d46364c52b848985dff874ef6d806a8fb601e&cache=be54f0f123f7d91f', + 'friendly_name': 'My Roku 3', + 'media_content_type': , + 'media_duration': 6496, + 'media_position': 313, + 'media_position_updated_at': datetime.datetime(2024, 12, 20, 4, 46, 23, 278644, tzinfo=datetime.timezone.utc), + 'source': "Pluto TV - It's Free TV", + 'source_list': list([ + 'Home', + 'Amazon Video on Demand', + 'Free FrameChannel Service', + 'MLB.TV®', + 'Mediafly', + 'Netflix', + 'Pandora', + "Pluto TV - It's Free TV", + 'Roku Channel Store', + ]), + 'supported_features': , + }), + 'context': , + 'entity_id': 'media_player.my_roku_3', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'paused', + }) +# --- +# name: test_entities[roku3-media-playing][media_player.my_roku_3-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'source_list': list([ + 'Home', + 'Amazon Video on Demand', + 'Free FrameChannel Service', + 'MLB.TV®', + 'Mediafly', + 'Netflix', + 'Pandora', + "Pluto TV - It's Free TV", + 'Roku Channel Store', + ]), + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'media_player', + 'entity_category': None, + 'entity_id': 'media_player.my_roku_3', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'roku', + 'previous_unique_id': None, + 'supported_features': , + 'translation_key': None, + 'unique_id': '1GU48T017973', + 'unit_of_measurement': None, + }) +# --- +# name: test_entities[roku3-media-playing][media_player.my_roku_3-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'app_id': '74519', + 'app_name': "Pluto TV - It's Free TV", + 'device_class': 'receiver', + 'entity_picture': '/api/media_player_proxy/media_player.my_roku_3?token=6ab003edbdf03f5beab0aacb4ee82e6e0d178c80b56d74edd7f348fbc3882bf6&cache=be54f0f123f7d91f', + 'friendly_name': 'My Roku 3', + 'media_content_type': , + 'media_duration': 6496, + 'media_position': 38, + 'media_position_updated_at': datetime.datetime(2024, 12, 20, 4, 46, 23, 323203, tzinfo=datetime.timezone.utc), + 'source': "Pluto TV - It's Free TV", + 'source_list': list([ + 'Home', + 'Amazon Video on Demand', + 'Free FrameChannel Service', + 'MLB.TV®', + 'Mediafly', + 'Netflix', + 'Pandora', + "Pluto TV - It's Free TV", + 'Roku Channel Store', + ]), + 'supported_features': , + }), + 'context': , + 'entity_id': 'media_player.my_roku_3', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'playing', + }) +# --- +# name: test_entities[roku3-screensaver][media_player.my_roku_3-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'source_list': list([ + 'Home', + 'Amazon Video on Demand', + 'Free FrameChannel Service', + 'MLB.TV®', + 'Mediafly', + 'Netflix', + 'Pandora', + "Pluto TV - It's Free TV", + 'Roku Channel Store', + ]), + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'media_player', + 'entity_category': None, + 'entity_id': 'media_player.my_roku_3', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'roku', + 'previous_unique_id': None, + 'supported_features': , + 'translation_key': None, + 'unique_id': '1GU48T017973', + 'unit_of_measurement': None, + }) +# --- +# name: test_entities[roku3-screensaver][media_player.my_roku_3-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'app_name': 'Roku', + 'device_class': 'receiver', + 'friendly_name': 'My Roku 3', + 'source': 'Roku', + 'source_list': list([ + 'Home', + 'Amazon Video on Demand', + 'Free FrameChannel Service', + 'MLB.TV®', + 'Mediafly', + 'Netflix', + 'Pandora', + "Pluto TV - It's Free TV", + 'Roku Channel Store', + ]), + 'supported_features': , + }), + 'context': , + 'entity_id': 'media_player.my_roku_3', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'idle', + }) +# --- +# name: test_entities[roku3][media_player.my_roku_3-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'source_list': list([ + 'Home', + 'Amazon Video on Demand', + 'Free FrameChannel Service', + 'MLB.TV®', + 'Mediafly', + 'Netflix', + 'Pandora', + "Pluto TV - It's Free TV", + 'Roku Channel Store', + ]), + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'media_player', + 'entity_category': None, + 'entity_id': 'media_player.my_roku_3', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'roku', + 'previous_unique_id': None, + 'supported_features': , + 'translation_key': None, + 'unique_id': '1GU48T017973', + 'unit_of_measurement': None, + }) +# --- +# name: test_entities[roku3][media_player.my_roku_3-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'app_name': 'Roku', + 'device_class': 'receiver', + 'friendly_name': 'My Roku 3', + 'source': 'Roku', + 'source_list': list([ + 'Home', + 'Amazon Video on Demand', + 'Free FrameChannel Service', + 'MLB.TV®', + 'Mediafly', + 'Netflix', + 'Pandora', + "Pluto TV - It's Free TV", + 'Roku Channel Store', + ]), + 'supported_features': , + }), + 'context': , + 'entity_id': 'media_player.my_roku_3', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'idle', + }) +# --- +# name: test_entities[rokutv-7820x][media_player.58_onn_roku_tv-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'source_list': list([ + 'Home', + 'Amazon Video on Demand', + 'Antenna TV', + 'Blu-ray player', + 'Free FrameChannel Service', + 'MLB.TV®', + 'Mediafly', + 'Netflix', + 'Pandora', + "Pluto TV - It's Free TV", + 'Roku Channel Store', + 'Satellite TV', + ]), + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'media_player', + 'entity_category': None, + 'entity_id': 'media_player.58_onn_roku_tv', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': None, + 'platform': 'roku', + 'previous_unique_id': None, + 'supported_features': , + 'translation_key': None, + 'unique_id': 'YN00H5555555', + 'unit_of_measurement': None, + }) +# --- +# name: test_entities[rokutv-7820x][media_player.58_onn_roku_tv-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'app_id': 'tvinput.dtv', + 'app_name': 'Antenna TV', + 'device_class': 'tv', + 'entity_picture': '/api/media_player_proxy/media_player.58_onn_roku_tv?token=98a23df6bbb5d177ad741987614efa5130764520f97c4afac6a876eff0a8d1a6&cache=545b6ca11153d83a', + 'friendly_name': '58" Onn Roku TV', + 'media_channel': 'getTV (14.3)', + 'media_content_type': , + 'media_title': 'Airwolf', + 'source': 'Antenna TV', + 'source_list': list([ + 'Home', + 'Amazon Video on Demand', + 'Antenna TV', + 'Blu-ray player', + 'Free FrameChannel Service', + 'MLB.TV®', + 'Mediafly', + 'Netflix', + 'Pandora', + "Pluto TV - It's Free TV", + 'Roku Channel Store', + 'Satellite TV', + ]), + 'supported_features': , + }), + 'context': , + 'entity_id': 'media_player.58_onn_roku_tv', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'on', + }) +# --- diff --git a/tests/components/roku/snapshots/test_select.ambr b/tests/components/roku/snapshots/test_select.ambr new file mode 100644 index 00000000000..f6d515ee409 --- /dev/null +++ b/tests/components/roku/snapshots/test_select.ambr @@ -0,0 +1,204 @@ +# serializer version: 1 +# name: test_entities[roku3][select.my_roku_3_application-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'options': list([ + 'Home', + 'Amazon Video on Demand', + 'Free FrameChannel Service', + 'MLB.TV®', + 'Mediafly', + 'Netflix', + 'Pandora', + "Pluto TV - It's Free TV", + 'Roku Channel Store', + ]), + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'select', + 'entity_category': None, + 'entity_id': 'select.my_roku_3_application', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Application', + 'platform': 'roku', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'application', + 'unique_id': '1GU48T017973_application', + 'unit_of_measurement': None, + }) +# --- +# name: test_entities[roku3][select.my_roku_3_application-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'My Roku 3 Application', + 'options': list([ + 'Home', + 'Amazon Video on Demand', + 'Free FrameChannel Service', + 'MLB.TV®', + 'Mediafly', + 'Netflix', + 'Pandora', + "Pluto TV - It's Free TV", + 'Roku Channel Store', + ]), + }), + 'context': , + 'entity_id': 'select.my_roku_3_application', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'Home', + }) +# --- +# name: test_entities[rokutv-7820x][select.58_onn_roku_tv_application-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'options': list([ + 'Home', + 'Amazon Video on Demand', + 'Antenna TV', + 'Blu-ray player', + 'Free FrameChannel Service', + 'MLB.TV®', + 'Mediafly', + 'Netflix', + 'Pandora', + "Pluto TV - It's Free TV", + 'Roku Channel Store', + 'Satellite TV', + ]), + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'select', + 'entity_category': None, + 'entity_id': 'select.58_onn_roku_tv_application', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Application', + 'platform': 'roku', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'application', + 'unique_id': 'YN00H5555555_application', + 'unit_of_measurement': None, + }) +# --- +# name: test_entities[rokutv-7820x][select.58_onn_roku_tv_application-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': '58" Onn Roku TV Application', + 'options': list([ + 'Home', + 'Amazon Video on Demand', + 'Antenna TV', + 'Blu-ray player', + 'Free FrameChannel Service', + 'MLB.TV®', + 'Mediafly', + 'Netflix', + 'Pandora', + "Pluto TV - It's Free TV", + 'Roku Channel Store', + 'Satellite TV', + ]), + }), + 'context': , + 'entity_id': 'select.58_onn_roku_tv_application', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'Antenna TV', + }) +# --- +# name: test_entities[rokutv-7820x][select.58_onn_roku_tv_channel-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'options': list([ + '99.1', + 'QVC (1.3)', + 'WhatsOn (1.1)', + 'getTV (14.3)', + ]), + }), + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'select', + 'entity_category': None, + 'entity_id': 'select.58_onn_roku_tv_channel', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Channel', + 'platform': 'roku', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'channel', + 'unique_id': 'YN00H5555555_channel', + 'unit_of_measurement': None, + }) +# --- +# name: test_entities[rokutv-7820x][select.58_onn_roku_tv_channel-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': '58" Onn Roku TV Channel', + 'options': list([ + '99.1', + 'QVC (1.3)', + 'WhatsOn (1.1)', + 'getTV (14.3)', + ]), + }), + 'context': , + 'entity_id': 'select.58_onn_roku_tv_channel', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'getTV (14.3)', + }) +# --- diff --git a/tests/components/roku/snapshots/test_sensor.ambr b/tests/components/roku/snapshots/test_sensor.ambr new file mode 100644 index 00000000000..493b0540a05 --- /dev/null +++ b/tests/components/roku/snapshots/test_sensor.ambr @@ -0,0 +1,185 @@ +# serializer version: 1 +# name: test_entities[roku3][sensor.my_roku_3_active_app-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.my_roku_3_active_app', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Active app', + 'platform': 'roku', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'active_app', + 'unique_id': '1GU48T017973_active_app', + 'unit_of_measurement': None, + }) +# --- +# name: test_entities[roku3][sensor.my_roku_3_active_app-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'My Roku 3 Active app', + }), + 'context': , + 'entity_id': 'sensor.my_roku_3_active_app', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'Roku', + }) +# --- +# name: test_entities[roku3][sensor.my_roku_3_active_app_id-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.my_roku_3_active_app_id', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Active app ID', + 'platform': 'roku', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'active_app_id', + 'unique_id': '1GU48T017973_active_app_id', + 'unit_of_measurement': None, + }) +# --- +# name: test_entities[roku3][sensor.my_roku_3_active_app_id-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': 'My Roku 3 Active app ID', + }), + 'context': , + 'entity_id': 'sensor.my_roku_3_active_app_id', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_entities[rokutv-7820x][sensor.58_onn_roku_tv_active_app-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.58_onn_roku_tv_active_app', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Active app', + 'platform': 'roku', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'active_app', + 'unique_id': 'YN00H5555555_active_app', + 'unit_of_measurement': None, + }) +# --- +# name: test_entities[rokutv-7820x][sensor.58_onn_roku_tv_active_app-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': '58" Onn Roku TV Active app', + }), + 'context': , + 'entity_id': 'sensor.58_onn_roku_tv_active_app', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'Antenna TV', + }) +# --- +# name: test_entities[rokutv-7820x][sensor.58_onn_roku_tv_active_app_id-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': None, + 'config_entry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'sensor', + 'entity_category': , + 'entity_id': 'sensor.58_onn_roku_tv_active_app_id', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': None, + 'original_icon': None, + 'original_name': 'Active app ID', + 'platform': 'roku', + 'previous_unique_id': None, + 'supported_features': 0, + 'translation_key': 'active_app_id', + 'unique_id': 'YN00H5555555_active_app_id', + 'unit_of_measurement': None, + }) +# --- +# name: test_entities[rokutv-7820x][sensor.58_onn_roku_tv_active_app_id-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'friendly_name': '58" Onn Roku TV Active app ID', + }), + 'context': , + 'entity_id': 'sensor.58_onn_roku_tv_active_app_id', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'tvinput.dtv', + }) +# --- diff --git a/tests/components/roku/test_binary_sensor.py b/tests/components/roku/test_binary_sensor.py index ad27a857101..4c990eca95b 100644 --- a/tests/components/roku/test_binary_sensor.py +++ b/tests/components/roku/test_binary_sensor.py @@ -1,161 +1,31 @@ """Tests for the sensors provided by the Roku integration.""" -from unittest.mock import MagicMock +from unittest.mock import MagicMock, patch import pytest from rokuecp import Device as RokuDevice +from syrupy import SnapshotAssertion -from homeassistant.components.binary_sensor import STATE_OFF, STATE_ON -from homeassistant.components.roku.const import DOMAIN -from homeassistant.const import ATTR_DEVICE_CLASS, ATTR_FRIENDLY_NAME, EntityCategory +from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers import device_registry as dr, entity_registry as er +from homeassistant.helpers import entity_registry as er -from . import UPNP_SERIAL +from . import setup_integration -from tests.common import MockConfigEntry +from tests.common import MockConfigEntry, snapshot_platform -async def test_roku_binary_sensors( +@pytest.mark.parametrize("mock_device", ["roku3", "rokutv-7820x"], indirect=True) +async def test_entities( hass: HomeAssistant, - device_registry: dr.DeviceRegistry, + snapshot: SnapshotAssertion, entity_registry: er.EntityRegistry, - init_integration: MockConfigEntry, -) -> None: - """Test the Roku binary sensors.""" - state = hass.states.get("binary_sensor.my_roku_3_headphones_connected") - entry = entity_registry.async_get("binary_sensor.my_roku_3_headphones_connected") - assert entry - assert state - assert entry.unique_id == f"{UPNP_SERIAL}_headphones_connected" - assert entry.entity_category is None - assert state.state == STATE_OFF - assert state.attributes.get(ATTR_FRIENDLY_NAME) == "My Roku 3 Headphones connected" - assert ATTR_DEVICE_CLASS not in state.attributes - - state = hass.states.get("binary_sensor.my_roku_3_supports_airplay") - entry = entity_registry.async_get("binary_sensor.my_roku_3_supports_airplay") - assert entry - assert state - assert entry.unique_id == f"{UPNP_SERIAL}_supports_airplay" - assert entry.entity_category == EntityCategory.DIAGNOSTIC - assert state.state == STATE_OFF - assert state.attributes.get(ATTR_FRIENDLY_NAME) == "My Roku 3 Supports AirPlay" - assert ATTR_DEVICE_CLASS not in state.attributes - - state = hass.states.get("binary_sensor.my_roku_3_supports_ethernet") - entry = entity_registry.async_get("binary_sensor.my_roku_3_supports_ethernet") - assert entry - assert state - assert entry.unique_id == f"{UPNP_SERIAL}_supports_ethernet" - assert entry.entity_category == EntityCategory.DIAGNOSTIC - assert state.state == STATE_ON - assert state.attributes.get(ATTR_FRIENDLY_NAME) == "My Roku 3 Supports ethernet" - assert ATTR_DEVICE_CLASS not in state.attributes - - state = hass.states.get("binary_sensor.my_roku_3_supports_find_remote") - entry = entity_registry.async_get("binary_sensor.my_roku_3_supports_find_remote") - assert entry - assert state - assert entry.unique_id == f"{UPNP_SERIAL}_supports_find_remote" - assert entry.entity_category == EntityCategory.DIAGNOSTIC - assert state.state == STATE_OFF - assert state.attributes.get(ATTR_FRIENDLY_NAME) == "My Roku 3 Supports find remote" - assert ATTR_DEVICE_CLASS not in state.attributes - - assert entry.device_id - device_entry = device_registry.async_get(entry.device_id) - assert device_entry - assert device_entry.identifiers == {(DOMAIN, UPNP_SERIAL)} - assert device_entry.connections == { - (dr.CONNECTION_NETWORK_MAC, "b0:a7:37:96:4d:fb"), - (dr.CONNECTION_NETWORK_MAC, "b0:a7:37:96:4d:fa"), - } - assert device_entry.manufacturer == "Roku" - assert device_entry.model == "Roku 3" - assert device_entry.name == "My Roku 3" - assert device_entry.entry_type is None - assert device_entry.sw_version == "7.5.0" - assert device_entry.hw_version == "4200X" - assert device_entry.suggested_area is None - - -@pytest.mark.parametrize("mock_device", ["roku/rokutv-7820x.json"], indirect=True) -async def test_rokutv_binary_sensors( - hass: HomeAssistant, - device_registry: dr.DeviceRegistry, - entity_registry: er.EntityRegistry, - init_integration: MockConfigEntry, + mock_config_entry: MockConfigEntry, mock_device: RokuDevice, mock_roku: MagicMock, ) -> None: - """Test the Roku binary sensors.""" - state = hass.states.get("binary_sensor.58_onn_roku_tv_headphones_connected") - entry = entity_registry.async_get( - "binary_sensor.58_onn_roku_tv_headphones_connected" - ) - assert entry - assert state - assert entry.unique_id == "YN00H5555555_headphones_connected" - assert entry.entity_category is None - assert state.state == STATE_OFF - assert ( - state.attributes.get(ATTR_FRIENDLY_NAME) - == '58" Onn Roku TV Headphones connected' - ) - assert ATTR_DEVICE_CLASS not in state.attributes + """Test the Roku binary sensor entities.""" + with patch("homeassistant.components.roku.PLATFORMS", [Platform.BINARY_SENSOR]): + await setup_integration(hass, mock_config_entry, mock_device) - state = hass.states.get("binary_sensor.58_onn_roku_tv_supports_airplay") - entry = entity_registry.async_get("binary_sensor.58_onn_roku_tv_supports_airplay") - assert entry - assert state - assert entry.unique_id == "YN00H5555555_supports_airplay" - assert entry.entity_category == EntityCategory.DIAGNOSTIC - assert state.state == STATE_ON - assert ( - state.attributes.get(ATTR_FRIENDLY_NAME) == '58" Onn Roku TV Supports AirPlay' - ) - assert ATTR_DEVICE_CLASS not in state.attributes - - state = hass.states.get("binary_sensor.58_onn_roku_tv_supports_ethernet") - entry = entity_registry.async_get("binary_sensor.58_onn_roku_tv_supports_ethernet") - assert entry - assert state - assert entry.unique_id == "YN00H5555555_supports_ethernet" - assert entry.entity_category == EntityCategory.DIAGNOSTIC - assert state.state == STATE_ON - assert ( - state.attributes.get(ATTR_FRIENDLY_NAME) == '58" Onn Roku TV Supports ethernet' - ) - assert ATTR_DEVICE_CLASS not in state.attributes - - state = hass.states.get("binary_sensor.58_onn_roku_tv_supports_find_remote") - entry = entity_registry.async_get( - "binary_sensor.58_onn_roku_tv_supports_find_remote" - ) - assert entry - assert state - assert entry.unique_id == "YN00H5555555_supports_find_remote" - assert entry.entity_category == EntityCategory.DIAGNOSTIC - assert state.state == STATE_ON - assert ( - state.attributes.get(ATTR_FRIENDLY_NAME) - == '58" Onn Roku TV Supports find remote' - ) - assert ATTR_DEVICE_CLASS not in state.attributes - - assert entry.device_id - device_entry = device_registry.async_get(entry.device_id) - assert device_entry - assert device_entry.identifiers == {(DOMAIN, "YN00H5555555")} - assert device_entry.connections == { - (dr.CONNECTION_NETWORK_MAC, "d8:13:99:f8:b0:c6"), - (dr.CONNECTION_NETWORK_MAC, "d4:3a:2e:07:fd:cb"), - } - assert device_entry.manufacturer == "Onn" - assert device_entry.model == "100005844" - assert device_entry.name == '58" Onn Roku TV' - assert device_entry.entry_type is None - assert device_entry.sw_version == "9.2.0" - assert device_entry.hw_version == "7820X" - assert device_entry.suggested_area == "Living room" + await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id) diff --git a/tests/components/roku/test_config_flow.py b/tests/components/roku/test_config_flow.py index 57ddf5d51a6..09f7994a33b 100644 --- a/tests/components/roku/test_config_flow.py +++ b/tests/components/roku/test_config_flow.py @@ -163,7 +163,7 @@ async def test_homekit_unknown_error( assert result["reason"] == "unknown" -@pytest.mark.parametrize("mock_device", ["roku/rokutv-7820x.json"], indirect=True) +@pytest.mark.parametrize("mock_device", ["rokutv-7820x"], indirect=True) async def test_homekit_discovery( hass: HomeAssistant, mock_roku_config_flow: MagicMock, diff --git a/tests/components/roku/test_media_player.py b/tests/components/roku/test_media_player.py index 5f8a41d16ac..d3dd81641fa 100644 --- a/tests/components/roku/test_media_player.py +++ b/tests/components/roku/test_media_player.py @@ -5,26 +5,24 @@ from unittest.mock import MagicMock, patch from freezegun.api import FrozenDateTimeFactory import pytest -from rokuecp import RokuConnectionError, RokuConnectionTimeoutError, RokuError +from rokuecp import ( + Device as RokuDevice, + RokuConnectionError, + RokuConnectionTimeoutError, + RokuError, +) +from syrupy import SnapshotAssertion from homeassistant.components.media_player import ( - ATTR_APP_ID, - ATTR_APP_NAME, ATTR_INPUT_SOURCE, - ATTR_MEDIA_CHANNEL, ATTR_MEDIA_CONTENT_ID, ATTR_MEDIA_CONTENT_TYPE, - ATTR_MEDIA_DURATION, ATTR_MEDIA_EXTRA, - ATTR_MEDIA_POSITION, - ATTR_MEDIA_TITLE, ATTR_MEDIA_VOLUME_MUTED, DOMAIN as MP_DOMAIN, SERVICE_PLAY_MEDIA, SERVICE_SELECT_SOURCE, MediaClass, - MediaPlayerDeviceClass, - MediaPlayerEntityFeature, MediaType, ) from homeassistant.components.roku.const import ( @@ -52,101 +50,50 @@ from homeassistant.const import ( SERVICE_VOLUME_MUTE, SERVICE_VOLUME_UP, STATE_IDLE, - STATE_ON, - STATE_PAUSED, - STATE_PLAYING, - STATE_STANDBY, STATE_UNAVAILABLE, + Platform, ) from homeassistant.core import HomeAssistant from homeassistant.core_config import async_process_ha_core_config -from homeassistant.helpers import device_registry as dr, entity_registry as er +from homeassistant.helpers import entity_registry as er from homeassistant.setup import async_setup_component from homeassistant.util import dt as dt_util -from tests.common import MockConfigEntry, async_fire_time_changed +from . import setup_integration + +from tests.common import MockConfigEntry, async_fire_time_changed, snapshot_platform from tests.typing import WebSocketGenerator MAIN_ENTITY_ID = f"{MP_DOMAIN}.my_roku_3" TV_ENTITY_ID = f"{MP_DOMAIN}.58_onn_roku_tv" -async def test_setup( +@pytest.mark.parametrize( + "mock_device", + [ + "roku3", + "roku3-idle", + "roku3-app", + "roku3-screensaver", + "roku3-media-paused", + "roku3-media-playing", + "rokutv-7820x", + ], + indirect=True, +) +async def test_entities( hass: HomeAssistant, - device_registry: dr.DeviceRegistry, + snapshot: SnapshotAssertion, entity_registry: er.EntityRegistry, - init_integration: MockConfigEntry, -) -> None: - """Test setup with basic config.""" - state = hass.states.get(MAIN_ENTITY_ID) - entry = entity_registry.async_get(MAIN_ENTITY_ID) - - assert state - assert entry - assert entry.original_device_class is MediaPlayerDeviceClass.RECEIVER - assert entry.unique_id == "1GU48T017973" - - assert entry.device_id - device_entry = device_registry.async_get(entry.device_id) - assert device_entry - assert device_entry.identifiers == {(DOMAIN, "1GU48T017973")} - assert device_entry.connections == { - (dr.CONNECTION_NETWORK_MAC, "b0:a7:37:96:4d:fb"), - (dr.CONNECTION_NETWORK_MAC, "b0:a7:37:96:4d:fa"), - } - assert device_entry.manufacturer == "Roku" - assert device_entry.model == "Roku 3" - assert device_entry.name == "My Roku 3" - assert device_entry.entry_type is None - assert device_entry.sw_version == "7.5.0" - assert device_entry.hw_version == "4200X" - assert device_entry.suggested_area is None - - -@pytest.mark.parametrize("mock_device", ["roku/roku3-idle.json"], indirect=True) -async def test_idle_setup( - hass: HomeAssistant, - init_integration: MockConfigEntry, + mock_config_entry: MockConfigEntry, + mock_device: RokuDevice, mock_roku: MagicMock, ) -> None: - """Test setup with idle device.""" - state = hass.states.get(MAIN_ENTITY_ID) - assert state - assert state.state == STATE_STANDBY + """Test the Roku media player entities.""" + with patch("homeassistant.components.roku.PLATFORMS", [Platform.MEDIA_PLAYER]): + await setup_integration(hass, mock_config_entry, mock_device) - -@pytest.mark.parametrize("mock_device", ["roku/rokutv-7820x.json"], indirect=True) -async def test_tv_setup( - hass: HomeAssistant, - device_registry: dr.DeviceRegistry, - entity_registry: er.EntityRegistry, - init_integration: MockConfigEntry, - mock_roku: MagicMock, -) -> None: - """Test Roku TV setup.""" - state = hass.states.get(TV_ENTITY_ID) - entry = entity_registry.async_get(TV_ENTITY_ID) - - assert state - assert entry - assert entry.original_device_class is MediaPlayerDeviceClass.TV - assert entry.unique_id == "YN00H5555555" - - assert entry.device_id - device_entry = device_registry.async_get(entry.device_id) - assert device_entry - assert device_entry.identifiers == {(DOMAIN, "YN00H5555555")} - assert device_entry.connections == { - (dr.CONNECTION_NETWORK_MAC, "d8:13:99:f8:b0:c6"), - (dr.CONNECTION_NETWORK_MAC, "d4:3a:2e:07:fd:cb"), - } - assert device_entry.manufacturer == "Onn" - assert device_entry.model == "100005844" - assert device_entry.name == '58" Onn Roku TV' - assert device_entry.entry_type is None - assert device_entry.sw_version == "9.2.0" - assert device_entry.hw_version == "7820X" - assert device_entry.suggested_area == "Living room" + await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id) @pytest.mark.parametrize( @@ -183,160 +130,6 @@ async def test_availability( assert hass.states.get(MAIN_ENTITY_ID).state == STATE_IDLE -async def test_supported_features( - hass: HomeAssistant, - init_integration: MockConfigEntry, - mock_roku: MagicMock, -) -> None: - """Test supported features.""" - # Features supported for Rokus - state = hass.states.get(MAIN_ENTITY_ID) - assert ( - state.attributes.get("supported_features") - == MediaPlayerEntityFeature.PREVIOUS_TRACK - | MediaPlayerEntityFeature.NEXT_TRACK - | MediaPlayerEntityFeature.VOLUME_STEP - | MediaPlayerEntityFeature.VOLUME_MUTE - | MediaPlayerEntityFeature.SELECT_SOURCE - | MediaPlayerEntityFeature.PAUSE - | MediaPlayerEntityFeature.PLAY - | MediaPlayerEntityFeature.PLAY_MEDIA - | MediaPlayerEntityFeature.TURN_ON - | MediaPlayerEntityFeature.TURN_OFF - | MediaPlayerEntityFeature.BROWSE_MEDIA - ) - - -@pytest.mark.parametrize("mock_device", ["roku/rokutv-7820x.json"], indirect=True) -async def test_tv_supported_features( - hass: HomeAssistant, - init_integration: MockConfigEntry, - mock_roku: MagicMock, -) -> None: - """Test supported features for Roku TV.""" - state = hass.states.get(TV_ENTITY_ID) - assert state - assert ( - state.attributes.get("supported_features") - == MediaPlayerEntityFeature.PREVIOUS_TRACK - | MediaPlayerEntityFeature.NEXT_TRACK - | MediaPlayerEntityFeature.VOLUME_STEP - | MediaPlayerEntityFeature.VOLUME_MUTE - | MediaPlayerEntityFeature.SELECT_SOURCE - | MediaPlayerEntityFeature.PAUSE - | MediaPlayerEntityFeature.PLAY - | MediaPlayerEntityFeature.PLAY_MEDIA - | MediaPlayerEntityFeature.TURN_ON - | MediaPlayerEntityFeature.TURN_OFF - | MediaPlayerEntityFeature.BROWSE_MEDIA - ) - - -async def test_attributes( - hass: HomeAssistant, init_integration: MockConfigEntry -) -> None: - """Test attributes.""" - state = hass.states.get(MAIN_ENTITY_ID) - assert state - assert state.state == STATE_IDLE - - assert state.attributes.get(ATTR_MEDIA_CONTENT_TYPE) is None - assert state.attributes.get(ATTR_APP_ID) is None - assert state.attributes.get(ATTR_APP_NAME) == "Roku" - assert state.attributes.get(ATTR_INPUT_SOURCE) == "Roku" - - -@pytest.mark.parametrize("mock_device", ["roku/roku3-app.json"], indirect=True) -async def test_attributes_app( - hass: HomeAssistant, - init_integration: MockConfigEntry, - mock_roku: MagicMock, -) -> None: - """Test attributes for app.""" - state = hass.states.get(MAIN_ENTITY_ID) - assert state - assert state.state == STATE_ON - - assert state.attributes.get(ATTR_MEDIA_CONTENT_TYPE) == MediaType.APP - assert state.attributes.get(ATTR_APP_ID) == "12" - assert state.attributes.get(ATTR_APP_NAME) == "Netflix" - assert state.attributes.get(ATTR_INPUT_SOURCE) == "Netflix" - - -@pytest.mark.parametrize( - "mock_device", ["roku/roku3-media-playing.json"], indirect=True -) -async def test_attributes_app_media_playing( - hass: HomeAssistant, - init_integration: MockConfigEntry, - mock_roku: MagicMock, -) -> None: - """Test attributes for app with playing media.""" - state = hass.states.get(MAIN_ENTITY_ID) - assert state - assert state.state == STATE_PLAYING - - assert state.attributes.get(ATTR_MEDIA_CONTENT_TYPE) == MediaType.APP - assert state.attributes.get(ATTR_MEDIA_DURATION) == 6496 - assert state.attributes.get(ATTR_MEDIA_POSITION) == 38 - assert state.attributes.get(ATTR_APP_ID) == "74519" - assert state.attributes.get(ATTR_APP_NAME) == "Pluto TV - It's Free TV" - assert state.attributes.get(ATTR_INPUT_SOURCE) == "Pluto TV - It's Free TV" - - -@pytest.mark.parametrize("mock_device", ["roku/roku3-media-paused.json"], indirect=True) -async def test_attributes_app_media_paused( - hass: HomeAssistant, - init_integration: MockConfigEntry, - mock_roku: MagicMock, -) -> None: - """Test attributes for app with paused media.""" - state = hass.states.get(MAIN_ENTITY_ID) - assert state - assert state.state == STATE_PAUSED - - assert state.attributes.get(ATTR_MEDIA_CONTENT_TYPE) == MediaType.APP - assert state.attributes.get(ATTR_MEDIA_DURATION) == 6496 - assert state.attributes.get(ATTR_MEDIA_POSITION) == 313 - assert state.attributes.get(ATTR_APP_ID) == "74519" - assert state.attributes.get(ATTR_APP_NAME) == "Pluto TV - It's Free TV" - assert state.attributes.get(ATTR_INPUT_SOURCE) == "Pluto TV - It's Free TV" - - -@pytest.mark.parametrize("mock_device", ["roku/roku3-screensaver.json"], indirect=True) -async def test_attributes_screensaver( - hass: HomeAssistant, - init_integration: MockConfigEntry, - mock_roku: MagicMock, -) -> None: - """Test attributes for app with screensaver.""" - state = hass.states.get(MAIN_ENTITY_ID) - assert state - assert state.state == STATE_IDLE - - assert state.attributes.get(ATTR_MEDIA_CONTENT_TYPE) is None - assert state.attributes.get(ATTR_APP_ID) is None - assert state.attributes.get(ATTR_APP_NAME) == "Roku" - assert state.attributes.get(ATTR_INPUT_SOURCE) == "Roku" - - -@pytest.mark.parametrize("mock_device", ["roku/rokutv-7820x.json"], indirect=True) -async def test_tv_attributes( - hass: HomeAssistant, init_integration: MockConfigEntry -) -> None: - """Test attributes for Roku TV.""" - state = hass.states.get(TV_ENTITY_ID) - assert state - assert state.state == STATE_ON - - assert state.attributes.get(ATTR_APP_ID) == "tvinput.dtv" - assert state.attributes.get(ATTR_APP_NAME) == "Antenna TV" - assert state.attributes.get(ATTR_INPUT_SOURCE) == "Antenna TV" - assert state.attributes.get(ATTR_MEDIA_CONTENT_TYPE) == MediaType.CHANNEL - assert state.attributes.get(ATTR_MEDIA_CHANNEL) == "getTV (14.3)" - assert state.attributes.get(ATTR_MEDIA_TITLE) == "Airwolf" - - async def test_services( hass: HomeAssistant, init_integration: MockConfigEntry, @@ -676,7 +469,7 @@ async def test_services_play_media_local_source( ) -@pytest.mark.parametrize("mock_device", ["roku/rokutv-7820x.json"], indirect=True) +@pytest.mark.parametrize("mock_device", ["rokutv-7820x"], indirect=True) async def test_tv_services( hass: HomeAssistant, init_integration: MockConfigEntry, @@ -958,7 +751,7 @@ async def test_media_browse_local_source( ) -@pytest.mark.parametrize("mock_device", ["roku/rokutv-7820x.json"], indirect=True) +@pytest.mark.parametrize("mock_device", ["rokutv-7820x"], indirect=True) async def test_tv_media_browse( hass: HomeAssistant, init_integration, diff --git a/tests/components/roku/test_select.py b/tests/components/roku/test_select.py index 78cd65250f8..bcbc49d7e09 100644 --- a/tests/components/roku/test_select.py +++ b/tests/components/roku/test_select.py @@ -1,71 +1,53 @@ """Tests for the Roku select platform.""" -from unittest.mock import MagicMock +from unittest.mock import MagicMock, patch import pytest from rokuecp import ( - Application, Device as RokuDevice, RokuConnectionError, RokuConnectionTimeoutError, RokuError, ) +from syrupy import SnapshotAssertion -from homeassistant.components.roku.const import DOMAIN -from homeassistant.components.roku.coordinator import SCAN_INTERVAL -from homeassistant.components.select import ( - ATTR_OPTION, - ATTR_OPTIONS, - DOMAIN as SELECT_DOMAIN, -) -from homeassistant.const import ATTR_ENTITY_ID, SERVICE_SELECT_OPTION +from homeassistant.components.select import ATTR_OPTION, DOMAIN as SELECT_DOMAIN +from homeassistant.const import ATTR_ENTITY_ID, SERVICE_SELECT_OPTION, Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import entity_registry as er -import homeassistant.util.dt as dt_util -from tests.common import MockConfigEntry, async_fire_time_changed +from . import setup_integration + +from tests.common import MockConfigEntry, snapshot_platform -async def test_application_state( +@pytest.mark.parametrize("mock_device", ["roku3", "rokutv-7820x"], indirect=True) +@pytest.mark.usefixtures("entity_registry_enabled_by_default") +async def test_entities( hass: HomeAssistant, + snapshot: SnapshotAssertion, entity_registry: er.EntityRegistry, mock_config_entry: MockConfigEntry, mock_device: RokuDevice, mock_roku: MagicMock, ) -> None: - """Test the creation and values of the Roku selects.""" - entity_registry.async_get_or_create( - SELECT_DOMAIN, - DOMAIN, - "1GU48T017973_application", - suggested_object_id="my_roku_3_application", - disabled_by=None, - ) + """Test the Roku select entities.""" + with patch("homeassistant.components.roku.PLATFORMS", [Platform.SELECT]): + await setup_integration(hass, mock_config_entry, mock_device) - mock_config_entry.add_to_hass(hass) - await hass.config_entries.async_setup(mock_config_entry.entry_id) - await hass.async_block_till_done() + await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id) - state = hass.states.get("select.my_roku_3_application") - assert state - assert state.attributes.get(ATTR_OPTIONS) == [ - "Home", - "Amazon Video on Demand", - "Free FrameChannel Service", - "MLB.TV" + "\u00ae", - "Mediafly", - "Netflix", - "Pandora", - "Pluto TV - It's Free TV", - "Roku Channel Store", - ] - assert state.state == "Home" - - entry = entity_registry.async_get("select.my_roku_3_application") - assert entry - assert entry.unique_id == "1GU48T017973_application" +@pytest.mark.usefixtures("entity_registry_enabled_by_default") +async def test_application_select( + hass: HomeAssistant, + mock_device: RokuDevice, + mock_roku: MagicMock, + init_integration: MockConfigEntry, +) -> None: + """Test the behavior of the Roku application select entity.""" + # application name await hass.services.async_call( SELECT_DOMAIN, SERVICE_SELECT_OPTION, @@ -78,16 +60,8 @@ async def test_application_state( assert mock_roku.launch.call_count == 1 mock_roku.launch.assert_called_with("12") - mock_device.app = mock_device.apps[1] - - async_fire_time_changed(hass, dt_util.utcnow() + SCAN_INTERVAL) - await hass.async_block_till_done() - - state = hass.states.get("select.my_roku_3_application") - assert state - - assert state.state == "Netflix" + # home await hass.services.async_call( SELECT_DOMAIN, SERVICE_SELECT_OPTION, @@ -100,15 +74,6 @@ async def test_application_state( assert mock_roku.remote.call_count == 1 mock_roku.remote.assert_called_with("home") - mock_device.app = Application( - app_id=None, name="Roku", version=None, screensaver=None - ) - async_fire_time_changed(hass, dt_util.utcnow() + (SCAN_INTERVAL * 2)) - await hass.async_block_till_done() - - state = hass.states.get("select.my_roku_3_application") - assert state - assert state.state == "Home" @pytest.mark.parametrize( @@ -119,27 +84,15 @@ async def test_application_state( (RokuError, "Invalid response from Roku API"), ], ) +@pytest.mark.usefixtures("entity_registry_enabled_by_default") async def test_application_select_error( hass: HomeAssistant, - entity_registry: er.EntityRegistry, - mock_config_entry: MockConfigEntry, mock_roku: MagicMock, + init_integration: MockConfigEntry, error: RokuError, error_string: str, ) -> None: """Test error handling of the Roku selects.""" - entity_registry.async_get_or_create( - SELECT_DOMAIN, - DOMAIN, - "1GU48T017973_application", - suggested_object_id="my_roku_3_application", - disabled_by=None, - ) - - mock_config_entry.add_to_hass(hass) - await hass.config_entries.async_setup(mock_config_entry.entry_id) - await hass.async_block_till_done() - mock_roku.launch.side_effect = error with pytest.raises(HomeAssistantError, match=error_string): @@ -153,36 +106,18 @@ async def test_application_select_error( blocking=True, ) - state = hass.states.get("select.my_roku_3_application") - assert state - assert state.state == "Home" assert mock_roku.launch.call_count == 1 mock_roku.launch.assert_called_with("12") -@pytest.mark.parametrize("mock_device", ["roku/rokutv-7820x.json"], indirect=True) -async def test_channel_state( +@pytest.mark.parametrize("mock_device", ["rokutv-7820x"], indirect=True) +async def test_channel_select( hass: HomeAssistant, - entity_registry: er.EntityRegistry, init_integration: MockConfigEntry, mock_device: RokuDevice, mock_roku: MagicMock, ) -> None: - """Test the creation and values of the Roku selects.""" - state = hass.states.get("select.58_onn_roku_tv_channel") - assert state - assert state.attributes.get(ATTR_OPTIONS) == [ - "99.1", - "QVC (1.3)", - "WhatsOn (1.1)", - "getTV (14.3)", - ] - assert state.state == "getTV (14.3)" - - entry = entity_registry.async_get("select.58_onn_roku_tv_channel") - assert entry - assert entry.unique_id == "YN00H5555555_channel" - + """Test the behavior of the Roku channel select entity.""" # channel name await hass.services.async_call( SELECT_DOMAIN, @@ -196,14 +131,6 @@ async def test_channel_state( assert mock_roku.tune.call_count == 1 mock_roku.tune.assert_called_with("1.1") - mock_device.channel = mock_device.channels[0] - - async_fire_time_changed(hass, dt_util.utcnow() + SCAN_INTERVAL) - await hass.async_block_till_done() - - state = hass.states.get("select.58_onn_roku_tv_channel") - assert state - assert state.state == "WhatsOn (1.1)" # channel number await hass.services.async_call( @@ -218,17 +145,9 @@ async def test_channel_state( assert mock_roku.tune.call_count == 2 mock_roku.tune.assert_called_with("99.1") - mock_device.channel = mock_device.channels[3] - - async_fire_time_changed(hass, dt_util.utcnow() + SCAN_INTERVAL) - await hass.async_block_till_done() - - state = hass.states.get("select.58_onn_roku_tv_channel") - assert state - assert state.state == "99.1" -@pytest.mark.parametrize("mock_device", ["roku/rokutv-7820x.json"], indirect=True) +@pytest.mark.parametrize("mock_device", ["rokutv-7820x"], indirect=True) async def test_channel_select_error( hass: HomeAssistant, init_integration: MockConfigEntry, @@ -248,6 +167,7 @@ async def test_channel_select_error( blocking=True, ) + # assert no state changes state = hass.states.get("select.58_onn_roku_tv_channel") assert state assert state.state == "getTV (14.3)" diff --git a/tests/components/roku/test_sensor.py b/tests/components/roku/test_sensor.py index e65424e3e66..1112143f941 100644 --- a/tests/components/roku/test_sensor.py +++ b/tests/components/roku/test_sensor.py @@ -1,109 +1,31 @@ """Tests for the sensors provided by the Roku integration.""" -from unittest.mock import MagicMock +from unittest.mock import MagicMock, patch import pytest +from rokuecp import Device as RokuDevice +from syrupy import SnapshotAssertion -from homeassistant.components.roku.const import DOMAIN -from homeassistant.const import ( - ATTR_DEVICE_CLASS, - ATTR_FRIENDLY_NAME, - STATE_UNKNOWN, - EntityCategory, -) +from homeassistant.const import Platform from homeassistant.core import HomeAssistant -from homeassistant.helpers import device_registry as dr, entity_registry as er +from homeassistant.helpers import entity_registry as er -from . import UPNP_SERIAL +from . import setup_integration -from tests.common import MockConfigEntry +from tests.common import MockConfigEntry, snapshot_platform -async def test_roku_sensors( +@pytest.mark.parametrize("mock_device", ["roku3", "rokutv-7820x"], indirect=True) +async def test_entities( hass: HomeAssistant, - device_registry: dr.DeviceRegistry, + snapshot: SnapshotAssertion, entity_registry: er.EntityRegistry, - init_integration: MockConfigEntry, -) -> None: - """Test the Roku sensors.""" - state = hass.states.get("sensor.my_roku_3_active_app") - entry = entity_registry.async_get("sensor.my_roku_3_active_app") - assert entry - assert state - assert entry.unique_id == f"{UPNP_SERIAL}_active_app" - assert entry.entity_category == EntityCategory.DIAGNOSTIC - assert state.state == "Roku" - assert state.attributes.get(ATTR_FRIENDLY_NAME) == "My Roku 3 Active app" - assert ATTR_DEVICE_CLASS not in state.attributes - - state = hass.states.get("sensor.my_roku_3_active_app_id") - entry = entity_registry.async_get("sensor.my_roku_3_active_app_id") - assert entry - assert state - assert entry.unique_id == f"{UPNP_SERIAL}_active_app_id" - assert entry.entity_category == EntityCategory.DIAGNOSTIC - assert state.state == STATE_UNKNOWN - assert state.attributes.get(ATTR_FRIENDLY_NAME) == "My Roku 3 Active app ID" - assert ATTR_DEVICE_CLASS not in state.attributes - - assert entry.device_id - device_entry = device_registry.async_get(entry.device_id) - assert device_entry - assert device_entry.identifiers == {(DOMAIN, UPNP_SERIAL)} - assert device_entry.connections == { - (dr.CONNECTION_NETWORK_MAC, "b0:a7:37:96:4d:fb"), - (dr.CONNECTION_NETWORK_MAC, "b0:a7:37:96:4d:fa"), - } - assert device_entry.manufacturer == "Roku" - assert device_entry.model == "Roku 3" - assert device_entry.name == "My Roku 3" - assert device_entry.entry_type is None - assert device_entry.sw_version == "7.5.0" - assert device_entry.hw_version == "4200X" - assert device_entry.suggested_area is None - - -@pytest.mark.parametrize("mock_device", ["roku/rokutv-7820x.json"], indirect=True) -async def test_rokutv_sensors( - hass: HomeAssistant, - device_registry: dr.DeviceRegistry, - entity_registry: er.EntityRegistry, - init_integration: MockConfigEntry, + mock_config_entry: MockConfigEntry, + mock_device: RokuDevice, mock_roku: MagicMock, ) -> None: - """Test the Roku TV sensors.""" - state = hass.states.get("sensor.58_onn_roku_tv_active_app") - entry = entity_registry.async_get("sensor.58_onn_roku_tv_active_app") - assert entry - assert state - assert entry.unique_id == "YN00H5555555_active_app" - assert entry.entity_category == EntityCategory.DIAGNOSTIC - assert state.state == "Antenna TV" - assert state.attributes.get(ATTR_FRIENDLY_NAME) == '58" Onn Roku TV Active app' - assert ATTR_DEVICE_CLASS not in state.attributes + """Test the Roku sensor entities.""" + with patch("homeassistant.components.roku.PLATFORMS", [Platform.SENSOR]): + await setup_integration(hass, mock_config_entry, mock_device) - state = hass.states.get("sensor.58_onn_roku_tv_active_app_id") - entry = entity_registry.async_get("sensor.58_onn_roku_tv_active_app_id") - assert entry - assert state - assert entry.unique_id == "YN00H5555555_active_app_id" - assert entry.entity_category == EntityCategory.DIAGNOSTIC - assert state.state == "tvinput.dtv" - assert state.attributes.get(ATTR_FRIENDLY_NAME) == '58" Onn Roku TV Active app ID' - assert ATTR_DEVICE_CLASS not in state.attributes - - assert entry.device_id - device_entry = device_registry.async_get(entry.device_id) - assert device_entry - assert device_entry.identifiers == {(DOMAIN, "YN00H5555555")} - assert device_entry.connections == { - (dr.CONNECTION_NETWORK_MAC, "d8:13:99:f8:b0:c6"), - (dr.CONNECTION_NETWORK_MAC, "d4:3a:2e:07:fd:cb"), - } - assert device_entry.manufacturer == "Onn" - assert device_entry.model == "100005844" - assert device_entry.name == '58" Onn Roku TV' - assert device_entry.entry_type is None - assert device_entry.sw_version == "9.2.0" - assert device_entry.hw_version == "7820X" - assert device_entry.suggested_area == "Living room" + await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)