2018-02-25 09:58:13 +00:00
|
|
|
"""Tests for the HomeKit component."""
|
2018-02-19 22:46:22 +00:00
|
|
|
import unittest
|
2018-03-15 01:48:21 +00:00
|
|
|
from unittest.mock import call, patch, ANY, Mock
|
2018-03-01 23:20:02 +00:00
|
|
|
|
2018-02-19 22:46:22 +00:00
|
|
|
from homeassistant import setup
|
2018-03-15 01:48:21 +00:00
|
|
|
from homeassistant.core import State
|
|
|
|
from homeassistant.components.homekit import HomeKit, generate_aid
|
|
|
|
from homeassistant.components.homekit.accessories import HomeBridge
|
|
|
|
from homeassistant.components.homekit.const import (
|
|
|
|
DOMAIN, HOMEKIT_FILE, CONF_AUTO_START,
|
|
|
|
DEFAULT_PORT, SERVICE_HOMEKIT_START)
|
|
|
|
from homeassistant.helpers.entityfilter import generate_filter
|
2018-02-19 22:46:22 +00:00
|
|
|
from homeassistant.const import (
|
|
|
|
CONF_PORT, EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP)
|
|
|
|
|
|
|
|
from tests.common import get_test_home_assistant
|
|
|
|
|
2018-03-01 23:20:02 +00:00
|
|
|
IP_ADDRESS = '127.0.0.1'
|
2018-03-15 01:48:21 +00:00
|
|
|
PATH_HOMEKIT = 'homeassistant.components.homekit'
|
2018-02-19 22:46:22 +00:00
|
|
|
|
|
|
|
|
2018-02-25 09:58:13 +00:00
|
|
|
class TestHomeKit(unittest.TestCase):
|
|
|
|
"""Test setup of HomeKit component and HomeKit class."""
|
2018-02-19 22:46:22 +00:00
|
|
|
|
|
|
|
def setUp(self):
|
|
|
|
"""Setup things to be run when tests are started."""
|
|
|
|
self.hass = get_test_home_assistant()
|
|
|
|
|
|
|
|
def tearDown(self):
|
2018-02-25 09:58:13 +00:00
|
|
|
"""Stop down everything that was started."""
|
2018-02-19 22:46:22 +00:00
|
|
|
self.hass.stop()
|
|
|
|
|
2018-03-15 01:48:21 +00:00
|
|
|
def test_generate_aid(self):
|
|
|
|
"""Test generate aid method."""
|
|
|
|
aid = generate_aid('demo.entity')
|
|
|
|
self.assertIsInstance(aid, int)
|
|
|
|
self.assertTrue(aid >= 2 and aid <= 18446744073709551615)
|
2018-03-01 23:20:02 +00:00
|
|
|
|
2018-03-15 01:48:21 +00:00
|
|
|
with patch(PATH_HOMEKIT + '.adler32') as mock_adler32:
|
|
|
|
mock_adler32.side_effect = [0, 1]
|
|
|
|
self.assertIsNone(generate_aid('demo.entity'))
|
2018-02-19 22:46:22 +00:00
|
|
|
|
2018-03-01 23:20:02 +00:00
|
|
|
@patch(PATH_HOMEKIT + '.HomeKit')
|
|
|
|
def test_setup_min(self, mock_homekit):
|
2018-03-15 01:48:21 +00:00
|
|
|
"""Test async_setup with min config options."""
|
2018-02-19 22:46:22 +00:00
|
|
|
self.assertTrue(setup.setup_component(
|
2018-03-15 01:48:21 +00:00
|
|
|
self.hass, DOMAIN, {DOMAIN: {}}))
|
2018-02-19 22:46:22 +00:00
|
|
|
|
2018-03-15 01:48:21 +00:00
|
|
|
self.assertEqual(mock_homekit.mock_calls, [
|
|
|
|
call(self.hass, DEFAULT_PORT, ANY, {}),
|
|
|
|
call().setup()])
|
2018-02-19 22:46:22 +00:00
|
|
|
|
2018-03-15 01:48:21 +00:00
|
|
|
# Test auto start enabled
|
|
|
|
mock_homekit.reset_mock()
|
2018-03-01 23:20:02 +00:00
|
|
|
self.hass.bus.fire(EVENT_HOMEASSISTANT_START)
|
2018-02-19 22:46:22 +00:00
|
|
|
self.hass.block_till_done()
|
|
|
|
|
2018-03-15 01:48:21 +00:00
|
|
|
self.assertEqual(mock_homekit.mock_calls, [call().start(ANY)])
|
2018-02-19 22:46:22 +00:00
|
|
|
|
2018-03-01 23:20:02 +00:00
|
|
|
@patch(PATH_HOMEKIT + '.HomeKit')
|
2018-03-15 01:48:21 +00:00
|
|
|
def test_setup_auto_start_disabled(self, mock_homekit):
|
|
|
|
"""Test async_setup with auto start disabled and test service calls."""
|
|
|
|
mock_homekit.return_value = homekit = Mock()
|
|
|
|
|
|
|
|
config = {DOMAIN: {CONF_AUTO_START: False, CONF_PORT: 11111}}
|
2018-02-19 22:46:22 +00:00
|
|
|
self.assertTrue(setup.setup_component(
|
2018-03-15 01:48:21 +00:00
|
|
|
self.hass, DOMAIN, config))
|
2018-02-19 22:46:22 +00:00
|
|
|
|
2018-03-15 01:48:21 +00:00
|
|
|
self.hass.bus.fire(EVENT_HOMEASSISTANT_START)
|
|
|
|
self.hass.block_till_done()
|
|
|
|
|
|
|
|
self.assertEqual(mock_homekit.mock_calls, [
|
|
|
|
call(self.hass, 11111, ANY, {}),
|
|
|
|
call().setup()])
|
|
|
|
|
|
|
|
# Test start call with driver stopped.
|
|
|
|
homekit.reset_mock()
|
|
|
|
homekit.configure_mock(**{'started': False})
|
|
|
|
|
|
|
|
self.hass.services.call('homekit', 'start')
|
|
|
|
self.assertEqual(homekit.mock_calls, [call.start()])
|
2018-02-19 22:46:22 +00:00
|
|
|
|
2018-03-15 01:48:21 +00:00
|
|
|
# Test start call with driver started.
|
|
|
|
homekit.reset_mock()
|
|
|
|
homekit.configure_mock(**{'started': True})
|
2018-02-19 22:46:22 +00:00
|
|
|
|
2018-03-15 01:48:21 +00:00
|
|
|
self.hass.services.call(DOMAIN, SERVICE_HOMEKIT_START)
|
|
|
|
self.assertEqual(homekit.mock_calls, [])
|
2018-02-19 22:46:22 +00:00
|
|
|
|
2018-03-15 01:48:21 +00:00
|
|
|
def test_homekit_setup(self):
|
|
|
|
"""Test setup of bridge and driver."""
|
|
|
|
homekit = HomeKit(self.hass, DEFAULT_PORT, {}, {})
|
|
|
|
|
|
|
|
with patch(PATH_HOMEKIT + '.accessories.HomeDriver') as mock_driver, \
|
2018-03-01 23:20:02 +00:00
|
|
|
patch('homeassistant.util.get_local_ip') as mock_ip:
|
|
|
|
mock_ip.return_value = IP_ADDRESS
|
2018-03-15 01:48:21 +00:00
|
|
|
homekit.setup()
|
2018-02-25 09:58:13 +00:00
|
|
|
|
|
|
|
path = self.hass.config.path(HOMEKIT_FILE)
|
2018-03-15 01:48:21 +00:00
|
|
|
self.assertTrue(isinstance(homekit.bridge, HomeBridge))
|
|
|
|
self.assertEqual(mock_driver.mock_calls, [
|
|
|
|
call(homekit.bridge, DEFAULT_PORT, IP_ADDRESS, path)])
|
|
|
|
|
|
|
|
# Test if stop listener is setup
|
|
|
|
self.assertEqual(
|
|
|
|
self.hass.bus.listeners.get(EVENT_HOMEASSISTANT_STOP), 1)
|
|
|
|
|
|
|
|
def test_homekit_add_accessory(self):
|
|
|
|
"""Add accessory if config exists and get_acc returns an accessory."""
|
|
|
|
homekit = HomeKit(self.hass, None, lambda entity_id: True, {})
|
|
|
|
homekit.bridge = HomeBridge(self.hass)
|
|
|
|
|
|
|
|
with patch(PATH_HOMEKIT + '.accessories.HomeBridge.add_accessory') \
|
|
|
|
as mock_add_acc, \
|
|
|
|
patch(PATH_HOMEKIT + '.get_accessory') as mock_get_acc:
|
|
|
|
mock_get_acc.side_effect = [None, 'acc', None]
|
|
|
|
homekit.add_bridge_accessory(State('light.demo', 'on'))
|
|
|
|
self.assertEqual(mock_get_acc.call_args,
|
|
|
|
call(self.hass, ANY, 363398124, {}))
|
|
|
|
self.assertFalse(mock_add_acc.called)
|
|
|
|
homekit.add_bridge_accessory(State('demo.test', 'on'))
|
|
|
|
self.assertEqual(mock_get_acc.call_args,
|
|
|
|
call(self.hass, ANY, 294192020, {}))
|
|
|
|
self.assertTrue(mock_add_acc.called)
|
|
|
|
homekit.add_bridge_accessory(State('demo.test_2', 'on'))
|
|
|
|
self.assertEqual(mock_get_acc.call_args,
|
|
|
|
call(self.hass, ANY, 429982757, {}))
|
|
|
|
self.assertEqual(mock_add_acc.mock_calls, [call('acc')])
|
|
|
|
|
|
|
|
def test_homekit_entity_filter(self):
|
|
|
|
"""Test the entity filter."""
|
|
|
|
entity_filter = generate_filter(['cover'], ['demo.test'], [], [])
|
|
|
|
homekit = HomeKit(self.hass, None, entity_filter, {})
|
|
|
|
|
|
|
|
with patch(PATH_HOMEKIT + '.get_accessory') as mock_get_acc:
|
|
|
|
mock_get_acc.return_value = None
|
|
|
|
|
|
|
|
homekit.add_bridge_accessory(State('cover.test', 'open'))
|
|
|
|
self.assertTrue(mock_get_acc.called)
|
|
|
|
mock_get_acc.reset_mock()
|
|
|
|
|
|
|
|
homekit.add_bridge_accessory(State('demo.test', 'on'))
|
|
|
|
self.assertTrue(mock_get_acc.called)
|
|
|
|
mock_get_acc.reset_mock()
|
|
|
|
|
|
|
|
homekit.add_bridge_accessory(State('light.demo', 'light'))
|
|
|
|
self.assertFalse(mock_get_acc.called)
|
|
|
|
|
|
|
|
@patch(PATH_HOMEKIT + '.show_setup_message')
|
|
|
|
@patch(PATH_HOMEKIT + '.HomeKit.add_bridge_accessory')
|
|
|
|
def test_homekit_start(self, mock_add_bridge_acc, mock_show_setup_msg):
|
|
|
|
"""Test HomeKit start method."""
|
|
|
|
homekit = HomeKit(self.hass, None, {}, {'cover.demo': {}})
|
|
|
|
homekit.bridge = HomeBridge(self.hass)
|
|
|
|
homekit.driver = Mock()
|
|
|
|
|
|
|
|
self.hass.states.set('light.demo', 'on')
|
|
|
|
state = self.hass.states.all()[0]
|
|
|
|
|
|
|
|
homekit.start()
|
|
|
|
|
|
|
|
self.assertEqual(mock_add_bridge_acc.mock_calls, [call(state)])
|
|
|
|
self.assertEqual(mock_show_setup_msg.mock_calls, [
|
|
|
|
call(homekit.bridge, self.hass)])
|
|
|
|
self.assertEqual(homekit.driver.mock_calls, [call.start()])
|
|
|
|
self.assertTrue(homekit.started)
|
|
|
|
|
|
|
|
# Test start() if already started
|
|
|
|
homekit.driver.reset_mock()
|
|
|
|
homekit.start()
|
|
|
|
self.assertEqual(homekit.driver.mock_calls, [])
|
|
|
|
|
|
|
|
def test_homekit_stop(self):
|
|
|
|
"""Test HomeKit stop method."""
|
|
|
|
homekit = HomeKit(None, None, None, None)
|
|
|
|
homekit.driver = Mock()
|
|
|
|
|
|
|
|
# Test if started = False
|
|
|
|
homekit.stop()
|
|
|
|
self.assertFalse(homekit.driver.stop.called)
|
|
|
|
|
|
|
|
# Test if driver not started
|
|
|
|
homekit.started = True
|
|
|
|
homekit.driver.configure_mock(**{'run_sentinel': None})
|
|
|
|
homekit.stop()
|
|
|
|
self.assertFalse(homekit.driver.stop.called)
|
|
|
|
|
|
|
|
# Test if driver is started
|
|
|
|
homekit.driver.configure_mock(**{'run_sentinel': 'sentinel'})
|
|
|
|
homekit.stop()
|
|
|
|
self.assertTrue(homekit.driver.stop.called)
|