Use registry to find linked batteries for homekit (#33519)
This commit is contained in:
parent
46920e9be6
commit
96649a7e27
12 changed files with 555 additions and 127 deletions
|
@ -1,10 +1,12 @@
|
|||
"""Tests for the HomeKit component."""
|
||||
from unittest.mock import ANY, Mock, patch
|
||||
|
||||
from asynctest import CoroutineMock
|
||||
import pytest
|
||||
from zeroconf import InterfaceChoice
|
||||
|
||||
from homeassistant import setup
|
||||
from homeassistant.components.binary_sensor import DEVICE_CLASS_BATTERY_CHARGING
|
||||
from homeassistant.components.homekit import (
|
||||
MAX_DEVICES,
|
||||
STATUS_READY,
|
||||
|
@ -27,22 +29,39 @@ from homeassistant.components.homekit.const import (
|
|||
SERVICE_HOMEKIT_START,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
ATTR_DEVICE_CLASS,
|
||||
ATTR_ENTITY_ID,
|
||||
CONF_IP_ADDRESS,
|
||||
CONF_NAME,
|
||||
CONF_PORT,
|
||||
DEVICE_CLASS_BATTERY,
|
||||
EVENT_HOMEASSISTANT_START,
|
||||
EVENT_HOMEASSISTANT_STOP,
|
||||
STATE_ON,
|
||||
)
|
||||
from homeassistant.core import State
|
||||
from homeassistant.helpers import device_registry
|
||||
from homeassistant.helpers.entityfilter import generate_filter
|
||||
|
||||
from tests.common import MockConfigEntry, mock_device_registry, mock_registry
|
||||
from tests.components.homekit.common import patch_debounce
|
||||
|
||||
IP_ADDRESS = "127.0.0.1"
|
||||
PATH_HOMEKIT = "homeassistant.components.homekit"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def device_reg(hass):
|
||||
"""Return an empty, loaded, registry."""
|
||||
return mock_device_registry(hass)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def entity_reg(hass):
|
||||
"""Return an empty, loaded, registry."""
|
||||
return mock_registry(hass)
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def debounce_patcher():
|
||||
"""Patch debounce method."""
|
||||
|
@ -66,7 +85,7 @@ async def test_setup_min(hass):
|
|||
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
mock_homekit().start.assert_called_with(ANY)
|
||||
mock_homekit().async_start.assert_called_with(ANY)
|
||||
|
||||
|
||||
async def test_setup_auto_start_disabled(hass):
|
||||
|
@ -83,6 +102,7 @@ async def test_setup_auto_start_disabled(hass):
|
|||
|
||||
with patch(f"{PATH_HOMEKIT}.HomeKit") as mock_homekit:
|
||||
mock_homekit.return_value = homekit = Mock()
|
||||
type(homekit).async_start = CoroutineMock()
|
||||
assert await setup.async_setup_component(hass, DOMAIN, config)
|
||||
|
||||
mock_homekit.assert_any_call(
|
||||
|
@ -92,23 +112,26 @@ async def test_setup_auto_start_disabled(hass):
|
|||
|
||||
# Test auto_start disabled
|
||||
homekit.reset_mock()
|
||||
homekit.async_start.reset_mock()
|
||||
hass.bus.async_fire(EVENT_HOMEASSISTANT_START)
|
||||
await hass.async_block_till_done()
|
||||
assert homekit.start.called is False
|
||||
assert homekit.async_start.called is False
|
||||
|
||||
# Test start call with driver is ready
|
||||
homekit.reset_mock()
|
||||
homekit.async_start.reset_mock()
|
||||
homekit.status = STATUS_READY
|
||||
|
||||
await hass.services.async_call(DOMAIN, SERVICE_HOMEKIT_START, blocking=True)
|
||||
assert homekit.start.called is True
|
||||
assert homekit.async_start.called is True
|
||||
|
||||
# Test start call with driver started
|
||||
homekit.reset_mock()
|
||||
homekit.async_start.reset_mock()
|
||||
homekit.status = STATUS_STOPPED
|
||||
|
||||
await hass.services.async_call(DOMAIN, SERVICE_HOMEKIT_START, blocking=True)
|
||||
assert homekit.start.called is False
|
||||
assert homekit.async_start.called is False
|
||||
|
||||
|
||||
async def test_homekit_setup(hass, hk_driver):
|
||||
|
@ -279,6 +302,7 @@ async def test_homekit_start(hass, hk_driver, debounce_patcher):
|
|||
homekit.bridge = Mock()
|
||||
homekit.bridge.accessories = []
|
||||
homekit.driver = hk_driver
|
||||
homekit._filter = Mock(return_value=True)
|
||||
|
||||
hass.states.async_set("light.demo", "on")
|
||||
state = hass.states.async_all()[0]
|
||||
|
@ -290,7 +314,7 @@ async def test_homekit_start(hass, hk_driver, debounce_patcher):
|
|||
) as hk_driver_add_acc, patch(
|
||||
"pyhap.accessory_driver.AccessoryDriver.start"
|
||||
) as hk_driver_start:
|
||||
await hass.async_add_executor_job(homekit.start)
|
||||
await homekit.async_start()
|
||||
|
||||
mock_add_acc.assert_called_with(state)
|
||||
mock_setup_msg.assert_called_with(hass, pin, ANY)
|
||||
|
@ -300,7 +324,7 @@ async def test_homekit_start(hass, hk_driver, debounce_patcher):
|
|||
|
||||
# Test start() if already started
|
||||
hk_driver_start.reset_mock()
|
||||
await hass.async_add_executor_job(homekit.start)
|
||||
await homekit.async_start()
|
||||
assert not hk_driver_start.called
|
||||
|
||||
|
||||
|
@ -326,7 +350,7 @@ async def test_homekit_start_with_a_broken_accessory(hass, hk_driver, debounce_p
|
|||
) as hk_driver_add_acc, patch(
|
||||
"pyhap.accessory_driver.AccessoryDriver.start"
|
||||
) as hk_driver_start:
|
||||
await hass.async_add_executor_job(homekit.start)
|
||||
await homekit.async_start()
|
||||
|
||||
mock_setup_msg.assert_called_with(hass, pin, ANY)
|
||||
hk_driver_add_acc.assert_called_with(homekit.bridge)
|
||||
|
@ -335,7 +359,7 @@ async def test_homekit_start_with_a_broken_accessory(hass, hk_driver, debounce_p
|
|||
|
||||
# Test start() if already started
|
||||
hk_driver_start.reset_mock()
|
||||
await hass.async_add_executor_job(homekit.start)
|
||||
await homekit.async_start()
|
||||
assert not hk_driver_start.called
|
||||
|
||||
|
||||
|
@ -344,17 +368,23 @@ async def test_homekit_stop(hass):
|
|||
homekit = HomeKit(hass, None, None, None, None, None, None)
|
||||
homekit.driver = Mock()
|
||||
|
||||
assert await setup.async_setup_component(hass, DOMAIN, {DOMAIN: {}})
|
||||
|
||||
assert homekit.status == STATUS_READY
|
||||
await hass.async_add_executor_job(homekit.stop)
|
||||
await homekit.async_stop()
|
||||
await hass.async_block_till_done()
|
||||
homekit.status = STATUS_WAIT
|
||||
await hass.async_add_executor_job(homekit.stop)
|
||||
await homekit.async_stop()
|
||||
await hass.async_block_till_done()
|
||||
homekit.status = STATUS_STOPPED
|
||||
await hass.async_add_executor_job(homekit.stop)
|
||||
await homekit.async_stop()
|
||||
await hass.async_block_till_done()
|
||||
assert homekit.driver.stop.called is False
|
||||
|
||||
# Test if driver is started
|
||||
homekit.status = STATUS_RUNNING
|
||||
await hass.async_add_executor_job(homekit.stop)
|
||||
await homekit.async_stop()
|
||||
await hass.async_block_till_done()
|
||||
assert homekit.driver.stop.called is True
|
||||
|
||||
|
||||
|
@ -408,5 +438,74 @@ async def test_homekit_too_many_accessories(hass, hk_driver):
|
|||
), patch("homeassistant.components.homekit._LOGGER.warning") as mock_warn, patch(
|
||||
f"{PATH_HOMEKIT}.show_setup_message"
|
||||
):
|
||||
await hass.async_add_executor_job(homekit.start)
|
||||
await homekit.async_start()
|
||||
await hass.async_block_till_done()
|
||||
assert mock_warn.called is True
|
||||
|
||||
|
||||
async def test_homekit_finds_linked_batteries(
|
||||
hass, hk_driver, debounce_patcher, device_reg, entity_reg
|
||||
):
|
||||
"""Test HomeKit start method."""
|
||||
assert await setup.async_setup_component(hass, DOMAIN, {DOMAIN: {}})
|
||||
|
||||
homekit = HomeKit(hass, None, None, None, {}, {"light.demo": {}}, None, None)
|
||||
homekit.driver = hk_driver
|
||||
homekit._filter = Mock(return_value=True)
|
||||
homekit.bridge = HomeBridge(hass, hk_driver, "mock_bridge")
|
||||
|
||||
config_entry = MockConfigEntry(domain="test", data={})
|
||||
config_entry.add_to_hass(hass)
|
||||
device_entry = device_reg.async_get_or_create(
|
||||
config_entry_id=config_entry.entry_id,
|
||||
connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")},
|
||||
)
|
||||
|
||||
binary_charging_sensor = entity_reg.async_get_or_create(
|
||||
"binary_sensor",
|
||||
"light",
|
||||
"battery_charging",
|
||||
device_id=device_entry.id,
|
||||
device_class=DEVICE_CLASS_BATTERY_CHARGING,
|
||||
)
|
||||
battery_sensor = entity_reg.async_get_or_create(
|
||||
"sensor",
|
||||
"light",
|
||||
"battery",
|
||||
device_id=device_entry.id,
|
||||
device_class=DEVICE_CLASS_BATTERY,
|
||||
)
|
||||
light = entity_reg.async_get_or_create(
|
||||
"light", "light", "demo", device_id=device_entry.id
|
||||
)
|
||||
|
||||
hass.states.async_set(
|
||||
binary_charging_sensor.entity_id,
|
||||
STATE_ON,
|
||||
{ATTR_DEVICE_CLASS: DEVICE_CLASS_BATTERY_CHARGING},
|
||||
)
|
||||
hass.states.async_set(
|
||||
battery_sensor.entity_id, 30, {ATTR_DEVICE_CLASS: DEVICE_CLASS_BATTERY}
|
||||
)
|
||||
hass.states.async_set(light.entity_id, STATE_ON)
|
||||
|
||||
def _mock_get_accessory(*args, **kwargs):
|
||||
return [None, "acc", None]
|
||||
|
||||
with patch.object(homekit.bridge, "add_accessory"), patch(
|
||||
f"{PATH_HOMEKIT}.show_setup_message"
|
||||
), patch(f"{PATH_HOMEKIT}.get_accessory") as mock_get_acc, patch(
|
||||
"pyhap.accessory_driver.AccessoryDriver.start"
|
||||
):
|
||||
await homekit.async_start()
|
||||
|
||||
mock_get_acc.assert_called_with(
|
||||
hass,
|
||||
hk_driver,
|
||||
ANY,
|
||||
ANY,
|
||||
{
|
||||
"linked_battery_charging_sensor": "binary_sensor.light_battery_charging",
|
||||
"linked_battery_sensor": "sensor.light_battery",
|
||||
},
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue