mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 20:27:08 +00:00
Simplify access to hass in service calls (#133062)
This commit is contained in:
parent
f9f37b9932
commit
899fb091fc
@ -2432,10 +2432,11 @@ class Service:
|
||||
class ServiceCall:
|
||||
"""Representation of a call to a service."""
|
||||
|
||||
__slots__ = ("domain", "service", "data", "context", "return_response")
|
||||
__slots__ = ("hass", "domain", "service", "data", "context", "return_response")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
domain: str,
|
||||
service: str,
|
||||
data: dict[str, Any] | None = None,
|
||||
@ -2443,6 +2444,7 @@ class ServiceCall:
|
||||
return_response: bool = False,
|
||||
) -> None:
|
||||
"""Initialize a service call."""
|
||||
self.hass = hass
|
||||
self.domain = domain
|
||||
self.service = service
|
||||
self.data = ReadOnlyDict(data or {})
|
||||
@ -2768,7 +2770,7 @@ class ServiceRegistry:
|
||||
processed_data = service_data
|
||||
|
||||
service_call = ServiceCall(
|
||||
domain, service, processed_data, context, return_response
|
||||
self._hass, domain, service, processed_data, context, return_response
|
||||
)
|
||||
|
||||
self._hass.bus.async_fire_internal(
|
||||
|
@ -184,6 +184,7 @@ async def test_turn_on_skips_domains_without_service(
|
||||
# because by mocking out the call service method, we mock out all
|
||||
# So we mimic how the service registry calls services
|
||||
service_call = ha.ServiceCall(
|
||||
hass,
|
||||
"homeassistant",
|
||||
"turn_on",
|
||||
{"entity_id": ["light.test", "sensor.bla", "binary_sensor.blub", "light.bla"]},
|
||||
|
@ -64,21 +64,22 @@ async def test_text_set_value(hass: HomeAssistant) -> None:
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
await _async_set_value(
|
||||
text, ServiceCall(DOMAIN, SERVICE_SET_VALUE, {ATTR_VALUE: ""})
|
||||
text, ServiceCall(hass, DOMAIN, SERVICE_SET_VALUE, {ATTR_VALUE: ""})
|
||||
)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
await _async_set_value(
|
||||
text, ServiceCall(DOMAIN, SERVICE_SET_VALUE, {ATTR_VALUE: "hello world!"})
|
||||
text,
|
||||
ServiceCall(hass, DOMAIN, SERVICE_SET_VALUE, {ATTR_VALUE: "hello world!"}),
|
||||
)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
await _async_set_value(
|
||||
text, ServiceCall(DOMAIN, SERVICE_SET_VALUE, {ATTR_VALUE: "HELLO"})
|
||||
text, ServiceCall(hass, DOMAIN, SERVICE_SET_VALUE, {ATTR_VALUE: "HELLO"})
|
||||
)
|
||||
|
||||
await _async_set_value(
|
||||
text, ServiceCall(DOMAIN, SERVICE_SET_VALUE, {ATTR_VALUE: "test2"})
|
||||
text, ServiceCall(hass, DOMAIN, SERVICE_SET_VALUE, {ATTR_VALUE: "test2"})
|
||||
)
|
||||
|
||||
assert text.state == "test2"
|
||||
|
@ -1899,7 +1899,7 @@ def service_calls(hass: HomeAssistant) -> Generator[list[ServiceCall]]:
|
||||
return_response: bool = False,
|
||||
) -> ServiceResponse:
|
||||
calls.append(
|
||||
ServiceCall(domain, service, service_data, context, return_response)
|
||||
ServiceCall(hass, domain, service, service_data, context, return_response)
|
||||
)
|
||||
try:
|
||||
return await _original_async_call(
|
||||
|
@ -189,13 +189,14 @@ async def test_extract_from_service_available_device(hass: HomeAssistant) -> Non
|
||||
]
|
||||
)
|
||||
|
||||
call_1 = ServiceCall("test", "service", data={"entity_id": ENTITY_MATCH_ALL})
|
||||
call_1 = ServiceCall(hass, "test", "service", data={"entity_id": ENTITY_MATCH_ALL})
|
||||
|
||||
assert sorted(
|
||||
ent.entity_id for ent in (await component.async_extract_from_service(call_1))
|
||||
) == ["test_domain.test_1", "test_domain.test_3"]
|
||||
|
||||
call_2 = ServiceCall(
|
||||
hass,
|
||||
"test",
|
||||
"service",
|
||||
data={"entity_id": ["test_domain.test_3", "test_domain.test_4"]},
|
||||
@ -256,17 +257,18 @@ async def test_extract_from_service_fails_if_no_entity_id(hass: HomeAssistant) -
|
||||
)
|
||||
|
||||
assert (
|
||||
await component.async_extract_from_service(ServiceCall("test", "service")) == []
|
||||
await component.async_extract_from_service(ServiceCall(hass, "test", "service"))
|
||||
== []
|
||||
)
|
||||
assert (
|
||||
await component.async_extract_from_service(
|
||||
ServiceCall("test", "service", {"entity_id": ENTITY_MATCH_NONE})
|
||||
ServiceCall(hass, "test", "service", {"entity_id": ENTITY_MATCH_NONE})
|
||||
)
|
||||
== []
|
||||
)
|
||||
assert (
|
||||
await component.async_extract_from_service(
|
||||
ServiceCall("test", "service", {"area_id": ENTITY_MATCH_NONE})
|
||||
ServiceCall(hass, "test", "service", {"area_id": ENTITY_MATCH_NONE})
|
||||
)
|
||||
== []
|
||||
)
|
||||
@ -283,6 +285,7 @@ async def test_extract_from_service_filter_out_non_existing_entities(
|
||||
)
|
||||
|
||||
call = ServiceCall(
|
||||
hass,
|
||||
"test",
|
||||
"service",
|
||||
{"entity_id": ["test_domain.test_2", "test_domain.non_exist"]},
|
||||
@ -299,7 +302,7 @@ async def test_extract_from_service_no_group_expand(hass: HomeAssistant) -> None
|
||||
await component.async_setup({})
|
||||
await component.async_add_entities([MockEntity(entity_id="group.test_group")])
|
||||
|
||||
call = ServiceCall("test", "service", {"entity_id": ["group.test_group"]})
|
||||
call = ServiceCall(hass, "test", "service", {"entity_id": ["group.test_group"]})
|
||||
|
||||
extracted = await component.async_extract_from_service(call, expand_group=False)
|
||||
assert len(extracted) == 1
|
||||
@ -465,7 +468,7 @@ async def test_extract_all_omit_entity_id(
|
||||
[MockEntity(name="test_1"), MockEntity(name="test_2")]
|
||||
)
|
||||
|
||||
call = ServiceCall("test", "service")
|
||||
call = ServiceCall(hass, "test", "service")
|
||||
|
||||
assert (
|
||||
sorted(
|
||||
@ -485,7 +488,7 @@ async def test_extract_all_use_match_all(
|
||||
[MockEntity(name="test_1"), MockEntity(name="test_2")]
|
||||
)
|
||||
|
||||
call = ServiceCall("test", "service", {"entity_id": "all"})
|
||||
call = ServiceCall(hass, "test", "service", {"entity_id": "all"})
|
||||
|
||||
assert sorted(
|
||||
ent.entity_id for ent in await component.async_extract_from_service(call)
|
||||
|
@ -642,11 +642,11 @@ async def test_extract_entity_ids(hass: HomeAssistant) -> None:
|
||||
order=None,
|
||||
)
|
||||
|
||||
call = ServiceCall("light", "turn_on", {ATTR_ENTITY_ID: "light.Bowl"})
|
||||
call = ServiceCall(hass, "light", "turn_on", {ATTR_ENTITY_ID: "light.Bowl"})
|
||||
|
||||
assert {"light.bowl"} == await service.async_extract_entity_ids(hass, call)
|
||||
|
||||
call = ServiceCall("light", "turn_on", {ATTR_ENTITY_ID: "group.test"})
|
||||
call = ServiceCall(hass, "light", "turn_on", {ATTR_ENTITY_ID: "group.test"})
|
||||
|
||||
assert {"light.ceiling", "light.kitchen"} == await service.async_extract_entity_ids(
|
||||
hass, call
|
||||
@ -659,7 +659,7 @@ async def test_extract_entity_ids(hass: HomeAssistant) -> None:
|
||||
assert (
|
||||
await service.async_extract_entity_ids(
|
||||
hass,
|
||||
ServiceCall("light", "turn_on", {ATTR_ENTITY_ID: ENTITY_MATCH_NONE}),
|
||||
ServiceCall(hass, "light", "turn_on", {ATTR_ENTITY_ID: ENTITY_MATCH_NONE}),
|
||||
)
|
||||
== set()
|
||||
)
|
||||
@ -669,20 +669,22 @@ async def test_extract_entity_ids_from_area(
|
||||
hass: HomeAssistant, floor_area_mock
|
||||
) -> None:
|
||||
"""Test extract_entity_ids method with areas."""
|
||||
call = ServiceCall("light", "turn_on", {"area_id": "own-area"})
|
||||
call = ServiceCall(hass, "light", "turn_on", {"area_id": "own-area"})
|
||||
|
||||
assert {
|
||||
"light.in_own_area",
|
||||
} == await service.async_extract_entity_ids(hass, call)
|
||||
|
||||
call = ServiceCall("light", "turn_on", {"area_id": "test-area"})
|
||||
call = ServiceCall(hass, "light", "turn_on", {"area_id": "test-area"})
|
||||
|
||||
assert {
|
||||
"light.in_area",
|
||||
"light.assigned_to_area",
|
||||
} == await service.async_extract_entity_ids(hass, call)
|
||||
|
||||
call = ServiceCall("light", "turn_on", {"area_id": ["test-area", "diff-area"]})
|
||||
call = ServiceCall(
|
||||
hass, "light", "turn_on", {"area_id": ["test-area", "diff-area"]}
|
||||
)
|
||||
|
||||
assert {
|
||||
"light.in_area",
|
||||
@ -692,7 +694,7 @@ async def test_extract_entity_ids_from_area(
|
||||
|
||||
assert (
|
||||
await service.async_extract_entity_ids(
|
||||
hass, ServiceCall("light", "turn_on", {"area_id": ENTITY_MATCH_NONE})
|
||||
hass, ServiceCall(hass, "light", "turn_on", {"area_id": ENTITY_MATCH_NONE})
|
||||
)
|
||||
== set()
|
||||
)
|
||||
@ -703,13 +705,13 @@ async def test_extract_entity_ids_from_devices(
|
||||
) -> None:
|
||||
"""Test extract_entity_ids method with devices."""
|
||||
assert await service.async_extract_entity_ids(
|
||||
hass, ServiceCall("light", "turn_on", {"device_id": "device-no-area-id"})
|
||||
hass, ServiceCall(hass, "light", "turn_on", {"device_id": "device-no-area-id"})
|
||||
) == {
|
||||
"light.no_area",
|
||||
}
|
||||
|
||||
assert await service.async_extract_entity_ids(
|
||||
hass, ServiceCall("light", "turn_on", {"device_id": "device-area-a-id"})
|
||||
hass, ServiceCall(hass, "light", "turn_on", {"device_id": "device-area-a-id"})
|
||||
) == {
|
||||
"light.in_area_a",
|
||||
"light.in_area_b",
|
||||
@ -717,7 +719,8 @@ async def test_extract_entity_ids_from_devices(
|
||||
|
||||
assert (
|
||||
await service.async_extract_entity_ids(
|
||||
hass, ServiceCall("light", "turn_on", {"device_id": "non-existing-id"})
|
||||
hass,
|
||||
ServiceCall(hass, "light", "turn_on", {"device_id": "non-existing-id"}),
|
||||
)
|
||||
== set()
|
||||
)
|
||||
@ -726,14 +729,16 @@ async def test_extract_entity_ids_from_devices(
|
||||
@pytest.mark.usefixtures("floor_area_mock")
|
||||
async def test_extract_entity_ids_from_floor(hass: HomeAssistant) -> None:
|
||||
"""Test extract_entity_ids method with floors."""
|
||||
call = ServiceCall("light", "turn_on", {"floor_id": "test-floor"})
|
||||
call = ServiceCall(hass, "light", "turn_on", {"floor_id": "test-floor"})
|
||||
|
||||
assert {
|
||||
"light.in_area",
|
||||
"light.assigned_to_area",
|
||||
} == await service.async_extract_entity_ids(hass, call)
|
||||
|
||||
call = ServiceCall("light", "turn_on", {"floor_id": ["test-floor", "floor-a"]})
|
||||
call = ServiceCall(
|
||||
hass, "light", "turn_on", {"floor_id": ["test-floor", "floor-a"]}
|
||||
)
|
||||
|
||||
assert {
|
||||
"light.in_area",
|
||||
@ -743,7 +748,7 @@ async def test_extract_entity_ids_from_floor(hass: HomeAssistant) -> None:
|
||||
|
||||
assert (
|
||||
await service.async_extract_entity_ids(
|
||||
hass, ServiceCall("light", "turn_on", {"floor_id": ENTITY_MATCH_NONE})
|
||||
hass, ServiceCall(hass, "light", "turn_on", {"floor_id": ENTITY_MATCH_NONE})
|
||||
)
|
||||
== set()
|
||||
)
|
||||
@ -752,13 +757,13 @@ async def test_extract_entity_ids_from_floor(hass: HomeAssistant) -> None:
|
||||
@pytest.mark.usefixtures("label_mock")
|
||||
async def test_extract_entity_ids_from_labels(hass: HomeAssistant) -> None:
|
||||
"""Test extract_entity_ids method with labels."""
|
||||
call = ServiceCall("light", "turn_on", {"label_id": "my-label"})
|
||||
call = ServiceCall(hass, "light", "turn_on", {"label_id": "my-label"})
|
||||
|
||||
assert {
|
||||
"light.with_my_label",
|
||||
} == await service.async_extract_entity_ids(hass, call)
|
||||
|
||||
call = ServiceCall("light", "turn_on", {"label_id": "label1"})
|
||||
call = ServiceCall(hass, "light", "turn_on", {"label_id": "label1"})
|
||||
|
||||
assert {
|
||||
"light.with_label1_from_device",
|
||||
@ -767,14 +772,14 @@ async def test_extract_entity_ids_from_labels(hass: HomeAssistant) -> None:
|
||||
"light.with_label1_and_label2_from_device",
|
||||
} == await service.async_extract_entity_ids(hass, call)
|
||||
|
||||
call = ServiceCall("light", "turn_on", {"label_id": ["label2"]})
|
||||
call = ServiceCall(hass, "light", "turn_on", {"label_id": ["label2"]})
|
||||
|
||||
assert {
|
||||
"light.with_labels_from_device",
|
||||
"light.with_label1_and_label2_from_device",
|
||||
} == await service.async_extract_entity_ids(hass, call)
|
||||
|
||||
call = ServiceCall("light", "turn_on", {"label_id": ["label_area"]})
|
||||
call = ServiceCall(hass, "light", "turn_on", {"label_id": ["label_area"]})
|
||||
|
||||
assert {
|
||||
"light.with_labels_from_device",
|
||||
@ -782,7 +787,7 @@ async def test_extract_entity_ids_from_labels(hass: HomeAssistant) -> None:
|
||||
|
||||
assert (
|
||||
await service.async_extract_entity_ids(
|
||||
hass, ServiceCall("light", "turn_on", {"label_id": ENTITY_MATCH_NONE})
|
||||
hass, ServiceCall(hass, "light", "turn_on", {"label_id": ENTITY_MATCH_NONE})
|
||||
)
|
||||
== set()
|
||||
)
|
||||
@ -1281,7 +1286,7 @@ async def test_call_with_required_features(hass: HomeAssistant, mock_entities) -
|
||||
hass,
|
||||
mock_entities,
|
||||
HassJob(test_service_mock),
|
||||
ServiceCall("test_domain", "test_service", {"entity_id": "all"}),
|
||||
ServiceCall(hass, "test_domain", "test_service", {"entity_id": "all"}),
|
||||
required_features=[SUPPORT_A],
|
||||
)
|
||||
|
||||
@ -1305,7 +1310,7 @@ async def test_call_with_required_features(hass: HomeAssistant, mock_entities) -
|
||||
mock_entities,
|
||||
HassJob(test_service_mock),
|
||||
ServiceCall(
|
||||
"test_domain", "test_service", {"entity_id": "light.living_room"}
|
||||
hass, "test_domain", "test_service", {"entity_id": "light.living_room"}
|
||||
),
|
||||
required_features=[SUPPORT_A],
|
||||
)
|
||||
@ -1321,7 +1326,7 @@ async def test_call_with_both_required_features(
|
||||
hass,
|
||||
mock_entities,
|
||||
HassJob(test_service_mock),
|
||||
ServiceCall("test_domain", "test_service", {"entity_id": "all"}),
|
||||
ServiceCall(hass, "test_domain", "test_service", {"entity_id": "all"}),
|
||||
required_features=[SUPPORT_A | SUPPORT_B],
|
||||
)
|
||||
|
||||
@ -1340,7 +1345,7 @@ async def test_call_with_one_of_required_features(
|
||||
hass,
|
||||
mock_entities,
|
||||
HassJob(test_service_mock),
|
||||
ServiceCall("test_domain", "test_service", {"entity_id": "all"}),
|
||||
ServiceCall(hass, "test_domain", "test_service", {"entity_id": "all"}),
|
||||
required_features=[SUPPORT_A, SUPPORT_C],
|
||||
)
|
||||
|
||||
@ -1361,7 +1366,9 @@ async def test_call_with_sync_func(hass: HomeAssistant, mock_entities) -> None:
|
||||
hass,
|
||||
mock_entities,
|
||||
HassJob(test_service_mock),
|
||||
ServiceCall("test_domain", "test_service", {"entity_id": "light.kitchen"}),
|
||||
ServiceCall(
|
||||
hass, "test_domain", "test_service", {"entity_id": "light.kitchen"}
|
||||
),
|
||||
)
|
||||
assert test_service_mock.call_count == 1
|
||||
|
||||
@ -1374,6 +1381,7 @@ async def test_call_with_sync_attr(hass: HomeAssistant, mock_entities) -> None:
|
||||
mock_entities,
|
||||
"sync_method",
|
||||
ServiceCall(
|
||||
hass,
|
||||
"test_domain",
|
||||
"test_service",
|
||||
{"entity_id": "light.kitchen", "area_id": "abcd"},
|
||||
@ -1392,6 +1400,7 @@ async def test_call_context_user_not_exist(hass: HomeAssistant) -> None:
|
||||
{},
|
||||
Mock(),
|
||||
ServiceCall(
|
||||
hass,
|
||||
"test_domain",
|
||||
"test_service",
|
||||
context=Context(user_id="non-existing"),
|
||||
@ -1419,6 +1428,7 @@ async def test_call_context_target_all(
|
||||
mock_entities,
|
||||
Mock(),
|
||||
ServiceCall(
|
||||
hass,
|
||||
"test_domain",
|
||||
"test_service",
|
||||
data={"entity_id": ENTITY_MATCH_ALL},
|
||||
@ -1447,6 +1457,7 @@ async def test_call_context_target_specific(
|
||||
mock_entities,
|
||||
Mock(),
|
||||
ServiceCall(
|
||||
hass,
|
||||
"test_domain",
|
||||
"test_service",
|
||||
{"entity_id": "light.kitchen"},
|
||||
@ -1474,6 +1485,7 @@ async def test_call_context_target_specific_no_auth(
|
||||
mock_entities,
|
||||
Mock(),
|
||||
ServiceCall(
|
||||
hass,
|
||||
"test_domain",
|
||||
"test_service",
|
||||
{"entity_id": "light.kitchen"},
|
||||
@ -1494,7 +1506,7 @@ async def test_call_no_context_target_all(
|
||||
mock_entities,
|
||||
Mock(),
|
||||
ServiceCall(
|
||||
"test_domain", "test_service", data={"entity_id": ENTITY_MATCH_ALL}
|
||||
hass, "test_domain", "test_service", data={"entity_id": ENTITY_MATCH_ALL}
|
||||
),
|
||||
)
|
||||
|
||||
@ -1513,6 +1525,7 @@ async def test_call_no_context_target_specific(
|
||||
mock_entities,
|
||||
Mock(),
|
||||
ServiceCall(
|
||||
hass,
|
||||
"test_domain",
|
||||
"test_service",
|
||||
{"entity_id": ["light.kitchen", "light.non-existing"]},
|
||||
@ -1534,7 +1547,7 @@ async def test_call_with_match_all(
|
||||
hass,
|
||||
mock_entities,
|
||||
Mock(),
|
||||
ServiceCall("test_domain", "test_service", {"entity_id": "all"}),
|
||||
ServiceCall(hass, "test_domain", "test_service", {"entity_id": "all"}),
|
||||
)
|
||||
|
||||
assert len(mock_handle_entity_call.mock_calls) == 4
|
||||
@ -1551,7 +1564,7 @@ async def test_call_with_omit_entity_id(
|
||||
hass,
|
||||
mock_entities,
|
||||
Mock(),
|
||||
ServiceCall("test_domain", "test_service"),
|
||||
ServiceCall(hass, "test_domain", "test_service"),
|
||||
)
|
||||
|
||||
assert len(mock_handle_entity_call.mock_calls) == 0
|
||||
@ -1797,7 +1810,7 @@ async def test_extract_from_service_available_device(hass: HomeAssistant) -> Non
|
||||
MockEntity(name="test_4", entity_id="test_domain.test_4", available=False),
|
||||
]
|
||||
|
||||
call_1 = ServiceCall("test", "service", data={"entity_id": ENTITY_MATCH_ALL})
|
||||
call_1 = ServiceCall(hass, "test", "service", data={"entity_id": ENTITY_MATCH_ALL})
|
||||
|
||||
assert [
|
||||
ent.entity_id
|
||||
@ -1805,6 +1818,7 @@ async def test_extract_from_service_available_device(hass: HomeAssistant) -> Non
|
||||
] == ["test_domain.test_1", "test_domain.test_3"]
|
||||
|
||||
call_2 = ServiceCall(
|
||||
hass,
|
||||
"test",
|
||||
"service",
|
||||
data={"entity_id": ["test_domain.test_3", "test_domain.test_4"]},
|
||||
@ -1820,6 +1834,7 @@ async def test_extract_from_service_available_device(hass: HomeAssistant) -> Non
|
||||
hass,
|
||||
entities,
|
||||
ServiceCall(
|
||||
hass,
|
||||
"test",
|
||||
"service",
|
||||
data={"entity_id": ENTITY_MATCH_NONE},
|
||||
@ -1835,7 +1850,7 @@ async def test_extract_from_service_empty_if_no_entity_id(hass: HomeAssistant) -
|
||||
MockEntity(name="test_1", entity_id="test_domain.test_1"),
|
||||
MockEntity(name="test_2", entity_id="test_domain.test_2"),
|
||||
]
|
||||
call = ServiceCall("test", "service")
|
||||
call = ServiceCall(hass, "test", "service")
|
||||
|
||||
assert [
|
||||
ent.entity_id
|
||||
@ -1853,6 +1868,7 @@ async def test_extract_from_service_filter_out_non_existing_entities(
|
||||
]
|
||||
|
||||
call = ServiceCall(
|
||||
hass,
|
||||
"test",
|
||||
"service",
|
||||
{"entity_id": ["test_domain.test_2", "test_domain.non_exist"]},
|
||||
@ -1874,12 +1890,14 @@ async def test_extract_from_service_area_id(
|
||||
MockEntity(name="diff_area", entity_id="light.diff_area"),
|
||||
]
|
||||
|
||||
call = ServiceCall("light", "turn_on", {"area_id": "test-area"})
|
||||
call = ServiceCall(hass, "light", "turn_on", {"area_id": "test-area"})
|
||||
extracted = await service.async_extract_entities(hass, entities, call)
|
||||
assert len(extracted) == 1
|
||||
assert extracted[0].entity_id == "light.in_area"
|
||||
|
||||
call = ServiceCall("light", "turn_on", {"area_id": ["test-area", "diff-area"]})
|
||||
call = ServiceCall(
|
||||
hass, "light", "turn_on", {"area_id": ["test-area", "diff-area"]}
|
||||
)
|
||||
extracted = await service.async_extract_entities(hass, entities, call)
|
||||
assert len(extracted) == 2
|
||||
assert sorted(ent.entity_id for ent in extracted) == [
|
||||
@ -1888,6 +1906,7 @@ async def test_extract_from_service_area_id(
|
||||
]
|
||||
|
||||
call = ServiceCall(
|
||||
hass,
|
||||
"light",
|
||||
"turn_on",
|
||||
{"area_id": ["test-area", "diff-area"], "device_id": "device-no-area-id"},
|
||||
@ -1912,17 +1931,17 @@ async def test_extract_from_service_label_id(hass: HomeAssistant) -> None:
|
||||
),
|
||||
]
|
||||
|
||||
call = ServiceCall("light", "turn_on", {"label_id": "label_area"})
|
||||
call = ServiceCall(hass, "light", "turn_on", {"label_id": "label_area"})
|
||||
extracted = await service.async_extract_entities(hass, entities, call)
|
||||
assert len(extracted) == 1
|
||||
assert extracted[0].entity_id == "light.with_labels_from_device"
|
||||
|
||||
call = ServiceCall("light", "turn_on", {"label_id": "my-label"})
|
||||
call = ServiceCall(hass, "light", "turn_on", {"label_id": "my-label"})
|
||||
extracted = await service.async_extract_entities(hass, entities, call)
|
||||
assert len(extracted) == 1
|
||||
assert extracted[0].entity_id == "light.with_my_label"
|
||||
|
||||
call = ServiceCall("light", "turn_on", {"label_id": ["my-label", "label1"]})
|
||||
call = ServiceCall(hass, "light", "turn_on", {"label_id": ["my-label", "label1"]})
|
||||
extracted = await service.async_extract_entities(hass, entities, call)
|
||||
assert len(extracted) == 2
|
||||
assert sorted(ent.entity_id for ent in extracted) == [
|
||||
@ -1931,6 +1950,7 @@ async def test_extract_from_service_label_id(hass: HomeAssistant) -> None:
|
||||
]
|
||||
|
||||
call = ServiceCall(
|
||||
hass,
|
||||
"light",
|
||||
"turn_on",
|
||||
{"label_id": ["my-label", "label1"], "device_id": "device-no-labels"},
|
||||
@ -1949,6 +1969,7 @@ async def test_entity_service_call_warn_referenced(
|
||||
) -> None:
|
||||
"""Test we only warn for referenced entities in entity_service_call."""
|
||||
call = ServiceCall(
|
||||
hass,
|
||||
"light",
|
||||
"turn_on",
|
||||
{
|
||||
@ -1972,6 +1993,7 @@ async def test_async_extract_entities_warn_referenced(
|
||||
) -> None:
|
||||
"""Test we only warn for referenced entities in async_extract_entities."""
|
||||
call = ServiceCall(
|
||||
hass,
|
||||
"light",
|
||||
"turn_on",
|
||||
{
|
||||
@ -1997,6 +2019,7 @@ async def test_async_extract_config_entry_ids(hass: HomeAssistant) -> None:
|
||||
device_no_entities = dr.DeviceEntry(id="device-no-entities", config_entries={"abc"})
|
||||
|
||||
call = ServiceCall(
|
||||
hass,
|
||||
"homeassistant",
|
||||
"reload_config_entry",
|
||||
{
|
||||
@ -2042,17 +2065,33 @@ async def test_reload_service_helper(hass: HomeAssistant) -> None:
|
||||
reloader = service.ReloadServiceHelper(reload_service_handler, reload_targets)
|
||||
tasks = [
|
||||
# This reload task will start executing first, (target1)
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target1"})),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target1"})
|
||||
),
|
||||
# These reload tasks will be deduplicated to (target2, target3, target4, target1)
|
||||
# while the first task is reloaded, note that target1 can't be deduplicated
|
||||
# because it's already being reloaded.
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target2"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target3"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target4"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target1"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target2"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target3"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target4"})),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target2"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target3"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target4"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target1"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target2"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target3"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target4"})
|
||||
),
|
||||
]
|
||||
await asyncio.gather(*tasks)
|
||||
assert reloaded == unordered(
|
||||
@ -2063,13 +2102,21 @@ async def test_reload_service_helper(hass: HomeAssistant) -> None:
|
||||
reloaded.clear()
|
||||
tasks = [
|
||||
# This reload task will start executing first, (target1)
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target1"})),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target1"})
|
||||
),
|
||||
# These reload tasks will be deduplicated to (target2, target3, target4, all)
|
||||
# while the first task is reloaded.
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target2"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target3"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target4"})),
|
||||
reloader.execute_service(ServiceCall("test", "test")),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target2"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target3"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target4"})
|
||||
),
|
||||
reloader.execute_service(ServiceCall(hass, "test", "test")),
|
||||
]
|
||||
await asyncio.gather(*tasks)
|
||||
assert reloaded == unordered(["target1", "target2", "target3", "target4", "all"])
|
||||
@ -2078,13 +2125,21 @@ async def test_reload_service_helper(hass: HomeAssistant) -> None:
|
||||
reloaded.clear()
|
||||
tasks = [
|
||||
# This reload task will start executing first, (all)
|
||||
reloader.execute_service(ServiceCall("test", "test")),
|
||||
reloader.execute_service(ServiceCall(hass, "test", "test")),
|
||||
# These reload tasks will be deduplicated to (target1, target2, target3, target4)
|
||||
# while the first task is reloaded.
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target1"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target2"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target3"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target4"})),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target1"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target2"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target3"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target4"})
|
||||
),
|
||||
]
|
||||
await asyncio.gather(*tasks)
|
||||
assert reloaded == unordered(["all", "target1", "target2", "target3", "target4"])
|
||||
@ -2093,21 +2148,45 @@ async def test_reload_service_helper(hass: HomeAssistant) -> None:
|
||||
reloaded.clear()
|
||||
tasks = [
|
||||
# This reload task will start executing first, (target1)
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target1"})),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target1"})
|
||||
),
|
||||
# These reload tasks will be deduplicated to (target2, target3, target4, target1)
|
||||
# while the first task is reloaded, note that target1 can't be deduplicated
|
||||
# because it's already being reloaded.
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target2"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target3"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target4"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target1"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target2"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target3"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target4"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target1"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target2"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target3"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target4"})),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target2"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target3"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target4"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target1"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target2"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target3"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target4"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target1"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target2"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target3"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target4"})
|
||||
),
|
||||
]
|
||||
await asyncio.gather(*tasks)
|
||||
assert reloaded == unordered(
|
||||
@ -2118,14 +2197,22 @@ async def test_reload_service_helper(hass: HomeAssistant) -> None:
|
||||
reloaded.clear()
|
||||
tasks = [
|
||||
# This reload task will start executing first, (target1)
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target1"})),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target1"})
|
||||
),
|
||||
# These reload tasks will be deduplicated to (target2, target3, target4, all)
|
||||
# while the first task is reloaded.
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target2"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target3"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target4"})),
|
||||
reloader.execute_service(ServiceCall("test", "test")),
|
||||
reloader.execute_service(ServiceCall("test", "test")),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target2"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target3"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target4"})
|
||||
),
|
||||
reloader.execute_service(ServiceCall(hass, "test", "test")),
|
||||
reloader.execute_service(ServiceCall(hass, "test", "test")),
|
||||
]
|
||||
await asyncio.gather(*tasks)
|
||||
assert reloaded == unordered(["target1", "target2", "target3", "target4", "all"])
|
||||
@ -2134,17 +2221,33 @@ async def test_reload_service_helper(hass: HomeAssistant) -> None:
|
||||
reloaded.clear()
|
||||
tasks = [
|
||||
# This reload task will start executing first, (all)
|
||||
reloader.execute_service(ServiceCall("test", "test")),
|
||||
reloader.execute_service(ServiceCall(hass, "test", "test")),
|
||||
# These reload tasks will be deduplicated to (target1, target2, target3, target4)
|
||||
# while the first task is reloaded.
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target1"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target2"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target3"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target4"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target1"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target2"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target3"})),
|
||||
reloader.execute_service(ServiceCall("test", "test", {"target": "target4"})),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target1"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target2"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target3"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target4"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target1"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target2"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target3"})
|
||||
),
|
||||
reloader.execute_service(
|
||||
ServiceCall(hass, "test", "test", {"target": "target4"})
|
||||
),
|
||||
]
|
||||
await asyncio.gather(*tasks)
|
||||
assert reloaded == unordered(["all", "target1", "target2", "target3", "target4"])
|
||||
|
@ -1562,10 +1562,10 @@ async def test_statemachine_avoids_updating_attributes(hass: HomeAssistant) -> N
|
||||
|
||||
def test_service_call_repr() -> None:
|
||||
"""Test ServiceCall repr."""
|
||||
call = ha.ServiceCall("homeassistant", "start")
|
||||
call = ha.ServiceCall(None, "homeassistant", "start")
|
||||
assert str(call) == f"<ServiceCall homeassistant.start (c:{call.context.id})>"
|
||||
|
||||
call2 = ha.ServiceCall("homeassistant", "start", {"fast": "yes"})
|
||||
call2 = ha.ServiceCall(None, "homeassistant", "start", {"fast": "yes"})
|
||||
assert (
|
||||
str(call2)
|
||||
== f"<ServiceCall homeassistant.start (c:{call2.context.id}): fast=yes>"
|
||||
|
Loading…
x
Reference in New Issue
Block a user