1
0
mirror of https://github.com/home-assistant/core.git synced 2025-12-24 12:59:34 +00:00

Rewritten HomeKit tests (#14377)

* Use pytest fixtures and parametrize
* Use async
This commit is contained in:
cdce8p
2018-05-11 01:21:59 +02:00
committed by GitHub
parent 6843893d9f
commit 8fcf085829
11 changed files with 1255 additions and 1591 deletions

View File

@@ -1,6 +1,7 @@
"""Tests for the HomeKit component."""
import unittest
from unittest.mock import call, patch, ANY, Mock
from unittest.mock import patch, ANY, Mock
import pytest
from homeassistant import setup
from homeassistant.core import State
@@ -16,208 +17,193 @@ from homeassistant.const import (
CONF_IP_ADDRESS, CONF_PORT,
EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP)
from tests.common import get_test_home_assistant
from tests.components.homekit.test_accessories import patch_debounce
IP_ADDRESS = '127.0.0.1'
PATH_HOMEKIT = 'homeassistant.components.homekit'
class TestHomeKit(unittest.TestCase):
"""Test setup of HomeKit component and HomeKit class."""
@pytest.fixture('module')
def debounce_patcher(request):
"""Patch debounce method."""
patcher = patch_debounce()
patcher.start()
request.addfinalizer(patcher.stop)
@classmethod
def setUpClass(cls):
"""Setup debounce patcher."""
cls.patcher = patch_debounce()
cls.patcher.start()
@classmethod
def tearDownClass(cls):
"""Stop debounce patcher."""
cls.patcher.stop()
def test_generate_aid():
"""Test generate aid method."""
aid = generate_aid('demo.entity')
assert isinstance(aid, int)
assert aid >= 2 and aid <= 18446744073709551615
def setUp(self):
"""Setup things to be run when tests are started."""
self.hass = get_test_home_assistant()
with patch(PATH_HOMEKIT + '.adler32') as mock_adler32:
mock_adler32.side_effect = [0, 1]
assert generate_aid('demo.entity') is None
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)
async def test_setup_min(hass):
"""Test async_setup with min config options."""
with patch(PATH_HOMEKIT + '.HomeKit') as mock_homekit:
assert await setup.async_setup_component(
hass, DOMAIN, {DOMAIN: {}})
with patch(PATH_HOMEKIT + '.adler32') as mock_adler32:
mock_adler32.side_effect = [0, 1]
self.assertIsNone(generate_aid('demo.entity'))
mock_homekit.assert_any_call(hass, DEFAULT_PORT, None, ANY, {})
assert mock_homekit().setup.called is True
@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: {}}))
# Test auto start enabled
mock_homekit.reset_mock()
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
await hass.async_block_till_done()
self.assertEqual(mock_homekit.mock_calls, [
call(self.hass, DEFAULT_PORT, None, ANY, {}),
call().setup()])
mock_homekit().start.assert_called_with(ANY)
# 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)])
async def test_setup_auto_start_disabled(hass):
"""Test async_setup with auto start disabled and test service calls."""
config = {DOMAIN: {CONF_AUTO_START: False, CONF_PORT: 11111,
CONF_IP_ADDRESS: '172.0.0.0'}}
@patch(PATH_HOMEKIT + '.HomeKit')
def test_setup_auto_start_disabled(self, mock_homekit):
"""Test async_setup with auto start disabled and test service calls."""
with patch(PATH_HOMEKIT + '.HomeKit') as mock_homekit:
mock_homekit.return_value = homekit = Mock()
assert await setup.async_setup_component(
hass, DOMAIN, config)
config = {DOMAIN: {CONF_AUTO_START: False, CONF_PORT: 11111,
CONF_IP_ADDRESS: '172.0.0.0'}}
self.assertTrue(setup.setup_component(
self.hass, DOMAIN, config))
self.hass.block_till_done()
mock_homekit.assert_any_call(hass, 11111, '172.0.0.0', ANY, {})
assert mock_homekit().setup.called is True
self.assertEqual(mock_homekit.mock_calls, [
call(self.hass, 11111, '172.0.0.0', ANY, {}),
call().setup()])
# Test auto_start disabled
homekit.reset_mock()
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
await hass.async_block_till_done()
assert homekit.start.called is False
# Test auto_start disabled
homekit.reset_mock()
self.hass.bus.fire(EVENT_HOMEASSISTANT_START)
self.hass.block_till_done()
self.assertEqual(homekit.mock_calls, [])
# Test start call with driver is ready
homekit.reset_mock()
homekit.status = STATUS_READY
# Test start call with driver is ready
homekit.reset_mock()
homekit.status = STATUS_READY
await hass.services.async_call(
DOMAIN, SERVICE_HOMEKIT_START, blocking=True)
assert homekit.start.called is True
self.hass.services.call('homekit', 'start')
self.assertEqual(homekit.mock_calls, [call.start()])
# Test start call with driver started
homekit.reset_mock()
homekit.status = STATUS_STOPPED
# Test start call with driver started
homekit.reset_mock()
homekit.status = STATUS_STOPPED
await hass.services.async_call(
DOMAIN, SERVICE_HOMEKIT_START, blocking=True)
assert homekit.start.called is False
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, None, {}, {})
async def test_homekit_setup(hass):
"""Test setup of bridge and driver."""
homekit = HomeKit(hass, DEFAULT_PORT, None, {}, {})
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()
with patch(PATH_HOMEKIT + '.accessories.HomeDriver') as mock_driver, \
patch('homeassistant.util.get_local_ip') as mock_ip:
mock_ip.return_value = IP_ADDRESS
await hass.async_add_job(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)])
path = hass.config.path(HOMEKIT_FILE)
assert isinstance(homekit.bridge, HomeBridge)
mock_driver.assert_called_with(
homekit.bridge, DEFAULT_PORT, IP_ADDRESS, path)
# Test if stop listener is setup
self.assertEqual(
self.hass.bus.listeners.get(EVENT_HOMEASSISTANT_STOP), 1)
# Test if stop listener is setup
assert hass.bus.async_listeners().get(EVENT_HOMEASSISTANT_STOP) == 1
def test_homekit_setup_ip_address(self):
"""Test setup with given IP address."""
homekit = HomeKit(self.hass, DEFAULT_PORT, '172.0.0.0', {}, {})
with patch(PATH_HOMEKIT + '.accessories.HomeDriver') as mock_driver:
homekit.setup()
mock_driver.assert_called_with(ANY, DEFAULT_PORT, '172.0.0.0', ANY)
async def test_homekit_setup_ip_address(hass):
"""Test setup with given IP address."""
homekit = HomeKit(hass, DEFAULT_PORT, '172.0.0.0', {}, {})
def test_homekit_add_accessory(self):
"""Add accessory if config exists and get_acc returns an accessory."""
homekit = HomeKit(self.hass, None, None, lambda entity_id: True, {})
homekit.bridge = HomeBridge(self.hass)
with patch(PATH_HOMEKIT + '.accessories.HomeDriver') as mock_driver:
await hass.async_add_job(homekit.setup)
mock_driver.assert_called_with(ANY, DEFAULT_PORT, '172.0.0.0', ANY)
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, None, entity_filter, {})
async def test_homekit_add_accessory(hass):
"""Add accessory if config exists and get_acc returns an accessory."""
homekit = HomeKit(hass, None, None, lambda entity_id: True, {})
homekit.bridge = HomeBridge(hass)
with patch(PATH_HOMEKIT + '.get_accessory') as mock_get_acc:
mock_get_acc.return_value = None
with patch(PATH_HOMEKIT + '.accessories.HomeBridge.add_accessory') \
as mock_add_acc, \
patch(PATH_HOMEKIT + '.get_accessory') as mock_get_acc:
homekit.add_bridge_accessory(State('cover.test', 'open'))
self.assertTrue(mock_get_acc.called)
mock_get_acc.reset_mock()
mock_get_acc.side_effect = [None, 'acc', None]
homekit.add_bridge_accessory(State('light.demo', 'on'))
mock_get_acc.assert_called_with(hass, ANY, 363398124, {})
assert mock_add_acc.called is False
homekit.add_bridge_accessory(State('demo.test', 'on'))
self.assertTrue(mock_get_acc.called)
mock_get_acc.reset_mock()
homekit.add_bridge_accessory(State('demo.test', 'on'))
mock_get_acc.assert_called_with(hass, ANY, 294192020, {})
assert mock_add_acc.called is True
homekit.add_bridge_accessory(State('light.demo', 'light'))
self.assertFalse(mock_get_acc.called)
homekit.add_bridge_accessory(State('demo.test_2', 'on'))
mock_get_acc.assert_called_with(hass, ANY, 429982757, {})
mock_add_acc.assert_called_with('acc')
@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, None, {}, {'cover.demo': {}})
homekit.bridge = HomeBridge(self.hass)
homekit.driver = Mock()
self.hass.states.set('light.demo', 'on')
state = self.hass.states.all()[0]
async def test_homekit_entity_filter(hass):
"""Test the entity filter."""
entity_filter = generate_filter(['cover'], ['demo.test'], [], [])
homekit = HomeKit(hass, None, None, entity_filter, {})
homekit.start()
self.hass.block_till_done()
with patch(PATH_HOMEKIT + '.get_accessory') as mock_get_acc:
mock_get_acc.return_value = None
self.assertEqual(mock_add_bridge_acc.mock_calls, [call(state)])
self.assertEqual(mock_show_setup_msg.mock_calls, [
call(self.hass, homekit.bridge)])
self.assertEqual(homekit.driver.mock_calls, [call.start()])
self.assertEqual(homekit.status, STATUS_RUNNING)
homekit.add_bridge_accessory(State('cover.test', 'open'))
assert mock_get_acc.called is True
mock_get_acc.reset_mock()
# Test start() if already started
homekit.driver.reset_mock()
homekit.start()
self.hass.block_till_done()
self.assertEqual(homekit.driver.mock_calls, [])
homekit.add_bridge_accessory(State('demo.test', 'on'))
assert mock_get_acc.called is True
mock_get_acc.reset_mock()
def test_homekit_stop(self):
"""Test HomeKit stop method."""
homekit = HomeKit(self.hass, None, None, None, None)
homekit.driver = Mock()
homekit.add_bridge_accessory(State('light.demo', 'light'))
assert mock_get_acc.called is False
self.assertEqual(homekit.status, STATUS_READY)
homekit.stop()
self.hass.block_till_done()
homekit.status = STATUS_WAIT
homekit.stop()
self.hass.block_till_done()
homekit.status = STATUS_STOPPED
homekit.stop()
self.hass.block_till_done()
self.assertFalse(homekit.driver.stop.called)
# Test if driver is started
homekit.status = STATUS_RUNNING
homekit.stop()
self.hass.block_till_done()
self.assertTrue(homekit.driver.stop.called)
async def test_homekit_start(hass, debounce_patcher):
"""Test HomeKit start method."""
homekit = HomeKit(hass, None, None, {}, {'cover.demo': {}})
homekit.bridge = HomeBridge(hass)
homekit.driver = Mock()
hass.states.async_set('light.demo', 'on')
state = hass.states.async_all()[0]
with patch(PATH_HOMEKIT + '.HomeKit.add_bridge_accessory') as \
mock_add_acc, \
patch(PATH_HOMEKIT + '.show_setup_message') as mock_setup_msg:
await hass.async_add_job(homekit.start)
mock_add_acc.assert_called_with(state)
mock_setup_msg.assert_called_with(hass, homekit.bridge)
assert homekit.driver.start.called is True
assert homekit.status == STATUS_RUNNING
# Test start() if already started
homekit.driver.reset_mock()
await hass.async_add_job(homekit.start)
assert homekit.driver.start.called is False
async def test_homekit_stop(hass):
"""Test HomeKit stop method."""
homekit = HomeKit(hass, None, None, None, None)
homekit.driver = Mock()
assert homekit.status == STATUS_READY
await hass.async_add_job(homekit.stop)
homekit.status = STATUS_WAIT
await hass.async_add_job(homekit.stop)
homekit.status = STATUS_STOPPED
await hass.async_add_job(homekit.stop)
assert homekit.driver.stop.called is False
# Test if driver is started
homekit.status = STATUS_RUNNING
await hass.async_add_job(homekit.stop)
assert homekit.driver.stop.called is True