222 lines
8.0 KiB
Python
222 lines
8.0 KiB
Python
"""The tests for the Xiaomi router device tracker platform."""
|
|
import logging
|
|
import unittest
|
|
from unittest import mock
|
|
from unittest.mock import patch
|
|
|
|
import requests
|
|
|
|
from homeassistant.components.device_tracker import DOMAIN, xiaomi as xiaomi
|
|
from homeassistant.components.device_tracker.xiaomi import get_scanner
|
|
from homeassistant.const import (CONF_HOST, CONF_USERNAME, CONF_PASSWORD,
|
|
CONF_PLATFORM)
|
|
from tests.common import get_test_home_assistant
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
INVALID_USERNAME = 'bob'
|
|
URL_AUTHORIZE = 'http://192.168.0.1/cgi-bin/luci/api/xqsystem/login'
|
|
URL_LIST_END = 'api/misystem/devicelist'
|
|
|
|
|
|
def mocked_requests(*args, **kwargs):
|
|
"""Mock requests.get invocations."""
|
|
class MockResponse:
|
|
"""Class to represent a mocked response."""
|
|
|
|
def __init__(self, json_data, status_code):
|
|
"""Initialize the mock response class."""
|
|
self.json_data = json_data
|
|
self.status_code = status_code
|
|
|
|
def json(self):
|
|
"""Return the json of the response."""
|
|
return self.json_data
|
|
|
|
@property
|
|
def content(self):
|
|
"""Return the content of the response."""
|
|
return self.json()
|
|
|
|
def raise_for_status(self):
|
|
"""Raise an HTTPError if status is not 200."""
|
|
if self.status_code != 200:
|
|
raise requests.HTTPError(self.status_code)
|
|
|
|
data = kwargs.get('data')
|
|
|
|
if data and data.get('username', None) == INVALID_USERNAME:
|
|
return MockResponse({
|
|
"code": "401",
|
|
"msg": "Invalid token"
|
|
}, 200)
|
|
elif str(args[0]).startswith(URL_AUTHORIZE):
|
|
print("deliver authorized")
|
|
return MockResponse({
|
|
"url": "/cgi-bin/luci/;stok=ef5860/web/home",
|
|
"token": "ef5860",
|
|
"code": "0"
|
|
}, 200)
|
|
elif str(args[0]).endswith(URL_LIST_END):
|
|
return MockResponse({
|
|
"mac": "1C:98:EC:0E:D5:A4",
|
|
"list": [
|
|
{
|
|
"mac": "23:83:BF:F6:38:A0",
|
|
"oname": "12255ff",
|
|
"isap": 0,
|
|
"parent": "",
|
|
"authority": {
|
|
"wan": 1,
|
|
"pridisk": 0,
|
|
"admin": 1,
|
|
"lan": 0
|
|
},
|
|
"push": 0,
|
|
"online": 1,
|
|
"name": "Device1",
|
|
"times": 0,
|
|
"ip": [
|
|
{
|
|
"downspeed": "0",
|
|
"online": "496957",
|
|
"active": 1,
|
|
"upspeed": "0",
|
|
"ip": "192.168.0.25"
|
|
}
|
|
],
|
|
"statistics": {
|
|
"downspeed": "0",
|
|
"online": "496957",
|
|
"upspeed": "0"
|
|
},
|
|
"icon": "",
|
|
"type": 1
|
|
},
|
|
{
|
|
"mac": "1D:98:EC:5E:D5:A6",
|
|
"oname": "CdddFG58",
|
|
"isap": 0,
|
|
"parent": "",
|
|
"authority": {
|
|
"wan": 1,
|
|
"pridisk": 0,
|
|
"admin": 1,
|
|
"lan": 0
|
|
},
|
|
"push": 0,
|
|
"online": 1,
|
|
"name": "Device2",
|
|
"times": 0,
|
|
"ip": [
|
|
{
|
|
"downspeed": "0",
|
|
"online": "347325",
|
|
"active": 1,
|
|
"upspeed": "0",
|
|
"ip": "192.168.0.3"
|
|
}
|
|
],
|
|
"statistics": {
|
|
"downspeed": "0",
|
|
"online": "347325",
|
|
"upspeed": "0"
|
|
},
|
|
"icon": "",
|
|
"type": 0
|
|
},
|
|
],
|
|
"code": 0
|
|
}, 200)
|
|
else:
|
|
_LOGGER.debug('UNKNOWN ROUTE')
|
|
|
|
|
|
class TestXiaomiDeviceScanner(unittest.TestCase):
|
|
"""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.XioamiDeviceScanner',
|
|
return_value=mock.MagicMock())
|
|
def test_config(self, xiaomi_mock):
|
|
"""Testing minimal configuration."""
|
|
config = {
|
|
DOMAIN: xiaomi.PLATFORM_SCHEMA({
|
|
CONF_PLATFORM: xiaomi.DOMAIN,
|
|
CONF_HOST: '192.168.0.1',
|
|
CONF_PASSWORD: 'passwordTest'
|
|
})
|
|
}
|
|
xiaomi.get_scanner(self.hass, config)
|
|
self.assertEqual(xiaomi_mock.call_count, 1)
|
|
self.assertEqual(xiaomi_mock.call_args, mock.call(config[DOMAIN]))
|
|
call_arg = xiaomi_mock.call_args[0][0]
|
|
self.assertEqual(call_arg['username'], 'admin')
|
|
self.assertEqual(call_arg['password'], 'passwordTest')
|
|
self.assertEqual(call_arg['host'], '192.168.0.1')
|
|
self.assertEqual(call_arg['platform'], 'device_tracker')
|
|
|
|
@mock.patch(
|
|
'homeassistant.components.device_tracker.xiaomi.XioamiDeviceScanner',
|
|
return_value=mock.MagicMock())
|
|
def test_config_full(self, xiaomi_mock):
|
|
"""Testing full configuration."""
|
|
config = {
|
|
DOMAIN: xiaomi.PLATFORM_SCHEMA({
|
|
CONF_PLATFORM: xiaomi.DOMAIN,
|
|
CONF_HOST: '192.168.0.1',
|
|
CONF_USERNAME: 'alternativeAdminName',
|
|
CONF_PASSWORD: 'passwordTest'
|
|
})
|
|
}
|
|
xiaomi.get_scanner(self.hass, config)
|
|
self.assertEqual(xiaomi_mock.call_count, 1)
|
|
self.assertEqual(xiaomi_mock.call_args, mock.call(config[DOMAIN]))
|
|
call_arg = xiaomi_mock.call_args[0][0]
|
|
self.assertEqual(call_arg['username'], 'alternativeAdminName')
|
|
self.assertEqual(call_arg['password'], 'passwordTest')
|
|
self.assertEqual(call_arg['host'], '192.168.0.1')
|
|
self.assertEqual(call_arg['platform'], 'device_tracker')
|
|
|
|
@patch('requests.get', side_effect=mocked_requests)
|
|
@patch('requests.post', side_effect=mocked_requests)
|
|
def test_invalid_credential(self, mock_get, mock_post):
|
|
""""Testing invalid credential handling."""
|
|
config = {
|
|
DOMAIN: xiaomi.PLATFORM_SCHEMA({
|
|
CONF_PLATFORM: xiaomi.DOMAIN,
|
|
CONF_HOST: '192.168.0.1',
|
|
CONF_USERNAME: INVALID_USERNAME,
|
|
CONF_PASSWORD: 'passwordTest'
|
|
})
|
|
}
|
|
self.assertIsNone(get_scanner(self.hass, config))
|
|
|
|
@patch('requests.get', side_effect=mocked_requests)
|
|
@patch('requests.post', side_effect=mocked_requests)
|
|
def test_valid_credential(self, mock_get, mock_post):
|
|
""""Testing valid refresh."""
|
|
config = {
|
|
DOMAIN: xiaomi.PLATFORM_SCHEMA({
|
|
CONF_PLATFORM: xiaomi.DOMAIN,
|
|
CONF_HOST: '192.168.0.1',
|
|
CONF_USERNAME: 'admin',
|
|
CONF_PASSWORD: 'passwordTest'
|
|
})
|
|
}
|
|
scanner = get_scanner(self.hass, config)
|
|
self.assertIsNotNone(scanner)
|
|
self.assertEqual(2, len(scanner.scan_devices()))
|
|
self.assertEqual("Device1",
|
|
scanner.get_device_name("23:83:BF:F6:38:A0"))
|
|
self.assertEqual("Device2",
|
|
scanner.get_device_name("1D:98:EC:5E:D5:A6"))
|