core/tests/components/microsoft_face/test_init.py

356 lines
11 KiB
Python

"""The tests for the microsoft face platform."""
from unittest.mock import patch
import pytest
from homeassistant.components import camera, microsoft_face as mf
from homeassistant.components.microsoft_face import (
ATTR_CAMERA_ENTITY,
ATTR_GROUP,
ATTR_PERSON,
DOMAIN,
SERVICE_CREATE_GROUP,
SERVICE_CREATE_PERSON,
SERVICE_DELETE_GROUP,
SERVICE_DELETE_PERSON,
SERVICE_FACE_PERSON,
SERVICE_TRAIN_GROUP,
)
from homeassistant.const import ATTR_NAME
from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component
from tests.common import assert_setup_component, load_fixture
from tests.test_util.aiohttp import AiohttpClientMocker
@pytest.fixture(autouse=True)
async def setup_homeassistant(hass: HomeAssistant):
"""Set up the homeassistant integration."""
await async_setup_component(hass, "homeassistant", {})
def create_group(hass: HomeAssistant, name: str) -> None:
"""Create a new person group.
This is a legacy helper method. Do not use it for new tests.
"""
data = {ATTR_NAME: name}
hass.async_create_task(hass.services.async_call(DOMAIN, SERVICE_CREATE_GROUP, data))
def delete_group(hass: HomeAssistant, name: str) -> None:
"""Delete a person group.
This is a legacy helper method. Do not use it for new tests.
"""
data = {ATTR_NAME: name}
hass.async_create_task(hass.services.async_call(DOMAIN, SERVICE_DELETE_GROUP, data))
def train_group(hass: HomeAssistant, group: str) -> None:
"""Train a person group.
This is a legacy helper method. Do not use it for new tests.
"""
data = {ATTR_GROUP: group}
hass.async_create_task(hass.services.async_call(DOMAIN, SERVICE_TRAIN_GROUP, data))
def create_person(hass: HomeAssistant, group: str, name: str) -> None:
"""Create a person in a group.
This is a legacy helper method. Do not use it for new tests.
"""
data = {ATTR_GROUP: group, ATTR_NAME: name}
hass.async_create_task(
hass.services.async_call(DOMAIN, SERVICE_CREATE_PERSON, data)
)
def delete_person(hass: HomeAssistant, group: str, name: str) -> None:
"""Delete a person in a group.
This is a legacy helper method. Do not use it for new tests.
"""
data = {ATTR_GROUP: group, ATTR_NAME: name}
hass.async_create_task(
hass.services.async_call(DOMAIN, SERVICE_DELETE_PERSON, data)
)
def face_person(
hass: HomeAssistant, group: str, person: str, camera_entity: str
) -> None:
"""Add a new face picture to a person.
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}
hass.async_create_task(hass.services.async_call(DOMAIN, SERVICE_FACE_PERSON, data))
CONFIG = {mf.DOMAIN: {"api_key": "12345678abcdef"}}
ENDPOINT_URL = f"https://westus.{mf.FACE_API_URL}"
@pytest.fixture
def mock_update():
"""Mock update store."""
with patch(
"homeassistant.components.microsoft_face.MicrosoftFace.update_store",
return_value=None,
) as mock_update_store:
yield mock_update_store
async def test_setup_component(hass: HomeAssistant, mock_update) -> None:
"""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: HomeAssistant, mock_update) -> None:
"""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: HomeAssistant, mock_update) -> None:
"""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: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None:
"""Set up component."""
aioclient_mock.get(
ENDPOINT_URL.format("persongroups"),
text=load_fixture("persongroups.json", "microsoft_face"),
)
aioclient_mock.get(
ENDPOINT_URL.format("persongroups/test_group1/persons"),
text=load_fixture("persons.json", "microsoft_face"),
)
aioclient_mock.get(
ENDPOINT_URL.format("persongroups/test_group2/persons"),
text=load_fixture("persons.json", "microsoft_face"),
)
with assert_setup_component(3, mf.DOMAIN):
await async_setup_component(hass, mf.DOMAIN, CONFIG)
assert len(aioclient_mock.mock_calls) == 3
entity_group1 = hass.states.get("microsoft_face.test_group1")
entity_group2 = hass.states.get("microsoft_face.test_group2")
assert entity_group1 is not None
assert entity_group2 is not None
assert entity_group1.attributes["Ryan"] == "25985303-c537-4467-b41d-bdb45cd95ca1"
assert entity_group1.attributes["David"] == "2ae4935b-9659-44c3-977f-61fac20d0538"
assert entity_group2.attributes["Ryan"] == "25985303-c537-4467-b41d-bdb45cd95ca1"
assert entity_group2.attributes["David"] == "2ae4935b-9659-44c3-977f-61fac20d0538"
async def test_service_groups(
hass: HomeAssistant, mock_update, aioclient_mock: AiohttpClientMocker
) -> None:
"""Set up component, test groups services."""
aioclient_mock.put(
ENDPOINT_URL.format("persongroups/service_group"),
status=200,
text="{}",
)
aioclient_mock.delete(
ENDPOINT_URL.format("persongroups/service_group"),
status=200,
text="{}",
)
with assert_setup_component(3, mf.DOMAIN):
await async_setup_component(hass, mf.DOMAIN, CONFIG)
create_group(hass, "Service Group")
await hass.async_block_till_done()
entity = hass.states.get("microsoft_face.service_group")
assert entity is not None
assert len(aioclient_mock.mock_calls) == 1
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: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None:
"""Set up component, test person services."""
aioclient_mock.get(
ENDPOINT_URL.format("persongroups"),
text=load_fixture("persongroups.json", "microsoft_face"),
)
aioclient_mock.get(
ENDPOINT_URL.format("persongroups/test_group1/persons"),
text=load_fixture("persons.json", "microsoft_face"),
)
aioclient_mock.get(
ENDPOINT_URL.format("persongroups/test_group2/persons"),
text=load_fixture("persons.json", "microsoft_face"),
)
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("create_person.json", "microsoft_face"),
)
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: HomeAssistant, mock_update, aioclient_mock: AiohttpClientMocker
) -> None:
"""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: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None:
"""Set up component, test person face services."""
aioclient_mock.get(
ENDPOINT_URL.format("persongroups"),
text=load_fixture("persongroups.json", "microsoft_face"),
)
aioclient_mock.get(
ENDPOINT_URL.format("persongroups/test_group1/persons"),
text=load_fixture("persons.json", "microsoft_face"),
)
aioclient_mock.get(
ENDPOINT_URL.format("persongroups/test_group2/persons"),
text=load_fixture("persons.json", "microsoft_face"),
)
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",
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: HomeAssistant, mock_update, aioclient_mock: AiohttpClientMocker
) -> None:
"""Set up component, test groups services with error."""
aioclient_mock.put(
ENDPOINT_URL.format("persongroups/service_group"),
status=400,
text="{'error': {'message': 'Error'}}",
)
with assert_setup_component(3, mf.DOMAIN):
await async_setup_component(hass, mf.DOMAIN, CONFIG)
create_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) == 1
async def test_service_status_timeout(
hass: HomeAssistant, mock_update, aioclient_mock: AiohttpClientMocker
) -> None:
"""Set up component, test groups services with timeout."""
aioclient_mock.put(
ENDPOINT_URL.format("persongroups/service_group"),
status=400,
exc=TimeoutError(),
)
with assert_setup_component(3, mf.DOMAIN):
await async_setup_component(hass, mf.DOMAIN, CONFIG)
create_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) == 1