core/tests/components/withings/conftest.py

346 lines
11 KiB
Python

"""Fixtures for withings tests."""
import time
from typing import Awaitable, Callable, List
import asynctest
import nokia
import pytest
import homeassistant.components.api as api
import homeassistant.components.http as http
import homeassistant.components.withings.const as const
from homeassistant.components.withings import CONFIG_SCHEMA, DOMAIN
from homeassistant.config import async_process_ha_core_config
from homeassistant.const import CONF_UNIT_SYSTEM, CONF_UNIT_SYSTEM_METRIC
from homeassistant.setup import async_setup_component
from .common import (
NOKIA_MEASURES_RESPONSE,
NOKIA_SLEEP_RESPONSE,
NOKIA_SLEEP_SUMMARY_RESPONSE,
)
class WithingsFactoryConfig:
"""Configuration for withings test fixture."""
PROFILE_1 = "Person 1"
PROFILE_2 = "Person 2"
def __init__(
self,
api_config: dict = None,
http_config: dict = None,
measures: List[str] = None,
unit_system: str = None,
throttle_interval: int = const.THROTTLE_INTERVAL,
nokia_request_response="DATA",
nokia_measures_response: nokia.NokiaMeasures = NOKIA_MEASURES_RESPONSE,
nokia_sleep_response: nokia.NokiaSleep = NOKIA_SLEEP_RESPONSE,
nokia_sleep_summary_response: nokia.NokiaSleepSummary = NOKIA_SLEEP_SUMMARY_RESPONSE,
) -> None:
"""Constructor."""
self._throttle_interval = throttle_interval
self._nokia_request_response = nokia_request_response
self._nokia_measures_response = nokia_measures_response
self._nokia_sleep_response = nokia_sleep_response
self._nokia_sleep_summary_response = nokia_sleep_summary_response
self._withings_config = {
const.CLIENT_ID: "my_client_id",
const.CLIENT_SECRET: "my_client_secret",
const.PROFILES: [
WithingsFactoryConfig.PROFILE_1,
WithingsFactoryConfig.PROFILE_2,
],
}
self._api_config = api_config or {"base_url": "http://localhost/"}
self._http_config = http_config or {}
self._measures = measures
assert self._withings_config, "withings_config must be set."
assert isinstance(
self._withings_config, dict
), "withings_config must be a dict."
assert isinstance(self._api_config, dict), "api_config must be a dict."
assert isinstance(self._http_config, dict), "http_config must be a dict."
self._hass_config = {
"homeassistant": {CONF_UNIT_SYSTEM: unit_system or CONF_UNIT_SYSTEM_METRIC},
api.DOMAIN: self._api_config,
http.DOMAIN: self._http_config,
DOMAIN: self._withings_config,
}
@property
def withings_config(self):
"""Get withings component config."""
return self._withings_config
@property
def api_config(self):
"""Get api component config."""
return self._api_config
@property
def http_config(self):
"""Get http component config."""
return self._http_config
@property
def measures(self):
"""Get the measures."""
return self._measures
@property
def hass_config(self):
"""Home assistant config."""
return self._hass_config
@property
def throttle_interval(self):
"""Throttle interval."""
return self._throttle_interval
@property
def nokia_request_response(self):
"""Request response."""
return self._nokia_request_response
@property
def nokia_measures_response(self) -> nokia.NokiaMeasures:
"""Measures response."""
return self._nokia_measures_response
@property
def nokia_sleep_response(self) -> nokia.NokiaSleep:
"""Sleep response."""
return self._nokia_sleep_response
@property
def nokia_sleep_summary_response(self) -> nokia.NokiaSleepSummary:
"""Sleep summary response."""
return self._nokia_sleep_summary_response
class WithingsFactoryData:
"""Data about the configured withing test component."""
def __init__(
self,
hass,
flow_id,
nokia_auth_get_credentials_mock,
nokia_api_request_mock,
nokia_api_get_measures_mock,
nokia_api_get_sleep_mock,
nokia_api_get_sleep_summary_mock,
data_manager_get_throttle_interval_mock,
):
"""Constructor."""
self._hass = hass
self._flow_id = flow_id
self._nokia_auth_get_credentials_mock = nokia_auth_get_credentials_mock
self._nokia_api_request_mock = nokia_api_request_mock
self._nokia_api_get_measures_mock = nokia_api_get_measures_mock
self._nokia_api_get_sleep_mock = nokia_api_get_sleep_mock
self._nokia_api_get_sleep_summary_mock = nokia_api_get_sleep_summary_mock
self._data_manager_get_throttle_interval_mock = (
data_manager_get_throttle_interval_mock
)
@property
def hass(self):
"""Get hass instance."""
return self._hass
@property
def flow_id(self):
"""Get flow id."""
return self._flow_id
@property
def nokia_auth_get_credentials_mock(self):
"""Get auth credentials mock."""
return self._nokia_auth_get_credentials_mock
@property
def nokia_api_request_mock(self):
"""Get request mock."""
return self._nokia_api_request_mock
@property
def nokia_api_get_measures_mock(self):
"""Get measures mock."""
return self._nokia_api_get_measures_mock
@property
def nokia_api_get_sleep_mock(self):
"""Get sleep mock."""
return self._nokia_api_get_sleep_mock
@property
def nokia_api_get_sleep_summary_mock(self):
"""Get sleep summary mock."""
return self._nokia_api_get_sleep_summary_mock
@property
def data_manager_get_throttle_interval_mock(self):
"""Get throttle mock."""
return self._data_manager_get_throttle_interval_mock
async def configure_user(self):
"""Present a form with user profiles."""
step = await self.hass.config_entries.flow.async_configure(self.flow_id, None)
assert step["step_id"] == "user"
async def configure_profile(self, profile: str):
"""Select the user profile. Present a form with authorization link."""
print("CONFIG_PROFILE:", profile)
step = await self.hass.config_entries.flow.async_configure(
self.flow_id, {const.PROFILE: profile}
)
assert step["step_id"] == "auth"
async def configure_code(self, profile: str, code: str):
"""Handle authorization code. Create config entries."""
step = await self.hass.config_entries.flow.async_configure(
self.flow_id, {const.PROFILE: profile, const.CODE: code}
)
assert step["type"] == "external_done"
await self.hass.async_block_till_done()
step = await self.hass.config_entries.flow.async_configure(
self.flow_id, {const.PROFILE: profile, const.CODE: code}
)
assert step["type"] == "create_entry"
await self.hass.async_block_till_done()
async def configure_all(self, profile: str, code: str):
"""Configure all flow steps."""
await self.configure_user()
await self.configure_profile(profile)
await self.configure_code(profile, code)
WithingsFactory = Callable[[WithingsFactoryConfig], Awaitable[WithingsFactoryData]]
@pytest.fixture(name="withings_factory")
def withings_factory_fixture(request, hass) -> WithingsFactory:
"""Home assistant platform fixture."""
patches = []
async def factory(config: WithingsFactoryConfig) -> WithingsFactoryData:
CONFIG_SCHEMA(config.hass_config.get(DOMAIN))
await async_process_ha_core_config(
hass, config.hass_config.get("homeassistant")
)
assert await async_setup_component(hass, http.DOMAIN, config.hass_config)
assert await async_setup_component(hass, api.DOMAIN, config.hass_config)
nokia_auth_get_credentials_patch = asynctest.patch(
"nokia.NokiaAuth.get_credentials",
return_value=nokia.NokiaCredentials(
access_token="my_access_token",
token_expiry=time.time() + 600,
token_type="my_token_type",
refresh_token="my_refresh_token",
user_id="my_user_id",
client_id=config.withings_config.get(const.CLIENT_ID),
consumer_secret=config.withings_config.get(const.CLIENT_SECRET),
),
)
nokia_auth_get_credentials_mock = nokia_auth_get_credentials_patch.start()
nokia_api_request_patch = asynctest.patch(
"nokia.NokiaApi.request", return_value=config.nokia_request_response
)
nokia_api_request_mock = nokia_api_request_patch.start()
nokia_api_get_measures_patch = asynctest.patch(
"nokia.NokiaApi.get_measures", return_value=config.nokia_measures_response
)
nokia_api_get_measures_mock = nokia_api_get_measures_patch.start()
nokia_api_get_sleep_patch = asynctest.patch(
"nokia.NokiaApi.get_sleep", return_value=config.nokia_sleep_response
)
nokia_api_get_sleep_mock = nokia_api_get_sleep_patch.start()
nokia_api_get_sleep_summary_patch = asynctest.patch(
"nokia.NokiaApi.get_sleep_summary",
return_value=config.nokia_sleep_summary_response,
)
nokia_api_get_sleep_summary_mock = nokia_api_get_sleep_summary_patch.start()
data_manager_get_throttle_interval_patch = asynctest.patch(
"homeassistant.components.withings.common.WithingsDataManager"
".get_throttle_interval",
return_value=config.throttle_interval,
)
data_manager_get_throttle_interval_mock = (
data_manager_get_throttle_interval_patch.start()
)
get_measures_patch = asynctest.patch(
"homeassistant.components.withings.sensor.get_measures",
return_value=config.measures,
)
get_measures_patch.start()
patches.extend(
[
nokia_auth_get_credentials_patch,
nokia_api_request_patch,
nokia_api_get_measures_patch,
nokia_api_get_sleep_patch,
nokia_api_get_sleep_summary_patch,
data_manager_get_throttle_interval_patch,
get_measures_patch,
]
)
# Collect the flow id.
tasks = []
orig_async_create_task = hass.async_create_task
def create_task(*args):
task = orig_async_create_task(*args)
tasks.append(task)
return task
async_create_task_patch = asynctest.patch.object(
hass, "async_create_task", side_effect=create_task
)
with async_create_task_patch:
assert await async_setup_component(hass, DOMAIN, config.hass_config)
await hass.async_block_till_done()
flow_id = tasks[2].result()["flow_id"]
return WithingsFactoryData(
hass,
flow_id,
nokia_auth_get_credentials_mock,
nokia_api_request_mock,
nokia_api_get_measures_mock,
nokia_api_get_sleep_mock,
nokia_api_get_sleep_summary_mock,
data_manager_get_throttle_interval_mock,
)
def cleanup():
for patch in patches:
patch.stop()
request.addfinalizer(cleanup)
return factory