1
0
mirror of https://github.com/esphome/esphome.git synced 2025-11-15 14:25:45 +00:00
Files
esphome/tests/integration/test_homeassistant_service_calls_multiple_clients.py
2025-08-05 13:40:59 +00:00

99 lines
3.9 KiB
Python

"""Integration test to verify that homeassistant.service calls are still sent to all clients.
This test ensures that our fix for duplicate events doesn't break the expected
behavior for service calls, which should be sent to all connected clients.
"""
from __future__ import annotations
import asyncio
from aioesphomeapi import HomeassistantServiceCall
import pytest
from .types import APIClientConnectedFactory, RunCompiledFunction
@pytest.mark.asyncio
async def test_homeassistant_service_calls_to_all_clients(
yaml_config: str,
run_compiled: RunCompiledFunction,
api_client_connected: APIClientConnectedFactory,
) -> None:
"""Test that homeassistant.service calls are sent to all connected clients."""
# Track service calls received by each client
client1_service_calls: list[HomeassistantServiceCall] = []
client2_service_calls: list[HomeassistantServiceCall] = []
def on_service_call_client1(service_call: HomeassistantServiceCall) -> None:
"""Track service calls received by first client."""
if not service_call.is_event: # Only track service calls, not events
client1_service_calls.append(service_call)
def on_service_call_client2(service_call: HomeassistantServiceCall) -> None:
"""Track service calls received by second client."""
if not service_call.is_event: # Only track service calls, not events
client2_service_calls.append(service_call)
# Connect TWO API clients
async with (
run_compiled(yaml_config),
api_client_connected() as client1,
api_client_connected() as client2,
):
# Subscribe both clients to service calls
client1.subscribe_service_calls(on_service_call_client1)
client2.subscribe_service_calls(on_service_call_client2)
# Get device info to ensure both clients are connected
device_info1 = await client1.device_info()
device_info2 = await client2.device_info()
assert device_info1 is not None
assert device_info2 is not None
assert device_info1.name == device_info2.name
# List entities and services
entities1, services1 = await client1.list_entities_services()
# Find the test service
test_service = next(
(s for s in services1 if s.name == "trigger_service_call_test"), None
)
assert test_service is not None, "trigger_service_call_test service not found"
# Clear any initial service calls
client1_service_calls.clear()
client2_service_calls.clear()
# Trigger the service call
client1.execute_service(test_service, {})
# Wait for service calls to be processed
await asyncio.sleep(0.5)
# Now check the results
print(f"Client1 received {len(client1_service_calls)} service calls")
print(f"Client2 received {len(client2_service_calls)} service calls")
# For service calls (not events), both clients should receive the call
# This is the correct behavior for service calls
assert len(client1_service_calls) > 0, (
"Client1 should have received service calls"
)
assert len(client2_service_calls) > 0, (
"Client2 should have received service calls"
)
# Both clients should have received the same service calls
assert len(client1_service_calls) == len(client2_service_calls), (
f"Both clients should receive the same number of service calls. "
f"Client1: {len(client1_service_calls)}, Client2: {len(client2_service_calls)}"
)
# Verify the service call details
for call1, call2 in zip(client1_service_calls, client2_service_calls):
assert call1.service == call2.service, "Service names should match"
assert not call1.is_event, "These should be service calls, not events"
assert not call2.is_event, "These should be service calls, not events"