Add support for Hue push updates (#50591)

This commit is contained in:
Paulus Schoutsen 2021-05-14 13:39:57 -07:00 committed by GitHub
parent 7fd2f8090d
commit 646af533f0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 181 additions and 93 deletions

View file

@ -1,4 +1,5 @@
"""Test Hue bridge."""
import asyncio
from unittest.mock import AsyncMock, Mock, patch
import pytest
@ -12,8 +13,19 @@ from homeassistant.components.hue.const import (
)
from homeassistant.exceptions import ConfigEntryNotReady
ORIG_SUBSCRIBE_EVENTS = bridge.HueBridge._subscribe_events
async def test_bridge_setup(hass):
@pytest.fixture(autouse=True)
def mock_subscribe_events():
"""Mock subscribe events method."""
with patch(
"homeassistant.components.hue.bridge.HueBridge._subscribe_events"
) as mock:
yield mock
async def test_bridge_setup(hass, mock_subscribe_events):
"""Test a successful setup."""
entry = Mock()
api = Mock(initialize=AsyncMock())
@ -31,6 +43,8 @@ async def test_bridge_setup(hass):
forward_entries = {c[1][1] for c in mock_forward.mock_calls}
assert forward_entries == {"light", "binary_sensor", "sensor"}
assert len(mock_subscribe_events.mock_calls) == 1
async def test_bridge_setup_invalid_username(hass):
"""Test we start config flow if username is no longer whitelisted."""
@ -78,20 +92,23 @@ async def test_reset_if_entry_had_wrong_auth(hass):
assert await hue_bridge.async_reset()
async def test_reset_unloads_entry_if_setup(hass):
async def test_reset_unloads_entry_if_setup(hass, mock_subscribe_events):
"""Test calling reset while the entry has been setup."""
entry = Mock()
entry.data = {"host": "1.2.3.4", "username": "mock-username"}
entry.options = {CONF_ALLOW_HUE_GROUPS: False, CONF_ALLOW_UNREACHABLE: False}
hue_bridge = bridge.HueBridge(hass, entry)
with patch.object(bridge, "authenticate_bridge", return_value=Mock()), patch(
"aiohue.Bridge", return_value=Mock()
with patch.object(bridge, "authenticate_bridge"), patch(
"aiohue.Bridge"
), patch.object(hass.config_entries, "async_forward_entry_setup") as mock_forward:
assert await hue_bridge.async_setup() is True
await asyncio.sleep(0)
assert len(hass.services.async_services()) == 0
assert len(mock_forward.mock_calls) == 3
assert len(mock_subscribe_events.mock_calls) == 1
with patch.object(
hass.config_entries, "async_forward_entry_unload", return_value=True
@ -109,9 +126,7 @@ async def test_handle_unauthorized(hass):
entry.options = {CONF_ALLOW_HUE_GROUPS: False, CONF_ALLOW_UNREACHABLE: False}
hue_bridge = bridge.HueBridge(hass, entry)
with patch.object(bridge, "authenticate_bridge", return_value=Mock()), patch(
"aiohue.Bridge", return_value=Mock()
):
with patch.object(bridge, "authenticate_bridge"), patch("aiohue.Bridge"):
assert await hue_bridge.async_setup() is True
assert hue_bridge.authorized is True
@ -282,3 +297,78 @@ async def test_hue_activate_scene_scene_not_found(hass, mock_api):
call.data = {"group_name": "Group 1", "scene_name": "Cozy dinner"}
with patch("aiohue.Bridge", return_value=mock_api):
assert await hue_bridge.hue_activate_scene(call.data) is False
async def test_event_updates(hass, caplog):
"""Test calling reset while the entry has been setup."""
events = asyncio.Queue()
async def iterate_queue():
while True:
event = await events.get()
if event is None:
return
yield event
async def wait_empty_queue():
count = 0
while not events.empty() and count < 50:
await asyncio.sleep(0)
count += 1
hue_bridge = bridge.HueBridge(None, None)
hue_bridge.api = Mock(listen_events=iterate_queue)
subscription_task = asyncio.create_task(ORIG_SUBSCRIBE_EVENTS(hue_bridge))
calls = []
def obj_updated():
calls.append(True)
unsub = hue_bridge.listen_updates("lights", "2", obj_updated)
events.put_nowait(Mock(ITEM_TYPE="lights", id="1"))
await wait_empty_queue()
assert len(calls) == 0
events.put_nowait(Mock(ITEM_TYPE="lights", id="2"))
await wait_empty_queue()
assert len(calls) == 1
unsub()
events.put_nowait(Mock(ITEM_TYPE="lights", id="2"))
await wait_empty_queue()
assert len(calls) == 1
# Test we can override update listener.
def obj_updated_false():
calls.append(False)
unsub = hue_bridge.listen_updates("lights", "2", obj_updated)
unsub_false = hue_bridge.listen_updates("lights", "2", obj_updated_false)
assert "Overwriting update callback" in caplog.text
events.put_nowait(Mock(ITEM_TYPE="lights", id="2"))
await wait_empty_queue()
assert len(calls) == 2
assert calls[-1] is False
# Also call multiple times to make sure that works.
unsub()
unsub()
unsub_false()
unsub_false()
events.put_nowait(Mock(ITEM_TYPE="lights", id="2"))
await wait_empty_queue()
assert len(calls) == 2
events.put_nowait(None)
await subscription_task