mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
Add more test coverage for fitbit sensors (#100776)
This commit is contained in:
parent
451c085587
commit
ae29ddee74
@ -104,13 +104,19 @@ async def mock_sensor_platform_setup(
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture(name="profile_id")
|
@pytest.fixture(name="profile_id")
|
||||||
async def mock_profile_id() -> str:
|
def mock_profile_id() -> str:
|
||||||
"""Fixture for the profile id returned from the API response."""
|
"""Fixture for the profile id returned from the API response."""
|
||||||
return PROFILE_USER_ID
|
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", autouse=True)
|
@pytest.fixture(name="profile", autouse=True)
|
||||||
async def mock_profile(requests_mock: Mocker, profile_id: str) -> None:
|
def mock_profile(requests_mock: Mocker, profile_id: str, profile_locale: str) -> None:
|
||||||
"""Fixture to setup fake requests made to Fitbit API during config flow."""
|
"""Fixture to setup fake requests made to Fitbit API during config flow."""
|
||||||
requests_mock.register_uri(
|
requests_mock.register_uri(
|
||||||
"GET",
|
"GET",
|
||||||
@ -120,20 +126,20 @@ async def mock_profile(requests_mock: Mocker, profile_id: str) -> None:
|
|||||||
"user": {
|
"user": {
|
||||||
"encodedId": profile_id,
|
"encodedId": profile_id,
|
||||||
"fullName": "My name",
|
"fullName": "My name",
|
||||||
"locale": "en_US",
|
"locale": profile_locale,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(name="devices_response")
|
@pytest.fixture(name="devices_response")
|
||||||
async def mock_device_response() -> list[dict[str, Any]]:
|
def mock_device_response() -> list[dict[str, Any]]:
|
||||||
"""Return the list of devices."""
|
"""Return the list of devices."""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
async def mock_devices(requests_mock: Mocker, devices_response: dict[str, Any]) -> None:
|
def mock_devices(requests_mock: Mocker, devices_response: dict[str, Any]) -> None:
|
||||||
"""Fixture to setup fake device responses."""
|
"""Fixture to setup fake device responses."""
|
||||||
requests_mock.register_uri(
|
requests_mock.register_uri(
|
||||||
"GET",
|
"GET",
|
||||||
@ -151,7 +157,7 @@ def timeseries_response(resource: str, value: str) -> dict[str, Any]:
|
|||||||
|
|
||||||
|
|
||||||
@pytest.fixture(name="register_timeseries")
|
@pytest.fixture(name="register_timeseries")
|
||||||
async def mock_register_timeseries(
|
def mock_register_timeseries(
|
||||||
requests_mock: Mocker,
|
requests_mock: Mocker,
|
||||||
) -> Callable[[str, dict[str, Any]], None]:
|
) -> Callable[[str, dict[str, Any]], None]:
|
||||||
"""Fixture to setup fake timeseries API responses."""
|
"""Fixture to setup fake timeseries API responses."""
|
||||||
|
280
tests/components/fitbit/snapshots/test_sensor.ambr
Normal file
280
tests/components/fitbit/snapshots/test_sensor.ambr
Normal file
@ -0,0 +1,280 @@
|
|||||||
|
# serializer version: 1
|
||||||
|
# name: test_sensors[monitored_resources0-sensor.activity_calories-activities/activityCalories-135]
|
||||||
|
tuple(
|
||||||
|
'135',
|
||||||
|
ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by Fitbit.com',
|
||||||
|
'friendly_name': 'Activity Calories',
|
||||||
|
'icon': 'mdi:fire',
|
||||||
|
'unit_of_measurement': 'cal',
|
||||||
|
}),
|
||||||
|
'fitbit-api-user-id-1_activities/activityCalories',
|
||||||
|
)
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[monitored_resources1-sensor.calories-activities/calories-139]
|
||||||
|
tuple(
|
||||||
|
'139',
|
||||||
|
ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by Fitbit.com',
|
||||||
|
'friendly_name': 'Calories',
|
||||||
|
'icon': 'mdi:fire',
|
||||||
|
'unit_of_measurement': 'cal',
|
||||||
|
}),
|
||||||
|
'fitbit-api-user-id-1_activities/calories',
|
||||||
|
)
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[monitored_resources10-sensor.steps-activities/steps-5600]
|
||||||
|
tuple(
|
||||||
|
'5600',
|
||||||
|
ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by Fitbit.com',
|
||||||
|
'friendly_name': 'Steps',
|
||||||
|
'icon': 'mdi:walk',
|
||||||
|
'unit_of_measurement': 'steps',
|
||||||
|
}),
|
||||||
|
'fitbit-api-user-id-1_activities/steps',
|
||||||
|
)
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[monitored_resources11-sensor.weight-body/weight-175]
|
||||||
|
tuple(
|
||||||
|
'175.0',
|
||||||
|
ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by Fitbit.com',
|
||||||
|
'device_class': 'weight',
|
||||||
|
'friendly_name': 'Weight',
|
||||||
|
'icon': 'mdi:human',
|
||||||
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
|
'unit_of_measurement': <UnitOfMass.KILOGRAMS: 'kg'>,
|
||||||
|
}),
|
||||||
|
'fitbit-api-user-id-1_body/weight',
|
||||||
|
)
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[monitored_resources12-sensor.body_fat-body/fat-18]
|
||||||
|
tuple(
|
||||||
|
'18.0',
|
||||||
|
ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by Fitbit.com',
|
||||||
|
'friendly_name': 'Body Fat',
|
||||||
|
'icon': 'mdi:human',
|
||||||
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
|
'unit_of_measurement': '%',
|
||||||
|
}),
|
||||||
|
'fitbit-api-user-id-1_body/fat',
|
||||||
|
)
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[monitored_resources13-sensor.bmi-body/bmi-23.7]
|
||||||
|
tuple(
|
||||||
|
'23.7',
|
||||||
|
ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by Fitbit.com',
|
||||||
|
'friendly_name': 'BMI',
|
||||||
|
'icon': 'mdi:human',
|
||||||
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
|
'unit_of_measurement': 'BMI',
|
||||||
|
}),
|
||||||
|
'fitbit-api-user-id-1_body/bmi',
|
||||||
|
)
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[monitored_resources14-sensor.awakenings_count-sleep/awakeningsCount-7]
|
||||||
|
tuple(
|
||||||
|
'7',
|
||||||
|
ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by Fitbit.com',
|
||||||
|
'friendly_name': 'Awakenings Count',
|
||||||
|
'icon': 'mdi:sleep',
|
||||||
|
'unit_of_measurement': 'times awaken',
|
||||||
|
}),
|
||||||
|
'fitbit-api-user-id-1_sleep/awakeningsCount',
|
||||||
|
)
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[monitored_resources15-sensor.sleep_efficiency-sleep/efficiency-80]
|
||||||
|
tuple(
|
||||||
|
'80',
|
||||||
|
ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by Fitbit.com',
|
||||||
|
'friendly_name': 'Sleep Efficiency',
|
||||||
|
'icon': 'mdi:sleep',
|
||||||
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
|
'unit_of_measurement': '%',
|
||||||
|
}),
|
||||||
|
'fitbit-api-user-id-1_sleep/efficiency',
|
||||||
|
)
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[monitored_resources16-sensor.minutes_after_wakeup-sleep/minutesAfterWakeup-17]
|
||||||
|
tuple(
|
||||||
|
'17',
|
||||||
|
ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by Fitbit.com',
|
||||||
|
'device_class': 'duration',
|
||||||
|
'friendly_name': 'Minutes After Wakeup',
|
||||||
|
'icon': 'mdi:sleep',
|
||||||
|
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
|
||||||
|
}),
|
||||||
|
'fitbit-api-user-id-1_sleep/minutesAfterWakeup',
|
||||||
|
)
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[monitored_resources17-sensor.sleep_minutes_asleep-sleep/minutesAsleep-360]
|
||||||
|
tuple(
|
||||||
|
'360',
|
||||||
|
ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by Fitbit.com',
|
||||||
|
'device_class': 'duration',
|
||||||
|
'friendly_name': 'Sleep Minutes Asleep',
|
||||||
|
'icon': 'mdi:sleep',
|
||||||
|
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
|
||||||
|
}),
|
||||||
|
'fitbit-api-user-id-1_sleep/minutesAsleep',
|
||||||
|
)
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[monitored_resources18-sensor.sleep_minutes_awake-sleep/minutesAwake-35]
|
||||||
|
tuple(
|
||||||
|
'35',
|
||||||
|
ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by Fitbit.com',
|
||||||
|
'device_class': 'duration',
|
||||||
|
'friendly_name': 'Sleep Minutes Awake',
|
||||||
|
'icon': 'mdi:sleep',
|
||||||
|
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
|
||||||
|
}),
|
||||||
|
'fitbit-api-user-id-1_sleep/minutesAwake',
|
||||||
|
)
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[monitored_resources19-sensor.sleep_minutes_to_fall_asleep-sleep/minutesToFallAsleep-35]
|
||||||
|
tuple(
|
||||||
|
'35',
|
||||||
|
ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by Fitbit.com',
|
||||||
|
'device_class': 'duration',
|
||||||
|
'friendly_name': 'Sleep Minutes to Fall Asleep',
|
||||||
|
'icon': 'mdi:sleep',
|
||||||
|
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
|
||||||
|
}),
|
||||||
|
'fitbit-api-user-id-1_sleep/minutesToFallAsleep',
|
||||||
|
)
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[monitored_resources2-sensor.distance-activities/distance-12.7]
|
||||||
|
tuple(
|
||||||
|
'12.70',
|
||||||
|
ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by Fitbit.com',
|
||||||
|
'device_class': 'distance',
|
||||||
|
'friendly_name': 'Distance',
|
||||||
|
'icon': 'mdi:map-marker',
|
||||||
|
'unit_of_measurement': <UnitOfLength.KILOMETERS: 'km'>,
|
||||||
|
}),
|
||||||
|
'fitbit-api-user-id-1_activities/distance',
|
||||||
|
)
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[monitored_resources20-sensor.sleep_start_time-sleep/startTime-2020-01-27T00:17:30.000]
|
||||||
|
tuple(
|
||||||
|
'2020-01-27T00:17:30.000',
|
||||||
|
ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by Fitbit.com',
|
||||||
|
'friendly_name': 'Sleep Start Time',
|
||||||
|
'icon': 'mdi:clock',
|
||||||
|
}),
|
||||||
|
'fitbit-api-user-id-1_sleep/startTime',
|
||||||
|
)
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[monitored_resources21-sensor.sleep_time_in_bed-sleep/timeInBed-462]
|
||||||
|
tuple(
|
||||||
|
'462',
|
||||||
|
ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by Fitbit.com',
|
||||||
|
'device_class': 'duration',
|
||||||
|
'friendly_name': 'Sleep Time in Bed',
|
||||||
|
'icon': 'mdi:hotel',
|
||||||
|
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
|
||||||
|
}),
|
||||||
|
'fitbit-api-user-id-1_sleep/timeInBed',
|
||||||
|
)
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[monitored_resources3-sensor.elevation-activities/elevation-7600.24]
|
||||||
|
tuple(
|
||||||
|
'7600.24',
|
||||||
|
ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by Fitbit.com',
|
||||||
|
'device_class': 'distance',
|
||||||
|
'friendly_name': 'Elevation',
|
||||||
|
'icon': 'mdi:walk',
|
||||||
|
'unit_of_measurement': <UnitOfLength.METERS: 'm'>,
|
||||||
|
}),
|
||||||
|
'fitbit-api-user-id-1_activities/elevation',
|
||||||
|
)
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[monitored_resources4-sensor.floors-activities/floors-8]
|
||||||
|
tuple(
|
||||||
|
'8',
|
||||||
|
ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by Fitbit.com',
|
||||||
|
'friendly_name': 'Floors',
|
||||||
|
'icon': 'mdi:walk',
|
||||||
|
'unit_of_measurement': 'floors',
|
||||||
|
}),
|
||||||
|
'fitbit-api-user-id-1_activities/floors',
|
||||||
|
)
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[monitored_resources5-sensor.resting_heart_rate-activities/heart-api_value5]
|
||||||
|
tuple(
|
||||||
|
'76',
|
||||||
|
ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by Fitbit.com',
|
||||||
|
'friendly_name': 'Resting Heart Rate',
|
||||||
|
'icon': 'mdi:heart-pulse',
|
||||||
|
'unit_of_measurement': 'bpm',
|
||||||
|
}),
|
||||||
|
'fitbit-api-user-id-1_activities/heart',
|
||||||
|
)
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[monitored_resources6-sensor.minutes_fairly_active-activities/minutesFairlyActive-35]
|
||||||
|
tuple(
|
||||||
|
'35',
|
||||||
|
ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by Fitbit.com',
|
||||||
|
'device_class': 'duration',
|
||||||
|
'friendly_name': 'Minutes Fairly Active',
|
||||||
|
'icon': 'mdi:walk',
|
||||||
|
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
|
||||||
|
}),
|
||||||
|
'fitbit-api-user-id-1_activities/minutesFairlyActive',
|
||||||
|
)
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[monitored_resources7-sensor.minutes_lightly_active-activities/minutesLightlyActive-95]
|
||||||
|
tuple(
|
||||||
|
'95',
|
||||||
|
ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by Fitbit.com',
|
||||||
|
'device_class': 'duration',
|
||||||
|
'friendly_name': 'Minutes Lightly Active',
|
||||||
|
'icon': 'mdi:walk',
|
||||||
|
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
|
||||||
|
}),
|
||||||
|
'fitbit-api-user-id-1_activities/minutesLightlyActive',
|
||||||
|
)
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[monitored_resources8-sensor.minutes_sedentary-activities/minutesSedentary-18]
|
||||||
|
tuple(
|
||||||
|
'18',
|
||||||
|
ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by Fitbit.com',
|
||||||
|
'device_class': 'duration',
|
||||||
|
'friendly_name': 'Minutes Sedentary',
|
||||||
|
'icon': 'mdi:seat-recline-normal',
|
||||||
|
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
|
||||||
|
}),
|
||||||
|
'fitbit-api-user-id-1_activities/minutesSedentary',
|
||||||
|
)
|
||||||
|
# ---
|
||||||
|
# name: test_sensors[monitored_resources9-sensor.minutes_very_active-activities/minutesVeryActive-20]
|
||||||
|
tuple(
|
||||||
|
'20',
|
||||||
|
ReadOnlyDict({
|
||||||
|
'attribution': 'Data provided by Fitbit.com',
|
||||||
|
'device_class': 'duration',
|
||||||
|
'friendly_name': 'Minutes Very Active',
|
||||||
|
'icon': 'mdi:run',
|
||||||
|
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
|
||||||
|
}),
|
||||||
|
'fitbit-api-user-id-1_activities/minutesVeryActive',
|
||||||
|
)
|
||||||
|
# ---
|
@ -5,10 +5,12 @@ from collections.abc import Awaitable, Callable
|
|||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from syrupy.assertion import SnapshotAssertion
|
||||||
|
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import entity_registry as er
|
||||||
|
|
||||||
from .conftest import timeseries_response
|
from .conftest import PROFILE_USER_ID, timeseries_response
|
||||||
|
|
||||||
DEVICE_RESPONSE_CHARGE_2 = {
|
DEVICE_RESPONSE_CHARGE_2 = {
|
||||||
"battery": "Medium",
|
"battery": "Medium",
|
||||||
@ -31,30 +33,169 @@ DEVICE_RESPONSE_ARIA_AIR = {
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"monitored_resources",
|
(
|
||||||
[["activities/steps"]],
|
"monitored_resources",
|
||||||
|
"entity_id",
|
||||||
|
"api_resource",
|
||||||
|
"api_value",
|
||||||
|
),
|
||||||
|
[
|
||||||
|
(
|
||||||
|
["activities/activityCalories"],
|
||||||
|
"sensor.activity_calories",
|
||||||
|
"activities/activityCalories",
|
||||||
|
"135",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
["activities/calories"],
|
||||||
|
"sensor.calories",
|
||||||
|
"activities/calories",
|
||||||
|
"139",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
["activities/distance"],
|
||||||
|
"sensor.distance",
|
||||||
|
"activities/distance",
|
||||||
|
"12.7",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
["activities/elevation"],
|
||||||
|
"sensor.elevation",
|
||||||
|
"activities/elevation",
|
||||||
|
"7600.24",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
["activities/floors"],
|
||||||
|
"sensor.floors",
|
||||||
|
"activities/floors",
|
||||||
|
"8",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
["activities/heart"],
|
||||||
|
"sensor.resting_heart_rate",
|
||||||
|
"activities/heart",
|
||||||
|
{"restingHeartRate": 76},
|
||||||
|
),
|
||||||
|
(
|
||||||
|
["activities/minutesFairlyActive"],
|
||||||
|
"sensor.minutes_fairly_active",
|
||||||
|
"activities/minutesFairlyActive",
|
||||||
|
35,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
["activities/minutesLightlyActive"],
|
||||||
|
"sensor.minutes_lightly_active",
|
||||||
|
"activities/minutesLightlyActive",
|
||||||
|
95,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
["activities/minutesSedentary"],
|
||||||
|
"sensor.minutes_sedentary",
|
||||||
|
"activities/minutesSedentary",
|
||||||
|
18,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
["activities/minutesVeryActive"],
|
||||||
|
"sensor.minutes_very_active",
|
||||||
|
"activities/minutesVeryActive",
|
||||||
|
20,
|
||||||
|
),
|
||||||
|
(
|
||||||
|
["activities/steps"],
|
||||||
|
"sensor.steps",
|
||||||
|
"activities/steps",
|
||||||
|
"5600",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
["body/weight"],
|
||||||
|
"sensor.weight",
|
||||||
|
"body/weight",
|
||||||
|
"175",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
["body/fat"],
|
||||||
|
"sensor.body_fat",
|
||||||
|
"body/fat",
|
||||||
|
"18",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
["body/bmi"],
|
||||||
|
"sensor.bmi",
|
||||||
|
"body/bmi",
|
||||||
|
"23.7",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
["sleep/awakeningsCount"],
|
||||||
|
"sensor.awakenings_count",
|
||||||
|
"sleep/awakeningsCount",
|
||||||
|
"7",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
["sleep/efficiency"],
|
||||||
|
"sensor.sleep_efficiency",
|
||||||
|
"sleep/efficiency",
|
||||||
|
"80",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
["sleep/minutesAfterWakeup"],
|
||||||
|
"sensor.minutes_after_wakeup",
|
||||||
|
"sleep/minutesAfterWakeup",
|
||||||
|
"17",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
["sleep/minutesAsleep"],
|
||||||
|
"sensor.sleep_minutes_asleep",
|
||||||
|
"sleep/minutesAsleep",
|
||||||
|
"360",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
["sleep/minutesAwake"],
|
||||||
|
"sensor.sleep_minutes_awake",
|
||||||
|
"sleep/minutesAwake",
|
||||||
|
"35",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
["sleep/minutesToFallAsleep"],
|
||||||
|
"sensor.sleep_minutes_to_fall_asleep",
|
||||||
|
"sleep/minutesToFallAsleep",
|
||||||
|
"35",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
["sleep/startTime"],
|
||||||
|
"sensor.sleep_start_time",
|
||||||
|
"sleep/startTime",
|
||||||
|
"2020-01-27T00:17:30.000",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
["sleep/timeInBed"],
|
||||||
|
"sensor.sleep_time_in_bed",
|
||||||
|
"sleep/timeInBed",
|
||||||
|
"462",
|
||||||
|
),
|
||||||
|
],
|
||||||
)
|
)
|
||||||
async def test_step_sensor(
|
async def test_sensors(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
sensor_platform_setup: Callable[[], Awaitable[bool]],
|
sensor_platform_setup: Callable[[], Awaitable[bool]],
|
||||||
register_timeseries: Callable[[str, dict[str, Any]], None],
|
register_timeseries: Callable[[str, dict[str, Any]], None],
|
||||||
|
entity_registry: er.EntityRegistry,
|
||||||
|
entity_id: str,
|
||||||
|
api_resource: str,
|
||||||
|
api_value: str,
|
||||||
|
snapshot: SnapshotAssertion,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test battery level sensor."""
|
"""Test sensors."""
|
||||||
|
|
||||||
register_timeseries(
|
register_timeseries(
|
||||||
"activities/steps", timeseries_response("activities-steps", "5600")
|
api_resource, timeseries_response(api_resource.replace("/", "-"), api_value)
|
||||||
)
|
)
|
||||||
await sensor_platform_setup()
|
await sensor_platform_setup()
|
||||||
|
|
||||||
state = hass.states.get("sensor.steps")
|
state = hass.states.get(entity_id)
|
||||||
assert state
|
assert state
|
||||||
assert state.state == "5600"
|
entry = entity_registry.async_get(entity_id)
|
||||||
assert state.attributes == {
|
assert entry
|
||||||
"attribution": "Data provided by Fitbit.com",
|
assert (state.state, state.attributes, entry.unique_id) == snapshot
|
||||||
"friendly_name": "Steps",
|
|
||||||
"icon": "mdi:walk",
|
|
||||||
"unit_of_measurement": "steps",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
@ -64,6 +205,7 @@ async def test_step_sensor(
|
|||||||
async def test_device_battery_level(
|
async def test_device_battery_level(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
sensor_platform_setup: Callable[[], Awaitable[bool]],
|
sensor_platform_setup: Callable[[], Awaitable[bool]],
|
||||||
|
entity_registry: er.EntityRegistry,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test battery level sensor for devices."""
|
"""Test battery level sensor for devices."""
|
||||||
|
|
||||||
@ -80,6 +222,10 @@ async def test_device_battery_level(
|
|||||||
"type": "tracker",
|
"type": "tracker",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entry = entity_registry.async_get("sensor.charge_2_battery")
|
||||||
|
assert entry
|
||||||
|
assert entry.unique_id == f"{PROFILE_USER_ID}_devices/battery_816713257"
|
||||||
|
|
||||||
state = hass.states.get("sensor.aria_air_battery")
|
state = hass.states.get("sensor.aria_air_battery")
|
||||||
assert state
|
assert state
|
||||||
assert state.state == "High"
|
assert state.state == "High"
|
||||||
@ -90,3 +236,81 @@ async def test_device_battery_level(
|
|||||||
"model": "Aria Air",
|
"model": "Aria Air",
|
||||||
"type": "scale",
|
"type": "scale",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entity_registry = er.async_get(hass)
|
||||||
|
entry = entity_registry.async_get("sensor.aria_air_battery")
|
||||||
|
assert entry
|
||||||
|
assert entry.unique_id == f"{PROFILE_USER_ID}_devices/battery_016713257"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("monitored_resources", "profile_locale", "expected_unit"),
|
||||||
|
[
|
||||||
|
(["body/weight"], "en_US", "kg"),
|
||||||
|
(["body/weight"], "en_GB", "st"),
|
||||||
|
(["body/weight"], "es_ES", "kg"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_profile_local(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
sensor_platform_setup: Callable[[], Awaitable[bool]],
|
||||||
|
register_timeseries: Callable[[str, dict[str, Any]], None],
|
||||||
|
expected_unit: str,
|
||||||
|
) -> None:
|
||||||
|
"""Test the fitbit profile locale impact on unit of measure."""
|
||||||
|
|
||||||
|
register_timeseries("body/weight", timeseries_response("body-weight", "175"))
|
||||||
|
await sensor_platform_setup()
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.weight")
|
||||||
|
assert state
|
||||||
|
assert state.attributes.get("unit_of_measurement") == expected_unit
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("sensor_platform_config", "api_response", "expected_state"),
|
||||||
|
[
|
||||||
|
(
|
||||||
|
{"clock_format": "12H", "monitored_resources": ["sleep/startTime"]},
|
||||||
|
"17:05",
|
||||||
|
"5:05 PM",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{"clock_format": "12H", "monitored_resources": ["sleep/startTime"]},
|
||||||
|
"5:05",
|
||||||
|
"5:05 AM",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{"clock_format": "12H", "monitored_resources": ["sleep/startTime"]},
|
||||||
|
"00:05",
|
||||||
|
"12:05 AM",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{"clock_format": "24H", "monitored_resources": ["sleep/startTime"]},
|
||||||
|
"17:05",
|
||||||
|
"17:05",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
{"clock_format": "12H", "monitored_resources": ["sleep/startTime"]},
|
||||||
|
"",
|
||||||
|
"-",
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_sleep_time_clock_format(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
sensor_platform_setup: Callable[[], Awaitable[bool]],
|
||||||
|
register_timeseries: Callable[[str, dict[str, Any]], None],
|
||||||
|
api_response: str,
|
||||||
|
expected_state: str,
|
||||||
|
) -> None:
|
||||||
|
"""Test the clock format configuration."""
|
||||||
|
|
||||||
|
register_timeseries(
|
||||||
|
"sleep/startTime", timeseries_response("sleep-startTime", api_response)
|
||||||
|
)
|
||||||
|
await sensor_platform_setup()
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.sleep_start_time")
|
||||||
|
assert state
|
||||||
|
assert state.state == expected_state
|
||||||
|
Loading…
x
Reference in New Issue
Block a user