Add missing Home Connect context at event listener registration for appliance options (#139292)

* Add missing context at event listener registration for appliance options

* Add tests
This commit is contained in:
J. Diego Rodríguez Royo 2025-02-25 23:05:52 +01:00 committed by GitHub
parent 622be70fee
commit 8644fb1887
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 141 additions and 15 deletions

View File

@ -72,6 +72,10 @@ def _handle_paired_or_connected_appliance(
for entity in get_option_entities_for_appliance(entry, appliance)
if entity.unique_id not in known_entity_unique_ids
)
for event_key in (
EventKey.BSH_COMMON_ROOT_ACTIVE_PROGRAM,
EventKey.BSH_COMMON_ROOT_SELECTED_PROGRAM,
):
changed_options_listener_remove_callback = (
entry.runtime_data.async_add_listener(
partial(
@ -82,6 +86,7 @@ def _handle_paired_or_connected_appliance(
get_option_entities_for_appliance,
async_add_entities,
),
(appliance.info.ha_id, event_key),
)
)
entry.async_on_unload(changed_options_listener_remove_callback)

View File

@ -5,6 +5,7 @@ from unittest.mock import AsyncMock, MagicMock
from aiohomeconnect.model import (
ArrayOfEvents,
ArrayOfHomeAppliances,
ArrayOfPrograms,
Event,
EventKey,
@ -233,6 +234,126 @@ async def test_program_options_retrieval(
assert hass.states.is_state(entity_id, STATE_UNKNOWN)
@pytest.mark.parametrize(
"event_key",
[
EventKey.BSH_COMMON_ROOT_ACTIVE_PROGRAM,
EventKey.BSH_COMMON_ROOT_SELECTED_PROGRAM,
],
)
@pytest.mark.parametrize(
("appliance_ha_id", "option_key", "option_entity_id"),
[
(
"Dishwasher",
OptionKey.DISHCARE_DISHWASHER_HALF_LOAD,
"switch.dishwasher_half_load",
)
],
indirect=["appliance_ha_id"],
)
async def test_program_options_retrieval_after_appliance_connection(
event_key: EventKey,
appliance_ha_id: str,
option_key: OptionKey,
option_entity_id: str,
hass: HomeAssistant,
config_entry: MockConfigEntry,
integration_setup: Callable[[MagicMock], Awaitable[bool]],
setup_credentials: None,
client: MagicMock,
) -> None:
"""Test that the options are correctly retrieved at the start and updated on program updates."""
array_of_home_appliances = client.get_home_appliances.return_value
async def get_home_appliances_with_options_mock() -> ArrayOfHomeAppliances:
return ArrayOfHomeAppliances(
[
appliance
for appliance in array_of_home_appliances.homeappliances
if appliance.ha_id != appliance_ha_id
]
)
client.get_home_appliances = AsyncMock(
side_effect=get_home_appliances_with_options_mock
)
client.get_available_program = AsyncMock(
return_value=ProgramDefinition(
ProgramKey.UNKNOWN,
options=[],
)
)
assert config_entry.state == ConfigEntryState.NOT_LOADED
assert await integration_setup(client)
assert config_entry.state == ConfigEntryState.LOADED
assert not hass.states.get(option_entity_id)
await client.add_events(
[
EventMessage(
appliance_ha_id,
EventType.CONNECTED,
data=ArrayOfEvents(
[
Event(
key=EventKey.BSH_COMMON_APPLIANCE_CONNECTED,
raw_key=EventKey.BSH_COMMON_APPLIANCE_CONNECTED.value,
timestamp=0,
level="",
handling="",
value="",
)
]
),
)
]
)
await hass.async_block_till_done()
assert not hass.states.get(option_entity_id)
client.get_available_program = AsyncMock(
return_value=ProgramDefinition(
ProgramKey.UNKNOWN,
options=[
ProgramDefinitionOption(
option_key,
"Boolean",
constraints=ProgramDefinitionConstraints(
default=False,
),
),
],
)
)
await client.add_events(
[
EventMessage(
appliance_ha_id,
EventType.NOTIFY,
data=ArrayOfEvents(
[
Event(
key=event_key,
raw_key=event_key.value,
timestamp=0,
level="",
handling="",
value=ProgramKey.DISHCARE_DISHWASHER_AUTO_1,
)
]
),
)
]
)
await hass.async_block_till_done()
assert hass.states.get(option_entity_id)
@pytest.mark.parametrize(
(
"set_active_program_option_side_effect",