mirror of https://github.com/home-assistant/core
241 lines
6.9 KiB
Python
241 lines
6.9 KiB
Python
"""Test fixtures for fitbit."""
|
|
|
|
from collections.abc import Awaitable, Callable
|
|
import datetime
|
|
from http import HTTPStatus
|
|
import time
|
|
from typing import Any
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
from requests_mock.mocker import Mocker
|
|
|
|
from homeassistant.components.application_credentials import (
|
|
ClientCredential,
|
|
async_import_client_credential,
|
|
)
|
|
from homeassistant.components.fitbit.const import DOMAIN, OAUTH_SCOPES
|
|
from homeassistant.const import Platform
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.setup import async_setup_component
|
|
|
|
from tests.common import MockConfigEntry
|
|
|
|
CLIENT_ID = "1234"
|
|
CLIENT_SECRET = "5678"
|
|
PROFILE_USER_ID = "fitbit-api-user-id-1"
|
|
FAKE_ACCESS_TOKEN = "some-access-token"
|
|
FAKE_REFRESH_TOKEN = "some-refresh-token"
|
|
FAKE_AUTH_IMPL = "conftest-imported-cred"
|
|
FULL_NAME = "First Last"
|
|
DISPLAY_NAME = "First L."
|
|
PROFILE_DATA = {
|
|
"fullName": FULL_NAME,
|
|
"displayName": DISPLAY_NAME,
|
|
"displayNameSetting": "name",
|
|
"firstName": "First",
|
|
"lastName": "Last",
|
|
}
|
|
|
|
PROFILE_API_URL = "https://api.fitbit.com/1/user/-/profile.json"
|
|
DEVICES_API_URL = "https://api.fitbit.com/1/user/-/devices.json"
|
|
TIMESERIES_API_URL_FORMAT = (
|
|
"https://api.fitbit.com/1/user/-/{resource}/date/today/7d.json"
|
|
)
|
|
|
|
# These constants differ from values in the config entry or fitbit.conf
|
|
SERVER_ACCESS_TOKEN = {
|
|
"refresh_token": "server-refresh-token",
|
|
"access_token": "server-access-token",
|
|
"type": "Bearer",
|
|
"expires_in": 60,
|
|
"scope": " ".join(OAUTH_SCOPES),
|
|
}
|
|
|
|
|
|
@pytest.fixture(name="token_expiration_time")
|
|
def mcok_token_expiration_time() -> float:
|
|
"""Fixture for expiration time of the config entry auth token."""
|
|
return time.time() + 86400
|
|
|
|
|
|
@pytest.fixture(name="scopes")
|
|
def mock_scopes() -> list[str]:
|
|
"""Fixture for expiration time of the config entry auth token."""
|
|
return OAUTH_SCOPES
|
|
|
|
|
|
@pytest.fixture(name="token_entry")
|
|
def mock_token_entry(token_expiration_time: float, scopes: list[str]) -> dict[str, Any]:
|
|
"""Fixture for OAuth 'token' data for a ConfigEntry."""
|
|
return {
|
|
"access_token": FAKE_ACCESS_TOKEN,
|
|
"refresh_token": FAKE_REFRESH_TOKEN,
|
|
"scope": " ".join(scopes),
|
|
"token_type": "Bearer",
|
|
"expires_at": token_expiration_time,
|
|
}
|
|
|
|
|
|
@pytest.fixture(name="config_entry")
|
|
def mock_config_entry(
|
|
token_entry: dict[str, Any], imported_config_data: dict[str, Any]
|
|
) -> MockConfigEntry:
|
|
"""Fixture for a config entry."""
|
|
return MockConfigEntry(
|
|
domain=DOMAIN,
|
|
data={
|
|
"auth_implementation": FAKE_AUTH_IMPL,
|
|
"token": token_entry,
|
|
**imported_config_data,
|
|
},
|
|
unique_id=PROFILE_USER_ID,
|
|
title=DISPLAY_NAME,
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
async def setup_credentials(hass: HomeAssistant) -> None:
|
|
"""Fixture to setup credentials."""
|
|
assert await async_setup_component(hass, "application_credentials", {})
|
|
await async_import_client_credential(
|
|
hass,
|
|
DOMAIN,
|
|
ClientCredential(CLIENT_ID, CLIENT_SECRET),
|
|
FAKE_AUTH_IMPL,
|
|
)
|
|
|
|
|
|
@pytest.fixture(name="monitored_resources")
|
|
def mock_monitored_resources() -> list[str] | None:
|
|
"""Fixture for the fitbit yaml config monitored_resources field."""
|
|
return None
|
|
|
|
|
|
@pytest.fixture(name="configured_unit_system")
|
|
def mock_configured_unit_syststem() -> str | None:
|
|
"""Fixture for the fitbit yaml config monitored_resources field."""
|
|
return None
|
|
|
|
|
|
@pytest.fixture(name="imported_config_data")
|
|
def mock_imported_config_data(
|
|
monitored_resources: list[str] | None,
|
|
configured_unit_system: str | None,
|
|
) -> dict[str, Any]:
|
|
"""Fixture for the fitbit sensor platform configuration data in configuration.yaml."""
|
|
config = {}
|
|
if monitored_resources is not None:
|
|
config["monitored_resources"] = monitored_resources
|
|
if configured_unit_system is not None:
|
|
config["unit_system"] = configured_unit_system
|
|
return config
|
|
|
|
|
|
@pytest.fixture
|
|
def platforms() -> list[Platform]:
|
|
"""Fixture to specify platforms to test."""
|
|
return []
|
|
|
|
|
|
@pytest.fixture(name="integration_setup")
|
|
async def mock_integration_setup(
|
|
hass: HomeAssistant,
|
|
config_entry: MockConfigEntry,
|
|
platforms: list[str],
|
|
) -> Callable[[], Awaitable[bool]]:
|
|
"""Fixture to set up the integration."""
|
|
config_entry.add_to_hass(hass)
|
|
|
|
async def run() -> bool:
|
|
with patch(f"homeassistant.components.{DOMAIN}.PLATFORMS", platforms):
|
|
result = await hass.config_entries.async_setup(config_entry.entry_id)
|
|
await hass.async_block_till_done()
|
|
return result
|
|
|
|
return run
|
|
|
|
|
|
@pytest.fixture(name="profile_id")
|
|
def mock_profile_id() -> str:
|
|
"""Fixture for the profile id returned from the API response."""
|
|
return PROFILE_USER_ID
|
|
|
|
|
|
@pytest.fixture(name="profile_locale")
|
|
def mock_profile_locale() -> str:
|
|
"""Fixture to set the API response for the user profile."""
|
|
return "en_US"
|
|
|
|
|
|
@pytest.fixture(name="profile_data")
|
|
def mock_profile_data() -> dict[str, Any]:
|
|
"""Fixture to return other profile data fields."""
|
|
return PROFILE_DATA
|
|
|
|
|
|
@pytest.fixture(name="profile_response")
|
|
def mock_profile_response(
|
|
profile_id: str, profile_locale: str, profile_data: dict[str, Any]
|
|
) -> dict[str, Any]:
|
|
"""Fixture to construct the fake profile API response."""
|
|
return {
|
|
"user": {
|
|
"encodedId": profile_id,
|
|
"locale": profile_locale,
|
|
**profile_data,
|
|
},
|
|
}
|
|
|
|
|
|
@pytest.fixture(name="profile", autouse=True)
|
|
def mock_profile(requests_mock: Mocker, profile_response: dict[str, Any]) -> None:
|
|
"""Fixture to setup fake requests made to Fitbit API during config flow."""
|
|
requests_mock.register_uri(
|
|
"GET",
|
|
PROFILE_API_URL,
|
|
status_code=HTTPStatus.OK,
|
|
json=profile_response,
|
|
)
|
|
|
|
|
|
@pytest.fixture(name="devices_response")
|
|
def mock_device_response() -> list[dict[str, Any]]:
|
|
"""Return the list of devices."""
|
|
return []
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def mock_devices(requests_mock: Mocker, devices_response: dict[str, Any]) -> None:
|
|
"""Fixture to setup fake device responses."""
|
|
requests_mock.register_uri(
|
|
"GET",
|
|
DEVICES_API_URL,
|
|
status_code=HTTPStatus.OK,
|
|
json=devices_response,
|
|
)
|
|
|
|
|
|
def timeseries_response(resource: str, value: str) -> dict[str, Any]:
|
|
"""Create a timeseries response value."""
|
|
return {
|
|
resource: [{"dateTime": datetime.datetime.today().isoformat(), "value": value}]
|
|
}
|
|
|
|
|
|
@pytest.fixture(name="register_timeseries")
|
|
def mock_register_timeseries(
|
|
requests_mock: Mocker,
|
|
) -> Callable[[str, dict[str, Any]], None]:
|
|
"""Fixture to setup fake timeseries API responses."""
|
|
|
|
def register(resource: str, response: dict[str, Any]) -> None:
|
|
requests_mock.register_uri(
|
|
"GET",
|
|
TIMESERIES_API_URL_FORMAT.format(resource=resource),
|
|
status_code=HTTPStatus.OK,
|
|
json=response,
|
|
)
|
|
|
|
return register
|