mirror of
https://github.com/home-assistant/core
synced 2024-07-09 04:58:30 +02:00
Add slots to the service registry (#95857)
This commit is contained in:
parent
bd7057f7b1
commit
ea57f78392
@ -1726,6 +1726,8 @@ class ServiceCall:
|
||||
class ServiceRegistry:
|
||||
"""Offer the services over the eventbus."""
|
||||
|
||||
__slots__ = ("_services", "_hass")
|
||||
|
||||
def __init__(self, hass: HomeAssistant) -> None:
|
||||
"""Initialize a service registry."""
|
||||
self._services: dict[str, dict[str, Service]] = {}
|
||||
|
@ -1,7 +1,7 @@
|
||||
"""Test Google Smart Home."""
|
||||
import asyncio
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import ANY, call, patch
|
||||
from unittest.mock import ANY, patch
|
||||
|
||||
import pytest
|
||||
from pytest_unordered import unordered
|
||||
@ -488,76 +488,41 @@ async def test_execute(
|
||||
events = async_capture_events(hass, EVENT_COMMAND_RECEIVED)
|
||||
service_events = async_capture_events(hass, EVENT_CALL_SERVICE)
|
||||
|
||||
with patch.object(
|
||||
hass.services, "async_call", wraps=hass.services.async_call
|
||||
) as call_service_mock:
|
||||
result = await sh.async_handle_message(
|
||||
hass,
|
||||
MockConfig(should_report_state=report_state),
|
||||
None,
|
||||
{
|
||||
"requestId": REQ_ID,
|
||||
"inputs": [
|
||||
{
|
||||
"intent": "action.devices.EXECUTE",
|
||||
"payload": {
|
||||
"commands": [
|
||||
{
|
||||
"devices": [
|
||||
{"id": "light.non_existing"},
|
||||
{"id": "light.ceiling_lights"},
|
||||
{"id": "light.kitchen_lights"},
|
||||
],
|
||||
"execution": [
|
||||
{
|
||||
"command": "action.devices.commands.OnOff",
|
||||
"params": {"on": True},
|
||||
},
|
||||
{
|
||||
"command": "action.devices.commands.BrightnessAbsolute",
|
||||
"params": {"brightness": 20},
|
||||
},
|
||||
],
|
||||
}
|
||||
]
|
||||
},
|
||||
}
|
||||
],
|
||||
},
|
||||
const.SOURCE_CLOUD,
|
||||
)
|
||||
assert call_service_mock.call_count == 4
|
||||
expected_calls = [
|
||||
call(
|
||||
"light",
|
||||
"turn_on",
|
||||
{"entity_id": "light.ceiling_lights"},
|
||||
blocking=not report_state,
|
||||
context=ANY,
|
||||
),
|
||||
call(
|
||||
"light",
|
||||
"turn_on",
|
||||
{"entity_id": "light.kitchen_lights"},
|
||||
blocking=not report_state,
|
||||
context=ANY,
|
||||
),
|
||||
call(
|
||||
"light",
|
||||
"turn_on",
|
||||
{"entity_id": "light.ceiling_lights", "brightness_pct": 20},
|
||||
blocking=not report_state,
|
||||
context=ANY,
|
||||
),
|
||||
call(
|
||||
"light",
|
||||
"turn_on",
|
||||
{"entity_id": "light.kitchen_lights", "brightness_pct": 20},
|
||||
blocking=not report_state,
|
||||
context=ANY,
|
||||
),
|
||||
]
|
||||
call_service_mock.assert_has_awaits(expected_calls, any_order=True)
|
||||
result = await sh.async_handle_message(
|
||||
hass,
|
||||
MockConfig(should_report_state=report_state),
|
||||
None,
|
||||
{
|
||||
"requestId": REQ_ID,
|
||||
"inputs": [
|
||||
{
|
||||
"intent": "action.devices.EXECUTE",
|
||||
"payload": {
|
||||
"commands": [
|
||||
{
|
||||
"devices": [
|
||||
{"id": "light.non_existing"},
|
||||
{"id": "light.ceiling_lights"},
|
||||
{"id": "light.kitchen_lights"},
|
||||
],
|
||||
"execution": [
|
||||
{
|
||||
"command": "action.devices.commands.OnOff",
|
||||
"params": {"on": True},
|
||||
},
|
||||
{
|
||||
"command": "action.devices.commands.BrightnessAbsolute",
|
||||
"params": {"brightness": 20},
|
||||
},
|
||||
],
|
||||
}
|
||||
]
|
||||
},
|
||||
}
|
||||
],
|
||||
},
|
||||
const.SOURCE_CLOUD,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result == {
|
||||
@ -682,11 +647,7 @@ async def test_execute_times_out(
|
||||
# Make DemoLigt.async_turn_on hang waiting for the turn_on_wait event
|
||||
await turn_on_wait.wait()
|
||||
|
||||
with patch.object(
|
||||
hass.services, "async_call", wraps=hass.services.async_call
|
||||
) as call_service_mock, patch.object(
|
||||
DemoLight, "async_turn_on", wraps=slow_turn_on
|
||||
):
|
||||
with patch.object(DemoLight, "async_turn_on", wraps=slow_turn_on):
|
||||
result = await sh.async_handle_message(
|
||||
hass,
|
||||
MockConfig(should_report_state=report_state),
|
||||
@ -722,51 +683,10 @@ async def test_execute_times_out(
|
||||
},
|
||||
const.SOURCE_CLOUD,
|
||||
)
|
||||
# Only the two first calls are executed
|
||||
assert call_service_mock.call_count == 2
|
||||
expected_calls = [
|
||||
call(
|
||||
"light",
|
||||
"turn_on",
|
||||
{"entity_id": "light.ceiling_lights"},
|
||||
blocking=not report_state,
|
||||
context=ANY,
|
||||
),
|
||||
call(
|
||||
"light",
|
||||
"turn_on",
|
||||
{"entity_id": "light.kitchen_lights"},
|
||||
blocking=not report_state,
|
||||
context=ANY,
|
||||
),
|
||||
]
|
||||
call_service_mock.assert_has_awaits(expected_calls, any_order=True)
|
||||
|
||||
turn_on_wait.set()
|
||||
await hass.async_block_till_done()
|
||||
await hass.async_block_till_done()
|
||||
# The remaining two calls should now have executed
|
||||
assert call_service_mock.call_count == 4
|
||||
expected_calls.extend(
|
||||
[
|
||||
call(
|
||||
"light",
|
||||
"turn_on",
|
||||
{"entity_id": "light.ceiling_lights", "brightness_pct": 20},
|
||||
blocking=not report_state,
|
||||
context=ANY,
|
||||
),
|
||||
call(
|
||||
"light",
|
||||
"turn_on",
|
||||
{"entity_id": "light.kitchen_lights", "brightness_pct": 20},
|
||||
blocking=not report_state,
|
||||
context=ANY,
|
||||
),
|
||||
]
|
||||
)
|
||||
call_service_mock.assert_has_awaits(expected_calls, any_order=True)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result == {
|
||||
"requestId": REQ_ID,
|
||||
|
@ -1,5 +1,4 @@
|
||||
"""The tests for the Group Light platform."""
|
||||
import unittest.mock
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import async_timeout
|
||||
@ -16,7 +15,6 @@ from homeassistant.components.light import (
|
||||
ATTR_COLOR_TEMP_KELVIN,
|
||||
ATTR_EFFECT,
|
||||
ATTR_EFFECT_LIST,
|
||||
ATTR_FLASH,
|
||||
ATTR_HS_COLOR,
|
||||
ATTR_MAX_COLOR_TEMP_KELVIN,
|
||||
ATTR_MIN_COLOR_TEMP_KELVIN,
|
||||
@ -26,7 +24,6 @@ from homeassistant.components.light import (
|
||||
ATTR_SUPPORTED_COLOR_MODES,
|
||||
ATTR_TRANSITION,
|
||||
ATTR_WHITE,
|
||||
ATTR_XY_COLOR,
|
||||
DOMAIN as LIGHT_DOMAIN,
|
||||
SERVICE_TOGGLE,
|
||||
SERVICE_TURN_OFF,
|
||||
@ -39,16 +36,17 @@ from homeassistant.components.light import (
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID,
|
||||
ATTR_SUPPORTED_FEATURES,
|
||||
EVENT_CALL_SERVICE,
|
||||
STATE_OFF,
|
||||
STATE_ON,
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_UNKNOWN,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import Event, HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.common import get_fixture_path
|
||||
from tests.common import async_capture_events, get_fixture_path
|
||||
|
||||
|
||||
async def test_default_state(hass: HomeAssistant) -> None:
|
||||
@ -1443,6 +1441,7 @@ async def test_invalid_service_calls(hass: HomeAssistant) -> None:
|
||||
await group.async_setup_platform(
|
||||
hass, {"name": "test", "entities": ["light.test1", "light.test2"]}, add_entities
|
||||
)
|
||||
await async_setup_component(hass, "light", {})
|
||||
await hass.async_block_till_done()
|
||||
await hass.async_start()
|
||||
await hass.async_block_till_done()
|
||||
@ -1451,35 +1450,38 @@ async def test_invalid_service_calls(hass: HomeAssistant) -> None:
|
||||
grouped_light = add_entities.call_args[0][0][0]
|
||||
grouped_light.hass = hass
|
||||
|
||||
with unittest.mock.patch.object(hass.services, "async_call") as mock_call:
|
||||
await grouped_light.async_turn_on(brightness=150, four_oh_four="404")
|
||||
data = {ATTR_ENTITY_ID: ["light.test1", "light.test2"], ATTR_BRIGHTNESS: 150}
|
||||
mock_call.assert_called_once_with(
|
||||
LIGHT_DOMAIN, SERVICE_TURN_ON, data, blocking=True, context=None
|
||||
)
|
||||
mock_call.reset_mock()
|
||||
service_call_events = async_capture_events(hass, EVENT_CALL_SERVICE)
|
||||
|
||||
await grouped_light.async_turn_off(transition=4, four_oh_four="404")
|
||||
data = {ATTR_ENTITY_ID: ["light.test1", "light.test2"], ATTR_TRANSITION: 4}
|
||||
mock_call.assert_called_once_with(
|
||||
LIGHT_DOMAIN, SERVICE_TURN_OFF, data, blocking=True, context=None
|
||||
)
|
||||
mock_call.reset_mock()
|
||||
await grouped_light.async_turn_on(brightness=150, four_oh_four="404")
|
||||
data = {ATTR_ENTITY_ID: ["light.test1", "light.test2"], ATTR_BRIGHTNESS: 150}
|
||||
assert len(service_call_events) == 1
|
||||
service_event_call: Event = service_call_events[0]
|
||||
assert service_event_call.data["domain"] == LIGHT_DOMAIN
|
||||
assert service_event_call.data["service"] == SERVICE_TURN_ON
|
||||
assert service_event_call.data["service_data"] == data
|
||||
service_call_events.clear()
|
||||
|
||||
data = {
|
||||
ATTR_BRIGHTNESS: 150,
|
||||
ATTR_XY_COLOR: (0.5, 0.42),
|
||||
ATTR_RGB_COLOR: (80, 120, 50),
|
||||
ATTR_COLOR_TEMP_KELVIN: 1234,
|
||||
ATTR_EFFECT: "Sunshine",
|
||||
ATTR_TRANSITION: 4,
|
||||
ATTR_FLASH: "long",
|
||||
}
|
||||
await grouped_light.async_turn_on(**data)
|
||||
data[ATTR_ENTITY_ID] = ["light.test1", "light.test2"]
|
||||
mock_call.assert_called_once_with(
|
||||
LIGHT_DOMAIN, SERVICE_TURN_ON, data, blocking=True, context=None
|
||||
)
|
||||
await grouped_light.async_turn_off(transition=4, four_oh_four="404")
|
||||
data = {ATTR_ENTITY_ID: ["light.test1", "light.test2"], ATTR_TRANSITION: 4}
|
||||
assert len(service_call_events) == 1
|
||||
service_event_call: Event = service_call_events[0]
|
||||
assert service_event_call.data["domain"] == LIGHT_DOMAIN
|
||||
assert service_event_call.data["service"] == SERVICE_TURN_OFF
|
||||
assert service_event_call.data["service_data"] == data
|
||||
service_call_events.clear()
|
||||
|
||||
data = {
|
||||
ATTR_BRIGHTNESS: 150,
|
||||
ATTR_COLOR_TEMP_KELVIN: 1234,
|
||||
ATTR_TRANSITION: 4,
|
||||
}
|
||||
await grouped_light.async_turn_on(**data)
|
||||
data[ATTR_ENTITY_ID] = ["light.test1", "light.test2"]
|
||||
service_event_call: Event = service_call_events[0]
|
||||
assert service_event_call.data["domain"] == LIGHT_DOMAIN
|
||||
assert service_event_call.data["service"] == SERVICE_TURN_ON
|
||||
assert service_event_call.data["service_data"] == data
|
||||
service_call_events.clear()
|
||||
|
||||
|
||||
async def test_reload(hass: HomeAssistant) -> None:
|
||||
|
@ -33,15 +33,12 @@ async def test_async_setup_entry__not_login(
|
||||
hass.config_entries, "async_forward_entry_setup"
|
||||
) as setup_mock, patch(
|
||||
"homeassistant.components.vesync.async_process_devices"
|
||||
) as process_mock, patch.object(
|
||||
hass.services, "async_register"
|
||||
) as register_mock:
|
||||
) as process_mock:
|
||||
assert not await async_setup_entry(hass, config_entry)
|
||||
await hass.async_block_till_done()
|
||||
assert setups_mock.call_count == 0
|
||||
assert setup_mock.call_count == 0
|
||||
assert process_mock.call_count == 0
|
||||
assert register_mock.call_count == 0
|
||||
|
||||
assert manager.login.call_count == 1
|
||||
assert DOMAIN not in hass.data
|
||||
|
@ -332,8 +332,8 @@ def zha_device_mock(
|
||||
|
||||
@pytest.fixture
|
||||
def hass_disable_services(hass):
|
||||
"""Mock service register."""
|
||||
with patch.object(hass.services, "async_register"), patch.object(
|
||||
hass.services, "has_service", return_value=True
|
||||
"""Mock services."""
|
||||
with patch.object(
|
||||
hass, "services", MagicMock(has_service=MagicMock(return_value=True))
|
||||
):
|
||||
yield hass
|
||||
|
Loading…
Reference in New Issue
Block a user