"""Test for the SmartThings media player platform.""" from unittest.mock import AsyncMock from pysmartthings import Attribute, Capability, Command, Status import pytest from syrupy import SnapshotAssertion from homeassistant.components.media_player import ( ATTR_INPUT_SOURCE, ATTR_MEDIA_REPEAT, ATTR_MEDIA_SHUFFLE, ATTR_MEDIA_VOLUME_LEVEL, ATTR_MEDIA_VOLUME_MUTED, DOMAIN as MEDIA_PLAYER_DOMAIN, SERVICE_SELECT_SOURCE, RepeatMode, ) from homeassistant.components.smartthings.const import MAIN from homeassistant.const import ( ATTR_ENTITY_ID, SERVICE_MEDIA_NEXT_TRACK, SERVICE_MEDIA_PAUSE, SERVICE_MEDIA_PLAY, SERVICE_MEDIA_PREVIOUS_TRACK, SERVICE_MEDIA_STOP, SERVICE_REPEAT_SET, SERVICE_SHUFFLE_SET, SERVICE_TURN_OFF, SERVICE_TURN_ON, SERVICE_VOLUME_DOWN, SERVICE_VOLUME_MUTE, SERVICE_VOLUME_SET, SERVICE_VOLUME_UP, STATE_OFF, STATE_PLAYING, Platform, ) from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er from . import setup_integration, snapshot_smartthings_entities, trigger_update from tests.common import MockConfigEntry async def test_all_entities( hass: HomeAssistant, snapshot: SnapshotAssertion, devices: AsyncMock, mock_config_entry: MockConfigEntry, entity_registry: er.EntityRegistry, ) -> None: """Test all entities.""" await setup_integration(hass, mock_config_entry) snapshot_smartthings_entities( hass, entity_registry, snapshot, Platform.MEDIA_PLAYER ) @pytest.mark.parametrize("device_fixture", ["hw_q80r_soundbar"]) @pytest.mark.parametrize( ("action", "command"), [ (SERVICE_TURN_ON, Command.ON), (SERVICE_TURN_OFF, Command.OFF), ], ) async def test_turn_on_off( hass: HomeAssistant, devices: AsyncMock, mock_config_entry: MockConfigEntry, action: str, command: Command, ) -> None: """Test media player turn on and off command.""" await setup_integration(hass, mock_config_entry) await hass.services.async_call( MEDIA_PLAYER_DOMAIN, action, {ATTR_ENTITY_ID: "media_player.soundbar"}, blocking=True, ) devices.execute_device_command.assert_called_once_with( "afcf3b91-0000-1111-2222-ddff2a0a6577", Capability.SWITCH, command, MAIN ) @pytest.mark.parametrize("device_fixture", ["hw_q80r_soundbar"]) @pytest.mark.parametrize( ("muted", "argument"), [ (True, "muted"), (False, "unmuted"), ], ) async def test_mute_unmute( hass: HomeAssistant, devices: AsyncMock, mock_config_entry: MockConfigEntry, muted: bool, argument: str, ) -> None: """Test media player mute and unmute command.""" await setup_integration(hass, mock_config_entry) await hass.services.async_call( MEDIA_PLAYER_DOMAIN, SERVICE_VOLUME_MUTE, {ATTR_ENTITY_ID: "media_player.soundbar", ATTR_MEDIA_VOLUME_MUTED: muted}, blocking=True, ) devices.execute_device_command.assert_called_once_with( "afcf3b91-0000-1111-2222-ddff2a0a6577", Capability.AUDIO_MUTE, Command.SET_MUTE, MAIN, argument=argument, ) @pytest.mark.parametrize("device_fixture", ["hw_q80r_soundbar"]) async def test_set_volume_level( hass: HomeAssistant, devices: AsyncMock, mock_config_entry: MockConfigEntry, ) -> None: """Test media player set volume level command.""" await setup_integration(hass, mock_config_entry) await hass.services.async_call( MEDIA_PLAYER_DOMAIN, SERVICE_VOLUME_SET, {ATTR_ENTITY_ID: "media_player.soundbar", ATTR_MEDIA_VOLUME_LEVEL: 0.31}, blocking=True, ) devices.execute_device_command.assert_called_once_with( "afcf3b91-0000-1111-2222-ddff2a0a6577", Capability.AUDIO_VOLUME, Command.SET_VOLUME, MAIN, argument=31, ) @pytest.mark.parametrize("device_fixture", ["hw_q80r_soundbar"]) async def test_volume_up( hass: HomeAssistant, devices: AsyncMock, mock_config_entry: MockConfigEntry, ) -> None: """Test media player increase volume level command.""" await setup_integration(hass, mock_config_entry) await hass.services.async_call( MEDIA_PLAYER_DOMAIN, SERVICE_VOLUME_UP, {ATTR_ENTITY_ID: "media_player.soundbar"}, blocking=True, ) devices.execute_device_command.assert_called_once_with( "afcf3b91-0000-1111-2222-ddff2a0a6577", Capability.AUDIO_VOLUME, Command.VOLUME_UP, MAIN, ) @pytest.mark.parametrize("device_fixture", ["hw_q80r_soundbar"]) async def test_volume_down( hass: HomeAssistant, devices: AsyncMock, mock_config_entry: MockConfigEntry, ) -> None: """Test media player decrease volume level command.""" await setup_integration(hass, mock_config_entry) await hass.services.async_call( MEDIA_PLAYER_DOMAIN, SERVICE_VOLUME_DOWN, {ATTR_ENTITY_ID: "media_player.soundbar"}, blocking=True, ) devices.execute_device_command.assert_called_once_with( "afcf3b91-0000-1111-2222-ddff2a0a6577", Capability.AUDIO_VOLUME, Command.VOLUME_DOWN, MAIN, ) @pytest.mark.parametrize("device_fixture", ["hw_q80r_soundbar"]) async def test_media_play( hass: HomeAssistant, devices: AsyncMock, mock_config_entry: MockConfigEntry, ) -> None: """Test media player play command.""" await setup_integration(hass, mock_config_entry) await hass.services.async_call( MEDIA_PLAYER_DOMAIN, SERVICE_MEDIA_PLAY, {ATTR_ENTITY_ID: "media_player.soundbar"}, blocking=True, ) devices.execute_device_command.assert_called_once_with( "afcf3b91-0000-1111-2222-ddff2a0a6577", Capability.MEDIA_PLAYBACK, Command.PLAY, MAIN, ) @pytest.mark.parametrize("device_fixture", ["hw_q80r_soundbar"]) async def test_media_pause( hass: HomeAssistant, devices: AsyncMock, mock_config_entry: MockConfigEntry, ) -> None: """Test media player pause command.""" await setup_integration(hass, mock_config_entry) await hass.services.async_call( MEDIA_PLAYER_DOMAIN, SERVICE_MEDIA_PAUSE, {ATTR_ENTITY_ID: "media_player.soundbar"}, blocking=True, ) devices.execute_device_command.assert_called_once_with( "afcf3b91-0000-1111-2222-ddff2a0a6577", Capability.MEDIA_PLAYBACK, Command.PAUSE, MAIN, ) @pytest.mark.parametrize("device_fixture", ["hw_q80r_soundbar"]) async def test_media_stop( hass: HomeAssistant, devices: AsyncMock, mock_config_entry: MockConfigEntry, ) -> None: """Test media player stop command.""" await setup_integration(hass, mock_config_entry) await hass.services.async_call( MEDIA_PLAYER_DOMAIN, SERVICE_MEDIA_STOP, {ATTR_ENTITY_ID: "media_player.soundbar"}, blocking=True, ) devices.execute_device_command.assert_called_once_with( "afcf3b91-0000-1111-2222-ddff2a0a6577", Capability.MEDIA_PLAYBACK, Command.STOP, MAIN, ) @pytest.mark.parametrize("device_fixture", ["hw_q80r_soundbar"]) async def test_media_previous_track( hass: HomeAssistant, devices: AsyncMock, mock_config_entry: MockConfigEntry, ) -> None: """Test media player previous track command.""" devices.get_device_status.return_value[MAIN][Capability.MEDIA_PLAYBACK] = { Attribute.SUPPORTED_PLAYBACK_COMMANDS: Status(["rewind"]) } await setup_integration(hass, mock_config_entry) await hass.services.async_call( MEDIA_PLAYER_DOMAIN, SERVICE_MEDIA_PREVIOUS_TRACK, {ATTR_ENTITY_ID: "media_player.soundbar"}, blocking=True, ) devices.execute_device_command.assert_called_once_with( "afcf3b91-0000-1111-2222-ddff2a0a6577", Capability.MEDIA_PLAYBACK, Command.REWIND, MAIN, ) @pytest.mark.parametrize("device_fixture", ["hw_q80r_soundbar"]) async def test_media_next_track( hass: HomeAssistant, devices: AsyncMock, mock_config_entry: MockConfigEntry, ) -> None: """Test media player next track command.""" devices.get_device_status.return_value[MAIN][Capability.MEDIA_PLAYBACK] = { Attribute.SUPPORTED_PLAYBACK_COMMANDS: Status(["fastForward"]) } await setup_integration(hass, mock_config_entry) await hass.services.async_call( MEDIA_PLAYER_DOMAIN, SERVICE_MEDIA_NEXT_TRACK, {ATTR_ENTITY_ID: "media_player.soundbar"}, blocking=True, ) devices.execute_device_command.assert_called_once_with( "afcf3b91-0000-1111-2222-ddff2a0a6577", Capability.MEDIA_PLAYBACK, Command.FAST_FORWARD, MAIN, ) @pytest.mark.parametrize("device_fixture", ["hw_q80r_soundbar"]) async def test_select_source( hass: HomeAssistant, devices: AsyncMock, mock_config_entry: MockConfigEntry, ) -> None: """Test media player stop command.""" await setup_integration(hass, mock_config_entry) await hass.services.async_call( MEDIA_PLAYER_DOMAIN, SERVICE_SELECT_SOURCE, {ATTR_ENTITY_ID: "media_player.soundbar", ATTR_INPUT_SOURCE: "digital"}, blocking=True, ) devices.execute_device_command.assert_called_once_with( "afcf3b91-0000-1111-2222-ddff2a0a6577", Capability.MEDIA_INPUT_SOURCE, Command.SET_INPUT_SOURCE, MAIN, "digital", ) @pytest.mark.parametrize("device_fixture", ["hw_q80r_soundbar"]) @pytest.mark.parametrize( ("shuffle", "argument"), [ (True, "enabled"), (False, "disabled"), ], ) async def test_media_shuffle_on_off( hass: HomeAssistant, devices: AsyncMock, mock_config_entry: MockConfigEntry, shuffle: bool, argument: bool, ) -> None: """Test media player media shuffle command.""" devices.get_device_status.return_value[MAIN][Capability.MEDIA_PLAYBACK_SHUFFLE] = { Attribute.PLAYBACK_SHUFFLE: Status(True) } await setup_integration(hass, mock_config_entry) await hass.services.async_call( MEDIA_PLAYER_DOMAIN, SERVICE_SHUFFLE_SET, {ATTR_ENTITY_ID: "media_player.soundbar", ATTR_MEDIA_SHUFFLE: shuffle}, blocking=True, ) devices.execute_device_command.assert_called_once_with( "afcf3b91-0000-1111-2222-ddff2a0a6577", Capability.MEDIA_PLAYBACK_SHUFFLE, Command.SET_PLAYBACK_SHUFFLE, MAIN, argument=argument, ) @pytest.mark.parametrize("device_fixture", ["hw_q80r_soundbar"]) @pytest.mark.parametrize( ("repeat", "argument"), [ (RepeatMode.OFF, "off"), (RepeatMode.ONE, "one"), (RepeatMode.ALL, "all"), ], ) async def test_media_repeat_mode( hass: HomeAssistant, devices: AsyncMock, mock_config_entry: MockConfigEntry, repeat: RepeatMode, argument: bool, ) -> None: """Test media player repeat mode command.""" devices.get_device_status.return_value[MAIN][Capability.MEDIA_PLAYBACK_REPEAT] = { Attribute.REPEAT_MODE: Status("one") } await setup_integration(hass, mock_config_entry) await hass.services.async_call( MEDIA_PLAYER_DOMAIN, SERVICE_REPEAT_SET, {ATTR_ENTITY_ID: "media_player.soundbar", ATTR_MEDIA_REPEAT: repeat}, blocking=True, ) devices.execute_device_command.assert_called_once_with( "afcf3b91-0000-1111-2222-ddff2a0a6577", Capability.MEDIA_PLAYBACK_REPEAT, Command.SET_PLAYBACK_REPEAT_MODE, MAIN, argument=argument, ) @pytest.mark.parametrize("device_fixture", ["hw_q80r_soundbar"]) async def test_state_update( hass: HomeAssistant, devices: AsyncMock, mock_config_entry: MockConfigEntry, ) -> None: """Test state update.""" await setup_integration(hass, mock_config_entry) assert hass.states.get("media_player.soundbar").state == STATE_PLAYING await trigger_update( hass, devices, "afcf3b91-0000-1111-2222-ddff2a0a6577", Capability.SWITCH, Attribute.SWITCH, "off", ) assert hass.states.get("media_player.soundbar").state == STATE_OFF