core/tests/components/homekit/test_homekit.py

192 lines
7.3 KiB
Python
Raw Normal View History

"""Tests for the HomeKit component."""
import unittest
from unittest.mock import call, patch, ANY, Mock
from homeassistant import setup
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
from homeassistant.const import (
CONF_PORT, EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP)
from tests.common import get_test_home_assistant
IP_ADDRESS = '127.0.0.1'
PATH_HOMEKIT = 'homeassistant.components.homekit'
class TestHomeKit(unittest.TestCase):
"""Test setup of HomeKit component and HomeKit class."""
def setUp(self):
"""Setup things to be run when tests are started."""
self.hass = get_test_home_assistant()
def tearDown(self):
"""Stop down everything that was started."""
self.hass.stop()
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)
with patch(PATH_HOMEKIT + '.adler32') as mock_adler32:
mock_adler32.side_effect = [0, 1]
self.assertIsNone(generate_aid('demo.entity'))
@patch(PATH_HOMEKIT + '.HomeKit')
def test_setup_min(self, mock_homekit):
"""Test async_setup with min config options."""
self.assertTrue(setup.setup_component(
self.hass, DOMAIN, {DOMAIN: {}}))
self.assertEqual(mock_homekit.mock_calls, [
call(self.hass, DEFAULT_PORT, ANY, {}),
call().setup()])
# Test auto start enabled
mock_homekit.reset_mock()
self.hass.bus.fire(EVENT_HOMEASSISTANT_START)
self.hass.block_till_done()
self.assertEqual(mock_homekit.mock_calls, [call().start(ANY)])
@patch(PATH_HOMEKIT + '.HomeKit')
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}}
self.assertTrue(setup.setup_component(
self.hass, DOMAIN, config))
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()])
# Test start call with driver started.
homekit.reset_mock()
homekit.configure_mock(**{'started': True})
self.hass.services.call(DOMAIN, SERVICE_HOMEKIT_START)
self.assertEqual(homekit.mock_calls, [])
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, \
patch('homeassistant.util.get_local_ip') as mock_ip:
mock_ip.return_value = IP_ADDRESS
homekit.setup()
path = self.hass.config.path(HOMEKIT_FILE)
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)