Files
home-assistant-core/tests/components/samsungtv/test_media_player.py
T
Penny Wood f195ecca4b Consolidate all platforms that have tests (#22109)
* Moved climate components with tests into platform dirs.

* Updated tests from climate component.

* Moved binary_sensor components with tests into platform dirs.

* Updated tests from binary_sensor component.

* Moved calendar components with tests into platform dirs.

* Updated tests from calendar component.

* Moved camera components with tests into platform dirs.

* Updated tests from camera component.

* Moved cover components with tests into platform dirs.

* Updated tests from cover component.

* Moved device_tracker components with tests into platform dirs.

* Updated tests from device_tracker component.

* Moved fan components with tests into platform dirs.

* Updated tests from fan component.

* Moved geo_location components with tests into platform dirs.

* Updated tests from geo_location component.

* Moved image_processing components with tests into platform dirs.

* Updated tests from image_processing component.

* Moved light components with tests into platform dirs.

* Updated tests from light component.

* Moved lock components with tests into platform dirs.

* Moved media_player components with tests into platform dirs.

* Updated tests from media_player component.

* Moved scene components with tests into platform dirs.

* Moved sensor components with tests into platform dirs.

* Updated tests from sensor component.

* Moved switch components with tests into platform dirs.

* Updated tests from sensor component.

* Moved vacuum components with tests into platform dirs.

* Updated tests from vacuum component.

* Moved weather components with tests into platform dirs.

* Fixed __init__.py files

* Fixes for stuff moved as part of this branch.

* Fix stuff needed to merge with balloob's branch.

* Formatting issues.

* Missing __init__.py files.

* Fix-ups

* Fixup

* Regenerated requirements.

* Linting errors fixed.

* Fixed more broken tests.

* Missing init files.

* Fix broken tests.

* More broken tests

* There seems to be a thread race condition.
I suspect the logger stuff is running in another thread, which means waiting until the aio loop is done is missing the log messages.
Used sleep instead because that allows the logger thread to run. I think the api_streams sensor might not be thread safe.

* Disabled tests, will remove sensor in #22147

* Updated coverage and codeowners.
2019-03-18 23:07:39 -07:00

350 lines
12 KiB
Python

"""Tests for samsungtv Components."""
import asyncio
import unittest
from unittest.mock import call, patch, MagicMock
from asynctest import mock
import pytest
import tests.common
from homeassistant.components.media_player.const import SUPPORT_TURN_ON, \
MEDIA_TYPE_CHANNEL, MEDIA_TYPE_URL
from homeassistant.components.samsungtv.media_player import setup_platform, \
CONF_TIMEOUT, SamsungTVDevice, SUPPORT_SAMSUNGTV
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PORT, STATE_ON, \
CONF_MAC, STATE_OFF
from tests.common import MockDependency
from homeassistant.util import dt as dt_util
from datetime import timedelta
WORKING_CONFIG = {
CONF_HOST: 'fake',
CONF_NAME: 'fake',
CONF_PORT: 8001,
CONF_TIMEOUT: 10,
CONF_MAC: 'fake',
'uuid': None,
}
DISCOVERY_INFO = {
'name': 'fake',
'model_name': 'fake',
'host': 'fake'
}
class AccessDenied(Exception):
"""Dummy Exception."""
class ConnectionClosed(Exception):
"""Dummy Exception."""
class UnhandledResponse(Exception):
"""Dummy Exception."""
class TestSamsungTv(unittest.TestCase):
"""Testing Samsungtv component."""
@MockDependency('samsungctl')
@MockDependency('wakeonlan')
def setUp(self, samsung_mock, wol_mock):
"""Set up test environment."""
self.hass = tests.common.get_test_home_assistant()
self.hass.start()
self.hass.block_till_done()
self.device = SamsungTVDevice(**WORKING_CONFIG)
self.device._exceptions_class = mock.Mock()
self.device._exceptions_class.UnhandledResponse = UnhandledResponse
self.device._exceptions_class.AccessDenied = AccessDenied
self.device._exceptions_class.ConnectionClosed = ConnectionClosed
def tearDown(self):
"""Tear down test data."""
self.hass.stop()
@MockDependency('samsungctl')
@MockDependency('wakeonlan')
def test_setup(self, samsung_mock, wol_mock):
"""Testing setup of platform."""
with mock.patch(
'homeassistant.components.samsungtv.media_player.socket'):
add_entities = mock.Mock()
setup_platform(
self.hass, WORKING_CONFIG, add_entities)
@MockDependency('samsungctl')
@MockDependency('wakeonlan')
def test_setup_discovery(self, samsung_mock, wol_mock):
"""Testing setup of platform with discovery."""
with mock.patch(
'homeassistant.components.samsungtv.media_player.socket'):
add_entities = mock.Mock()
setup_platform(self.hass, {}, add_entities,
discovery_info=DISCOVERY_INFO)
@MockDependency('samsungctl')
@MockDependency('wakeonlan')
@mock.patch(
'homeassistant.components.samsungtv.media_player._LOGGER.warning')
def test_setup_none(self, samsung_mock, wol_mock, mocked_warn):
"""Testing setup of platform with no data."""
with mock.patch(
'homeassistant.components.samsungtv.media_player.socket'):
add_entities = mock.Mock()
setup_platform(self.hass, {}, add_entities,
discovery_info=None)
mocked_warn.assert_called_once_with("Cannot determine device")
add_entities.assert_not_called()
def test_update_on(self):
"""Testing update tv on."""
self.device.update()
self.assertEqual(STATE_ON, self.device._state)
def test_update_off(self):
"""Testing update tv off."""
_remote = mock.Mock()
_remote.control = mock.Mock(
side_effect=OSError('Boom'))
self.device.get_remote = mock.Mock(return_value=_remote)
self.device.update()
assert STATE_OFF == self.device._state
def test_send_key(self):
"""Test for send key."""
self.device.send_key('KEY_POWER')
self.assertEqual(STATE_ON, self.device._state)
def test_send_key_broken_pipe(self):
"""Testing broken pipe Exception."""
_remote = mock.Mock()
_remote.control = mock.Mock(
side_effect=BrokenPipeError('Boom'))
self.device.get_remote = mock.Mock(return_value=_remote)
self.device.send_key('HELLO')
self.assertIsNone(self.device._remote)
self.assertEqual(STATE_ON, self.device._state)
def test_send_key_connection_closed_retry_succeed(self):
"""Test retry on connection closed."""
_remote = mock.Mock()
_remote.control = mock.Mock(side_effect=[
self.device._exceptions_class.ConnectionClosed('Boom'),
mock.DEFAULT])
self.device.get_remote = mock.Mock(return_value=_remote)
command = 'HELLO'
self.device.send_key(command)
self.assertEqual(STATE_ON, self.device._state)
# verify that _remote.control() get called twice because of retry logic
expected = [mock.call(command),
mock.call(command)]
assert expected == _remote.control.call_args_list
def test_send_key_unhandled_response(self):
"""Testing unhandled response exception."""
_remote = mock.Mock()
_remote.control = mock.Mock(
side_effect=self.device._exceptions_class.UnhandledResponse('Boom')
)
self.device.get_remote = mock.Mock(return_value=_remote)
self.device.send_key('HELLO')
self.assertIsNone(self.device._remote)
self.assertEqual(STATE_ON, self.device._state)
def test_send_key_os_error(self):
"""Testing broken pipe Exception."""
_remote = mock.Mock()
_remote.control = mock.Mock(
side_effect=OSError('Boom'))
self.device.get_remote = mock.Mock(return_value=_remote)
self.device.send_key('HELLO')
assert self.device._remote is None
assert STATE_OFF == self.device._state
def test_power_off_in_progress(self):
"""Test for power_off_in_progress."""
assert not self.device._power_off_in_progress()
self.device._end_of_power_off = dt_util.utcnow() + timedelta(
seconds=15)
assert self.device._power_off_in_progress()
def test_name(self):
"""Test for name property."""
assert 'fake' == self.device.name
def test_state(self):
"""Test for state property."""
self.device._state = STATE_ON
self.assertEqual(STATE_ON, self.device.state)
self.device._state = STATE_OFF
assert STATE_OFF == self.device.state
def test_is_volume_muted(self):
"""Test for is_volume_muted property."""
self.device._muted = False
assert not self.device.is_volume_muted
self.device._muted = True
assert self.device.is_volume_muted
def test_supported_features(self):
"""Test for supported_features property."""
self.device._mac = None
assert SUPPORT_SAMSUNGTV == self.device.supported_features
self.device._mac = "fake"
assert SUPPORT_SAMSUNGTV | SUPPORT_TURN_ON == \
self.device.supported_features
def test_turn_off(self):
"""Test for turn_off."""
self.device.send_key = mock.Mock()
_remote = mock.Mock()
_remote.close = mock.Mock()
self.get_remote = mock.Mock(return_value=_remote)
self.device._end_of_power_off = None
self.device.turn_off()
assert self.device._end_of_power_off is not None
self.device.send_key.assert_called_once_with('KEY_POWER')
self.device.send_key = mock.Mock()
self.device._config['method'] = 'legacy'
self.device.turn_off()
self.device.send_key.assert_called_once_with('KEY_POWEROFF')
@mock.patch(
'homeassistant.components.samsungtv.media_player._LOGGER.debug')
def test_turn_off_os_error(self, mocked_debug):
"""Test for turn_off with OSError."""
_remote = mock.Mock()
_remote.close = mock.Mock(side_effect=OSError("BOOM"))
self.device.get_remote = mock.Mock(return_value=_remote)
self.device.turn_off()
mocked_debug.assert_called_once_with("Could not establish connection.")
def test_volume_up(self):
"""Test for volume_up."""
self.device.send_key = mock.Mock()
self.device.volume_up()
self.device.send_key.assert_called_once_with("KEY_VOLUP")
def test_volume_down(self):
"""Test for volume_down."""
self.device.send_key = mock.Mock()
self.device.volume_down()
self.device.send_key.assert_called_once_with("KEY_VOLDOWN")
def test_mute_volume(self):
"""Test for mute_volume."""
self.device.send_key = mock.Mock()
self.device.mute_volume(True)
self.device.send_key.assert_called_once_with("KEY_MUTE")
def test_media_play_pause(self):
"""Test for media_next_track."""
self.device.send_key = mock.Mock()
self.device._playing = False
self.device.media_play_pause()
self.device.send_key.assert_called_once_with("KEY_PLAY")
assert self.device._playing
self.device.send_key = mock.Mock()
self.device.media_play_pause()
self.device.send_key.assert_called_once_with("KEY_PAUSE")
assert not self.device._playing
def test_media_play(self):
"""Test for media_play."""
self.device.send_key = mock.Mock()
self.device._playing = False
self.device.media_play()
self.device.send_key.assert_called_once_with("KEY_PLAY")
assert self.device._playing
def test_media_pause(self):
"""Test for media_pause."""
self.device.send_key = mock.Mock()
self.device._playing = True
self.device.media_pause()
self.device.send_key.assert_called_once_with("KEY_PAUSE")
assert not self.device._playing
def test_media_next_track(self):
"""Test for media_next_track."""
self.device.send_key = mock.Mock()
self.device.media_next_track()
self.device.send_key.assert_called_once_with("KEY_FF")
def test_media_previous_track(self):
"""Test for media_previous_track."""
self.device.send_key = mock.Mock()
self.device.media_previous_track()
self.device.send_key.assert_called_once_with("KEY_REWIND")
def test_turn_on(self):
"""Test turn on."""
self.device.send_key = mock.Mock()
self.device._mac = None
self.device.turn_on()
self.device.send_key.assert_called_once_with('KEY_POWERON')
self.device._wol.send_magic_packet = mock.Mock()
self.device._mac = "fake"
self.device.turn_on()
self.device._wol.send_magic_packet.assert_called_once_with("fake")
@pytest.fixture
def samsung_mock():
"""Mock samsungctl."""
with patch.dict('sys.modules', {
'samsungctl': MagicMock(),
}):
yield
async def test_play_media(hass, samsung_mock):
"""Test for play_media."""
asyncio_sleep = asyncio.sleep
sleeps = []
async def sleep(duration, loop):
sleeps.append(duration)
await asyncio_sleep(0, loop=loop)
with patch('asyncio.sleep', new=sleep):
device = SamsungTVDevice(**WORKING_CONFIG)
device.hass = hass
device.send_key = mock.Mock()
await device.async_play_media(MEDIA_TYPE_CHANNEL, "576")
exp = [call("KEY_5"), call("KEY_7"), call("KEY_6")]
assert device.send_key.call_args_list == exp
assert len(sleeps) == 3
async def test_play_media_invalid_type(hass, samsung_mock):
"""Test for play_media with invalid media type."""
url = "https://example.com"
device = SamsungTVDevice(**WORKING_CONFIG)
device.send_key = mock.Mock()
await device.async_play_media(MEDIA_TYPE_URL, url)
assert device.send_key.call_count == 0
async def test_play_media_channel_as_string(hass, samsung_mock):
"""Test for play_media with invalid channel as string."""
url = "https://example.com"
device = SamsungTVDevice(**WORKING_CONFIG)
device.send_key = mock.Mock()
await device.async_play_media(MEDIA_TYPE_CHANNEL, url)
assert device.send_key.call_count == 0
async def test_play_media_channel_as_non_positive(hass, samsung_mock):
"""Test for play_media with invalid channel as non positive integer."""
device = SamsungTVDevice(**WORKING_CONFIG)
device.send_key = mock.Mock()
await device.async_play_media(MEDIA_TYPE_CHANNEL, "-4")
assert device.send_key.call_count == 0