mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 19:27:45 +00:00
Use json to store Withings test data fixtures (#99998)
* Decouple Withings sensor tests from yaml * Improve Withings config flow tests * Improve Withings config flow tests * Fix feedback * Use fixtures to store Withings testdata structures * Use fixtures to store Withings testdata structures * Use JSON * Fix * Use load_json_object_fixture
This commit is contained in:
parent
58072189fc
commit
5781e5e03e
@ -1,6 +1,6 @@
|
|||||||
"""Tests for the withings component."""
|
"""Tests for the withings component."""
|
||||||
from collections.abc import Iterable
|
from collections.abc import Iterable
|
||||||
from typing import Any, Optional
|
from typing import Any
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
|
||||||
import arrow
|
import arrow
|
||||||
@ -10,6 +10,8 @@ from withings_api.common import (
|
|||||||
MeasureGetMeasGroupCategory,
|
MeasureGetMeasGroupCategory,
|
||||||
MeasureGetMeasResponse,
|
MeasureGetMeasResponse,
|
||||||
MeasureType,
|
MeasureType,
|
||||||
|
NotifyAppli,
|
||||||
|
NotifyListResponse,
|
||||||
SleepGetSummaryResponse,
|
SleepGetSummaryResponse,
|
||||||
UserGetDeviceResponse,
|
UserGetDeviceResponse,
|
||||||
)
|
)
|
||||||
@ -17,7 +19,9 @@ from withings_api.common import (
|
|||||||
from homeassistant.components.webhook import async_generate_url
|
from homeassistant.components.webhook import async_generate_url
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from .common import ProfileConfig, WebhookResponse
|
from .common import WebhookResponse
|
||||||
|
|
||||||
|
from tests.common import load_json_object_fixture
|
||||||
|
|
||||||
|
|
||||||
async def call_webhook(
|
async def call_webhook(
|
||||||
@ -43,19 +47,23 @@ async def call_webhook(
|
|||||||
class MockWithings:
|
class MockWithings:
|
||||||
"""Mock object for Withings."""
|
"""Mock object for Withings."""
|
||||||
|
|
||||||
def __init__(self, user_profile: ProfileConfig):
|
def __init__(
|
||||||
|
self,
|
||||||
|
device_fixture: str = "person0_get_device.json",
|
||||||
|
measurement_fixture: str = "person0_get_meas.json",
|
||||||
|
sleep_fixture: str = "person0_get_sleep.json",
|
||||||
|
notify_list_fixture: str = "person0_notify_list.json",
|
||||||
|
):
|
||||||
"""Initialize mock."""
|
"""Initialize mock."""
|
||||||
self.api_response_user_get_device = user_profile.api_response_user_get_device
|
self.device_fixture = device_fixture
|
||||||
self.api_response_measure_get_meas = user_profile.api_response_measure_get_meas
|
self.measurement_fixture = measurement_fixture
|
||||||
self.api_response_sleep_get_summary = (
|
self.sleep_fixture = sleep_fixture
|
||||||
user_profile.api_response_sleep_get_summary
|
self.notify_list_fixture = notify_list_fixture
|
||||||
)
|
|
||||||
|
|
||||||
def user_get_device(self) -> UserGetDeviceResponse:
|
def user_get_device(self) -> UserGetDeviceResponse:
|
||||||
"""Get devices."""
|
"""Get devices."""
|
||||||
if isinstance(self.api_response_user_get_device, Exception):
|
fixture = load_json_object_fixture(f"withings/{self.device_fixture}")
|
||||||
raise self.api_response_user_get_device
|
return UserGetDeviceResponse(**fixture)
|
||||||
return self.api_response_user_get_device
|
|
||||||
|
|
||||||
def measure_get_meas(
|
def measure_get_meas(
|
||||||
self,
|
self,
|
||||||
@ -67,19 +75,25 @@ class MockWithings:
|
|||||||
lastupdate: DateType | None = None,
|
lastupdate: DateType | None = None,
|
||||||
) -> MeasureGetMeasResponse:
|
) -> MeasureGetMeasResponse:
|
||||||
"""Get measurements."""
|
"""Get measurements."""
|
||||||
if isinstance(self.api_response_measure_get_meas, Exception):
|
fixture = load_json_object_fixture(f"withings/{self.measurement_fixture}")
|
||||||
raise self.api_response_measure_get_meas
|
return MeasureGetMeasResponse(**fixture)
|
||||||
return self.api_response_measure_get_meas
|
|
||||||
|
|
||||||
def sleep_get_summary(
|
def sleep_get_summary(
|
||||||
self,
|
self,
|
||||||
data_fields: Iterable[GetSleepSummaryField],
|
data_fields: Iterable[GetSleepSummaryField],
|
||||||
startdateymd: Optional[DateType] = arrow.utcnow(),
|
startdateymd: DateType | None = arrow.utcnow(),
|
||||||
enddateymd: Optional[DateType] = arrow.utcnow(),
|
enddateymd: DateType | None = arrow.utcnow(),
|
||||||
offset: Optional[int] = None,
|
offset: int | None = None,
|
||||||
lastupdate: Optional[DateType] = arrow.utcnow(),
|
lastupdate: DateType | None = arrow.utcnow(),
|
||||||
) -> SleepGetSummaryResponse:
|
) -> SleepGetSummaryResponse:
|
||||||
"""Get sleep."""
|
"""Get sleep."""
|
||||||
if isinstance(self.api_response_sleep_get_summary, Exception):
|
fixture = load_json_object_fixture(f"withings/{self.sleep_fixture}")
|
||||||
raise self.api_response_sleep_get_summary
|
return SleepGetSummaryResponse(**fixture)
|
||||||
return self.api_response_sleep_get_summary
|
|
||||||
|
def notify_list(
|
||||||
|
self,
|
||||||
|
appli: NotifyAppli | None = None,
|
||||||
|
) -> NotifyListResponse:
|
||||||
|
"""Get sleep."""
|
||||||
|
fixture = load_json_object_fixture(f"withings/{self.notify_list_fixture}")
|
||||||
|
return NotifyListResponse(**fixture)
|
||||||
|
@ -4,20 +4,7 @@ import time
|
|||||||
from typing import Any
|
from typing import Any
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
import arrow
|
|
||||||
import pytest
|
import pytest
|
||||||
from withings_api.common import (
|
|
||||||
GetSleepSummaryData,
|
|
||||||
GetSleepSummarySerie,
|
|
||||||
MeasureGetMeasGroup,
|
|
||||||
MeasureGetMeasGroupAttrib,
|
|
||||||
MeasureGetMeasGroupCategory,
|
|
||||||
MeasureGetMeasMeasure,
|
|
||||||
MeasureGetMeasResponse,
|
|
||||||
MeasureType,
|
|
||||||
SleepGetSummaryResponse,
|
|
||||||
SleepModel,
|
|
||||||
)
|
|
||||||
|
|
||||||
from homeassistant.components.application_credentials import (
|
from homeassistant.components.application_credentials import (
|
||||||
ClientCredential,
|
ClientCredential,
|
||||||
@ -27,10 +14,9 @@ from homeassistant.components.withings.const import DOMAIN
|
|||||||
from homeassistant.config import async_process_ha_core_config
|
from homeassistant.config import async_process_ha_core_config
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
from homeassistant.util import dt as dt_util
|
|
||||||
|
|
||||||
from . import MockWithings
|
from . import MockWithings
|
||||||
from .common import ComponentFactory, new_profile_config
|
from .common import ComponentFactory
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
from tests.test_util.aiohttp import AiohttpClientMocker
|
from tests.test_util.aiohttp import AiohttpClientMocker
|
||||||
@ -46,231 +32,9 @@ SCOPES = [
|
|||||||
"user.sleepevents",
|
"user.sleepevents",
|
||||||
]
|
]
|
||||||
TITLE = "henk"
|
TITLE = "henk"
|
||||||
|
USER_ID = 12345
|
||||||
WEBHOOK_ID = "55a7335ea8dee830eed4ef8f84cda8f6d80b83af0847dc74032e86120bffed5e"
|
WEBHOOK_ID = "55a7335ea8dee830eed4ef8f84cda8f6d80b83af0847dc74032e86120bffed5e"
|
||||||
|
|
||||||
PERSON0 = new_profile_config(
|
|
||||||
profile="12345",
|
|
||||||
user_id=12345,
|
|
||||||
api_response_measure_get_meas=MeasureGetMeasResponse(
|
|
||||||
measuregrps=(
|
|
||||||
MeasureGetMeasGroup(
|
|
||||||
attrib=MeasureGetMeasGroupAttrib.DEVICE_ENTRY_FOR_USER,
|
|
||||||
category=MeasureGetMeasGroupCategory.REAL,
|
|
||||||
created=arrow.utcnow().shift(hours=-1),
|
|
||||||
date=arrow.utcnow().shift(hours=-1),
|
|
||||||
deviceid="DEV_ID",
|
|
||||||
grpid=1,
|
|
||||||
measures=(
|
|
||||||
MeasureGetMeasMeasure(type=MeasureType.WEIGHT, unit=0, value=70),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.FAT_MASS_WEIGHT, unit=0, value=5
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.FAT_FREE_MASS, unit=0, value=60
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.MUSCLE_MASS, unit=0, value=50
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(type=MeasureType.BONE_MASS, unit=0, value=10),
|
|
||||||
MeasureGetMeasMeasure(type=MeasureType.HEIGHT, unit=0, value=2),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.TEMPERATURE, unit=0, value=40
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.BODY_TEMPERATURE, unit=0, value=40
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.SKIN_TEMPERATURE, unit=0, value=20
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.FAT_RATIO, unit=-3, value=70
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.DIASTOLIC_BLOOD_PRESSURE, unit=0, value=70
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.SYSTOLIC_BLOOD_PRESSURE, unit=0, value=100
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.HEART_RATE, unit=0, value=60
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(type=MeasureType.SP02, unit=-2, value=95),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.HYDRATION, unit=-2, value=95
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.PULSE_WAVE_VELOCITY, unit=0, value=100
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
MeasureGetMeasGroup(
|
|
||||||
attrib=MeasureGetMeasGroupAttrib.DEVICE_ENTRY_FOR_USER,
|
|
||||||
category=MeasureGetMeasGroupCategory.REAL,
|
|
||||||
created=arrow.utcnow().shift(hours=-2),
|
|
||||||
date=arrow.utcnow().shift(hours=-2),
|
|
||||||
deviceid="DEV_ID",
|
|
||||||
grpid=1,
|
|
||||||
measures=(
|
|
||||||
MeasureGetMeasMeasure(type=MeasureType.WEIGHT, unit=0, value=71),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.FAT_MASS_WEIGHT, unit=0, value=51
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.FAT_FREE_MASS, unit=0, value=61
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.MUSCLE_MASS, unit=0, value=51
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(type=MeasureType.BONE_MASS, unit=0, value=11),
|
|
||||||
MeasureGetMeasMeasure(type=MeasureType.HEIGHT, unit=0, value=21),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.TEMPERATURE, unit=0, value=41
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.BODY_TEMPERATURE, unit=0, value=41
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.SKIN_TEMPERATURE, unit=0, value=21
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.FAT_RATIO, unit=-3, value=71
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.DIASTOLIC_BLOOD_PRESSURE, unit=0, value=71
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.SYSTOLIC_BLOOD_PRESSURE, unit=0, value=101
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.HEART_RATE, unit=0, value=61
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(type=MeasureType.SP02, unit=-2, value=96),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.HYDRATION, unit=-2, value=96
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.PULSE_WAVE_VELOCITY, unit=0, value=101
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
MeasureGetMeasGroup(
|
|
||||||
attrib=MeasureGetMeasGroupAttrib.DEVICE_ENTRY_FOR_USER_AMBIGUOUS,
|
|
||||||
category=MeasureGetMeasGroupCategory.REAL,
|
|
||||||
created=arrow.utcnow(),
|
|
||||||
date=arrow.utcnow(),
|
|
||||||
deviceid="DEV_ID",
|
|
||||||
grpid=1,
|
|
||||||
measures=(
|
|
||||||
MeasureGetMeasMeasure(type=MeasureType.WEIGHT, unit=0, value=71),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.FAT_MASS_WEIGHT, unit=0, value=4
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.FAT_FREE_MASS, unit=0, value=40
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.MUSCLE_MASS, unit=0, value=51
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(type=MeasureType.BONE_MASS, unit=0, value=11),
|
|
||||||
MeasureGetMeasMeasure(type=MeasureType.HEIGHT, unit=0, value=201),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.TEMPERATURE, unit=0, value=41
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.BODY_TEMPERATURE, unit=0, value=34
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.SKIN_TEMPERATURE, unit=0, value=21
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.FAT_RATIO, unit=-3, value=71
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.DIASTOLIC_BLOOD_PRESSURE, unit=0, value=71
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.SYSTOLIC_BLOOD_PRESSURE, unit=0, value=101
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.HEART_RATE, unit=0, value=61
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(type=MeasureType.SP02, unit=-2, value=98),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.HYDRATION, unit=-2, value=96
|
|
||||||
),
|
|
||||||
MeasureGetMeasMeasure(
|
|
||||||
type=MeasureType.PULSE_WAVE_VELOCITY, unit=0, value=102
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
more=False,
|
|
||||||
timezone=dt_util.UTC,
|
|
||||||
updatetime=arrow.get("2019-08-01"),
|
|
||||||
offset=0,
|
|
||||||
),
|
|
||||||
api_response_sleep_get_summary=SleepGetSummaryResponse(
|
|
||||||
more=False,
|
|
||||||
offset=0,
|
|
||||||
series=(
|
|
||||||
GetSleepSummarySerie(
|
|
||||||
timezone=dt_util.UTC,
|
|
||||||
model=SleepModel.SLEEP_MONITOR,
|
|
||||||
startdate=arrow.get("2019-02-01"),
|
|
||||||
enddate=arrow.get("2019-02-01"),
|
|
||||||
date=arrow.get("2019-02-01"),
|
|
||||||
modified=arrow.get(12345),
|
|
||||||
data=GetSleepSummaryData(
|
|
||||||
breathing_disturbances_intensity=110,
|
|
||||||
deepsleepduration=111,
|
|
||||||
durationtosleep=112,
|
|
||||||
durationtowakeup=113,
|
|
||||||
hr_average=114,
|
|
||||||
hr_max=115,
|
|
||||||
hr_min=116,
|
|
||||||
lightsleepduration=117,
|
|
||||||
remsleepduration=118,
|
|
||||||
rr_average=119,
|
|
||||||
rr_max=120,
|
|
||||||
rr_min=121,
|
|
||||||
sleep_score=122,
|
|
||||||
snoring=123,
|
|
||||||
snoringepisodecount=124,
|
|
||||||
wakeupcount=125,
|
|
||||||
wakeupduration=126,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
GetSleepSummarySerie(
|
|
||||||
timezone=dt_util.UTC,
|
|
||||||
model=SleepModel.SLEEP_MONITOR,
|
|
||||||
startdate=arrow.get("2019-02-01"),
|
|
||||||
enddate=arrow.get("2019-02-01"),
|
|
||||||
date=arrow.get("2019-02-01"),
|
|
||||||
modified=arrow.get(12345),
|
|
||||||
data=GetSleepSummaryData(
|
|
||||||
breathing_disturbances_intensity=210,
|
|
||||||
deepsleepduration=211,
|
|
||||||
durationtosleep=212,
|
|
||||||
durationtowakeup=213,
|
|
||||||
hr_average=214,
|
|
||||||
hr_max=215,
|
|
||||||
hr_min=216,
|
|
||||||
lightsleepduration=217,
|
|
||||||
remsleepduration=218,
|
|
||||||
rr_average=219,
|
|
||||||
rr_max=220,
|
|
||||||
rr_min=221,
|
|
||||||
sleep_score=222,
|
|
||||||
snoring=223,
|
|
||||||
snoringepisodecount=224,
|
|
||||||
wakeupcount=225,
|
|
||||||
wakeupduration=226,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def component_factory(
|
def component_factory(
|
||||||
@ -318,12 +82,12 @@ def mock_config_entry(expires_at: int, scopes: list[str]) -> MockConfigEntry:
|
|||||||
return MockConfigEntry(
|
return MockConfigEntry(
|
||||||
domain=DOMAIN,
|
domain=DOMAIN,
|
||||||
title=TITLE,
|
title=TITLE,
|
||||||
unique_id="12345",
|
unique_id=str(USER_ID),
|
||||||
data={
|
data={
|
||||||
"auth_implementation": DOMAIN,
|
"auth_implementation": DOMAIN,
|
||||||
"token": {
|
"token": {
|
||||||
"status": 0,
|
"status": 0,
|
||||||
"userid": "12345",
|
"userid": str(USER_ID),
|
||||||
"access_token": "mock-access-token",
|
"access_token": "mock-access-token",
|
||||||
"refresh_token": "mock-refresh-token",
|
"refresh_token": "mock-refresh-token",
|
||||||
"expires_at": expires_at,
|
"expires_at": expires_at,
|
||||||
@ -356,7 +120,7 @@ async def mock_setup_integration(
|
|||||||
)
|
)
|
||||||
|
|
||||||
async def func() -> MockWithings:
|
async def func() -> MockWithings:
|
||||||
mock = MockWithings(PERSON0)
|
mock = MockWithings()
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.withings.common.ConfigEntryWithingsApi",
|
"homeassistant.components.withings.common.ConfigEntryWithingsApi",
|
||||||
return_value=mock,
|
return_value=mock,
|
||||||
|
18
tests/components/withings/fixtures/person0_get_device.json
Normal file
18
tests/components/withings/fixtures/person0_get_device.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"status": 0,
|
||||||
|
"body": {
|
||||||
|
"devices": [
|
||||||
|
{
|
||||||
|
"type": "Scale",
|
||||||
|
"battery": "high",
|
||||||
|
"model": "Body+",
|
||||||
|
"model_id": 5,
|
||||||
|
"timezone": "Europe/Amsterdam",
|
||||||
|
"first_session_date": null,
|
||||||
|
"last_session_date": 1693867179,
|
||||||
|
"deviceid": "f998be4b9ccc9e136fd8cd8e8e344c31ec3b271d",
|
||||||
|
"hash_deviceid": "f998be4b9ccc9e136fd8cd8e8e344c31ec3b271d"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
278
tests/components/withings/fixtures/person0_get_meas.json
Normal file
278
tests/components/withings/fixtures/person0_get_meas.json
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
{
|
||||||
|
"more": false,
|
||||||
|
"timezone": "UTC",
|
||||||
|
"updatetime": 1564617600,
|
||||||
|
"offset": 0,
|
||||||
|
"measuregrps": [
|
||||||
|
{
|
||||||
|
"attrib": 0,
|
||||||
|
"category": 1,
|
||||||
|
"created": 1564660800,
|
||||||
|
"date": 1564660800,
|
||||||
|
"deviceid": "DEV_ID",
|
||||||
|
"grpid": 1,
|
||||||
|
"measures": [
|
||||||
|
{
|
||||||
|
"type": 1,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 8,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 5,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 76,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 88,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 4,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 12,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 40
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 71,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 40
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 73,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 6,
|
||||||
|
"unit": -3,
|
||||||
|
"value": 70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 9,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 70
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 10,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 11,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 60
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 54,
|
||||||
|
"unit": -2,
|
||||||
|
"value": 95
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 77,
|
||||||
|
"unit": -2,
|
||||||
|
"value": 95
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 91,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 100
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"attrib": 0,
|
||||||
|
"category": 1,
|
||||||
|
"created": 1564657200,
|
||||||
|
"date": 1564657200,
|
||||||
|
"deviceid": "DEV_ID",
|
||||||
|
"grpid": 1,
|
||||||
|
"measures": [
|
||||||
|
{
|
||||||
|
"type": 1,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 71
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 8,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 51
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 5,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 61
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 76,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 51
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 88,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 4,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 21
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 12,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 41
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 71,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 41
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 73,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 21
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 6,
|
||||||
|
"unit": -3,
|
||||||
|
"value": 71
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 9,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 71
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 10,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 101
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 11,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 61
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 54,
|
||||||
|
"unit": -2,
|
||||||
|
"value": 96
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 77,
|
||||||
|
"unit": -2,
|
||||||
|
"value": 96
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 91,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 101
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"attrib": 1,
|
||||||
|
"category": 1,
|
||||||
|
"created": 1564664400,
|
||||||
|
"date": 1564664400,
|
||||||
|
"deviceid": "DEV_ID",
|
||||||
|
"grpid": 1,
|
||||||
|
"measures": [
|
||||||
|
{
|
||||||
|
"type": 1,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 71
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 8,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 5,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 40
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 76,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 51
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 88,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 11
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 4,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 201
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 12,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 41
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 71,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 34
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 73,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 21
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 6,
|
||||||
|
"unit": -3,
|
||||||
|
"value": 71
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 9,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 71
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 10,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 101
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 11,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 61
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 54,
|
||||||
|
"unit": -2,
|
||||||
|
"value": 98
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 77,
|
||||||
|
"unit": -2,
|
||||||
|
"value": 96
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": 91,
|
||||||
|
"unit": 0,
|
||||||
|
"value": 102
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
60
tests/components/withings/fixtures/person0_get_sleep.json
Normal file
60
tests/components/withings/fixtures/person0_get_sleep.json
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
{
|
||||||
|
"more": false,
|
||||||
|
"offset": 0,
|
||||||
|
"series": [
|
||||||
|
{
|
||||||
|
"timezone": "UTC",
|
||||||
|
"model": 32,
|
||||||
|
"startdate": 1548979200,
|
||||||
|
"enddate": 1548979200,
|
||||||
|
"date": 1548979200,
|
||||||
|
"modified": 12345,
|
||||||
|
"data": {
|
||||||
|
"breathing_disturbances_intensity": 110,
|
||||||
|
"deepsleepduration": 111,
|
||||||
|
"durationtosleep": 112,
|
||||||
|
"durationtowakeup": 113,
|
||||||
|
"hr_average": 114,
|
||||||
|
"hr_max": 115,
|
||||||
|
"hr_min": 116,
|
||||||
|
"lightsleepduration": 117,
|
||||||
|
"remsleepduration": 118,
|
||||||
|
"rr_average": 119,
|
||||||
|
"rr_max": 120,
|
||||||
|
"rr_min": 121,
|
||||||
|
"sleep_score": 122,
|
||||||
|
"snoring": 123,
|
||||||
|
"snoringepisodecount": 124,
|
||||||
|
"wakeupcount": 125,
|
||||||
|
"wakeupduration": 126
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"timezone": "UTC",
|
||||||
|
"model": 32,
|
||||||
|
"startdate": 1548979200,
|
||||||
|
"enddate": 1548979200,
|
||||||
|
"date": 1548979200,
|
||||||
|
"modified": 12345,
|
||||||
|
"data": {
|
||||||
|
"breathing_disturbances_intensity": 210,
|
||||||
|
"deepsleepduration": 211,
|
||||||
|
"durationtosleep": 212,
|
||||||
|
"durationtowakeup": 213,
|
||||||
|
"hr_average": 214,
|
||||||
|
"hr_max": 215,
|
||||||
|
"hr_min": 216,
|
||||||
|
"lightsleepduration": 217,
|
||||||
|
"remsleepduration": 218,
|
||||||
|
"rr_average": 219,
|
||||||
|
"rr_max": 220,
|
||||||
|
"rr_min": 221,
|
||||||
|
"sleep_score": 222,
|
||||||
|
"snoring": 223,
|
||||||
|
"snoringepisodecount": 224,
|
||||||
|
"wakeupcount": 225,
|
||||||
|
"wakeupduration": 226
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"profiles": []
|
||||||
|
}
|
@ -16,7 +16,7 @@ from homeassistant.helpers.entity_registry import EntityRegistry
|
|||||||
|
|
||||||
from . import MockWithings, call_webhook
|
from . import MockWithings, call_webhook
|
||||||
from .common import async_get_entity_id
|
from .common import async_get_entity_id
|
||||||
from .conftest import PERSON0, WEBHOOK_ID, ComponentSetup
|
from .conftest import USER_ID, WEBHOOK_ID, ComponentSetup
|
||||||
|
|
||||||
from tests.typing import ClientSessionGenerator
|
from tests.typing import ClientSessionGenerator
|
||||||
|
|
||||||
@ -26,36 +26,36 @@ WITHINGS_MEASUREMENTS_MAP: dict[Measurement, WithingsEntityDescription] = {
|
|||||||
|
|
||||||
|
|
||||||
EXPECTED_DATA = (
|
EXPECTED_DATA = (
|
||||||
(PERSON0, Measurement.WEIGHT_KG, 70.0),
|
(Measurement.WEIGHT_KG, 70.0),
|
||||||
(PERSON0, Measurement.FAT_MASS_KG, 5.0),
|
(Measurement.FAT_MASS_KG, 5.0),
|
||||||
(PERSON0, Measurement.FAT_FREE_MASS_KG, 60.0),
|
(Measurement.FAT_FREE_MASS_KG, 60.0),
|
||||||
(PERSON0, Measurement.MUSCLE_MASS_KG, 50.0),
|
(Measurement.MUSCLE_MASS_KG, 50.0),
|
||||||
(PERSON0, Measurement.BONE_MASS_KG, 10.0),
|
(Measurement.BONE_MASS_KG, 10.0),
|
||||||
(PERSON0, Measurement.HEIGHT_M, 2.0),
|
(Measurement.HEIGHT_M, 2.0),
|
||||||
(PERSON0, Measurement.FAT_RATIO_PCT, 0.07),
|
(Measurement.FAT_RATIO_PCT, 0.07),
|
||||||
(PERSON0, Measurement.DIASTOLIC_MMHG, 70.0),
|
(Measurement.DIASTOLIC_MMHG, 70.0),
|
||||||
(PERSON0, Measurement.SYSTOLIC_MMGH, 100.0),
|
(Measurement.SYSTOLIC_MMGH, 100.0),
|
||||||
(PERSON0, Measurement.HEART_PULSE_BPM, 60.0),
|
(Measurement.HEART_PULSE_BPM, 60.0),
|
||||||
(PERSON0, Measurement.SPO2_PCT, 0.95),
|
(Measurement.SPO2_PCT, 0.95),
|
||||||
(PERSON0, Measurement.HYDRATION, 0.95),
|
(Measurement.HYDRATION, 0.95),
|
||||||
(PERSON0, Measurement.PWV, 100.0),
|
(Measurement.PWV, 100.0),
|
||||||
(PERSON0, Measurement.SLEEP_BREATHING_DISTURBANCES_INTENSITY, 160.0),
|
(Measurement.SLEEP_BREATHING_DISTURBANCES_INTENSITY, 160.0),
|
||||||
(PERSON0, Measurement.SLEEP_DEEP_DURATION_SECONDS, 322),
|
(Measurement.SLEEP_DEEP_DURATION_SECONDS, 322),
|
||||||
(PERSON0, Measurement.SLEEP_HEART_RATE_AVERAGE, 164.0),
|
(Measurement.SLEEP_HEART_RATE_AVERAGE, 164.0),
|
||||||
(PERSON0, Measurement.SLEEP_HEART_RATE_MAX, 165.0),
|
(Measurement.SLEEP_HEART_RATE_MAX, 165.0),
|
||||||
(PERSON0, Measurement.SLEEP_HEART_RATE_MIN, 166.0),
|
(Measurement.SLEEP_HEART_RATE_MIN, 166.0),
|
||||||
(PERSON0, Measurement.SLEEP_LIGHT_DURATION_SECONDS, 334),
|
(Measurement.SLEEP_LIGHT_DURATION_SECONDS, 334),
|
||||||
(PERSON0, Measurement.SLEEP_REM_DURATION_SECONDS, 336),
|
(Measurement.SLEEP_REM_DURATION_SECONDS, 336),
|
||||||
(PERSON0, Measurement.SLEEP_RESPIRATORY_RATE_AVERAGE, 169.0),
|
(Measurement.SLEEP_RESPIRATORY_RATE_AVERAGE, 169.0),
|
||||||
(PERSON0, Measurement.SLEEP_RESPIRATORY_RATE_MAX, 170.0),
|
(Measurement.SLEEP_RESPIRATORY_RATE_MAX, 170.0),
|
||||||
(PERSON0, Measurement.SLEEP_RESPIRATORY_RATE_MIN, 171.0),
|
(Measurement.SLEEP_RESPIRATORY_RATE_MIN, 171.0),
|
||||||
(PERSON0, Measurement.SLEEP_SCORE, 222),
|
(Measurement.SLEEP_SCORE, 222),
|
||||||
(PERSON0, Measurement.SLEEP_SNORING, 173.0),
|
(Measurement.SLEEP_SNORING, 173.0),
|
||||||
(PERSON0, Measurement.SLEEP_SNORING_EPISODE_COUNT, 348),
|
(Measurement.SLEEP_SNORING_EPISODE_COUNT, 348),
|
||||||
(PERSON0, Measurement.SLEEP_TOSLEEP_DURATION_SECONDS, 162.0),
|
(Measurement.SLEEP_TOSLEEP_DURATION_SECONDS, 162.0),
|
||||||
(PERSON0, Measurement.SLEEP_TOWAKEUP_DURATION_SECONDS, 163.0),
|
(Measurement.SLEEP_TOWAKEUP_DURATION_SECONDS, 163.0),
|
||||||
(PERSON0, Measurement.SLEEP_WAKEUP_COUNT, 350),
|
(Measurement.SLEEP_WAKEUP_COUNT, 350),
|
||||||
(PERSON0, Measurement.SLEEP_WAKEUP_DURATION_SECONDS, 176.0),
|
(Measurement.SLEEP_WAKEUP_DURATION_SECONDS, 176.0),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ async def test_sensor_default_enabled_entities(
|
|||||||
await setup_integration()
|
await setup_integration()
|
||||||
entity_registry: EntityRegistry = er.async_get(hass)
|
entity_registry: EntityRegistry = er.async_get(hass)
|
||||||
|
|
||||||
mock = MockWithings(PERSON0)
|
mock = MockWithings()
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.withings.common.ConfigEntryWithingsApi",
|
"homeassistant.components.withings.common.ConfigEntryWithingsApi",
|
||||||
return_value=mock,
|
return_value=mock,
|
||||||
@ -93,31 +93,31 @@ async def test_sensor_default_enabled_entities(
|
|||||||
# Assert entities should exist.
|
# Assert entities should exist.
|
||||||
for attribute in SENSORS:
|
for attribute in SENSORS:
|
||||||
entity_id = await async_get_entity_id(
|
entity_id = await async_get_entity_id(
|
||||||
hass, attribute, PERSON0.user_id, SENSOR_DOMAIN
|
hass, attribute, USER_ID, SENSOR_DOMAIN
|
||||||
)
|
)
|
||||||
assert entity_id
|
assert entity_id
|
||||||
assert entity_registry.async_is_registered(entity_id)
|
assert entity_registry.async_is_registered(entity_id)
|
||||||
resp = await call_webhook(
|
resp = await call_webhook(
|
||||||
hass,
|
hass,
|
||||||
WEBHOOK_ID,
|
WEBHOOK_ID,
|
||||||
{"userid": PERSON0.user_id, "appli": NotifyAppli.SLEEP},
|
{"userid": USER_ID, "appli": NotifyAppli.SLEEP},
|
||||||
client,
|
client,
|
||||||
)
|
)
|
||||||
assert resp.message_code == 0
|
assert resp.message_code == 0
|
||||||
resp = await call_webhook(
|
resp = await call_webhook(
|
||||||
hass,
|
hass,
|
||||||
WEBHOOK_ID,
|
WEBHOOK_ID,
|
||||||
{"userid": PERSON0.user_id, "appli": NotifyAppli.WEIGHT},
|
{"userid": USER_ID, "appli": NotifyAppli.WEIGHT},
|
||||||
client,
|
client,
|
||||||
)
|
)
|
||||||
assert resp.message_code == 0
|
assert resp.message_code == 0
|
||||||
|
|
||||||
assert resp.message_code == 0
|
assert resp.message_code == 0
|
||||||
|
|
||||||
for person, measurement, expected in EXPECTED_DATA:
|
for measurement, expected in EXPECTED_DATA:
|
||||||
attribute = WITHINGS_MEASUREMENTS_MAP[measurement]
|
attribute = WITHINGS_MEASUREMENTS_MAP[measurement]
|
||||||
entity_id = await async_get_entity_id(
|
entity_id = await async_get_entity_id(
|
||||||
hass, attribute, person.user_id, SENSOR_DOMAIN
|
hass, attribute, USER_ID, SENSOR_DOMAIN
|
||||||
)
|
)
|
||||||
state_obj = hass.states.get(entity_id)
|
state_obj = hass.states.get(entity_id)
|
||||||
|
|
||||||
@ -131,11 +131,11 @@ async def test_all_entities(
|
|||||||
"""Test all entities."""
|
"""Test all entities."""
|
||||||
await setup_integration()
|
await setup_integration()
|
||||||
|
|
||||||
mock = MockWithings(PERSON0)
|
mock = MockWithings()
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.withings.common.ConfigEntryWithingsApi",
|
"homeassistant.components.withings.common.ConfigEntryWithingsApi",
|
||||||
return_value=mock,
|
return_value=mock,
|
||||||
):
|
):
|
||||||
for sensor in SENSORS:
|
for sensor in SENSORS:
|
||||||
entity_id = await async_get_entity_id(hass, sensor, 12345, SENSOR_DOMAIN)
|
entity_id = await async_get_entity_id(hass, sensor, USER_ID, SENSOR_DOMAIN)
|
||||||
assert hass.states.get(entity_id) == snapshot
|
assert hass.states.get(entity_id) == snapshot
|
||||||
|
Loading…
x
Reference in New Issue
Block a user