"""The tests for the microsoft face platform.""" import asyncio 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 def create_group(hass, name): """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, name): """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, group): """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, group, name): """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, group, name): """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, group, person, camera_entity): """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("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 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("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: 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("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", 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=asyncio.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