Improve type hints in conversation tests (#120306)

This commit is contained in:
epenet 2024-06-24 13:41:55 +02:00 committed by GitHub
parent aef2f7d707
commit b4d0de9c0f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,6 +1,7 @@
"""Test for the default agent."""
from collections import defaultdict
from typing import Any
from unittest.mock import AsyncMock, patch
from hassil.recognize import Intent, IntentData, MatchEntity, RecognizeResult
@ -34,7 +35,7 @@ from tests.common import MockConfigEntry, async_mock_service
@pytest.fixture
async def init_components(hass):
async def init_components(hass: HomeAssistant) -> None:
"""Initialize relevant components with empty configs."""
assert await async_setup_component(hass, "homeassistant", {})
assert await async_setup_component(hass, "conversation", {})
@ -50,8 +51,9 @@ async def init_components(hass):
{"entity_category": entity.EntityCategory.DIAGNOSTIC},
],
)
@pytest.mark.usefixtures("init_components")
async def test_hidden_entities_skipped(
hass: HomeAssistant, init_components, er_kwargs, entity_registry: er.EntityRegistry
hass: HomeAssistant, er_kwargs: dict[str, Any], entity_registry: er.EntityRegistry
) -> None:
"""Test we skip hidden entities."""
@ -69,7 +71,8 @@ async def test_hidden_entities_skipped(
assert result.response.error_code == intent.IntentResponseErrorCode.NO_VALID_TARGETS
async def test_exposed_domains(hass: HomeAssistant, init_components) -> None:
@pytest.mark.usefixtures("init_components")
async def test_exposed_domains(hass: HomeAssistant) -> None:
"""Test that we can't interact with entities that aren't exposed."""
hass.states.async_set(
"lock.front_door", "off", attributes={ATTR_FRIENDLY_NAME: "Front Door"}
@ -93,9 +96,9 @@ async def test_exposed_domains(hass: HomeAssistant, init_components) -> None:
assert result.response.error_code == intent.IntentResponseErrorCode.NO_VALID_TARGETS
@pytest.mark.usefixtures("init_components")
async def test_exposed_areas(
hass: HomeAssistant,
init_components,
area_registry: ar.AreaRegistry,
device_registry: dr.DeviceRegistry,
entity_registry: er.EntityRegistry,
@ -160,10 +163,8 @@ async def test_exposed_areas(
assert result.response.response_type == intent.IntentResponseType.QUERY_ANSWER
async def test_conversation_agent(
hass: HomeAssistant,
init_components,
) -> None:
@pytest.mark.usefixtures("init_components")
async def test_conversation_agent(hass: HomeAssistant) -> None:
"""Test DefaultAgent."""
agent = default_agent.async_get_default_agent(hass)
with patch(
@ -209,9 +210,9 @@ async def test_expose_flag_automatically_set(
}
@pytest.mark.usefixtures("init_components")
async def test_unexposed_entities_skipped(
hass: HomeAssistant,
init_components,
area_registry: ar.AreaRegistry,
entity_registry: er.EntityRegistry,
) -> None:
@ -262,7 +263,8 @@ async def test_unexposed_entities_skipped(
assert result.response.matched_states[0].entity_id == exposed_light.entity_id
async def test_trigger_sentences(hass: HomeAssistant, init_components) -> None:
@pytest.mark.usefixtures("init_components")
async def test_trigger_sentences(hass: HomeAssistant) -> None:
"""Test registering/unregistering/matching a few trigger sentences."""
trigger_sentences = ["It's party time", "It is time to party"]
trigger_response = "Cowabunga!"
@ -303,9 +305,8 @@ async def test_trigger_sentences(hass: HomeAssistant, init_components) -> None:
assert len(callback.mock_calls) == 0
async def test_shopping_list_add_item(
hass: HomeAssistant, init_components, sl_setup
) -> None:
@pytest.mark.usefixtures("init_components", "sl_setup")
async def test_shopping_list_add_item(hass: HomeAssistant) -> None:
"""Test adding an item to the shopping list through the default agent."""
result = await conversation.async_converse(
hass, "add apples to my shopping list", None, Context()
@ -316,7 +317,8 @@ async def test_shopping_list_add_item(
}
async def test_nevermind_item(hass: HomeAssistant, init_components) -> None:
@pytest.mark.usefixtures("init_components")
async def test_nevermind_item(hass: HomeAssistant) -> None:
"""Test HassNevermind intent through the default agent."""
result = await conversation.async_converse(hass, "nevermind", None, Context())
assert result.response.intent is not None
@ -326,9 +328,9 @@ async def test_nevermind_item(hass: HomeAssistant, init_components) -> None:
assert not result.response.speech
@pytest.mark.usefixtures("init_components")
async def test_device_area_context(
hass: HomeAssistant,
init_components,
area_registry: ar.AreaRegistry,
device_registry: dr.DeviceRegistry,
entity_registry: er.EntityRegistry,
@ -465,7 +467,8 @@ async def test_device_area_context(
}
async def test_error_no_device(hass: HomeAssistant, init_components) -> None:
@pytest.mark.usefixtures("init_components")
async def test_error_no_device(hass: HomeAssistant) -> None:
"""Test error message when device/entity is missing."""
result = await conversation.async_converse(
hass, "turn on missing entity", None, Context(), None
@ -479,7 +482,8 @@ async def test_error_no_device(hass: HomeAssistant, init_components) -> None:
)
async def test_error_no_area(hass: HomeAssistant, init_components) -> None:
@pytest.mark.usefixtures("init_components")
async def test_error_no_area(hass: HomeAssistant) -> None:
"""Test error message when area is missing."""
result = await conversation.async_converse(
hass, "turn on the lights in missing area", None, Context(), None
@ -493,7 +497,8 @@ async def test_error_no_area(hass: HomeAssistant, init_components) -> None:
)
async def test_error_no_floor(hass: HomeAssistant, init_components) -> None:
@pytest.mark.usefixtures("init_components")
async def test_error_no_floor(hass: HomeAssistant) -> None:
"""Test error message when floor is missing."""
result = await conversation.async_converse(
hass, "turn on all the lights on missing floor", None, Context(), None
@ -507,8 +512,9 @@ async def test_error_no_floor(hass: HomeAssistant, init_components) -> None:
)
@pytest.mark.usefixtures("init_components")
async def test_error_no_device_in_area(
hass: HomeAssistant, init_components, area_registry: ar.AreaRegistry
hass: HomeAssistant, area_registry: ar.AreaRegistry
) -> None:
"""Test error message when area is missing a device/entity."""
area_kitchen = area_registry.async_get_or_create("kitchen_id")
@ -525,9 +531,8 @@ async def test_error_no_device_in_area(
)
async def test_error_no_domain(
hass: HomeAssistant, init_components, area_registry: ar.AreaRegistry
) -> None:
@pytest.mark.usefixtures("init_components")
async def test_error_no_domain(hass: HomeAssistant) -> None:
"""Test error message when no devices/entities exist for a domain."""
# We don't have a sentence for turning on all fans
@ -558,8 +563,9 @@ async def test_error_no_domain(
)
@pytest.mark.usefixtures("init_components")
async def test_error_no_domain_in_area(
hass: HomeAssistant, init_components, area_registry: ar.AreaRegistry
hass: HomeAssistant, area_registry: ar.AreaRegistry
) -> None:
"""Test error message when no devices/entities for a domain exist in an area."""
area_kitchen = area_registry.async_get_or_create("kitchen_id")
@ -576,9 +582,9 @@ async def test_error_no_domain_in_area(
)
@pytest.mark.usefixtures("init_components")
async def test_error_no_domain_in_floor(
hass: HomeAssistant,
init_components,
area_registry: ar.AreaRegistry,
floor_registry: fr.FloorRegistry,
) -> None:
@ -618,7 +624,8 @@ async def test_error_no_domain_in_floor(
)
async def test_error_no_device_class(hass: HomeAssistant, init_components) -> None:
@pytest.mark.usefixtures("init_components")
async def test_error_no_device_class(hass: HomeAssistant) -> None:
"""Test error message when no entities of a device class exist."""
# Create a cover entity that is not a window.
# This ensures that the filtering below won't exit early because there are
@ -658,8 +665,9 @@ async def test_error_no_device_class(hass: HomeAssistant, init_components) -> No
)
@pytest.mark.usefixtures("init_components")
async def test_error_no_device_class_in_area(
hass: HomeAssistant, init_components, area_registry: ar.AreaRegistry
hass: HomeAssistant, area_registry: ar.AreaRegistry
) -> None:
"""Test error message when no entities of a device class exist in an area."""
area_bedroom = area_registry.async_get_or_create("bedroom_id")
@ -676,7 +684,8 @@ async def test_error_no_device_class_in_area(
)
async def test_error_no_intent(hass: HomeAssistant, init_components) -> None:
@pytest.mark.usefixtures("init_components")
async def test_error_no_intent(hass: HomeAssistant) -> None:
"""Test response with an intent match failure."""
with patch(
"homeassistant.components.conversation.default_agent.recognize_all",
@ -696,8 +705,9 @@ async def test_error_no_intent(hass: HomeAssistant, init_components) -> None:
)
@pytest.mark.usefixtures("init_components")
async def test_error_duplicate_names(
hass: HomeAssistant, init_components, entity_registry: er.EntityRegistry
hass: HomeAssistant, entity_registry: er.EntityRegistry
) -> None:
"""Test error message when multiple devices have the same name (or alias)."""
kitchen_light_1 = entity_registry.async_get_or_create("light", "demo", "1234")
@ -747,9 +757,9 @@ async def test_error_duplicate_names(
)
@pytest.mark.usefixtures("init_components")
async def test_error_duplicate_names_in_area(
hass: HomeAssistant,
init_components,
area_registry: ar.AreaRegistry,
entity_registry: er.EntityRegistry,
) -> None:
@ -805,7 +815,8 @@ async def test_error_duplicate_names_in_area(
)
async def test_error_wrong_state(hass: HomeAssistant, init_components) -> None:
@pytest.mark.usefixtures("init_components")
async def test_error_wrong_state(hass: HomeAssistant) -> None:
"""Test error message when no entities are in the correct state."""
assert await async_setup_component(hass, media_player.DOMAIN, {})
@ -824,9 +835,8 @@ async def test_error_wrong_state(hass: HomeAssistant, init_components) -> None:
assert result.response.speech["plain"]["speech"] == "Sorry, no device is playing"
async def test_error_feature_not_supported(
hass: HomeAssistant, init_components
) -> None:
@pytest.mark.usefixtures("init_components")
async def test_error_feature_not_supported(hass: HomeAssistant) -> None:
"""Test error message when no devices support a required feature."""
assert await async_setup_component(hass, media_player.DOMAIN, {})
@ -849,7 +859,8 @@ async def test_error_feature_not_supported(
)
async def test_error_no_timer_support(hass: HomeAssistant, init_components) -> None:
@pytest.mark.usefixtures("init_components")
async def test_error_no_timer_support(hass: HomeAssistant) -> None:
"""Test error message when a device does not support timers (no handler is registered)."""
device_id = "test_device"
@ -866,7 +877,8 @@ async def test_error_no_timer_support(hass: HomeAssistant, init_components) -> N
)
async def test_error_timer_not_found(hass: HomeAssistant, init_components) -> None:
@pytest.mark.usefixtures("init_components")
async def test_error_timer_not_found(hass: HomeAssistant) -> None:
"""Test error message when a timer cannot be matched."""
device_id = "test_device"
@ -888,9 +900,9 @@ async def test_error_timer_not_found(hass: HomeAssistant, init_components) -> No
)
@pytest.mark.usefixtures("init_components")
async def test_error_multiple_timers_matched(
hass: HomeAssistant,
init_components,
area_registry: ar.AreaRegistry,
device_registry: dr.DeviceRegistry,
) -> None:
@ -938,8 +950,9 @@ async def test_error_multiple_timers_matched(
)
@pytest.mark.usefixtures("init_components")
async def test_no_states_matched_default_error(
hass: HomeAssistant, init_components, area_registry: ar.AreaRegistry
hass: HomeAssistant, area_registry: ar.AreaRegistry
) -> None:
"""Test default response when no states match and slots are missing."""
area_kitchen = area_registry.async_get_or_create("kitchen_id")
@ -966,9 +979,9 @@ async def test_no_states_matched_default_error(
)
@pytest.mark.usefixtures("init_components")
async def test_empty_aliases(
hass: HomeAssistant,
init_components,
area_registry: ar.AreaRegistry,
device_registry: dr.DeviceRegistry,
entity_registry: er.EntityRegistry,
@ -1031,7 +1044,8 @@ async def test_empty_aliases(
assert floors.values[0].text_in.text == floor_1.name
async def test_all_domains_loaded(hass: HomeAssistant, init_components) -> None:
@pytest.mark.usefixtures("init_components")
async def test_all_domains_loaded(hass: HomeAssistant) -> None:
"""Test that sentences for all domains are always loaded."""
# light domain is not loaded
@ -1050,9 +1064,9 @@ async def test_all_domains_loaded(hass: HomeAssistant, init_components) -> None:
)
@pytest.mark.usefixtures("init_components")
async def test_same_named_entities_in_different_areas(
hass: HomeAssistant,
init_components,
area_registry: ar.AreaRegistry,
entity_registry: er.EntityRegistry,
) -> None:
@ -1147,9 +1161,9 @@ async def test_same_named_entities_in_different_areas(
assert result.response.response_type == intent.IntentResponseType.QUERY_ANSWER
@pytest.mark.usefixtures("init_components")
async def test_same_aliased_entities_in_different_areas(
hass: HomeAssistant,
init_components,
area_registry: ar.AreaRegistry,
entity_registry: er.EntityRegistry,
) -> None:
@ -1238,7 +1252,8 @@ async def test_same_aliased_entities_in_different_areas(
assert result.response.response_type == intent.IntentResponseType.QUERY_ANSWER
async def test_device_id_in_handler(hass: HomeAssistant, init_components) -> None:
@pytest.mark.usefixtures("init_components")
async def test_device_id_in_handler(hass: HomeAssistant) -> None:
"""Test that the default agent passes device_id to intent handler."""
device_id = "test_device"
@ -1270,9 +1285,8 @@ async def test_device_id_in_handler(hass: HomeAssistant, init_components) -> Non
assert handler.device_id == device_id
async def test_name_wildcard_lower_priority(
hass: HomeAssistant, init_components
) -> None:
@pytest.mark.usefixtures("init_components")
async def test_name_wildcard_lower_priority(hass: HomeAssistant) -> None:
"""Test that the default agent does not prioritize a {name} slot when it's a wildcard."""
class OrderBeerIntentHandler(intent.IntentHandler):