Exclude hidden entities from alexa (#68555)
This commit is contained in:
parent
04843a975e
commit
dc8e87a6f7
6 changed files with 123 additions and 59 deletions
|
@ -68,7 +68,10 @@ class AlexaConfig(AbstractConfig):
|
|||
|
||||
entity_registry = er.async_get(self.hass)
|
||||
if registry_entry := entity_registry.async_get(entity_id):
|
||||
auxiliary_entity = registry_entry.entity_category is not None
|
||||
auxiliary_entity = (
|
||||
registry_entry.entity_category is not None
|
||||
or registry_entry.hidden_by is not None
|
||||
)
|
||||
else:
|
||||
auxiliary_entity = False
|
||||
return not auxiliary_entity
|
||||
|
|
|
@ -3,8 +3,10 @@ import re
|
|||
from unittest.mock import Mock
|
||||
from uuid import uuid4
|
||||
|
||||
from homeassistant.components.alexa import config, smart_home
|
||||
from homeassistant.components.alexa import config, smart_home, smart_home_http
|
||||
from homeassistant.components.alexa.const import CONF_ENDPOINT, CONF_FILTER, CONF_LOCALE
|
||||
from homeassistant.core import Context, callback
|
||||
from homeassistant.helpers import entityfilter
|
||||
|
||||
from tests.common import async_mock_service
|
||||
|
||||
|
@ -13,7 +15,7 @@ TEST_TOKEN_URL = "https://api.amazon.com/auth/o2/token"
|
|||
TEST_LOCALE = "en-US"
|
||||
|
||||
|
||||
class MockConfig(config.AbstractConfig):
|
||||
class MockConfig(smart_home_http.AlexaConfig):
|
||||
"""Mock Alexa config."""
|
||||
|
||||
entity_config = {
|
||||
|
@ -26,7 +28,14 @@ class MockConfig(config.AbstractConfig):
|
|||
|
||||
def __init__(self, hass):
|
||||
"""Mock Alexa config."""
|
||||
super().__init__(hass)
|
||||
super().__init__(
|
||||
hass,
|
||||
{
|
||||
CONF_ENDPOINT: TEST_URL,
|
||||
CONF_FILTER: entityfilter.FILTER_SCHEMA({}),
|
||||
CONF_LOCALE: TEST_LOCALE,
|
||||
},
|
||||
)
|
||||
self._store = Mock(spec_set=config.AlexaConfigStore)
|
||||
|
||||
@property
|
||||
|
@ -34,25 +43,11 @@ class MockConfig(config.AbstractConfig):
|
|||
"""Return if config supports auth."""
|
||||
return True
|
||||
|
||||
@property
|
||||
def endpoint(self):
|
||||
"""Endpoint for report state."""
|
||||
return TEST_URL
|
||||
|
||||
@property
|
||||
def locale(self):
|
||||
"""Return config locale."""
|
||||
return TEST_LOCALE
|
||||
|
||||
@callback
|
||||
def user_identifier(self):
|
||||
"""Return an identifier for the user that represents this config."""
|
||||
return "mock-user-id"
|
||||
|
||||
def should_expose(self, entity_id):
|
||||
"""If an entity should be exposed."""
|
||||
return True
|
||||
|
||||
@callback
|
||||
def async_invalidate_access_token(self):
|
||||
"""Invalidate access token."""
|
||||
|
@ -65,9 +60,9 @@ class MockConfig(config.AbstractConfig):
|
|||
"""Accept a grant."""
|
||||
|
||||
|
||||
def get_default_config():
|
||||
def get_default_config(hass):
|
||||
"""Return a MockConfig instance."""
|
||||
return MockConfig(None)
|
||||
return MockConfig(hass)
|
||||
|
||||
|
||||
def get_new_request(namespace, name, endpoint=None):
|
||||
|
@ -117,7 +112,7 @@ async def assert_request_calls_service(
|
|||
calls = async_mock_service(hass, domain, service_name)
|
||||
|
||||
msg = await smart_home.async_handle_message(
|
||||
hass, get_default_config(), request, context
|
||||
hass, get_default_config(hass), request, context
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
@ -142,7 +137,7 @@ async def assert_request_fails(
|
|||
domain, service_name = service_not_called.split(".")
|
||||
call = async_mock_service(hass, domain, service_name)
|
||||
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(), request)
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(hass), request)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert not call
|
||||
|
@ -201,7 +196,7 @@ async def reported_properties(hass, endpoint, return_full_response=False):
|
|||
assertions about the properties.
|
||||
"""
|
||||
request = get_new_request("Alexa", "ReportState", endpoint)
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(), request)
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(hass), request)
|
||||
await hass.async_block_till_done()
|
||||
if return_full_response:
|
||||
return msg
|
||||
|
|
|
@ -55,7 +55,7 @@ async def test_api_adjust_brightness(hass, adjust):
|
|||
|
||||
call_light = async_mock_service(hass, "light", "turn_on")
|
||||
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(), request)
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(hass), request)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert "event" in msg
|
||||
|
@ -85,7 +85,7 @@ async def test_api_set_color_rgb(hass):
|
|||
|
||||
call_light = async_mock_service(hass, "light", "turn_on")
|
||||
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(), request)
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(hass), request)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert "event" in msg
|
||||
|
@ -111,7 +111,7 @@ async def test_api_set_color_temperature(hass):
|
|||
|
||||
call_light = async_mock_service(hass, "light", "turn_on")
|
||||
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(), request)
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(hass), request)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert "event" in msg
|
||||
|
@ -139,7 +139,7 @@ async def test_api_decrease_color_temp(hass, result, initial):
|
|||
|
||||
call_light = async_mock_service(hass, "light", "turn_on")
|
||||
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(), request)
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(hass), request)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert "event" in msg
|
||||
|
@ -167,7 +167,7 @@ async def test_api_increase_color_temp(hass, result, initial):
|
|||
|
||||
call_light = async_mock_service(hass, "light", "turn_on")
|
||||
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(), request)
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(hass), request)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert "event" in msg
|
||||
|
|
|
@ -3,6 +3,8 @@ from unittest.mock import patch
|
|||
|
||||
from homeassistant.components.alexa import smart_home
|
||||
from homeassistant.const import __version__
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.helpers.entity import EntityCategory
|
||||
|
||||
from . import get_default_config, get_new_request
|
||||
|
||||
|
@ -13,7 +15,63 @@ async def test_unsupported_domain(hass):
|
|||
|
||||
hass.states.async_set("woz.boop", "on", {"friendly_name": "Boop Woz"})
|
||||
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(), request)
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(hass), request)
|
||||
|
||||
assert "event" in msg
|
||||
msg = msg["event"]
|
||||
|
||||
assert not msg["payload"]["endpoints"]
|
||||
|
||||
|
||||
async def test_categorized_hidden_entities(hass):
|
||||
"""Discovery ignores hidden and categorized entities."""
|
||||
entity_registry = er.async_get(hass)
|
||||
request = get_new_request("Alexa.Discovery", "Discover")
|
||||
|
||||
entity_entry1 = entity_registry.async_get_or_create(
|
||||
"switch",
|
||||
"test",
|
||||
"switch_config_id",
|
||||
suggested_object_id="config_switch",
|
||||
entity_category=EntityCategory.CONFIG,
|
||||
)
|
||||
entity_entry2 = entity_registry.async_get_or_create(
|
||||
"switch",
|
||||
"test",
|
||||
"switch_diagnostic_id",
|
||||
suggested_object_id="diagnostic_switch",
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
)
|
||||
entity_entry3 = entity_registry.async_get_or_create(
|
||||
"switch",
|
||||
"test",
|
||||
"switch_system_id",
|
||||
suggested_object_id="system_switch",
|
||||
entity_category=EntityCategory.SYSTEM,
|
||||
)
|
||||
entity_entry4 = entity_registry.async_get_or_create(
|
||||
"switch",
|
||||
"test",
|
||||
"switch_hidden_integration_id",
|
||||
suggested_object_id="hidden_integration_switch",
|
||||
hidden_by=er.RegistryEntryHider.INTEGRATION,
|
||||
)
|
||||
entity_entry5 = entity_registry.async_get_or_create(
|
||||
"switch",
|
||||
"test",
|
||||
"switch_hidden_user_id",
|
||||
suggested_object_id="hidden_user_switch",
|
||||
hidden_by=er.RegistryEntryHider.USER,
|
||||
)
|
||||
|
||||
# These should not show up in the sync request
|
||||
hass.states.async_set(entity_entry1.entity_id, "on")
|
||||
hass.states.async_set(entity_entry2.entity_id, "something_else")
|
||||
hass.states.async_set(entity_entry3.entity_id, "blah")
|
||||
hass.states.async_set(entity_entry4.entity_id, "foo")
|
||||
hass.states.async_set(entity_entry5.entity_id, "bar")
|
||||
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(hass), request)
|
||||
|
||||
assert "event" in msg
|
||||
msg = msg["event"]
|
||||
|
@ -27,7 +85,7 @@ async def test_serialize_discovery(hass):
|
|||
|
||||
hass.states.async_set("switch.bla", "on", {"friendly_name": "Boop Woz"})
|
||||
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(), request)
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(hass), request)
|
||||
|
||||
assert "event" in msg
|
||||
msg = msg["event"]
|
||||
|
@ -51,7 +109,9 @@ async def test_serialize_discovery_recovers(hass, caplog):
|
|||
"homeassistant.components.alexa.capabilities.AlexaPowerController.serialize_discovery",
|
||||
side_effect=TypeError,
|
||||
):
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(), request)
|
||||
msg = await smart_home.async_handle_message(
|
||||
hass, get_default_config(hass), request
|
||||
)
|
||||
|
||||
assert "event" in msg
|
||||
msg = msg["event"]
|
||||
|
|
|
@ -121,7 +121,7 @@ async def test_wrong_version(hass):
|
|||
msg["directive"]["header"]["payloadVersion"] = "2"
|
||||
|
||||
with pytest.raises(AssertionError):
|
||||
await smart_home.async_handle_message(hass, get_default_config(), msg)
|
||||
await smart_home.async_handle_message(hass, get_default_config(hass), msg)
|
||||
|
||||
|
||||
async def discovery_test(device, hass, expected_endpoints=1):
|
||||
|
@ -131,7 +131,7 @@ async def discovery_test(device, hass, expected_endpoints=1):
|
|||
# setup test devices
|
||||
hass.states.async_set(*device)
|
||||
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(), request)
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(hass), request)
|
||||
|
||||
assert "event" in msg
|
||||
msg = msg["event"]
|
||||
|
@ -2308,7 +2308,7 @@ async def test_api_entity_not_exists(hass):
|
|||
|
||||
call_switch = async_mock_service(hass, "switch", "turn_on")
|
||||
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(), request)
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(hass), request)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert "event" in msg
|
||||
|
@ -2323,7 +2323,7 @@ async def test_api_entity_not_exists(hass):
|
|||
async def test_api_function_not_implemented(hass):
|
||||
"""Test api call that is not implemented to us."""
|
||||
request = get_new_request("Alexa.HAHAAH", "Sweet")
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(), request)
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(hass), request)
|
||||
|
||||
assert "event" in msg
|
||||
msg = msg["event"]
|
||||
|
@ -2347,7 +2347,7 @@ async def test_api_accept_grant(hass):
|
|||
}
|
||||
|
||||
# setup test devices
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(), request)
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(hass), request)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert "event" in msg
|
||||
|
@ -2400,7 +2400,9 @@ async def test_logging_request(hass, events):
|
|||
"""Test that we log requests."""
|
||||
context = Context()
|
||||
request = get_new_request("Alexa.Discovery", "Discover")
|
||||
await smart_home.async_handle_message(hass, get_default_config(), request, context)
|
||||
await smart_home.async_handle_message(
|
||||
hass, get_default_config(hass), request, context
|
||||
)
|
||||
|
||||
# To trigger event listener
|
||||
await hass.async_block_till_done()
|
||||
|
@ -2420,7 +2422,9 @@ async def test_logging_request_with_entity(hass, events):
|
|||
"""Test that we log requests."""
|
||||
context = Context()
|
||||
request = get_new_request("Alexa.PowerController", "TurnOn", "switch#xy")
|
||||
await smart_home.async_handle_message(hass, get_default_config(), request, context)
|
||||
await smart_home.async_handle_message(
|
||||
hass, get_default_config(hass), request, context
|
||||
)
|
||||
|
||||
# To trigger event listener
|
||||
await hass.async_block_till_done()
|
||||
|
@ -2446,7 +2450,7 @@ async def test_disabled(hass):
|
|||
call_switch = async_mock_service(hass, "switch", "turn_on")
|
||||
|
||||
msg = await smart_home.async_handle_message(
|
||||
hass, get_default_config(), request, enabled=False
|
||||
hass, get_default_config(hass), request, enabled=False
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
@ -2630,7 +2634,7 @@ async def test_range_unsupported_domain(hass):
|
|||
request["directive"]["header"]["instance"] = "switch.speed"
|
||||
|
||||
msg = await smart_home.async_handle_message(
|
||||
hass, get_default_config(), request, context
|
||||
hass, get_default_config(hass), request, context
|
||||
)
|
||||
|
||||
assert "event" in msg
|
||||
|
@ -2651,7 +2655,7 @@ async def test_mode_unsupported_domain(hass):
|
|||
request["directive"]["header"]["instance"] = "switch.direction"
|
||||
|
||||
msg = await smart_home.async_handle_message(
|
||||
hass, get_default_config(), request, context
|
||||
hass, get_default_config(hass), request, context
|
||||
)
|
||||
|
||||
assert "event" in msg
|
||||
|
@ -3393,7 +3397,7 @@ async def test_media_player_eq_bands_not_supported(hass):
|
|||
)
|
||||
request["directive"]["payload"] = {"bands": [{"name": "BASS", "value": -2}]}
|
||||
msg = await smart_home.async_handle_message(
|
||||
hass, get_default_config(), request, context
|
||||
hass, get_default_config(hass), request, context
|
||||
)
|
||||
|
||||
assert "event" in msg
|
||||
|
@ -3410,7 +3414,7 @@ async def test_media_player_eq_bands_not_supported(hass):
|
|||
"bands": [{"name": "BASS", "levelDelta": 3, "levelDirection": "UP"}]
|
||||
}
|
||||
msg = await smart_home.async_handle_message(
|
||||
hass, get_default_config(), request, context
|
||||
hass, get_default_config(hass), request, context
|
||||
)
|
||||
|
||||
assert "event" in msg
|
||||
|
@ -3427,7 +3431,7 @@ async def test_media_player_eq_bands_not_supported(hass):
|
|||
"bands": [{"name": "BASS", "levelDelta": 3, "levelDirection": "UP"}]
|
||||
}
|
||||
msg = await smart_home.async_handle_message(
|
||||
hass, get_default_config(), request, context
|
||||
hass, get_default_config(hass), request, context
|
||||
)
|
||||
|
||||
assert "event" in msg
|
||||
|
@ -3928,7 +3932,9 @@ async def test_initialize_camera_stream(hass, mock_camera, mock_stream):
|
|||
"homeassistant.components.demo.camera.DemoCamera.stream_source",
|
||||
return_value="rtsp://example.local",
|
||||
):
|
||||
msg = await smart_home.async_handle_message(hass, get_default_config(), request)
|
||||
msg = await smart_home.async_handle_message(
|
||||
hass, get_default_config(hass), request
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert "event" in msg
|
||||
|
@ -3982,7 +3988,7 @@ async def test_api_message_sets_authorized(hass):
|
|||
msg = get_new_request("Alexa.PowerController", "TurnOn", "switch#xy")
|
||||
async_mock_service(hass, "switch", "turn_on")
|
||||
|
||||
config = get_default_config()
|
||||
config = get_default_config(hass)
|
||||
config._store.set_authorized.assert_not_called()
|
||||
await smart_home.async_handle_message(hass, config, msg)
|
||||
config._store.set_authorized.assert_called_once_with(True)
|
||||
|
|
|
@ -21,7 +21,7 @@ async def test_report_state(hass, aioclient_mock):
|
|||
{"friendly_name": "Test Contact Sensor", "device_class": "door"},
|
||||
)
|
||||
|
||||
await state_report.async_enable_proactive_mode(hass, get_default_config())
|
||||
await state_report.async_enable_proactive_mode(hass, get_default_config(hass))
|
||||
|
||||
hass.states.async_set(
|
||||
"binary_sensor.test_contact",
|
||||
|
@ -66,7 +66,7 @@ async def test_report_state_fail(hass, aioclient_mock, caplog):
|
|||
{"friendly_name": "Test Contact Sensor", "device_class": "door"},
|
||||
)
|
||||
|
||||
await state_report.async_enable_proactive_mode(hass, get_default_config())
|
||||
await state_report.async_enable_proactive_mode(hass, get_default_config(hass))
|
||||
|
||||
hass.states.async_set(
|
||||
"binary_sensor.test_contact",
|
||||
|
@ -100,7 +100,7 @@ async def test_report_state_timeout(hass, aioclient_mock, caplog):
|
|||
{"friendly_name": "Test Contact Sensor", "device_class": "door"},
|
||||
)
|
||||
|
||||
await state_report.async_enable_proactive_mode(hass, get_default_config())
|
||||
await state_report.async_enable_proactive_mode(hass, get_default_config(hass))
|
||||
|
||||
hass.states.async_set(
|
||||
"binary_sensor.test_contact",
|
||||
|
@ -134,7 +134,7 @@ async def test_report_state_retry(hass, aioclient_mock):
|
|||
{"friendly_name": "Test Contact Sensor", "device_class": "door"},
|
||||
)
|
||||
|
||||
await state_report.async_enable_proactive_mode(hass, get_default_config())
|
||||
await state_report.async_enable_proactive_mode(hass, get_default_config(hass))
|
||||
|
||||
hass.states.async_set(
|
||||
"binary_sensor.test_contact",
|
||||
|
@ -162,7 +162,7 @@ async def test_report_state_unsets_authorized_on_error(hass, aioclient_mock):
|
|||
{"friendly_name": "Test Contact Sensor", "device_class": "door"},
|
||||
)
|
||||
|
||||
config = get_default_config()
|
||||
config = get_default_config(hass)
|
||||
await state_report.async_enable_proactive_mode(hass, config)
|
||||
|
||||
hass.states.async_set(
|
||||
|
@ -191,7 +191,7 @@ async def test_report_state_unsets_authorized_on_access_token_error(
|
|||
{"friendly_name": "Test Contact Sensor", "device_class": "door"},
|
||||
)
|
||||
|
||||
config = get_default_config()
|
||||
config = get_default_config(hass)
|
||||
|
||||
await state_report.async_enable_proactive_mode(hass, config)
|
||||
|
||||
|
@ -226,7 +226,7 @@ async def test_report_state_instance(hass, aioclient_mock):
|
|||
},
|
||||
)
|
||||
|
||||
await state_report.async_enable_proactive_mode(hass, get_default_config())
|
||||
await state_report.async_enable_proactive_mode(hass, get_default_config(hass))
|
||||
|
||||
hass.states.async_set(
|
||||
"fan.test_fan",
|
||||
|
@ -296,7 +296,7 @@ async def test_send_add_or_update_message(hass, aioclient_mock):
|
|||
"zwave.bla", # Unsupported
|
||||
]
|
||||
await state_report.async_send_add_or_update_message(
|
||||
hass, get_default_config(), entities
|
||||
hass, get_default_config(hass), entities
|
||||
)
|
||||
|
||||
assert len(aioclient_mock.mock_calls) == 1
|
||||
|
@ -323,7 +323,7 @@ async def test_send_delete_message(hass, aioclient_mock):
|
|||
)
|
||||
|
||||
await state_report.async_send_delete_message(
|
||||
hass, get_default_config(), ["binary_sensor.test_contact", "zwave.bla"]
|
||||
hass, get_default_config(hass), ["binary_sensor.test_contact", "zwave.bla"]
|
||||
)
|
||||
|
||||
assert len(aioclient_mock.mock_calls) == 1
|
||||
|
@ -349,7 +349,7 @@ async def test_doorbell_event(hass, aioclient_mock):
|
|||
{"friendly_name": "Test Doorbell Sensor", "device_class": "occupancy"},
|
||||
)
|
||||
|
||||
await state_report.async_enable_proactive_mode(hass, get_default_config())
|
||||
await state_report.async_enable_proactive_mode(hass, get_default_config(hass))
|
||||
|
||||
hass.states.async_set(
|
||||
"binary_sensor.test_doorbell",
|
||||
|
@ -407,7 +407,7 @@ async def test_doorbell_event_fail(hass, aioclient_mock, caplog):
|
|||
{"friendly_name": "Test Doorbell Sensor", "device_class": "occupancy"},
|
||||
)
|
||||
|
||||
await state_report.async_enable_proactive_mode(hass, get_default_config())
|
||||
await state_report.async_enable_proactive_mode(hass, get_default_config(hass))
|
||||
|
||||
hass.states.async_set(
|
||||
"binary_sensor.test_doorbell",
|
||||
|
@ -441,7 +441,7 @@ async def test_doorbell_event_timeout(hass, aioclient_mock, caplog):
|
|||
{"friendly_name": "Test Doorbell Sensor", "device_class": "occupancy"},
|
||||
)
|
||||
|
||||
await state_report.async_enable_proactive_mode(hass, get_default_config())
|
||||
await state_report.async_enable_proactive_mode(hass, get_default_config(hass))
|
||||
|
||||
hass.states.async_set(
|
||||
"binary_sensor.test_doorbell",
|
||||
|
@ -464,7 +464,7 @@ async def test_doorbell_event_timeout(hass, aioclient_mock, caplog):
|
|||
async def test_proactive_mode_filter_states(hass, aioclient_mock):
|
||||
"""Test all the cases that filter states."""
|
||||
aioclient_mock.post(TEST_URL, text="", status=202)
|
||||
config = get_default_config()
|
||||
config = get_default_config(hass)
|
||||
await state_report.async_enable_proactive_mode(hass, config)
|
||||
|
||||
# First state should report
|
||||
|
|
Loading…
Add table
Reference in a new issue