mirror of
https://github.com/home-assistant/core.git
synced 2025-07-24 21:57:51 +00:00
Convert some tests to async and drop usage get_test_home_assistant (#64394)
* Fix some tests * Update MS tests * Convert last logbook tests to async
This commit is contained in:
parent
394c6850a3
commit
08083f399e
@ -951,10 +951,11 @@ async def async_handle_snapshot_service(
|
|||||||
|
|
||||||
image = await camera.async_camera_image()
|
image = await camera.async_camera_image()
|
||||||
|
|
||||||
def _write_image(to_file: str, image_data: bytes | None) -> None:
|
if image is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
def _write_image(to_file: str, image_data: bytes) -> None:
|
||||||
"""Executor helper to write image."""
|
"""Executor helper to write image."""
|
||||||
if image_data is None:
|
|
||||||
return
|
|
||||||
os.makedirs(os.path.dirname(to_file), exist_ok=True)
|
os.makedirs(os.path.dirname(to_file), exist_ok=True)
|
||||||
with open(to_file, "wb") as img_file:
|
with open(to_file, "wb") as img_file:
|
||||||
img_file.write(image_data)
|
img_file.write(image_data)
|
||||||
|
@ -4,9 +4,6 @@ from unittest.mock import Mock, patch
|
|||||||
import aprslib
|
import aprslib
|
||||||
|
|
||||||
import homeassistant.components.aprs.device_tracker as device_tracker
|
import homeassistant.components.aprs.device_tracker as device_tracker
|
||||||
from homeassistant.const import EVENT_HOMEASSISTANT_START
|
|
||||||
|
|
||||||
from tests.common import get_test_home_assistant
|
|
||||||
|
|
||||||
DEFAULT_PORT = 14580
|
DEFAULT_PORT = 14580
|
||||||
|
|
||||||
@ -299,14 +296,11 @@ def test_aprs_listener_rx_msg_no_position():
|
|||||||
see.assert_not_called()
|
see.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
def test_setup_scanner():
|
async def test_setup_scanner(hass):
|
||||||
"""Test setup_scanner."""
|
"""Test setup_scanner."""
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.aprs.device_tracker.AprsListenerThread"
|
"homeassistant.components.aprs.device_tracker.AprsListenerThread"
|
||||||
) as listener:
|
) as listener:
|
||||||
hass = get_test_home_assistant()
|
|
||||||
hass.start()
|
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
"username": TEST_CALLSIGN,
|
"username": TEST_CALLSIGN,
|
||||||
"password": TEST_PASSWORD,
|
"password": TEST_PASSWORD,
|
||||||
@ -316,9 +310,9 @@ def test_setup_scanner():
|
|||||||
}
|
}
|
||||||
|
|
||||||
see = Mock()
|
see = Mock()
|
||||||
res = device_tracker.setup_scanner(hass, config, see)
|
res = await hass.async_add_executor_job(
|
||||||
hass.bus.fire(EVENT_HOMEASSISTANT_START)
|
device_tracker.setup_scanner, hass, config, see
|
||||||
hass.stop()
|
)
|
||||||
|
|
||||||
assert res
|
assert res
|
||||||
listener.assert_called_with(
|
listener.assert_called_with(
|
||||||
@ -326,12 +320,9 @@ def test_setup_scanner():
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_setup_scanner_timeout():
|
async def test_setup_scanner_timeout(hass):
|
||||||
"""Test setup_scanner failure from timeout."""
|
"""Test setup_scanner failure from timeout."""
|
||||||
with patch("aprslib.IS.connect", side_effect=TimeoutError):
|
with patch("aprslib.IS.connect", side_effect=TimeoutError):
|
||||||
hass = get_test_home_assistant()
|
|
||||||
hass.start()
|
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
"username": TEST_CALLSIGN,
|
"username": TEST_CALLSIGN,
|
||||||
"password": TEST_PASSWORD,
|
"password": TEST_PASSWORD,
|
||||||
@ -341,5 +332,6 @@ def test_setup_scanner_timeout():
|
|||||||
}
|
}
|
||||||
|
|
||||||
see = Mock()
|
see = Mock()
|
||||||
assert not device_tracker.setup_scanner(hass, config, see)
|
assert not await hass.async_add_executor_job(
|
||||||
hass.stop()
|
device_tracker.setup_scanner, hass, config, see
|
||||||
|
)
|
||||||
|
@ -279,8 +279,7 @@ async def test_snapshot_service(hass, mock_camera):
|
|||||||
mopen = mock_open()
|
mopen = mock_open()
|
||||||
|
|
||||||
with patch("homeassistant.components.camera.open", mopen, create=True), patch(
|
with patch("homeassistant.components.camera.open", mopen, create=True), patch(
|
||||||
"homeassistant.components.camera.os.path.exists",
|
"homeassistant.components.camera.os.makedirs",
|
||||||
Mock(spec="os.path.exists", return_value=True),
|
|
||||||
), patch.object(hass.config, "is_allowed_path", return_value=True):
|
), patch.object(hass.config, "is_allowed_path", return_value=True):
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
camera.DOMAIN,
|
camera.DOMAIN,
|
||||||
|
@ -35,37 +35,32 @@ from homeassistant.const import (
|
|||||||
import homeassistant.core as ha
|
import homeassistant.core as ha
|
||||||
from homeassistant.helpers.entityfilter import CONF_ENTITY_GLOBS
|
from homeassistant.helpers.entityfilter import CONF_ENTITY_GLOBS
|
||||||
from homeassistant.helpers.json import JSONEncoder
|
from homeassistant.helpers.json import JSONEncoder
|
||||||
from homeassistant.setup import async_setup_component, setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
import homeassistant.util.dt as dt_util
|
import homeassistant.util.dt as dt_util
|
||||||
|
|
||||||
from tests.common import get_test_home_assistant, init_recorder_component, mock_platform
|
from tests.common import (
|
||||||
|
async_capture_events,
|
||||||
|
async_init_recorder_component,
|
||||||
|
mock_platform,
|
||||||
|
)
|
||||||
from tests.components.recorder.common import trigger_db_commit
|
from tests.components.recorder.common import trigger_db_commit
|
||||||
|
|
||||||
EMPTY_CONFIG = logbook.CONFIG_SCHEMA({logbook.DOMAIN: {}})
|
EMPTY_CONFIG = logbook.CONFIG_SCHEMA({logbook.DOMAIN: {}})
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def hass_():
|
async def hass_(hass):
|
||||||
"""Set up things to be run when tests are started."""
|
"""Set up things to be run when tests are started."""
|
||||||
hass = get_test_home_assistant()
|
await async_init_recorder_component(hass) # Force an in memory DB
|
||||||
init_recorder_component(hass) # Force an in memory DB
|
assert await async_setup_component(hass, logbook.DOMAIN, EMPTY_CONFIG)
|
||||||
with patch("homeassistant.components.http.start_http_server_and_save_config"):
|
return hass
|
||||||
assert setup_component(hass, logbook.DOMAIN, EMPTY_CONFIG)
|
|
||||||
yield hass
|
|
||||||
hass.stop()
|
|
||||||
|
|
||||||
|
|
||||||
def test_service_call_create_logbook_entry(hass_):
|
async def test_service_call_create_logbook_entry(hass_):
|
||||||
"""Test if service call create log book entry."""
|
"""Test if service call create log book entry."""
|
||||||
calls = []
|
calls = async_capture_events(hass_, logbook.EVENT_LOGBOOK_ENTRY)
|
||||||
|
|
||||||
@ha.callback
|
await hass_.services.async_call(
|
||||||
def event_listener(event):
|
|
||||||
"""Append on event."""
|
|
||||||
calls.append(event)
|
|
||||||
|
|
||||||
hass_.bus.listen(logbook.EVENT_LOGBOOK_ENTRY, event_listener)
|
|
||||||
hass_.services.call(
|
|
||||||
logbook.DOMAIN,
|
logbook.DOMAIN,
|
||||||
"log",
|
"log",
|
||||||
{
|
{
|
||||||
@ -76,7 +71,7 @@ def test_service_call_create_logbook_entry(hass_):
|
|||||||
},
|
},
|
||||||
True,
|
True,
|
||||||
)
|
)
|
||||||
hass_.services.call(
|
await hass_.services.async_call(
|
||||||
logbook.DOMAIN,
|
logbook.DOMAIN,
|
||||||
"log",
|
"log",
|
||||||
{
|
{
|
||||||
@ -88,9 +83,11 @@ def test_service_call_create_logbook_entry(hass_):
|
|||||||
# Logbook entry service call results in firing an event.
|
# Logbook entry service call results in firing an event.
|
||||||
# Our service call will unblock when the event listeners have been
|
# Our service call will unblock when the event listeners have been
|
||||||
# scheduled. This means that they may not have been processed yet.
|
# scheduled. This means that they may not have been processed yet.
|
||||||
trigger_db_commit(hass_)
|
await hass_.async_add_executor_job(trigger_db_commit, hass_)
|
||||||
hass_.block_till_done()
|
await hass_.async_block_till_done()
|
||||||
hass_.data[recorder.DATA_INSTANCE].block_till_done()
|
await hass_.async_add_executor_job(
|
||||||
|
hass_.data[recorder.DATA_INSTANCE].block_till_done
|
||||||
|
)
|
||||||
|
|
||||||
events = list(
|
events = list(
|
||||||
logbook._get_events(
|
logbook._get_events(
|
||||||
@ -116,24 +113,17 @@ def test_service_call_create_logbook_entry(hass_):
|
|||||||
assert last_call.data.get(logbook.ATTR_DOMAIN) == "logbook"
|
assert last_call.data.get(logbook.ATTR_DOMAIN) == "logbook"
|
||||||
|
|
||||||
|
|
||||||
def test_service_call_create_log_book_entry_no_message(hass_):
|
async def test_service_call_create_log_book_entry_no_message(hass_):
|
||||||
"""Test if service call create log book entry without message."""
|
"""Test if service call create log book entry without message."""
|
||||||
calls = []
|
calls = async_capture_events(hass_, logbook.EVENT_LOGBOOK_ENTRY)
|
||||||
|
|
||||||
@ha.callback
|
|
||||||
def event_listener(event):
|
|
||||||
"""Append on event."""
|
|
||||||
calls.append(event)
|
|
||||||
|
|
||||||
hass_.bus.listen(logbook.EVENT_LOGBOOK_ENTRY, event_listener)
|
|
||||||
|
|
||||||
with pytest.raises(vol.Invalid):
|
with pytest.raises(vol.Invalid):
|
||||||
hass_.services.call(logbook.DOMAIN, "log", {}, True)
|
await hass_.services.async_call(logbook.DOMAIN, "log", {}, True)
|
||||||
|
|
||||||
# Logbook entry service call results in firing an event.
|
# Logbook entry service call results in firing an event.
|
||||||
# Our service call will unblock when the event listeners have been
|
# Our service call will unblock when the event listeners have been
|
||||||
# scheduled. This means that they may not have been processed yet.
|
# scheduled. This means that they may not have been processed yet.
|
||||||
hass_.block_till_done()
|
await hass_.async_block_till_done()
|
||||||
|
|
||||||
assert len(calls) == 0
|
assert len(calls) == 0
|
||||||
|
|
||||||
@ -310,7 +300,7 @@ def create_state_changed_event_from_old_new(
|
|||||||
|
|
||||||
async def test_logbook_view(hass, hass_client):
|
async def test_logbook_view(hass, hass_client):
|
||||||
"""Test the logbook view."""
|
"""Test the logbook view."""
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
await async_setup_component(hass, "logbook", {})
|
await async_setup_component(hass, "logbook", {})
|
||||||
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
||||||
client = await hass_client()
|
client = await hass_client()
|
||||||
@ -320,7 +310,7 @@ async def test_logbook_view(hass, hass_client):
|
|||||||
|
|
||||||
async def test_logbook_view_period_entity(hass, hass_client):
|
async def test_logbook_view_period_entity(hass, hass_client):
|
||||||
"""Test the logbook view with period and entity."""
|
"""Test the logbook view with period and entity."""
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
await async_setup_component(hass, "logbook", {})
|
await async_setup_component(hass, "logbook", {})
|
||||||
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
||||||
|
|
||||||
@ -404,7 +394,7 @@ async def test_logbook_view_period_entity(hass, hass_client):
|
|||||||
|
|
||||||
async def test_logbook_describe_event(hass, hass_client):
|
async def test_logbook_describe_event(hass, hass_client):
|
||||||
"""Test teaching logbook about a new event."""
|
"""Test teaching logbook about a new event."""
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
|
|
||||||
def _describe(event):
|
def _describe(event):
|
||||||
"""Describe an event."""
|
"""Describe an event."""
|
||||||
@ -471,7 +461,7 @@ async def test_exclude_described_event(hass, hass_client):
|
|||||||
Mock(async_describe_events=async_describe_events),
|
Mock(async_describe_events=async_describe_events),
|
||||||
)
|
)
|
||||||
|
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
assert await async_setup_component(
|
assert await async_setup_component(
|
||||||
hass,
|
hass,
|
||||||
logbook.DOMAIN,
|
logbook.DOMAIN,
|
||||||
@ -515,7 +505,7 @@ async def test_exclude_described_event(hass, hass_client):
|
|||||||
|
|
||||||
async def test_logbook_view_end_time_entity(hass, hass_client):
|
async def test_logbook_view_end_time_entity(hass, hass_client):
|
||||||
"""Test the logbook view with end_time and entity."""
|
"""Test the logbook view with end_time and entity."""
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
await async_setup_component(hass, "logbook", {})
|
await async_setup_component(hass, "logbook", {})
|
||||||
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
||||||
|
|
||||||
@ -573,7 +563,7 @@ async def test_logbook_view_end_time_entity(hass, hass_client):
|
|||||||
|
|
||||||
async def test_logbook_entity_filter_with_automations(hass, hass_client):
|
async def test_logbook_entity_filter_with_automations(hass, hass_client):
|
||||||
"""Test the logbook view with end_time and entity with automations and scripts."""
|
"""Test the logbook view with end_time and entity with automations and scripts."""
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
await async_setup_component(hass, "logbook", {})
|
await async_setup_component(hass, "logbook", {})
|
||||||
await async_setup_component(hass, "automation", {})
|
await async_setup_component(hass, "automation", {})
|
||||||
await async_setup_component(hass, "script", {})
|
await async_setup_component(hass, "script", {})
|
||||||
@ -648,7 +638,7 @@ async def test_logbook_entity_filter_with_automations(hass, hass_client):
|
|||||||
|
|
||||||
async def test_filter_continuous_sensor_values(hass, hass_client):
|
async def test_filter_continuous_sensor_values(hass, hass_client):
|
||||||
"""Test remove continuous sensor events from logbook."""
|
"""Test remove continuous sensor events from logbook."""
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
await async_setup_component(hass, "logbook", {})
|
await async_setup_component(hass, "logbook", {})
|
||||||
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
||||||
|
|
||||||
@ -684,7 +674,7 @@ async def test_filter_continuous_sensor_values(hass, hass_client):
|
|||||||
|
|
||||||
async def test_exclude_new_entities(hass, hass_client):
|
async def test_exclude_new_entities(hass, hass_client):
|
||||||
"""Test if events are excluded on first update."""
|
"""Test if events are excluded on first update."""
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
await async_setup_component(hass, "logbook", {})
|
await async_setup_component(hass, "logbook", {})
|
||||||
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
||||||
|
|
||||||
@ -719,7 +709,7 @@ async def test_exclude_new_entities(hass, hass_client):
|
|||||||
|
|
||||||
async def test_exclude_removed_entities(hass, hass_client):
|
async def test_exclude_removed_entities(hass, hass_client):
|
||||||
"""Test if events are excluded on last update."""
|
"""Test if events are excluded on last update."""
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
await async_setup_component(hass, "logbook", {})
|
await async_setup_component(hass, "logbook", {})
|
||||||
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
||||||
|
|
||||||
@ -761,7 +751,7 @@ async def test_exclude_removed_entities(hass, hass_client):
|
|||||||
|
|
||||||
async def test_exclude_attribute_changes(hass, hass_client):
|
async def test_exclude_attribute_changes(hass, hass_client):
|
||||||
"""Test if events of attribute changes are filtered."""
|
"""Test if events of attribute changes are filtered."""
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
await async_setup_component(hass, "logbook", {})
|
await async_setup_component(hass, "logbook", {})
|
||||||
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
||||||
|
|
||||||
@ -799,7 +789,7 @@ async def test_exclude_attribute_changes(hass, hass_client):
|
|||||||
|
|
||||||
async def test_logbook_entity_context_id(hass, hass_client):
|
async def test_logbook_entity_context_id(hass, hass_client):
|
||||||
"""Test the logbook view with end_time and entity with automations and scripts."""
|
"""Test the logbook view with end_time and entity with automations and scripts."""
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
await async_setup_component(hass, "logbook", {})
|
await async_setup_component(hass, "logbook", {})
|
||||||
await async_setup_component(hass, "automation", {})
|
await async_setup_component(hass, "automation", {})
|
||||||
await async_setup_component(hass, "script", {})
|
await async_setup_component(hass, "script", {})
|
||||||
@ -951,7 +941,7 @@ async def test_logbook_entity_context_id(hass, hass_client):
|
|||||||
|
|
||||||
async def test_logbook_entity_context_parent_id(hass, hass_client):
|
async def test_logbook_entity_context_parent_id(hass, hass_client):
|
||||||
"""Test the logbook view links events via context parent_id."""
|
"""Test the logbook view links events via context parent_id."""
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
await async_setup_component(hass, "logbook", {})
|
await async_setup_component(hass, "logbook", {})
|
||||||
await async_setup_component(hass, "automation", {})
|
await async_setup_component(hass, "automation", {})
|
||||||
await async_setup_component(hass, "script", {})
|
await async_setup_component(hass, "script", {})
|
||||||
@ -1132,7 +1122,7 @@ async def test_logbook_entity_context_parent_id(hass, hass_client):
|
|||||||
|
|
||||||
async def test_logbook_context_from_template(hass, hass_client):
|
async def test_logbook_context_from_template(hass, hass_client):
|
||||||
"""Test the logbook view with end_time and entity with automations and scripts."""
|
"""Test the logbook view with end_time and entity with automations and scripts."""
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
await async_setup_component(hass, "logbook", {})
|
await async_setup_component(hass, "logbook", {})
|
||||||
assert await async_setup_component(
|
assert await async_setup_component(
|
||||||
hass,
|
hass,
|
||||||
@ -1218,7 +1208,7 @@ async def test_logbook_context_from_template(hass, hass_client):
|
|||||||
|
|
||||||
async def test_logbook_entity_matches_only(hass, hass_client):
|
async def test_logbook_entity_matches_only(hass, hass_client):
|
||||||
"""Test the logbook view with a single entity and entity_matches_only."""
|
"""Test the logbook view with a single entity and entity_matches_only."""
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
await async_setup_component(hass, "logbook", {})
|
await async_setup_component(hass, "logbook", {})
|
||||||
assert await async_setup_component(
|
assert await async_setup_component(
|
||||||
hass,
|
hass,
|
||||||
@ -1292,7 +1282,7 @@ async def test_logbook_entity_matches_only(hass, hass_client):
|
|||||||
|
|
||||||
async def test_custom_log_entry_discoverable_via_entity_matches_only(hass, hass_client):
|
async def test_custom_log_entry_discoverable_via_entity_matches_only(hass, hass_client):
|
||||||
"""Test if a custom log entry is later discoverable via entity_matches_only."""
|
"""Test if a custom log entry is later discoverable via entity_matches_only."""
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
await async_setup_component(hass, "logbook", {})
|
await async_setup_component(hass, "logbook", {})
|
||||||
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
||||||
|
|
||||||
@ -1331,7 +1321,7 @@ async def test_custom_log_entry_discoverable_via_entity_matches_only(hass, hass_
|
|||||||
|
|
||||||
async def test_logbook_entity_matches_only_multiple(hass, hass_client):
|
async def test_logbook_entity_matches_only_multiple(hass, hass_client):
|
||||||
"""Test the logbook view with a multiple entities and entity_matches_only."""
|
"""Test the logbook view with a multiple entities and entity_matches_only."""
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
await async_setup_component(hass, "logbook", {})
|
await async_setup_component(hass, "logbook", {})
|
||||||
assert await async_setup_component(
|
assert await async_setup_component(
|
||||||
hass,
|
hass,
|
||||||
@ -1415,7 +1405,7 @@ async def test_logbook_entity_matches_only_multiple(hass, hass_client):
|
|||||||
|
|
||||||
async def test_logbook_invalid_entity(hass, hass_client):
|
async def test_logbook_invalid_entity(hass, hass_client):
|
||||||
"""Test the logbook view with requesting an invalid entity."""
|
"""Test the logbook view with requesting an invalid entity."""
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
await async_setup_component(hass, "logbook", {})
|
await async_setup_component(hass, "logbook", {})
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
client = await hass_client()
|
client = await hass_client()
|
||||||
@ -1434,7 +1424,7 @@ async def test_logbook_invalid_entity(hass, hass_client):
|
|||||||
|
|
||||||
async def test_icon_and_state(hass, hass_client):
|
async def test_icon_and_state(hass, hass_client):
|
||||||
"""Test to ensure state and custom icons are returned."""
|
"""Test to ensure state and custom icons are returned."""
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
await async_setup_component(hass, "logbook", {})
|
await async_setup_component(hass, "logbook", {})
|
||||||
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
||||||
|
|
||||||
@ -1481,7 +1471,7 @@ async def test_exclude_events_domain(hass, hass_client):
|
|||||||
logbook.DOMAIN: {CONF_EXCLUDE: {CONF_DOMAINS: ["switch", "alexa"]}},
|
logbook.DOMAIN: {CONF_EXCLUDE: {CONF_DOMAINS: ["switch", "alexa"]}},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
await async_setup_component(hass, "logbook", config)
|
await async_setup_component(hass, "logbook", config)
|
||||||
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
||||||
|
|
||||||
@ -1521,7 +1511,7 @@ async def test_exclude_events_domain_glob(hass, hass_client):
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
await async_setup_component(hass, "logbook", config)
|
await async_setup_component(hass, "logbook", config)
|
||||||
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
||||||
|
|
||||||
@ -1561,7 +1551,7 @@ async def test_include_events_entity(hass, hass_client):
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
await async_setup_component(hass, "logbook", config)
|
await async_setup_component(hass, "logbook", config)
|
||||||
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
||||||
|
|
||||||
@ -1594,7 +1584,7 @@ async def test_exclude_events_entity(hass, hass_client):
|
|||||||
logbook.DOMAIN: {CONF_EXCLUDE: {CONF_ENTITIES: [entity_id]}},
|
logbook.DOMAIN: {CONF_EXCLUDE: {CONF_ENTITIES: [entity_id]}},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
await async_setup_component(hass, "logbook", config)
|
await async_setup_component(hass, "logbook", config)
|
||||||
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
||||||
|
|
||||||
@ -1628,7 +1618,7 @@ async def test_include_events_domain(hass, hass_client):
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
await async_setup_component(hass, "logbook", config)
|
await async_setup_component(hass, "logbook", config)
|
||||||
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
||||||
|
|
||||||
@ -1672,7 +1662,7 @@ async def test_include_events_domain_glob(hass, hass_client):
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
await async_setup_component(hass, "logbook", config)
|
await async_setup_component(hass, "logbook", config)
|
||||||
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
||||||
|
|
||||||
@ -1724,7 +1714,7 @@ async def test_include_exclude_events(hass, hass_client):
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
await async_setup_component(hass, "logbook", config)
|
await async_setup_component(hass, "logbook", config)
|
||||||
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
||||||
|
|
||||||
@ -1778,7 +1768,7 @@ async def test_include_exclude_events_with_glob_filters(hass, hass_client):
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
await async_setup_component(hass, "logbook", config)
|
await async_setup_component(hass, "logbook", config)
|
||||||
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
||||||
|
|
||||||
@ -1821,7 +1811,7 @@ async def test_empty_config(hass, hass_client):
|
|||||||
logbook.DOMAIN: {},
|
logbook.DOMAIN: {},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
await async_setup_component(hass, "logbook", config)
|
await async_setup_component(hass, "logbook", config)
|
||||||
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
||||||
|
|
||||||
@ -1843,7 +1833,7 @@ async def test_empty_config(hass, hass_client):
|
|||||||
|
|
||||||
async def test_context_filter(hass, hass_client):
|
async def test_context_filter(hass, hass_client):
|
||||||
"""Test we can filter by context."""
|
"""Test we can filter by context."""
|
||||||
await hass.async_add_executor_job(init_recorder_component, hass)
|
await async_init_recorder_component(hass)
|
||||||
assert await async_setup_component(hass, "logbook", {})
|
assert await async_setup_component(hass, "logbook", {})
|
||||||
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
await hass.async_add_executor_job(hass.data[recorder.DATA_INSTANCE].block_till_done)
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components import camera, microsoft_face as mf
|
from homeassistant.components import camera, microsoft_face as mf
|
||||||
from homeassistant.components.microsoft_face import (
|
from homeassistant.components.microsoft_face import (
|
||||||
ATTR_CAMERA_ENTITY,
|
ATTR_CAMERA_ENTITY,
|
||||||
@ -16,9 +18,9 @@ from homeassistant.components.microsoft_face import (
|
|||||||
SERVICE_TRAIN_GROUP,
|
SERVICE_TRAIN_GROUP,
|
||||||
)
|
)
|
||||||
from homeassistant.const import ATTR_NAME
|
from homeassistant.const import ATTR_NAME
|
||||||
from homeassistant.setup import setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
from tests.common import assert_setup_component, get_test_home_assistant, load_fixture
|
from tests.common import assert_setup_component, load_fixture
|
||||||
|
|
||||||
|
|
||||||
def create_group(hass, name):
|
def create_group(hass, name):
|
||||||
@ -27,7 +29,7 @@ def create_group(hass, name):
|
|||||||
This is a legacy helper method. Do not use it for new tests.
|
This is a legacy helper method. Do not use it for new tests.
|
||||||
"""
|
"""
|
||||||
data = {ATTR_NAME: name}
|
data = {ATTR_NAME: name}
|
||||||
hass.services.call(DOMAIN, SERVICE_CREATE_GROUP, data)
|
hass.async_add_job(hass.services.async_call(DOMAIN, SERVICE_CREATE_GROUP, data))
|
||||||
|
|
||||||
|
|
||||||
def delete_group(hass, name):
|
def delete_group(hass, name):
|
||||||
@ -36,7 +38,7 @@ def delete_group(hass, name):
|
|||||||
This is a legacy helper method. Do not use it for new tests.
|
This is a legacy helper method. Do not use it for new tests.
|
||||||
"""
|
"""
|
||||||
data = {ATTR_NAME: name}
|
data = {ATTR_NAME: name}
|
||||||
hass.services.call(DOMAIN, SERVICE_DELETE_GROUP, data)
|
hass.async_add_job(hass.services.async_call(DOMAIN, SERVICE_DELETE_GROUP, data))
|
||||||
|
|
||||||
|
|
||||||
def train_group(hass, group):
|
def train_group(hass, group):
|
||||||
@ -45,7 +47,7 @@ def train_group(hass, group):
|
|||||||
This is a legacy helper method. Do not use it for new tests.
|
This is a legacy helper method. Do not use it for new tests.
|
||||||
"""
|
"""
|
||||||
data = {ATTR_GROUP: group}
|
data = {ATTR_GROUP: group}
|
||||||
hass.services.call(DOMAIN, SERVICE_TRAIN_GROUP, data)
|
hass.async_add_job(hass.services.async_call(DOMAIN, SERVICE_TRAIN_GROUP, data))
|
||||||
|
|
||||||
|
|
||||||
def create_person(hass, group, name):
|
def create_person(hass, group, name):
|
||||||
@ -54,7 +56,7 @@ def create_person(hass, group, name):
|
|||||||
This is a legacy helper method. Do not use it for new tests.
|
This is a legacy helper method. Do not use it for new tests.
|
||||||
"""
|
"""
|
||||||
data = {ATTR_GROUP: group, ATTR_NAME: name}
|
data = {ATTR_GROUP: group, ATTR_NAME: name}
|
||||||
hass.services.call(DOMAIN, SERVICE_CREATE_PERSON, data)
|
hass.async_add_job(hass.services.async_call(DOMAIN, SERVICE_CREATE_PERSON, data))
|
||||||
|
|
||||||
|
|
||||||
def delete_person(hass, group, name):
|
def delete_person(hass, group, name):
|
||||||
@ -63,7 +65,7 @@ def delete_person(hass, group, name):
|
|||||||
This is a legacy helper method. Do not use it for new tests.
|
This is a legacy helper method. Do not use it for new tests.
|
||||||
"""
|
"""
|
||||||
data = {ATTR_GROUP: group, ATTR_NAME: name}
|
data = {ATTR_GROUP: group, ATTR_NAME: name}
|
||||||
hass.services.call(DOMAIN, SERVICE_DELETE_PERSON, data)
|
hass.async_add_job(hass.services.async_call(DOMAIN, SERVICE_DELETE_PERSON, data))
|
||||||
|
|
||||||
|
|
||||||
def face_person(hass, group, person, camera_entity):
|
def face_person(hass, group, person, camera_entity):
|
||||||
@ -72,285 +74,254 @@ def face_person(hass, group, person, camera_entity):
|
|||||||
This is a legacy helper method. Do not use it for new tests.
|
This is a legacy helper method. Do not use it for new tests.
|
||||||
"""
|
"""
|
||||||
data = {ATTR_GROUP: group, ATTR_PERSON: person, ATTR_CAMERA_ENTITY: camera_entity}
|
data = {ATTR_GROUP: group, ATTR_PERSON: person, ATTR_CAMERA_ENTITY: camera_entity}
|
||||||
hass.services.call(DOMAIN, SERVICE_FACE_PERSON, data)
|
hass.async_add_job(hass.services.async_call(DOMAIN, SERVICE_FACE_PERSON, data))
|
||||||
|
|
||||||
|
|
||||||
class TestMicrosoftFaceSetup:
|
CONFIG = {mf.DOMAIN: {"api_key": "12345678abcdef"}}
|
||||||
"""Test the microsoft face component."""
|
ENDPOINT_URL = f"https://westus.{mf.FACE_API_URL}"
|
||||||
|
|
||||||
def setup_method(self):
|
|
||||||
"""Set up things to be run when tests are started."""
|
|
||||||
self.hass = get_test_home_assistant()
|
|
||||||
|
|
||||||
self.config = {mf.DOMAIN: {"api_key": "12345678abcdef"}}
|
@pytest.fixture
|
||||||
|
def mock_update():
|
||||||
self.endpoint_url = f"https://westus.{mf.FACE_API_URL}"
|
"""Mock update store."""
|
||||||
|
with patch(
|
||||||
def teardown_method(self):
|
|
||||||
"""Stop everything that was started."""
|
|
||||||
self.hass.stop()
|
|
||||||
|
|
||||||
@patch(
|
|
||||||
"homeassistant.components.microsoft_face.MicrosoftFace.update_store",
|
"homeassistant.components.microsoft_face.MicrosoftFace.update_store",
|
||||||
return_value=None,
|
return_value=None,
|
||||||
|
) as mock_update_store:
|
||||||
|
yield mock_update_store
|
||||||
|
|
||||||
|
|
||||||
|
async def test_setup_component(hass, mock_update):
|
||||||
|
"""Set up component."""
|
||||||
|
with assert_setup_component(3, mf.DOMAIN):
|
||||||
|
await async_setup_component(hass, mf.DOMAIN, CONFIG)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_setup_component_wrong_api_key(hass, mock_update):
|
||||||
|
"""Set up component without api key."""
|
||||||
|
with assert_setup_component(0, mf.DOMAIN):
|
||||||
|
await async_setup_component(hass, mf.DOMAIN, {mf.DOMAIN: {}})
|
||||||
|
|
||||||
|
|
||||||
|
async def test_setup_component_test_service(hass, mock_update):
|
||||||
|
"""Set up component."""
|
||||||
|
with assert_setup_component(3, mf.DOMAIN):
|
||||||
|
await async_setup_component(hass, mf.DOMAIN, CONFIG)
|
||||||
|
|
||||||
|
assert hass.services.has_service(mf.DOMAIN, "create_group")
|
||||||
|
assert hass.services.has_service(mf.DOMAIN, "delete_group")
|
||||||
|
assert hass.services.has_service(mf.DOMAIN, "train_group")
|
||||||
|
assert hass.services.has_service(mf.DOMAIN, "create_person")
|
||||||
|
assert hass.services.has_service(mf.DOMAIN, "delete_person")
|
||||||
|
assert hass.services.has_service(mf.DOMAIN, "face_person")
|
||||||
|
|
||||||
|
|
||||||
|
async def test_setup_component_test_entities(hass, aioclient_mock):
|
||||||
|
"""Set up component."""
|
||||||
|
aioclient_mock.get(
|
||||||
|
ENDPOINT_URL.format("persongroups"),
|
||||||
|
text=load_fixture("microsoft_face_persongroups.json"),
|
||||||
)
|
)
|
||||||
def test_setup_component(self, mock_update):
|
aioclient_mock.get(
|
||||||
"""Set up component."""
|
ENDPOINT_URL.format("persongroups/test_group1/persons"),
|
||||||
with assert_setup_component(3, mf.DOMAIN):
|
text=load_fixture("microsoft_face_persons.json"),
|
||||||
setup_component(self.hass, mf.DOMAIN, self.config)
|
|
||||||
|
|
||||||
@patch(
|
|
||||||
"homeassistant.components.microsoft_face.MicrosoftFace.update_store",
|
|
||||||
return_value=None,
|
|
||||||
)
|
)
|
||||||
def test_setup_component_wrong_api_key(self, mock_update):
|
aioclient_mock.get(
|
||||||
"""Set up component without api key."""
|
ENDPOINT_URL.format("persongroups/test_group2/persons"),
|
||||||
with assert_setup_component(0, mf.DOMAIN):
|
text=load_fixture("microsoft_face_persons.json"),
|
||||||
setup_component(self.hass, mf.DOMAIN, {mf.DOMAIN: {}})
|
|
||||||
|
|
||||||
@patch(
|
|
||||||
"homeassistant.components.microsoft_face.MicrosoftFace.update_store",
|
|
||||||
return_value=None,
|
|
||||||
)
|
)
|
||||||
def test_setup_component_test_service(self, mock_update):
|
|
||||||
"""Set up component."""
|
|
||||||
with assert_setup_component(3, mf.DOMAIN):
|
|
||||||
setup_component(self.hass, mf.DOMAIN, self.config)
|
|
||||||
|
|
||||||
assert self.hass.services.has_service(mf.DOMAIN, "create_group")
|
with assert_setup_component(3, mf.DOMAIN):
|
||||||
assert self.hass.services.has_service(mf.DOMAIN, "delete_group")
|
await async_setup_component(hass, mf.DOMAIN, CONFIG)
|
||||||
assert self.hass.services.has_service(mf.DOMAIN, "train_group")
|
|
||||||
assert self.hass.services.has_service(mf.DOMAIN, "create_person")
|
|
||||||
assert self.hass.services.has_service(mf.DOMAIN, "delete_person")
|
|
||||||
assert self.hass.services.has_service(mf.DOMAIN, "face_person")
|
|
||||||
|
|
||||||
def test_setup_component_test_entities(self, aioclient_mock):
|
assert len(aioclient_mock.mock_calls) == 3
|
||||||
"""Set up component."""
|
|
||||||
aioclient_mock.get(
|
|
||||||
self.endpoint_url.format("persongroups"),
|
|
||||||
text=load_fixture("microsoft_face_persongroups.json"),
|
|
||||||
)
|
|
||||||
aioclient_mock.get(
|
|
||||||
self.endpoint_url.format("persongroups/test_group1/persons"),
|
|
||||||
text=load_fixture("microsoft_face_persons.json"),
|
|
||||||
)
|
|
||||||
aioclient_mock.get(
|
|
||||||
self.endpoint_url.format("persongroups/test_group2/persons"),
|
|
||||||
text=load_fixture("microsoft_face_persons.json"),
|
|
||||||
)
|
|
||||||
|
|
||||||
with assert_setup_component(3, mf.DOMAIN):
|
entity_group1 = hass.states.get("microsoft_face.test_group1")
|
||||||
setup_component(self.hass, mf.DOMAIN, self.config)
|
entity_group2 = hass.states.get("microsoft_face.test_group2")
|
||||||
|
|
||||||
assert len(aioclient_mock.mock_calls) == 3
|
assert entity_group1 is not None
|
||||||
|
assert entity_group2 is not None
|
||||||
|
|
||||||
entity_group1 = self.hass.states.get("microsoft_face.test_group1")
|
assert entity_group1.attributes["Ryan"] == "25985303-c537-4467-b41d-bdb45cd95ca1"
|
||||||
entity_group2 = self.hass.states.get("microsoft_face.test_group2")
|
assert entity_group1.attributes["David"] == "2ae4935b-9659-44c3-977f-61fac20d0538"
|
||||||
|
|
||||||
assert entity_group1 is not None
|
assert entity_group2.attributes["Ryan"] == "25985303-c537-4467-b41d-bdb45cd95ca1"
|
||||||
assert entity_group2 is not None
|
assert entity_group2.attributes["David"] == "2ae4935b-9659-44c3-977f-61fac20d0538"
|
||||||
|
|
||||||
assert (
|
|
||||||
entity_group1.attributes["Ryan"] == "25985303-c537-4467-b41d-bdb45cd95ca1"
|
|
||||||
)
|
|
||||||
assert (
|
|
||||||
entity_group1.attributes["David"] == "2ae4935b-9659-44c3-977f-61fac20d0538"
|
|
||||||
)
|
|
||||||
|
|
||||||
assert (
|
async def test_service_groups(hass, mock_update, aioclient_mock):
|
||||||
entity_group2.attributes["Ryan"] == "25985303-c537-4467-b41d-bdb45cd95ca1"
|
"""Set up component, test groups services."""
|
||||||
)
|
aioclient_mock.put(
|
||||||
assert (
|
ENDPOINT_URL.format("persongroups/service_group"),
|
||||||
entity_group2.attributes["David"] == "2ae4935b-9659-44c3-977f-61fac20d0538"
|
status=200,
|
||||||
)
|
text="{}",
|
||||||
|
|
||||||
@patch(
|
|
||||||
"homeassistant.components.microsoft_face.MicrosoftFace.update_store",
|
|
||||||
return_value=None,
|
|
||||||
)
|
)
|
||||||
def test_service_groups(self, mock_update, aioclient_mock):
|
aioclient_mock.delete(
|
||||||
"""Set up component, test groups services."""
|
ENDPOINT_URL.format("persongroups/service_group"),
|
||||||
aioclient_mock.put(
|
status=200,
|
||||||
self.endpoint_url.format("persongroups/service_group"),
|
text="{}",
|
||||||
status=200,
|
|
||||||
text="{}",
|
|
||||||
)
|
|
||||||
aioclient_mock.delete(
|
|
||||||
self.endpoint_url.format("persongroups/service_group"),
|
|
||||||
status=200,
|
|
||||||
text="{}",
|
|
||||||
)
|
|
||||||
|
|
||||||
with assert_setup_component(3, mf.DOMAIN):
|
|
||||||
setup_component(self.hass, mf.DOMAIN, self.config)
|
|
||||||
|
|
||||||
create_group(self.hass, "Service Group")
|
|
||||||
self.hass.block_till_done()
|
|
||||||
|
|
||||||
entity = self.hass.states.get("microsoft_face.service_group")
|
|
||||||
assert entity is not None
|
|
||||||
assert len(aioclient_mock.mock_calls) == 1
|
|
||||||
|
|
||||||
delete_group(self.hass, "Service Group")
|
|
||||||
self.hass.block_till_done()
|
|
||||||
|
|
||||||
entity = self.hass.states.get("microsoft_face.service_group")
|
|
||||||
assert entity is None
|
|
||||||
assert len(aioclient_mock.mock_calls) == 2
|
|
||||||
|
|
||||||
def test_service_person(self, aioclient_mock):
|
|
||||||
"""Set up component, test person services."""
|
|
||||||
aioclient_mock.get(
|
|
||||||
self.endpoint_url.format("persongroups"),
|
|
||||||
text=load_fixture("microsoft_face_persongroups.json"),
|
|
||||||
)
|
|
||||||
aioclient_mock.get(
|
|
||||||
self.endpoint_url.format("persongroups/test_group1/persons"),
|
|
||||||
text=load_fixture("microsoft_face_persons.json"),
|
|
||||||
)
|
|
||||||
aioclient_mock.get(
|
|
||||||
self.endpoint_url.format("persongroups/test_group2/persons"),
|
|
||||||
text=load_fixture("microsoft_face_persons.json"),
|
|
||||||
)
|
|
||||||
|
|
||||||
with assert_setup_component(3, mf.DOMAIN):
|
|
||||||
setup_component(self.hass, mf.DOMAIN, self.config)
|
|
||||||
|
|
||||||
assert len(aioclient_mock.mock_calls) == 3
|
|
||||||
|
|
||||||
aioclient_mock.post(
|
|
||||||
self.endpoint_url.format("persongroups/test_group1/persons"),
|
|
||||||
text=load_fixture("microsoft_face_create_person.json"),
|
|
||||||
)
|
|
||||||
aioclient_mock.delete(
|
|
||||||
self.endpoint_url.format(
|
|
||||||
"persongroups/test_group1/persons/"
|
|
||||||
"25985303-c537-4467-b41d-bdb45cd95ca1"
|
|
||||||
),
|
|
||||||
status=200,
|
|
||||||
text="{}",
|
|
||||||
)
|
|
||||||
|
|
||||||
create_person(self.hass, "test group1", "Hans")
|
|
||||||
self.hass.block_till_done()
|
|
||||||
|
|
||||||
entity_group1 = self.hass.states.get("microsoft_face.test_group1")
|
|
||||||
|
|
||||||
assert len(aioclient_mock.mock_calls) == 4
|
|
||||||
assert entity_group1 is not None
|
|
||||||
assert (
|
|
||||||
entity_group1.attributes["Hans"] == "25985303-c537-4467-b41d-bdb45cd95ca1"
|
|
||||||
)
|
|
||||||
|
|
||||||
delete_person(self.hass, "test group1", "Hans")
|
|
||||||
self.hass.block_till_done()
|
|
||||||
|
|
||||||
entity_group1 = self.hass.states.get("microsoft_face.test_group1")
|
|
||||||
|
|
||||||
assert len(aioclient_mock.mock_calls) == 5
|
|
||||||
assert entity_group1 is not None
|
|
||||||
assert "Hans" not in entity_group1.attributes
|
|
||||||
|
|
||||||
@patch(
|
|
||||||
"homeassistant.components.microsoft_face.MicrosoftFace.update_store",
|
|
||||||
return_value=None,
|
|
||||||
)
|
)
|
||||||
def test_service_train(self, mock_update, aioclient_mock):
|
|
||||||
"""Set up component, test train groups services."""
|
|
||||||
with assert_setup_component(3, mf.DOMAIN):
|
|
||||||
setup_component(self.hass, mf.DOMAIN, self.config)
|
|
||||||
|
|
||||||
aioclient_mock.post(
|
with assert_setup_component(3, mf.DOMAIN):
|
||||||
self.endpoint_url.format("persongroups/service_group/train"),
|
await async_setup_component(hass, mf.DOMAIN, CONFIG)
|
||||||
status=200,
|
|
||||||
text="{}",
|
|
||||||
)
|
|
||||||
|
|
||||||
train_group(self.hass, "Service Group")
|
create_group(hass, "Service Group")
|
||||||
self.hass.block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
assert len(aioclient_mock.mock_calls) == 1
|
entity = hass.states.get("microsoft_face.service_group")
|
||||||
|
assert entity is not None
|
||||||
|
assert len(aioclient_mock.mock_calls) == 1
|
||||||
|
|
||||||
@patch(
|
delete_group(hass, "Service Group")
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
entity = hass.states.get("microsoft_face.service_group")
|
||||||
|
assert entity is None
|
||||||
|
assert len(aioclient_mock.mock_calls) == 2
|
||||||
|
|
||||||
|
|
||||||
|
async def test_service_person(hass, aioclient_mock):
|
||||||
|
"""Set up component, test person services."""
|
||||||
|
aioclient_mock.get(
|
||||||
|
ENDPOINT_URL.format("persongroups"),
|
||||||
|
text=load_fixture("microsoft_face_persongroups.json"),
|
||||||
|
)
|
||||||
|
aioclient_mock.get(
|
||||||
|
ENDPOINT_URL.format("persongroups/test_group1/persons"),
|
||||||
|
text=load_fixture("microsoft_face_persons.json"),
|
||||||
|
)
|
||||||
|
aioclient_mock.get(
|
||||||
|
ENDPOINT_URL.format("persongroups/test_group2/persons"),
|
||||||
|
text=load_fixture("microsoft_face_persons.json"),
|
||||||
|
)
|
||||||
|
|
||||||
|
with assert_setup_component(3, mf.DOMAIN):
|
||||||
|
await async_setup_component(hass, mf.DOMAIN, CONFIG)
|
||||||
|
|
||||||
|
assert len(aioclient_mock.mock_calls) == 3
|
||||||
|
|
||||||
|
aioclient_mock.post(
|
||||||
|
ENDPOINT_URL.format("persongroups/test_group1/persons"),
|
||||||
|
text=load_fixture("microsoft_face_create_person.json"),
|
||||||
|
)
|
||||||
|
aioclient_mock.delete(
|
||||||
|
ENDPOINT_URL.format(
|
||||||
|
"persongroups/test_group1/persons/" "25985303-c537-4467-b41d-bdb45cd95ca1"
|
||||||
|
),
|
||||||
|
status=200,
|
||||||
|
text="{}",
|
||||||
|
)
|
||||||
|
|
||||||
|
create_person(hass, "test group1", "Hans")
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
entity_group1 = hass.states.get("microsoft_face.test_group1")
|
||||||
|
|
||||||
|
assert len(aioclient_mock.mock_calls) == 4
|
||||||
|
assert entity_group1 is not None
|
||||||
|
assert entity_group1.attributes["Hans"] == "25985303-c537-4467-b41d-bdb45cd95ca1"
|
||||||
|
|
||||||
|
delete_person(hass, "test group1", "Hans")
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
entity_group1 = hass.states.get("microsoft_face.test_group1")
|
||||||
|
|
||||||
|
assert len(aioclient_mock.mock_calls) == 5
|
||||||
|
assert entity_group1 is not None
|
||||||
|
assert "Hans" not in entity_group1.attributes
|
||||||
|
|
||||||
|
|
||||||
|
async def test_service_train(hass, mock_update, aioclient_mock):
|
||||||
|
"""Set up component, test train groups services."""
|
||||||
|
with assert_setup_component(3, mf.DOMAIN):
|
||||||
|
await async_setup_component(hass, mf.DOMAIN, CONFIG)
|
||||||
|
|
||||||
|
aioclient_mock.post(
|
||||||
|
ENDPOINT_URL.format("persongroups/service_group/train"),
|
||||||
|
status=200,
|
||||||
|
text="{}",
|
||||||
|
)
|
||||||
|
|
||||||
|
train_group(hass, "Service Group")
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert len(aioclient_mock.mock_calls) == 1
|
||||||
|
|
||||||
|
|
||||||
|
async def test_service_face(hass, aioclient_mock):
|
||||||
|
"""Set up component, test person face services."""
|
||||||
|
aioclient_mock.get(
|
||||||
|
ENDPOINT_URL.format("persongroups"),
|
||||||
|
text=load_fixture("microsoft_face_persongroups.json"),
|
||||||
|
)
|
||||||
|
aioclient_mock.get(
|
||||||
|
ENDPOINT_URL.format("persongroups/test_group1/persons"),
|
||||||
|
text=load_fixture("microsoft_face_persons.json"),
|
||||||
|
)
|
||||||
|
aioclient_mock.get(
|
||||||
|
ENDPOINT_URL.format("persongroups/test_group2/persons"),
|
||||||
|
text=load_fixture("microsoft_face_persons.json"),
|
||||||
|
)
|
||||||
|
|
||||||
|
CONFIG["camera"] = {"platform": "demo"}
|
||||||
|
with assert_setup_component(3, mf.DOMAIN):
|
||||||
|
await async_setup_component(hass, mf.DOMAIN, CONFIG)
|
||||||
|
|
||||||
|
assert len(aioclient_mock.mock_calls) == 3
|
||||||
|
|
||||||
|
aioclient_mock.post(
|
||||||
|
ENDPOINT_URL.format(
|
||||||
|
"persongroups/test_group2/persons/"
|
||||||
|
"2ae4935b-9659-44c3-977f-61fac20d0538/persistedFaces"
|
||||||
|
),
|
||||||
|
status=200,
|
||||||
|
text="{}",
|
||||||
|
)
|
||||||
|
|
||||||
|
with patch(
|
||||||
"homeassistant.components.camera.async_get_image",
|
"homeassistant.components.camera.async_get_image",
|
||||||
return_value=camera.Image("image/jpeg", b"Test"),
|
return_value=camera.Image("image/jpeg", b"Test"),
|
||||||
|
):
|
||||||
|
face_person(hass, "test_group2", "David", "camera.demo_camera")
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert len(aioclient_mock.mock_calls) == 4
|
||||||
|
assert aioclient_mock.mock_calls[3][2] == b"Test"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_service_status_400(hass, mock_update, aioclient_mock):
|
||||||
|
"""Set up component, test groups services with error."""
|
||||||
|
aioclient_mock.put(
|
||||||
|
ENDPOINT_URL.format("persongroups/service_group"),
|
||||||
|
status=400,
|
||||||
|
text="{'error': {'message': 'Error'}}",
|
||||||
)
|
)
|
||||||
def test_service_face(self, camera_mock, aioclient_mock):
|
|
||||||
"""Set up component, test person face services."""
|
|
||||||
aioclient_mock.get(
|
|
||||||
self.endpoint_url.format("persongroups"),
|
|
||||||
text=load_fixture("microsoft_face_persongroups.json"),
|
|
||||||
)
|
|
||||||
aioclient_mock.get(
|
|
||||||
self.endpoint_url.format("persongroups/test_group1/persons"),
|
|
||||||
text=load_fixture("microsoft_face_persons.json"),
|
|
||||||
)
|
|
||||||
aioclient_mock.get(
|
|
||||||
self.endpoint_url.format("persongroups/test_group2/persons"),
|
|
||||||
text=load_fixture("microsoft_face_persons.json"),
|
|
||||||
)
|
|
||||||
|
|
||||||
self.config["camera"] = {"platform": "demo"}
|
with assert_setup_component(3, mf.DOMAIN):
|
||||||
with assert_setup_component(3, mf.DOMAIN):
|
await async_setup_component(hass, mf.DOMAIN, CONFIG)
|
||||||
setup_component(self.hass, mf.DOMAIN, self.config)
|
|
||||||
|
|
||||||
assert len(aioclient_mock.mock_calls) == 3
|
create_group(hass, "Service Group")
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
aioclient_mock.post(
|
entity = hass.states.get("microsoft_face.service_group")
|
||||||
self.endpoint_url.format(
|
assert entity is None
|
||||||
"persongroups/test_group2/persons/"
|
assert len(aioclient_mock.mock_calls) == 1
|
||||||
"2ae4935b-9659-44c3-977f-61fac20d0538/persistedFaces"
|
|
||||||
),
|
|
||||||
status=200,
|
|
||||||
text="{}",
|
|
||||||
)
|
|
||||||
|
|
||||||
face_person(self.hass, "test_group2", "David", "camera.demo_camera")
|
|
||||||
self.hass.block_till_done()
|
|
||||||
|
|
||||||
assert len(aioclient_mock.mock_calls) == 4
|
async def test_service_status_timeout(hass, mock_update, aioclient_mock):
|
||||||
assert aioclient_mock.mock_calls[3][2] == b"Test"
|
"""Set up component, test groups services with timeout."""
|
||||||
|
aioclient_mock.put(
|
||||||
@patch(
|
ENDPOINT_URL.format("persongroups/service_group"),
|
||||||
"homeassistant.components.microsoft_face.MicrosoftFace.update_store",
|
status=400,
|
||||||
return_value=None,
|
exc=asyncio.TimeoutError(),
|
||||||
)
|
)
|
||||||
def test_service_status_400(self, mock_update, aioclient_mock):
|
|
||||||
"""Set up component, test groups services with error."""
|
|
||||||
aioclient_mock.put(
|
|
||||||
self.endpoint_url.format("persongroups/service_group"),
|
|
||||||
status=400,
|
|
||||||
text="{'error': {'message': 'Error'}}",
|
|
||||||
)
|
|
||||||
|
|
||||||
with assert_setup_component(3, mf.DOMAIN):
|
with assert_setup_component(3, mf.DOMAIN):
|
||||||
setup_component(self.hass, mf.DOMAIN, self.config)
|
await async_setup_component(hass, mf.DOMAIN, CONFIG)
|
||||||
|
|
||||||
create_group(self.hass, "Service Group")
|
create_group(hass, "Service Group")
|
||||||
self.hass.block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
entity = self.hass.states.get("microsoft_face.service_group")
|
entity = hass.states.get("microsoft_face.service_group")
|
||||||
assert entity is None
|
assert entity is None
|
||||||
assert len(aioclient_mock.mock_calls) == 1
|
assert len(aioclient_mock.mock_calls) == 1
|
||||||
|
|
||||||
@patch(
|
|
||||||
"homeassistant.components.microsoft_face.MicrosoftFace.update_store",
|
|
||||||
return_value=None,
|
|
||||||
)
|
|
||||||
def test_service_status_timeout(self, mock_update, aioclient_mock):
|
|
||||||
"""Set up component, test groups services with timeout."""
|
|
||||||
aioclient_mock.put(
|
|
||||||
self.endpoint_url.format("persongroups/service_group"),
|
|
||||||
status=400,
|
|
||||||
exc=asyncio.TimeoutError(),
|
|
||||||
)
|
|
||||||
|
|
||||||
with assert_setup_component(3, mf.DOMAIN):
|
|
||||||
setup_component(self.hass, mf.DOMAIN, self.config)
|
|
||||||
|
|
||||||
create_group(self.hass, "Service Group")
|
|
||||||
self.hass.block_till_done()
|
|
||||||
|
|
||||||
entity = self.hass.states.get("microsoft_face.service_group")
|
|
||||||
assert entity is None
|
|
||||||
assert len(aioclient_mock.mock_calls) == 1
|
|
||||||
|
@ -1,171 +1,155 @@
|
|||||||
"""The tests for the microsoft face detect platform."""
|
"""The tests for the microsoft face detect platform."""
|
||||||
from unittest.mock import PropertyMock, patch
|
from unittest.mock import PropertyMock, patch
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
import homeassistant.components.image_processing as ip
|
import homeassistant.components.image_processing as ip
|
||||||
import homeassistant.components.microsoft_face as mf
|
import homeassistant.components.microsoft_face as mf
|
||||||
from homeassistant.const import ATTR_ENTITY_PICTURE
|
from homeassistant.const import ATTR_ENTITY_PICTURE
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.setup import setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
from tests.common import (
|
from tests.common import assert_setup_component, load_fixture
|
||||||
assert_setup_component,
|
|
||||||
get_test_home_assistant,
|
|
||||||
load_fixture,
|
|
||||||
mock_coro,
|
|
||||||
)
|
|
||||||
from tests.components.image_processing import common
|
from tests.components.image_processing import common
|
||||||
|
|
||||||
|
CONFIG = {
|
||||||
|
ip.DOMAIN: {
|
||||||
|
"platform": "microsoft_face_detect",
|
||||||
|
"source": {"entity_id": "camera.demo_camera", "name": "test local"},
|
||||||
|
"attributes": ["age", "gender"],
|
||||||
|
},
|
||||||
|
"camera": {"platform": "demo"},
|
||||||
|
mf.DOMAIN: {"api_key": "12345678abcdef6"},
|
||||||
|
}
|
||||||
|
|
||||||
class TestMicrosoftFaceDetectSetup:
|
ENDPOINT_URL = f"https://westus.{mf.FACE_API_URL}"
|
||||||
"""Test class for image processing."""
|
|
||||||
|
|
||||||
def setup_method(self):
|
|
||||||
"""Set up things to be run when tests are started."""
|
|
||||||
self.hass = get_test_home_assistant()
|
|
||||||
|
|
||||||
def teardown_method(self):
|
@pytest.fixture
|
||||||
"""Stop everything that was started."""
|
def store_mock():
|
||||||
self.hass.stop()
|
"""Mock update store."""
|
||||||
|
with patch(
|
||||||
@patch(
|
|
||||||
"homeassistant.components.microsoft_face.MicrosoftFace.update_store",
|
"homeassistant.components.microsoft_face.MicrosoftFace.update_store",
|
||||||
return_value=mock_coro(),
|
return_value=None,
|
||||||
)
|
) as mock_update_store:
|
||||||
def test_setup_platform(self, store_mock):
|
yield mock_update_store
|
||||||
"""Set up platform with one entity."""
|
|
||||||
config = {
|
|
||||||
ip.DOMAIN: {
|
|
||||||
"platform": "microsoft_face_detect",
|
|
||||||
"source": {"entity_id": "camera.demo_camera"},
|
|
||||||
"attributes": ["age", "gender"],
|
|
||||||
},
|
|
||||||
"camera": {"platform": "demo"},
|
|
||||||
mf.DOMAIN: {"api_key": "12345678abcdef6"},
|
|
||||||
}
|
|
||||||
|
|
||||||
with assert_setup_component(1, ip.DOMAIN):
|
|
||||||
setup_component(self.hass, ip.DOMAIN, config)
|
|
||||||
self.hass.block_till_done()
|
|
||||||
|
|
||||||
assert self.hass.states.get("image_processing.microsoftface_demo_camera")
|
|
||||||
|
|
||||||
@patch(
|
|
||||||
"homeassistant.components.microsoft_face.MicrosoftFace.update_store",
|
|
||||||
return_value=mock_coro(),
|
|
||||||
)
|
|
||||||
def test_setup_platform_name(self, store_mock):
|
|
||||||
"""Set up platform with one entity and set name."""
|
|
||||||
config = {
|
|
||||||
ip.DOMAIN: {
|
|
||||||
"platform": "microsoft_face_detect",
|
|
||||||
"source": {"entity_id": "camera.demo_camera", "name": "test local"},
|
|
||||||
},
|
|
||||||
"camera": {"platform": "demo"},
|
|
||||||
mf.DOMAIN: {"api_key": "12345678abcdef6"},
|
|
||||||
}
|
|
||||||
|
|
||||||
with assert_setup_component(1, ip.DOMAIN):
|
|
||||||
setup_component(self.hass, ip.DOMAIN, config)
|
|
||||||
self.hass.block_till_done()
|
|
||||||
|
|
||||||
assert self.hass.states.get("image_processing.test_local")
|
|
||||||
|
|
||||||
|
|
||||||
class TestMicrosoftFaceDetect:
|
@pytest.fixture
|
||||||
"""Test class for image processing."""
|
def poll_mock():
|
||||||
|
"""Disable polling."""
|
||||||
def setup_method(self):
|
with patch(
|
||||||
"""Set up things to be run when tests are started."""
|
|
||||||
self.hass = get_test_home_assistant()
|
|
||||||
|
|
||||||
self.config = {
|
|
||||||
ip.DOMAIN: {
|
|
||||||
"platform": "microsoft_face_detect",
|
|
||||||
"source": {"entity_id": "camera.demo_camera", "name": "test local"},
|
|
||||||
"attributes": ["age", "gender"],
|
|
||||||
},
|
|
||||||
"camera": {"platform": "demo"},
|
|
||||||
mf.DOMAIN: {"api_key": "12345678abcdef6"},
|
|
||||||
}
|
|
||||||
|
|
||||||
self.endpoint_url = f"https://westus.{mf.FACE_API_URL}"
|
|
||||||
|
|
||||||
def teardown_method(self):
|
|
||||||
"""Stop everything that was started."""
|
|
||||||
self.hass.stop()
|
|
||||||
|
|
||||||
@patch(
|
|
||||||
"homeassistant.components.microsoft_face_detect.image_processing."
|
"homeassistant.components.microsoft_face_detect.image_processing."
|
||||||
"MicrosoftFaceDetectEntity.should_poll",
|
"MicrosoftFaceDetectEntity.should_poll",
|
||||||
new_callable=PropertyMock(return_value=False),
|
new_callable=PropertyMock(return_value=False),
|
||||||
|
):
|
||||||
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
async def test_setup_platform(hass, store_mock):
|
||||||
|
"""Set up platform with one entity."""
|
||||||
|
config = {
|
||||||
|
ip.DOMAIN: {
|
||||||
|
"platform": "microsoft_face_detect",
|
||||||
|
"source": {"entity_id": "camera.demo_camera"},
|
||||||
|
"attributes": ["age", "gender"],
|
||||||
|
},
|
||||||
|
"camera": {"platform": "demo"},
|
||||||
|
mf.DOMAIN: {"api_key": "12345678abcdef6"},
|
||||||
|
}
|
||||||
|
|
||||||
|
with assert_setup_component(1, ip.DOMAIN):
|
||||||
|
await async_setup_component(hass, ip.DOMAIN, config)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert hass.states.get("image_processing.microsoftface_demo_camera")
|
||||||
|
|
||||||
|
|
||||||
|
async def test_setup_platform_name(hass, store_mock):
|
||||||
|
"""Set up platform with one entity and set name."""
|
||||||
|
config = {
|
||||||
|
ip.DOMAIN: {
|
||||||
|
"platform": "microsoft_face_detect",
|
||||||
|
"source": {"entity_id": "camera.demo_camera", "name": "test local"},
|
||||||
|
},
|
||||||
|
"camera": {"platform": "demo"},
|
||||||
|
mf.DOMAIN: {"api_key": "12345678abcdef6"},
|
||||||
|
}
|
||||||
|
|
||||||
|
with assert_setup_component(1, ip.DOMAIN):
|
||||||
|
await async_setup_component(hass, ip.DOMAIN, config)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert hass.states.get("image_processing.test_local")
|
||||||
|
|
||||||
|
|
||||||
|
async def test_ms_detect_process_image(hass, poll_mock, aioclient_mock):
|
||||||
|
"""Set up and scan a picture and test plates from event."""
|
||||||
|
aioclient_mock.get(
|
||||||
|
ENDPOINT_URL.format("persongroups"),
|
||||||
|
text=load_fixture("microsoft_face_persongroups.json"),
|
||||||
|
)
|
||||||
|
aioclient_mock.get(
|
||||||
|
ENDPOINT_URL.format("persongroups/test_group1/persons"),
|
||||||
|
text=load_fixture("microsoft_face_persons.json"),
|
||||||
|
)
|
||||||
|
aioclient_mock.get(
|
||||||
|
ENDPOINT_URL.format("persongroups/test_group2/persons"),
|
||||||
|
text=load_fixture("microsoft_face_persons.json"),
|
||||||
)
|
)
|
||||||
def test_ms_detect_process_image(self, poll_mock, aioclient_mock):
|
|
||||||
"""Set up and scan a picture and test plates from event."""
|
|
||||||
aioclient_mock.get(
|
|
||||||
self.endpoint_url.format("persongroups"),
|
|
||||||
text=load_fixture("microsoft_face_persongroups.json"),
|
|
||||||
)
|
|
||||||
aioclient_mock.get(
|
|
||||||
self.endpoint_url.format("persongroups/test_group1/persons"),
|
|
||||||
text=load_fixture("microsoft_face_persons.json"),
|
|
||||||
)
|
|
||||||
aioclient_mock.get(
|
|
||||||
self.endpoint_url.format("persongroups/test_group2/persons"),
|
|
||||||
text=load_fixture("microsoft_face_persons.json"),
|
|
||||||
)
|
|
||||||
|
|
||||||
setup_component(self.hass, ip.DOMAIN, self.config)
|
await async_setup_component(hass, ip.DOMAIN, CONFIG)
|
||||||
self.hass.block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
state = self.hass.states.get("camera.demo_camera")
|
state = hass.states.get("camera.demo_camera")
|
||||||
url = f"{self.hass.config.internal_url}{state.attributes.get(ATTR_ENTITY_PICTURE)}"
|
url = f"{hass.config.internal_url}{state.attributes.get(ATTR_ENTITY_PICTURE)}"
|
||||||
|
|
||||||
face_events = []
|
face_events = []
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def mock_face_event(event):
|
def mock_face_event(event):
|
||||||
"""Mock event."""
|
"""Mock event."""
|
||||||
face_events.append(event)
|
face_events.append(event)
|
||||||
|
|
||||||
self.hass.bus.listen("image_processing.detect_face", mock_face_event)
|
hass.bus.async_listen("image_processing.detect_face", mock_face_event)
|
||||||
|
|
||||||
aioclient_mock.get(url, content=b"image")
|
aioclient_mock.get(url, content=b"image")
|
||||||
|
|
||||||
aioclient_mock.post(
|
aioclient_mock.post(
|
||||||
self.endpoint_url.format("detect"),
|
ENDPOINT_URL.format("detect"),
|
||||||
text=load_fixture("microsoft_face_detect.json"),
|
text=load_fixture("microsoft_face_detect.json"),
|
||||||
params={"returnFaceAttributes": "age,gender"},
|
params={"returnFaceAttributes": "age,gender"},
|
||||||
)
|
)
|
||||||
|
|
||||||
common.scan(self.hass, entity_id="image_processing.test_local")
|
common.async_scan(hass, entity_id="image_processing.test_local")
|
||||||
self.hass.block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
state = self.hass.states.get("image_processing.test_local")
|
state = hass.states.get("image_processing.test_local")
|
||||||
|
|
||||||
assert len(face_events) == 1
|
assert len(face_events) == 1
|
||||||
assert state.attributes.get("total_faces") == 1
|
assert state.attributes.get("total_faces") == 1
|
||||||
assert state.state == "1"
|
assert state.state == "1"
|
||||||
|
|
||||||
assert face_events[0].data["age"] == 71.0
|
assert face_events[0].data["age"] == 71.0
|
||||||
assert face_events[0].data["gender"] == "male"
|
assert face_events[0].data["gender"] == "male"
|
||||||
assert face_events[0].data["entity_id"] == "image_processing.test_local"
|
assert face_events[0].data["entity_id"] == "image_processing.test_local"
|
||||||
|
|
||||||
# Test that later, if a request is made that results in no face
|
# Test that later, if a request is made that results in no face
|
||||||
# being detected, that this is reflected in the state object
|
# being detected, that this is reflected in the state object
|
||||||
aioclient_mock.clear_requests()
|
aioclient_mock.clear_requests()
|
||||||
aioclient_mock.post(
|
aioclient_mock.post(
|
||||||
self.endpoint_url.format("detect"),
|
ENDPOINT_URL.format("detect"),
|
||||||
text="[]",
|
text="[]",
|
||||||
params={"returnFaceAttributes": "age,gender"},
|
params={"returnFaceAttributes": "age,gender"},
|
||||||
)
|
)
|
||||||
|
|
||||||
common.scan(self.hass, entity_id="image_processing.test_local")
|
common.async_scan(hass, entity_id="image_processing.test_local")
|
||||||
self.hass.block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
state = self.hass.states.get("image_processing.test_local")
|
state = hass.states.get("image_processing.test_local")
|
||||||
|
|
||||||
# No more face events were fired
|
# No more face events were fired
|
||||||
assert len(face_events) == 1
|
assert len(face_events) == 1
|
||||||
# Total faces and actual qualified number of faces reset to zero
|
# Total faces and actual qualified number of faces reset to zero
|
||||||
assert state.attributes.get("total_faces") == 0
|
assert state.attributes.get("total_faces") == 0
|
||||||
assert state.state == "0"
|
assert state.state == "0"
|
||||||
|
@ -1,171 +1,156 @@
|
|||||||
"""The tests for the microsoft face identify platform."""
|
"""The tests for the microsoft face identify platform."""
|
||||||
from unittest.mock import PropertyMock, patch
|
from unittest.mock import PropertyMock, patch
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
import homeassistant.components.image_processing as ip
|
import homeassistant.components.image_processing as ip
|
||||||
import homeassistant.components.microsoft_face as mf
|
import homeassistant.components.microsoft_face as mf
|
||||||
from homeassistant.const import ATTR_ENTITY_PICTURE, STATE_UNKNOWN
|
from homeassistant.const import ATTR_ENTITY_PICTURE, STATE_UNKNOWN
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import callback
|
||||||
from homeassistant.setup import setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
from tests.common import (
|
from tests.common import assert_setup_component, load_fixture
|
||||||
assert_setup_component,
|
|
||||||
get_test_home_assistant,
|
|
||||||
load_fixture,
|
|
||||||
mock_coro,
|
|
||||||
)
|
|
||||||
from tests.components.image_processing import common
|
from tests.components.image_processing import common
|
||||||
|
|
||||||
|
|
||||||
class TestMicrosoftFaceIdentifySetup:
|
@pytest.fixture
|
||||||
"""Test class for image processing."""
|
def store_mock():
|
||||||
|
"""Mock update store."""
|
||||||
def setup_method(self):
|
with patch(
|
||||||
"""Set up things to be run when tests are started."""
|
|
||||||
self.hass = get_test_home_assistant()
|
|
||||||
|
|
||||||
def teardown_method(self):
|
|
||||||
"""Stop everything that was started."""
|
|
||||||
self.hass.stop()
|
|
||||||
|
|
||||||
@patch(
|
|
||||||
"homeassistant.components.microsoft_face.MicrosoftFace.update_store",
|
"homeassistant.components.microsoft_face.MicrosoftFace.update_store",
|
||||||
return_value=mock_coro(),
|
return_value=None,
|
||||||
)
|
) as mock_update_store:
|
||||||
def test_setup_platform(self, store_mock):
|
yield mock_update_store
|
||||||
"""Set up platform with one entity."""
|
|
||||||
config = {
|
|
||||||
ip.DOMAIN: {
|
|
||||||
"platform": "microsoft_face_identify",
|
|
||||||
"source": {"entity_id": "camera.demo_camera"},
|
|
||||||
"group": "Test Group1",
|
|
||||||
},
|
|
||||||
"camera": {"platform": "demo"},
|
|
||||||
mf.DOMAIN: {"api_key": "12345678abcdef6"},
|
|
||||||
}
|
|
||||||
|
|
||||||
with assert_setup_component(1, ip.DOMAIN):
|
|
||||||
setup_component(self.hass, ip.DOMAIN, config)
|
|
||||||
self.hass.block_till_done()
|
|
||||||
|
|
||||||
assert self.hass.states.get("image_processing.microsoftface_demo_camera")
|
|
||||||
|
|
||||||
@patch(
|
|
||||||
"homeassistant.components.microsoft_face.MicrosoftFace.update_store",
|
|
||||||
return_value=mock_coro(),
|
|
||||||
)
|
|
||||||
def test_setup_platform_name(self, store_mock):
|
|
||||||
"""Set up platform with one entity and set name."""
|
|
||||||
config = {
|
|
||||||
ip.DOMAIN: {
|
|
||||||
"platform": "microsoft_face_identify",
|
|
||||||
"source": {"entity_id": "camera.demo_camera", "name": "test local"},
|
|
||||||
"group": "Test Group1",
|
|
||||||
},
|
|
||||||
"camera": {"platform": "demo"},
|
|
||||||
mf.DOMAIN: {"api_key": "12345678abcdef6"},
|
|
||||||
}
|
|
||||||
|
|
||||||
with assert_setup_component(1, ip.DOMAIN):
|
|
||||||
setup_component(self.hass, ip.DOMAIN, config)
|
|
||||||
self.hass.block_till_done()
|
|
||||||
|
|
||||||
assert self.hass.states.get("image_processing.test_local")
|
|
||||||
|
|
||||||
|
|
||||||
class TestMicrosoftFaceIdentify:
|
@pytest.fixture
|
||||||
"""Test class for image processing."""
|
def poll_mock():
|
||||||
|
"""Disable polling."""
|
||||||
def setup_method(self):
|
with patch(
|
||||||
"""Set up things to be run when tests are started."""
|
|
||||||
self.hass = get_test_home_assistant()
|
|
||||||
|
|
||||||
self.config = {
|
|
||||||
ip.DOMAIN: {
|
|
||||||
"platform": "microsoft_face_identify",
|
|
||||||
"source": {"entity_id": "camera.demo_camera", "name": "test local"},
|
|
||||||
"group": "Test Group1",
|
|
||||||
},
|
|
||||||
"camera": {"platform": "demo"},
|
|
||||||
mf.DOMAIN: {"api_key": "12345678abcdef6"},
|
|
||||||
}
|
|
||||||
|
|
||||||
self.endpoint_url = f"https://westus.{mf.FACE_API_URL}"
|
|
||||||
|
|
||||||
def teardown_method(self):
|
|
||||||
"""Stop everything that was started."""
|
|
||||||
self.hass.stop()
|
|
||||||
|
|
||||||
@patch(
|
|
||||||
"homeassistant.components.microsoft_face_identify.image_processing."
|
"homeassistant.components.microsoft_face_identify.image_processing."
|
||||||
"MicrosoftFaceIdentifyEntity.should_poll",
|
"MicrosoftFaceIdentifyEntity.should_poll",
|
||||||
new_callable=PropertyMock(return_value=False),
|
new_callable=PropertyMock(return_value=False),
|
||||||
|
):
|
||||||
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
CONFIG = {
|
||||||
|
ip.DOMAIN: {
|
||||||
|
"platform": "microsoft_face_identify",
|
||||||
|
"source": {"entity_id": "camera.demo_camera", "name": "test local"},
|
||||||
|
"group": "Test Group1",
|
||||||
|
},
|
||||||
|
"camera": {"platform": "demo"},
|
||||||
|
mf.DOMAIN: {"api_key": "12345678abcdef6"},
|
||||||
|
}
|
||||||
|
|
||||||
|
ENDPOINT_URL = f"https://westus.{mf.FACE_API_URL}"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_setup_platform(hass, store_mock):
|
||||||
|
"""Set up platform with one entity."""
|
||||||
|
config = {
|
||||||
|
ip.DOMAIN: {
|
||||||
|
"platform": "microsoft_face_identify",
|
||||||
|
"source": {"entity_id": "camera.demo_camera"},
|
||||||
|
"group": "Test Group1",
|
||||||
|
},
|
||||||
|
"camera": {"platform": "demo"},
|
||||||
|
mf.DOMAIN: {"api_key": "12345678abcdef6"},
|
||||||
|
}
|
||||||
|
|
||||||
|
with assert_setup_component(1, ip.DOMAIN):
|
||||||
|
await async_setup_component(hass, ip.DOMAIN, config)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert hass.states.get("image_processing.microsoftface_demo_camera")
|
||||||
|
|
||||||
|
|
||||||
|
async def test_setup_platform_name(hass, store_mock):
|
||||||
|
"""Set up platform with one entity and set name."""
|
||||||
|
config = {
|
||||||
|
ip.DOMAIN: {
|
||||||
|
"platform": "microsoft_face_identify",
|
||||||
|
"source": {"entity_id": "camera.demo_camera", "name": "test local"},
|
||||||
|
"group": "Test Group1",
|
||||||
|
},
|
||||||
|
"camera": {"platform": "demo"},
|
||||||
|
mf.DOMAIN: {"api_key": "12345678abcdef6"},
|
||||||
|
}
|
||||||
|
|
||||||
|
with assert_setup_component(1, ip.DOMAIN):
|
||||||
|
await async_setup_component(hass, ip.DOMAIN, config)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert hass.states.get("image_processing.test_local")
|
||||||
|
|
||||||
|
|
||||||
|
async def test_ms_identify_process_image(hass, poll_mock, aioclient_mock):
|
||||||
|
"""Set up and scan a picture and test plates from event."""
|
||||||
|
aioclient_mock.get(
|
||||||
|
ENDPOINT_URL.format("persongroups"),
|
||||||
|
text=load_fixture("microsoft_face_persongroups.json"),
|
||||||
|
)
|
||||||
|
aioclient_mock.get(
|
||||||
|
ENDPOINT_URL.format("persongroups/test_group1/persons"),
|
||||||
|
text=load_fixture("microsoft_face_persons.json"),
|
||||||
|
)
|
||||||
|
aioclient_mock.get(
|
||||||
|
ENDPOINT_URL.format("persongroups/test_group2/persons"),
|
||||||
|
text=load_fixture("microsoft_face_persons.json"),
|
||||||
)
|
)
|
||||||
def test_ms_identify_process_image(self, poll_mock, aioclient_mock):
|
|
||||||
"""Set up and scan a picture and test plates from event."""
|
|
||||||
aioclient_mock.get(
|
|
||||||
self.endpoint_url.format("persongroups"),
|
|
||||||
text=load_fixture("microsoft_face_persongroups.json"),
|
|
||||||
)
|
|
||||||
aioclient_mock.get(
|
|
||||||
self.endpoint_url.format("persongroups/test_group1/persons"),
|
|
||||||
text=load_fixture("microsoft_face_persons.json"),
|
|
||||||
)
|
|
||||||
aioclient_mock.get(
|
|
||||||
self.endpoint_url.format("persongroups/test_group2/persons"),
|
|
||||||
text=load_fixture("microsoft_face_persons.json"),
|
|
||||||
)
|
|
||||||
|
|
||||||
setup_component(self.hass, ip.DOMAIN, self.config)
|
await async_setup_component(hass, ip.DOMAIN, CONFIG)
|
||||||
self.hass.block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
state = self.hass.states.get("camera.demo_camera")
|
state = hass.states.get("camera.demo_camera")
|
||||||
url = f"{self.hass.config.internal_url}{state.attributes.get(ATTR_ENTITY_PICTURE)}"
|
url = f"{hass.config.internal_url}{state.attributes.get(ATTR_ENTITY_PICTURE)}"
|
||||||
|
|
||||||
face_events = []
|
face_events = []
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def mock_face_event(event):
|
def mock_face_event(event):
|
||||||
"""Mock event."""
|
"""Mock event."""
|
||||||
face_events.append(event)
|
face_events.append(event)
|
||||||
|
|
||||||
self.hass.bus.listen("image_processing.detect_face", mock_face_event)
|
hass.bus.async_listen("image_processing.detect_face", mock_face_event)
|
||||||
|
|
||||||
aioclient_mock.get(url, content=b"image")
|
aioclient_mock.get(url, content=b"image")
|
||||||
|
|
||||||
aioclient_mock.post(
|
aioclient_mock.post(
|
||||||
self.endpoint_url.format("detect"),
|
ENDPOINT_URL.format("detect"),
|
||||||
text=load_fixture("microsoft_face_detect.json"),
|
text=load_fixture("microsoft_face_detect.json"),
|
||||||
)
|
)
|
||||||
aioclient_mock.post(
|
aioclient_mock.post(
|
||||||
self.endpoint_url.format("identify"),
|
ENDPOINT_URL.format("identify"),
|
||||||
text=load_fixture("microsoft_face_identify.json"),
|
text=load_fixture("microsoft_face_identify.json"),
|
||||||
)
|
)
|
||||||
|
|
||||||
common.scan(self.hass, entity_id="image_processing.test_local")
|
common.async_scan(hass, entity_id="image_processing.test_local")
|
||||||
self.hass.block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
state = self.hass.states.get("image_processing.test_local")
|
state = hass.states.get("image_processing.test_local")
|
||||||
|
|
||||||
assert len(face_events) == 1
|
assert len(face_events) == 1
|
||||||
assert state.attributes.get("total_faces") == 2
|
assert state.attributes.get("total_faces") == 2
|
||||||
assert state.state == "David"
|
assert state.state == "David"
|
||||||
|
|
||||||
assert face_events[0].data["name"] == "David"
|
assert face_events[0].data["name"] == "David"
|
||||||
assert face_events[0].data["confidence"] == float(92)
|
assert face_events[0].data["confidence"] == float(92)
|
||||||
assert face_events[0].data["entity_id"] == "image_processing.test_local"
|
assert face_events[0].data["entity_id"] == "image_processing.test_local"
|
||||||
|
|
||||||
# Test that later, if a request is made that results in no face
|
# Test that later, if a request is made that results in no face
|
||||||
# being detected, that this is reflected in the state object
|
# being detected, that this is reflected in the state object
|
||||||
aioclient_mock.clear_requests()
|
aioclient_mock.clear_requests()
|
||||||
aioclient_mock.post(self.endpoint_url.format("detect"), text="[]")
|
aioclient_mock.post(ENDPOINT_URL.format("detect"), text="[]")
|
||||||
|
|
||||||
common.scan(self.hass, entity_id="image_processing.test_local")
|
common.async_scan(hass, entity_id="image_processing.test_local")
|
||||||
self.hass.block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
state = self.hass.states.get("image_processing.test_local")
|
state = hass.states.get("image_processing.test_local")
|
||||||
|
|
||||||
# No more face events were fired
|
# No more face events were fired
|
||||||
assert len(face_events) == 1
|
assert len(face_events) == 1
|
||||||
# Total faces and actual qualified number of faces reset to zero
|
# Total faces and actual qualified number of faces reset to zero
|
||||||
assert state.attributes.get("total_faces") == 0
|
assert state.attributes.get("total_faces") == 0
|
||||||
assert state.state == STATE_UNKNOWN
|
assert state.state == STATE_UNKNOWN
|
||||||
|
Loading…
x
Reference in New Issue
Block a user