1
0
mirror of https://github.com/home-assistant/core.git synced 2025-12-24 21:06:19 +00:00
This commit is contained in:
Paulus Schoutsen
2019-07-31 12:25:30 -07:00
parent da05dfe708
commit 4de97abc3a
2676 changed files with 163166 additions and 140084 deletions

View File

@@ -8,16 +8,36 @@ from unittest.mock import patch, Mock
import pytest
from homeassistant.components.homekit.accessories import (
debounce, HomeAccessory, HomeBridge, HomeDriver)
debounce,
HomeAccessory,
HomeBridge,
HomeDriver,
)
from homeassistant.components.homekit.const import (
ATTR_DISPLAY_NAME, ATTR_VALUE,
BRIDGE_MODEL, BRIDGE_NAME, BRIDGE_SERIAL_NUMBER, CHAR_FIRMWARE_REVISION,
CHAR_MANUFACTURER, CHAR_MODEL, CHAR_NAME, CHAR_SERIAL_NUMBER,
CONF_LINKED_BATTERY_SENSOR, CONF_LOW_BATTERY_THRESHOLD,
MANUFACTURER, SERV_ACCESSORY_INFO)
ATTR_DISPLAY_NAME,
ATTR_VALUE,
BRIDGE_MODEL,
BRIDGE_NAME,
BRIDGE_SERIAL_NUMBER,
CHAR_FIRMWARE_REVISION,
CHAR_MANUFACTURER,
CHAR_MODEL,
CHAR_NAME,
CHAR_SERIAL_NUMBER,
CONF_LINKED_BATTERY_SENSOR,
CONF_LOW_BATTERY_THRESHOLD,
MANUFACTURER,
SERV_ACCESSORY_INFO,
)
from homeassistant.const import (
__version__, ATTR_BATTERY_CHARGING, ATTR_BATTERY_LEVEL, ATTR_ENTITY_ID,
ATTR_SERVICE, ATTR_NOW, EVENT_TIME_CHANGED)
__version__,
ATTR_BATTERY_CHARGING,
ATTR_BATTERY_LEVEL,
ATTR_ENTITY_ID,
ATTR_SERVICE,
ATTR_NOW,
EVENT_TIME_CHANGED,
)
import homeassistant.util.dt as dt_util
from tests.common import async_mock_service
@@ -25,6 +45,7 @@ from tests.common import async_mock_service
async def test_debounce(hass):
"""Test add_timeout decorator function."""
def demo_func(*args):
nonlocal arguments, counter
counter += 1
@@ -35,51 +56,49 @@ async def test_debounce(hass):
mock = Mock(hass=hass, debounce={})
debounce_demo = debounce(demo_func)
assert debounce_demo.__name__ == 'demo_func'
assert debounce_demo.__name__ == "demo_func"
now = datetime(2018, 1, 1, 20, 0, 0, tzinfo=dt_util.UTC)
with patch('homeassistant.util.dt.utcnow', return_value=now):
await hass.async_add_job(debounce_demo, mock, 'value')
hass.bus.async_fire(
EVENT_TIME_CHANGED, {ATTR_NOW: now + timedelta(seconds=3)})
with patch("homeassistant.util.dt.utcnow", return_value=now):
await hass.async_add_job(debounce_demo, mock, "value")
hass.bus.async_fire(EVENT_TIME_CHANGED, {ATTR_NOW: now + timedelta(seconds=3)})
await hass.async_block_till_done()
assert counter == 1
assert len(arguments) == 2
with patch('homeassistant.util.dt.utcnow', return_value=now):
await hass.async_add_job(debounce_demo, mock, 'value')
await hass.async_add_job(debounce_demo, mock, 'value')
with patch("homeassistant.util.dt.utcnow", return_value=now):
await hass.async_add_job(debounce_demo, mock, "value")
await hass.async_add_job(debounce_demo, mock, "value")
hass.bus.async_fire(
EVENT_TIME_CHANGED, {ATTR_NOW: now + timedelta(seconds=3)})
hass.bus.async_fire(EVENT_TIME_CHANGED, {ATTR_NOW: now + timedelta(seconds=3)})
await hass.async_block_till_done()
assert counter == 2
async def test_home_accessory(hass, hk_driver):
"""Test HomeAccessory class."""
entity_id = 'homekit.accessory'
entity_id = "homekit.accessory"
hass.states.async_set(entity_id, None)
await hass.async_block_till_done()
acc = HomeAccessory(hass, hk_driver, 'Home Accessory', entity_id, 2, None)
acc = HomeAccessory(hass, hk_driver, "Home Accessory", entity_id, 2, None)
assert acc.hass == hass
assert acc.display_name == 'Home Accessory'
assert acc.display_name == "Home Accessory"
assert acc.aid == 2
assert acc.category == 1 # Category.OTHER
assert len(acc.services) == 1
serv = acc.services[0] # SERV_ACCESSORY_INFO
assert serv.display_name == SERV_ACCESSORY_INFO
assert serv.get_characteristic(CHAR_NAME).value == 'Home Accessory'
assert serv.get_characteristic(CHAR_NAME).value == "Home Accessory"
assert serv.get_characteristic(CHAR_MANUFACTURER).value == MANUFACTURER
assert serv.get_characteristic(CHAR_MODEL).value == 'Homekit'
assert serv.get_characteristic(CHAR_SERIAL_NUMBER).value == \
'homekit.accessory'
assert serv.get_characteristic(CHAR_MODEL).value == "Homekit"
assert serv.get_characteristic(CHAR_SERIAL_NUMBER).value == "homekit.accessory"
hass.states.async_set(entity_id, 'on')
hass.states.async_set(entity_id, "on")
await hass.async_block_till_done()
with patch('homeassistant.components.homekit.accessories.'
'HomeAccessory.update_state') as mock_update_state:
with patch(
"homeassistant.components.homekit.accessories." "HomeAccessory.update_state"
) as mock_update_state:
await hass.async_add_job(acc.run)
await hass.async_block_till_done()
state = hass.states.get(entity_id)
@@ -90,24 +109,24 @@ async def test_home_accessory(hass, hk_driver):
assert mock_update_state.call_count == 1
with pytest.raises(NotImplementedError):
acc.update_state('new_state')
acc.update_state("new_state")
# Test model name from domain
entity_id = 'test_model.demo'
entity_id = "test_model.demo"
hass.states.async_set(entity_id, None)
await hass.async_block_till_done()
acc = HomeAccessory(hass, hk_driver, 'test_name', entity_id, 2, None)
acc = HomeAccessory(hass, hk_driver, "test_name", entity_id, 2, None)
serv = acc.services[0] # SERV_ACCESSORY_INFO
assert serv.get_characteristic(CHAR_MODEL).value == 'Test Model'
assert serv.get_characteristic(CHAR_MODEL).value == "Test Model"
async def test_battery_service(hass, hk_driver, caplog):
"""Test battery service."""
entity_id = 'homekit.accessory'
entity_id = "homekit.accessory"
hass.states.async_set(entity_id, None, {ATTR_BATTERY_LEVEL: 50})
await hass.async_block_till_done()
acc = HomeAccessory(hass, hk_driver, 'Battery Service', entity_id, 2, None)
acc = HomeAccessory(hass, hk_driver, "Battery Service", entity_id, 2, None)
acc.update_state = lambda x: None
assert acc._char_battery.value == 0
assert acc._char_low_battery.value == 0
@@ -125,19 +144,20 @@ async def test_battery_service(hass, hk_driver, caplog):
assert acc._char_low_battery.value == 1
assert acc._char_charging.value == 2
hass.states.async_set(entity_id, None, {ATTR_BATTERY_LEVEL: 'error'})
hass.states.async_set(entity_id, None, {ATTR_BATTERY_LEVEL: "error"})
await hass.async_block_till_done()
assert acc._char_battery.value == 15
assert acc._char_low_battery.value == 1
assert acc._char_charging.value == 2
assert 'ERROR' not in caplog.text
assert "ERROR" not in caplog.text
# Test charging
hass.states.async_set(entity_id, None, {
ATTR_BATTERY_LEVEL: 10, ATTR_BATTERY_CHARGING: True})
hass.states.async_set(
entity_id, None, {ATTR_BATTERY_LEVEL: 10, ATTR_BATTERY_CHARGING: True}
)
await hass.async_block_till_done()
acc = HomeAccessory(hass, hk_driver, 'Battery Service', entity_id, 2, None)
acc = HomeAccessory(hass, hk_driver, "Battery Service", entity_id, 2, None)
acc.update_state = lambda x: None
assert acc._char_battery.value == 0
assert acc._char_low_battery.value == 0
@@ -149,8 +169,9 @@ async def test_battery_service(hass, hk_driver, caplog):
assert acc._char_low_battery.value == 1
assert acc._char_charging.value == 1
hass.states.async_set(entity_id, None, {
ATTR_BATTERY_LEVEL: 100, ATTR_BATTERY_CHARGING: False})
hass.states.async_set(
entity_id, None, {ATTR_BATTERY_LEVEL: 100, ATTR_BATTERY_CHARGING: False}
)
await hass.async_block_till_done()
assert acc._char_battery.value == 100
assert acc._char_low_battery.value == 0
@@ -159,14 +180,20 @@ async def test_battery_service(hass, hk_driver, caplog):
async def test_linked_battery_sensor(hass, hk_driver, caplog):
"""Test battery service with linked_battery_sensor."""
entity_id = 'homekit.accessory'
linked_battery = 'sensor.battery'
hass.states.async_set(entity_id, 'open', {ATTR_BATTERY_LEVEL: 100})
entity_id = "homekit.accessory"
linked_battery = "sensor.battery"
hass.states.async_set(entity_id, "open", {ATTR_BATTERY_LEVEL: 100})
hass.states.async_set(linked_battery, 50, None)
await hass.async_block_till_done()
acc = HomeAccessory(hass, hk_driver, 'Battery Service', entity_id, 2,
{CONF_LINKED_BATTERY_SENSOR: linked_battery})
acc = HomeAccessory(
hass,
hk_driver,
"Battery Service",
entity_id,
2,
{CONF_LINKED_BATTERY_SENSOR: linked_battery},
)
acc.update_state = lambda x: None
assert acc.linked_battery_sensor == linked_battery
@@ -182,23 +209,28 @@ async def test_linked_battery_sensor(hass, hk_driver, caplog):
assert acc._char_low_battery.value == 1
# Ignore battery change on entity if it has linked_battery
hass.states.async_set(entity_id, 'open', {ATTR_BATTERY_LEVEL: 90})
hass.states.async_set(entity_id, "open", {ATTR_BATTERY_LEVEL: 90})
await hass.async_block_till_done()
assert acc._char_battery.value == 10
# Test none numeric state for linked_battery
hass.states.async_set(linked_battery, 'error', None)
hass.states.async_set(linked_battery, "error", None)
await hass.async_block_till_done()
assert acc._char_battery.value == 10
assert 'ERROR' not in caplog.text
assert "ERROR" not in caplog.text
# Test charging & low battery threshold
hass.states.async_set(linked_battery, 20, {ATTR_BATTERY_CHARGING: True})
await hass.async_block_till_done()
acc = HomeAccessory(hass, hk_driver, 'Battery Service', entity_id, 2,
{CONF_LINKED_BATTERY_SENSOR: linked_battery,
CONF_LOW_BATTERY_THRESHOLD: 50})
acc = HomeAccessory(
hass,
hk_driver,
"Battery Service",
entity_id,
2,
{CONF_LINKED_BATTERY_SENSOR: linked_battery, CONF_LOW_BATTERY_THRESHOLD: 50},
)
acc.update_state = lambda x: None
await hass.async_add_job(acc.run)
await hass.async_block_till_done()
@@ -215,19 +247,20 @@ async def test_linked_battery_sensor(hass, hk_driver, caplog):
async def test_call_service(hass, hk_driver, events):
"""Test call_service method."""
entity_id = 'homekit.accessory'
entity_id = "homekit.accessory"
hass.states.async_set(entity_id, None)
await hass.async_block_till_done()
acc = HomeAccessory(hass, hk_driver, 'Home Accessory', entity_id, 2, None)
call_service = async_mock_service(hass, 'cover', 'open_cover')
acc = HomeAccessory(hass, hk_driver, "Home Accessory", entity_id, 2, None)
call_service = async_mock_service(hass, "cover", "open_cover")
test_domain = 'cover'
test_service = 'open_cover'
test_value = 'value'
test_domain = "cover"
test_service = "open_cover"
test_value = "value"
await acc.async_call_service(
test_domain, test_service, {ATTR_ENTITY_ID: entity_id}, test_value)
test_domain, test_service, {ATTR_ENTITY_ID: entity_id}, test_value
)
await hass.async_block_till_done()
assert len(events) == 1
@@ -235,7 +268,7 @@ async def test_call_service(hass, hk_driver, events):
ATTR_ENTITY_ID: acc.entity_id,
ATTR_DISPLAY_NAME: acc.display_name,
ATTR_SERVICE: test_service,
ATTR_VALUE: test_value
ATTR_VALUE: test_value,
}
assert len(call_service) == 1
@@ -246,8 +279,8 @@ async def test_call_service(hass, hk_driver, events):
def test_home_bridge(hk_driver):
"""Test HomeBridge class."""
bridge = HomeBridge('hass', hk_driver, BRIDGE_NAME)
assert bridge.hass == 'hass'
bridge = HomeBridge("hass", hk_driver, BRIDGE_NAME)
assert bridge.hass == "hass"
assert bridge.display_name == BRIDGE_NAME
assert bridge.category == 2 # Category.BRIDGE
assert len(bridge.services) == 1
@@ -257,11 +290,10 @@ def test_home_bridge(hk_driver):
assert serv.get_characteristic(CHAR_FIRMWARE_REVISION).value == __version__
assert serv.get_characteristic(CHAR_MANUFACTURER).value == MANUFACTURER
assert serv.get_characteristic(CHAR_MODEL).value == BRIDGE_MODEL
assert serv.get_characteristic(CHAR_SERIAL_NUMBER).value == \
BRIDGE_SERIAL_NUMBER
assert serv.get_characteristic(CHAR_SERIAL_NUMBER).value == BRIDGE_SERIAL_NUMBER
bridge = HomeBridge('hass', hk_driver, 'test_name')
assert bridge.display_name == 'test_name'
bridge = HomeBridge("hass", hk_driver, "test_name")
assert bridge.display_name == "test_name"
assert len(bridge.services) == 1
serv = bridge.services[0] # SERV_ACCESSORY_INFO
@@ -271,35 +303,31 @@ def test_home_bridge(hk_driver):
def test_home_driver():
"""Test HomeDriver class."""
ip_address = '127.0.0.1'
ip_address = "127.0.0.1"
port = 51826
path = '.homekit.state'
pin = b'123-45-678'
path = ".homekit.state"
pin = b"123-45-678"
with patch('pyhap.accessory_driver.AccessoryDriver.__init__') \
as mock_driver:
driver = HomeDriver('hass', address=ip_address, port=port,
persist_file=path)
with patch("pyhap.accessory_driver.AccessoryDriver.__init__") as mock_driver:
driver = HomeDriver("hass", address=ip_address, port=port, persist_file=path)
mock_driver.assert_called_with(address=ip_address, port=port,
persist_file=path)
mock_driver.assert_called_with(address=ip_address, port=port, persist_file=path)
driver.state = Mock(pincode=pin)
# pair
with patch('pyhap.accessory_driver.AccessoryDriver.pair') as mock_pair, \
patch('homeassistant.components.homekit.accessories.'
'dismiss_setup_message') as mock_dissmiss_msg:
driver.pair('client_uuid', 'client_public')
with patch("pyhap.accessory_driver.AccessoryDriver.pair") as mock_pair, patch(
"homeassistant.components.homekit.accessories." "dismiss_setup_message"
) as mock_dissmiss_msg:
driver.pair("client_uuid", "client_public")
mock_pair.assert_called_with('client_uuid', 'client_public')
mock_dissmiss_msg.assert_called_with('hass')
mock_pair.assert_called_with("client_uuid", "client_public")
mock_dissmiss_msg.assert_called_with("hass")
# unpair
with patch('pyhap.accessory_driver.AccessoryDriver.unpair') \
as mock_unpair, \
patch('homeassistant.components.homekit.accessories.'
'show_setup_message') as mock_show_msg:
driver.unpair('client_uuid')
with patch("pyhap.accessory_driver.AccessoryDriver.unpair") as mock_unpair, patch(
"homeassistant.components.homekit.accessories." "show_setup_message"
) as mock_show_msg:
driver.unpair("client_uuid")
mock_unpair.assert_called_with('client_uuid')
mock_show_msg.assert_called_with('hass', pin)
mock_unpair.assert_called_with("client_uuid")
mock_show_msg.assert_called_with("hass", pin)