Async tests for remaining device trackers (#18682)

This commit is contained in:
Adam Mills 2018-11-24 15:10:57 -05:00 committed by GitHub
parent 6ebdc7dabc
commit 50a30d4dc9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 213 additions and 237 deletions

View File

@ -1,7 +1,7 @@
"""The tests for the tplink device tracker platform.""" """The tests for the tplink device tracker platform."""
import os import os
import unittest import pytest
from homeassistant.components import device_tracker from homeassistant.components import device_tracker
from homeassistant.components.device_tracker.tplink import Tplink4DeviceScanner from homeassistant.components.device_tracker.tplink import Tplink4DeviceScanner
@ -9,27 +9,19 @@ from homeassistant.const import (CONF_PLATFORM, CONF_PASSWORD, CONF_USERNAME,
CONF_HOST) CONF_HOST)
import requests_mock import requests_mock
from tests.common import get_test_home_assistant
@pytest.fixture(autouse=True)
def setup_comp(hass):
"""Initialize components."""
yaml_devices = hass.config.path(device_tracker.YAML_DEVICES)
yield
if os.path.isfile(yaml_devices):
os.remove(yaml_devices)
class TestTplink4DeviceScanner(unittest.TestCase): async def test_get_mac_addresses_from_both_bands(hass):
"""Tests for the Tplink4DeviceScanner class."""
def setUp(self): # pylint: disable=invalid-name
"""Set up things to be run when tests are started."""
self.hass = get_test_home_assistant()
def tearDown(self): # pylint: disable=invalid-name
"""Stop everything that was started."""
self.hass.stop()
try:
os.remove(self.hass.config.path(device_tracker.YAML_DEVICES))
except FileNotFoundError:
pass
@requests_mock.mock()
def test_get_mac_addresses_from_both_bands(self, m):
"""Test grabbing the mac addresses from 2.4 and 5 GHz clients pages.""" """Test grabbing the mac addresses from 2.4 and 5 GHz clients pages."""
with requests_mock.Mocker() as m:
conf_dict = { conf_dict = {
CONF_PLATFORM: 'tplink', CONF_PLATFORM: 'tplink',
CONF_HOST: 'fake-host', CONF_HOST: 'fake-host',

View File

@ -1,14 +1,12 @@
"""The tests for the Unifi direct device tracker platform.""" """The tests for the Unifi direct device tracker platform."""
import os import os
from datetime import timedelta from datetime import timedelta
import unittest from asynctest import mock, patch
from unittest import mock
from unittest.mock import patch
import pytest import pytest
import voluptuous as vol import voluptuous as vol
from homeassistant.setup import setup_component from homeassistant.setup import async_setup_component
from homeassistant.components import device_tracker from homeassistant.components import device_tracker
from homeassistant.components.device_tracker import ( from homeassistant.components.device_tracker import (
CONF_CONSIDER_HOME, CONF_TRACK_NEW, CONF_AWAY_HIDE, CONF_CONSIDER_HOME, CONF_TRACK_NEW, CONF_AWAY_HIDE,
@ -19,33 +17,24 @@ from homeassistant.const import (CONF_PLATFORM, CONF_PASSWORD, CONF_USERNAME,
CONF_HOST) CONF_HOST)
from tests.common import ( from tests.common import (
get_test_home_assistant, assert_setup_component, assert_setup_component, mock_component, load_fixture)
mock_component, load_fixture)
class TestComponentsDeviceTrackerUnifiDirect(unittest.TestCase):
"""Tests for the Unifi direct device tracker platform."""
hass = None
scanner_path = 'homeassistant.components.device_tracker.' + \ scanner_path = 'homeassistant.components.device_tracker.' + \
'unifi_direct.UnifiDeviceScanner' 'unifi_direct.UnifiDeviceScanner'
def setup_method(self, _):
"""Set up things to be run when tests are started."""
self.hass = get_test_home_assistant()
mock_component(self.hass, 'zone')
def teardown_method(self, _): @pytest.fixture(autouse=True)
"""Stop everything that was started.""" def setup_comp(hass):
self.hass.stop() """Initialize components."""
try: mock_component(hass, 'zone')
os.remove(self.hass.config.path(device_tracker.YAML_DEVICES)) yaml_devices = hass.config.path(device_tracker.YAML_DEVICES)
except FileNotFoundError: yield
pass if os.path.isfile(yaml_devices):
os.remove(yaml_devices)
@mock.patch(scanner_path,
return_value=mock.MagicMock()) @patch(scanner_path, return_value=mock.MagicMock())
def test_get_scanner(self, unifi_mock): async def test_get_scanner(unifi_mock, hass):
"""Test creating an Unifi direct scanner with a password.""" """Test creating an Unifi direct scanner with a password."""
conf_dict = { conf_dict = {
DOMAIN: { DOMAIN: {
@ -63,13 +52,14 @@ class TestComponentsDeviceTrackerUnifiDirect(unittest.TestCase):
} }
with assert_setup_component(1, DOMAIN): with assert_setup_component(1, DOMAIN):
assert setup_component(self.hass, DOMAIN, conf_dict) assert await async_setup_component(hass, DOMAIN, conf_dict)
conf_dict[DOMAIN][CONF_PORT] = 22 conf_dict[DOMAIN][CONF_PORT] = 22
assert unifi_mock.call_args == mock.call(conf_dict[DOMAIN]) assert unifi_mock.call_args == mock.call(conf_dict[DOMAIN])
@patch('pexpect.pxssh.pxssh') @patch('pexpect.pxssh.pxssh')
def test_get_device_name(self, mock_ssh): async def test_get_device_name(mock_ssh, hass):
"""Testing MAC matching.""" """Testing MAC matching."""
conf_dict = { conf_dict = {
DOMAIN: { DOMAIN: {
@ -83,7 +73,7 @@ class TestComponentsDeviceTrackerUnifiDirect(unittest.TestCase):
} }
} }
mock_ssh.return_value.before = load_fixture('unifi_direct.txt') mock_ssh.return_value.before = load_fixture('unifi_direct.txt')
scanner = get_scanner(self.hass, conf_dict) scanner = get_scanner(hass, conf_dict)
devices = scanner.scan_devices() devices = scanner.scan_devices()
assert 23 == len(devices) assert 23 == len(devices)
assert "iPhone" == \ assert "iPhone" == \
@ -91,9 +81,10 @@ class TestComponentsDeviceTrackerUnifiDirect(unittest.TestCase):
assert "iPhone" == \ assert "iPhone" == \
scanner.get_device_name("98:00:C6:56:34:12") scanner.get_device_name("98:00:C6:56:34:12")
@patch('pexpect.pxssh.pxssh.logout') @patch('pexpect.pxssh.pxssh.logout')
@patch('pexpect.pxssh.pxssh.login') @patch('pexpect.pxssh.pxssh.login')
def test_failed_to_log_in(self, mock_login, mock_logout): async def test_failed_to_log_in(mock_login, mock_logout, hass):
"""Testing exception at login results in False.""" """Testing exception at login results in False."""
from pexpect import exceptions from pexpect import exceptions
@ -110,15 +101,16 @@ class TestComponentsDeviceTrackerUnifiDirect(unittest.TestCase):
} }
mock_login.side_effect = exceptions.EOF("Test") mock_login.side_effect = exceptions.EOF("Test")
scanner = get_scanner(self.hass, conf_dict) scanner = get_scanner(hass, conf_dict)
assert not scanner assert not scanner
@patch('pexpect.pxssh.pxssh.logout') @patch('pexpect.pxssh.pxssh.logout')
@patch('pexpect.pxssh.pxssh.login', autospec=True) @patch('pexpect.pxssh.pxssh.login', autospec=True)
@patch('pexpect.pxssh.pxssh.prompt') @patch('pexpect.pxssh.pxssh.prompt')
@patch('pexpect.pxssh.pxssh.sendline') @patch('pexpect.pxssh.pxssh.sendline')
def test_to_get_update(self, mock_sendline, mock_prompt, mock_login, async def test_to_get_update(mock_sendline, mock_prompt, mock_login,
mock_logout): mock_logout, hass):
"""Testing exception in get_update matching.""" """Testing exception in get_update matching."""
conf_dict = { conf_dict = {
DOMAIN: { DOMAIN: {
@ -132,18 +124,20 @@ class TestComponentsDeviceTrackerUnifiDirect(unittest.TestCase):
} }
} }
scanner = get_scanner(self.hass, conf_dict) scanner = get_scanner(hass, conf_dict)
# mock_sendline.side_effect = AssertionError("Test") # mock_sendline.side_effect = AssertionError("Test")
mock_prompt.side_effect = AssertionError("Test") mock_prompt.side_effect = AssertionError("Test")
devices = scanner._get_update() # pylint: disable=protected-access devices = scanner._get_update() # pylint: disable=protected-access
assert devices is None assert devices is None
def test_good_response_parses(self):
def test_good_response_parses(hass):
"""Test that the response form the AP parses to JSON correctly.""" """Test that the response form the AP parses to JSON correctly."""
response = _response_to_json(load_fixture('unifi_direct.txt')) response = _response_to_json(load_fixture('unifi_direct.txt'))
assert response != {} assert response != {}
def test_bad_response_returns_none(self):
def test_bad_response_returns_none(hass):
"""Test that a bad response form the AP parses to JSON correctly.""" """Test that a bad response form the AP parses to JSON correctly."""
assert _response_to_json("{(}") == {} assert _response_to_json("{(}") == {}

View File

@ -1,8 +1,6 @@
"""The tests for the Xiaomi router device tracker platform.""" """The tests for the Xiaomi router device tracker platform."""
import logging import logging
import unittest from asynctest import mock, patch
from unittest import mock
from unittest.mock import patch
import requests import requests
@ -10,7 +8,6 @@ from homeassistant.components.device_tracker import DOMAIN, xiaomi as xiaomi
from homeassistant.components.device_tracker.xiaomi import get_scanner from homeassistant.components.device_tracker.xiaomi import get_scanner
from homeassistant.const import (CONF_HOST, CONF_USERNAME, CONF_PASSWORD, from homeassistant.const import (CONF_HOST, CONF_USERNAME, CONF_PASSWORD,
CONF_PLATFORM) CONF_PLATFORM)
from tests.common import get_test_home_assistant
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -152,21 +149,10 @@ def mocked_requests(*args, **kwargs):
_LOGGER.debug('UNKNOWN ROUTE') _LOGGER.debug('UNKNOWN ROUTE')
class TestXiaomiDeviceScanner(unittest.TestCase): @patch(
"""Xiaomi device scanner test class."""
def setUp(self):
"""Initialize values for this testcase class."""
self.hass = get_test_home_assistant()
def tearDown(self):
"""Stop everything that was started."""
self.hass.stop()
@mock.patch(
'homeassistant.components.device_tracker.xiaomi.XiaomiDeviceScanner', 'homeassistant.components.device_tracker.xiaomi.XiaomiDeviceScanner',
return_value=mock.MagicMock()) return_value=mock.MagicMock())
def test_config(self, xiaomi_mock): async def test_config(xiaomi_mock, hass):
"""Testing minimal configuration.""" """Testing minimal configuration."""
config = { config = {
DOMAIN: xiaomi.PLATFORM_SCHEMA({ DOMAIN: xiaomi.PLATFORM_SCHEMA({
@ -175,7 +161,7 @@ class TestXiaomiDeviceScanner(unittest.TestCase):
CONF_PASSWORD: 'passwordTest' CONF_PASSWORD: 'passwordTest'
}) })
} }
xiaomi.get_scanner(self.hass, config) xiaomi.get_scanner(hass, config)
assert xiaomi_mock.call_count == 1 assert xiaomi_mock.call_count == 1
assert xiaomi_mock.call_args == mock.call(config[DOMAIN]) assert xiaomi_mock.call_args == mock.call(config[DOMAIN])
call_arg = xiaomi_mock.call_args[0][0] call_arg = xiaomi_mock.call_args[0][0]
@ -184,10 +170,11 @@ class TestXiaomiDeviceScanner(unittest.TestCase):
assert call_arg['host'] == '192.168.0.1' assert call_arg['host'] == '192.168.0.1'
assert call_arg['platform'] == 'device_tracker' assert call_arg['platform'] == 'device_tracker'
@mock.patch(
@patch(
'homeassistant.components.device_tracker.xiaomi.XiaomiDeviceScanner', 'homeassistant.components.device_tracker.xiaomi.XiaomiDeviceScanner',
return_value=mock.MagicMock()) return_value=mock.MagicMock())
def test_config_full(self, xiaomi_mock): async def test_config_full(xiaomi_mock, hass):
"""Testing full configuration.""" """Testing full configuration."""
config = { config = {
DOMAIN: xiaomi.PLATFORM_SCHEMA({ DOMAIN: xiaomi.PLATFORM_SCHEMA({
@ -197,7 +184,7 @@ class TestXiaomiDeviceScanner(unittest.TestCase):
CONF_PASSWORD: 'passwordTest' CONF_PASSWORD: 'passwordTest'
}) })
} }
xiaomi.get_scanner(self.hass, config) xiaomi.get_scanner(hass, config)
assert xiaomi_mock.call_count == 1 assert xiaomi_mock.call_count == 1
assert xiaomi_mock.call_args == mock.call(config[DOMAIN]) assert xiaomi_mock.call_args == mock.call(config[DOMAIN])
call_arg = xiaomi_mock.call_args[0][0] call_arg = xiaomi_mock.call_args[0][0]
@ -206,9 +193,10 @@ class TestXiaomiDeviceScanner(unittest.TestCase):
assert call_arg['host'] == '192.168.0.1' assert call_arg['host'] == '192.168.0.1'
assert call_arg['platform'] == 'device_tracker' assert call_arg['platform'] == 'device_tracker'
@patch('requests.get', side_effect=mocked_requests) @patch('requests.get', side_effect=mocked_requests)
@patch('requests.post', side_effect=mocked_requests) @patch('requests.post', side_effect=mocked_requests)
def test_invalid_credential(self, mock_get, mock_post): async def test_invalid_credential(mock_get, mock_post, hass):
"""Testing invalid credential handling.""" """Testing invalid credential handling."""
config = { config = {
DOMAIN: xiaomi.PLATFORM_SCHEMA({ DOMAIN: xiaomi.PLATFORM_SCHEMA({
@ -218,11 +206,12 @@ class TestXiaomiDeviceScanner(unittest.TestCase):
CONF_PASSWORD: 'passwordTest' CONF_PASSWORD: 'passwordTest'
}) })
} }
assert get_scanner(self.hass, config) is None assert get_scanner(hass, config) is None
@patch('requests.get', side_effect=mocked_requests) @patch('requests.get', side_effect=mocked_requests)
@patch('requests.post', side_effect=mocked_requests) @patch('requests.post', side_effect=mocked_requests)
def test_valid_credential(self, mock_get, mock_post): async def test_valid_credential(mock_get, mock_post, hass):
"""Testing valid refresh.""" """Testing valid refresh."""
config = { config = {
DOMAIN: xiaomi.PLATFORM_SCHEMA({ DOMAIN: xiaomi.PLATFORM_SCHEMA({
@ -232,7 +221,7 @@ class TestXiaomiDeviceScanner(unittest.TestCase):
CONF_PASSWORD: 'passwordTest' CONF_PASSWORD: 'passwordTest'
}) })
} }
scanner = get_scanner(self.hass, config) scanner = get_scanner(hass, config)
assert scanner is not None assert scanner is not None
assert 2 == len(scanner.scan_devices()) assert 2 == len(scanner.scan_devices())
assert "Device1" == \ assert "Device1" == \
@ -240,9 +229,10 @@ class TestXiaomiDeviceScanner(unittest.TestCase):
assert "Device2" == \ assert "Device2" == \
scanner.get_device_name("1D:98:EC:5E:D5:A6") scanner.get_device_name("1D:98:EC:5E:D5:A6")
@patch('requests.get', side_effect=mocked_requests) @patch('requests.get', side_effect=mocked_requests)
@patch('requests.post', side_effect=mocked_requests) @patch('requests.post', side_effect=mocked_requests)
def test_token_timed_out(self, mock_get, mock_post): async def test_token_timed_out(mock_get, mock_post, hass):
"""Testing refresh with a timed out token. """Testing refresh with a timed out token.
New token is requested and list is downloaded a second time. New token is requested and list is downloaded a second time.
@ -255,7 +245,7 @@ class TestXiaomiDeviceScanner(unittest.TestCase):
CONF_PASSWORD: 'passwordTest' CONF_PASSWORD: 'passwordTest'
}) })
} }
scanner = get_scanner(self.hass, config) scanner = get_scanner(hass, config)
assert scanner is not None assert scanner is not None
assert 2 == len(scanner.scan_devices()) assert 2 == len(scanner.scan_devices())
assert "Device1" == \ assert "Device1" == \