From 637941df4dc271e93110cb846303161f06acd15a Mon Sep 17 00:00:00 2001 From: Aaron Bach Date: Sun, 14 May 2023 10:07:15 -0600 Subject: [PATCH] Fix a series of bugs due to Notion API changes (#93039) * Fix a series of bugs due to Notion API changes * Simplify * Reduce blast radius * Reduce blast radius * Fix tests --- homeassistant/components/notion/__init__.py | 96 ++++++++++------ .../components/notion/binary_sensor.py | 27 ++--- .../components/notion/diagnostics.py | 2 + homeassistant/components/notion/manifest.json | 2 +- homeassistant/components/notion/sensor.py | 35 +++--- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/notion/conftest.py | 30 +++-- .../notion/fixtures/bridge_data.json | 98 ++++++++-------- .../notion/fixtures/listener_data.json | 106 +++++++++--------- .../notion/fixtures/sensor_data.json | 70 ++++++------ .../fixtures/user_preferences_data.json | 10 ++ tests/components/notion/test_diagnostics.py | 24 ++-- 13 files changed, 283 insertions(+), 221 deletions(-) create mode 100644 tests/components/notion/fixtures/user_preferences_data.json diff --git a/homeassistant/components/notion/__init__.py b/homeassistant/components/notion/__init__.py index 5e55496fc54..ad228f08a4b 100644 --- a/homeassistant/components/notion/__init__.py +++ b/homeassistant/components/notion/__init__.py @@ -2,7 +2,7 @@ from __future__ import annotations import asyncio -from dataclasses import dataclass, field, fields +from dataclasses import dataclass, field from datetime import timedelta import logging import traceback @@ -10,9 +10,16 @@ from typing import Any from uuid import UUID from aionotion import async_get_client -from aionotion.bridge.models import Bridge +from aionotion.bridge.models import Bridge, BridgeAllResponse from aionotion.errors import InvalidCredentialsError, NotionError -from aionotion.sensor.models import Listener, ListenerKind, Sensor +from aionotion.sensor.models import ( + Listener, + ListenerAllResponse, + ListenerKind, + Sensor, + SensorAllResponse, +) +from aionotion.user.models import UserPreferences, UserPreferencesResponse from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform @@ -51,6 +58,11 @@ PLATFORMS = [Platform.BINARY_SENSOR, Platform.SENSOR] ATTR_SYSTEM_MODE = "system_mode" ATTR_SYSTEM_NAME = "system_name" +DATA_BRIDGES = "bridges" +DATA_LISTENERS = "listeners" +DATA_SENSORS = "sensors" +DATA_USER_PREFERENCES = "user_preferences" + DEFAULT_SCAN_INTERVAL = timedelta(minutes=1) CONFIG_SCHEMA = cv.removed(DOMAIN, raise_if_present=False) @@ -84,6 +96,9 @@ def is_uuid(value: str) -> bool: class NotionData: """Define a manager class for Notion data.""" + hass: HomeAssistant + entry: ConfigEntry + # Define a dict of bridges, indexed by bridge ID (an integer): bridges: dict[int, Bridge] = field(default_factory=dict) @@ -93,12 +108,40 @@ class NotionData: # Define a dict of sensors, indexed by sensor UUID (a string): sensors: dict[str, Sensor] = field(default_factory=dict) + # Define a user preferences response object: + user_preferences: UserPreferences | None = field(default=None) + + def update_data_from_response( + self, + response: BridgeAllResponse + | ListenerAllResponse + | SensorAllResponse + | UserPreferencesResponse, + ) -> None: + """Update data from an aionotion response.""" + if isinstance(response, BridgeAllResponse): + for bridge in response.bridges: + # If a new bridge is discovered, register it: + if bridge.id not in self.bridges: + _async_register_new_bridge(self.hass, self.entry, bridge) + self.bridges[bridge.id] = bridge + elif isinstance(response, ListenerAllResponse): + self.listeners = {listener.id: listener for listener in response.listeners} + elif isinstance(response, SensorAllResponse): + self.sensors = {sensor.uuid: sensor for sensor in response.sensors} + elif isinstance(response, UserPreferencesResponse): + self.user_preferences = response.user_preferences + def asdict(self) -> dict[str, Any]: """Represent this dataclass (and its Pydantic contents) as a dict.""" - return { - field.name: [obj.dict() for obj in getattr(self, field.name).values()] - for field in fields(self) + data: dict[str, Any] = { + DATA_BRIDGES: [bridge.dict() for bridge in self.bridges.values()], + DATA_LISTENERS: [listener.dict() for listener in self.listeners.values()], + DATA_SENSORS: [sensor.dict() for sensor in self.sensors.values()], } + if self.user_preferences: + data[DATA_USER_PREFERENCES] = self.user_preferences.dict() + return data async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: @@ -121,11 +164,12 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def async_update() -> NotionData: """Get the latest data from the Notion API.""" - data = NotionData() + data = NotionData(hass=hass, entry=entry) tasks = { - "bridges": client.bridge.async_all(), - "listeners": client.sensor.async_listeners(), - "sensors": client.sensor.async_all(), + DATA_BRIDGES: client.bridge.async_all(), + DATA_LISTENERS: client.sensor.async_listeners(), + DATA_SENSORS: client.sensor.async_all(), + DATA_USER_PREFERENCES: client.user.async_preferences(), } results = await asyncio.gather(*tasks.values(), return_exceptions=True) @@ -145,16 +189,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: f"There was an unknown error while updating {attr}: {result}" ) from result - for item in result: - if attr == "bridges": - # If a new bridge is discovered, register it: - if item.id not in data.bridges: - _async_register_new_bridge(hass, item, entry) - data.bridges[item.id] = item - elif attr == "listeners": - data.listeners[item.id] = item - else: - data.sensors[item.uuid] = item + data.update_data_from_response(result) return data @@ -216,7 +251,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: @callback def _async_register_new_bridge( - hass: HomeAssistant, bridge: Bridge, entry: ConfigEntry + hass: HomeAssistant, entry: ConfigEntry, bridge: Bridge ) -> None: """Register a new bridge.""" if name := bridge.name: @@ -279,6 +314,11 @@ class NotionEntity(CoordinatorEntity[DataUpdateCoordinator[NotionData]]): and self._listener_id in self.coordinator.data.listeners ) + @property + def listener(self) -> Listener: + """Return the listener related to this entity.""" + return self.coordinator.data.listeners[self._listener_id] + @callback def _async_update_bridge_id(self) -> None: """Update the entity's bridge ID if it has changed. @@ -310,21 +350,9 @@ class NotionEntity(CoordinatorEntity[DataUpdateCoordinator[NotionData]]): this_device.id, via_device_id=bridge_device.id ) - @callback - def _async_update_from_latest_data(self) -> None: - """Update the entity from the latest data.""" - raise NotImplementedError - @callback def _handle_coordinator_update(self) -> None: """Respond to a DataUpdateCoordinator update.""" if self._listener_id in self.coordinator.data.listeners: self._async_update_bridge_id() - self._async_update_from_latest_data() - - self.async_write_ha_state() - - async def async_added_to_hass(self) -> None: - """Handle entity which will be added.""" - await super().async_added_to_hass() - self._async_update_from_latest_data() + super()._handle_coordinator_update() diff --git a/homeassistant/components/notion/binary_sensor.py b/homeassistant/components/notion/binary_sensor.py index bd2de303d2d..f70af18c3e1 100644 --- a/homeassistant/components/notion/binary_sensor.py +++ b/homeassistant/components/notion/binary_sensor.py @@ -13,7 +13,7 @@ from homeassistant.components.binary_sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory -from homeassistant.core import HomeAssistant, callback +from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from . import NotionEntity @@ -37,7 +37,7 @@ from .model import NotionEntityDescriptionMixin class NotionBinarySensorDescriptionMixin: """Define an entity description mixin for binary and regular sensors.""" - on_state: Literal["alarm", "critical", "leak", "not_missing", "open"] + on_state: Literal["alarm", "leak", "low", "not_missing", "open"] @dataclass @@ -56,7 +56,7 @@ BINARY_SENSOR_DESCRIPTIONS = ( device_class=BinarySensorDeviceClass.BATTERY, entity_category=EntityCategory.DIAGNOSTIC, listener_kind=ListenerKind.BATTERY, - on_state="critical", + on_state="low", ), NotionBinarySensorDescription( key=SENSOR_DOOR, @@ -146,17 +146,10 @@ class NotionBinarySensor(NotionEntity, BinarySensorEntity): entity_description: NotionBinarySensorDescription - @callback - def _async_update_from_latest_data(self) -> None: - """Fetch new state data for the sensor.""" - listener = self.coordinator.data.listeners[self._listener_id] - - if listener.status.trigger_value: - state = listener.status.trigger_value - elif listener.insights.primary.value: - state = listener.insights.primary.value - else: - LOGGER.warning("Unknown listener structure: %s", listener) - state = None - - self._attr_is_on = self.entity_description.on_state == state + @property + def is_on(self) -> bool | None: + """Return true if the binary sensor is on.""" + if not self.listener.insights.primary.value: + LOGGER.warning("Unknown listener structure: %s", self.listener.dict()) + return False + return self.listener.insights.primary.value == self.entity_description.on_state diff --git a/homeassistant/components/notion/diagnostics.py b/homeassistant/components/notion/diagnostics.py index 06100580b39..86b84760016 100644 --- a/homeassistant/components/notion/diagnostics.py +++ b/homeassistant/components/notion/diagnostics.py @@ -16,6 +16,7 @@ CONF_DEVICE_KEY = "device_key" CONF_HARDWARE_ID = "hardware_id" CONF_LAST_BRIDGE_HARDWARE_ID = "last_bridge_hardware_id" CONF_TITLE = "title" +CONF_USER_ID = "user_id" TO_REDACT = { CONF_DEVICE_KEY, @@ -27,6 +28,7 @@ TO_REDACT = { CONF_TITLE, CONF_UNIQUE_ID, CONF_USERNAME, + CONF_USER_ID, } diff --git a/homeassistant/components/notion/manifest.json b/homeassistant/components/notion/manifest.json index f0952089ba8..168899c38e0 100644 --- a/homeassistant/components/notion/manifest.json +++ b/homeassistant/components/notion/manifest.json @@ -7,5 +7,5 @@ "integration_type": "hub", "iot_class": "cloud_polling", "loggers": ["aionotion"], - "requirements": ["aionotion==2023.05.1"] + "requirements": ["aionotion==2023.05.4"] } diff --git a/homeassistant/components/notion/sensor.py b/homeassistant/components/notion/sensor.py index f4e6e7cc322..e6ff3eaab69 100644 --- a/homeassistant/components/notion/sensor.py +++ b/homeassistant/components/notion/sensor.py @@ -11,11 +11,11 @@ from homeassistant.components.sensor import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfTemperature -from homeassistant.core import HomeAssistant, callback +from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from . import NotionEntity -from .const import DOMAIN, LOGGER, SENSOR_TEMPERATURE +from .const import DOMAIN, SENSOR_TEMPERATURE from .model import NotionEntityDescriptionMixin @@ -63,15 +63,24 @@ async def async_setup_entry( class NotionSensor(NotionEntity, SensorEntity): """Define a Notion sensor.""" - @callback - def _async_update_from_latest_data(self) -> None: - """Fetch new state data for the sensor.""" - listener = self.coordinator.data.listeners[self._listener_id] + @property + def native_unit_of_measurement(self) -> str | None: + """Return the unit of measurement of the sensor.""" + if self.listener.listener_kind == ListenerKind.TEMPERATURE: + if not self.coordinator.data.user_preferences: + return None + if self.coordinator.data.user_preferences.celsius_enabled: + return UnitOfTemperature.CELSIUS + return UnitOfTemperature.FAHRENHEIT + return None - if listener.listener_kind == ListenerKind.TEMPERATURE: - self._attr_native_value = round(listener.status.temperature, 1) # type: ignore[attr-defined] - else: - LOGGER.error( - "Unknown listener type for sensor %s", - self.coordinator.data.sensors[self._sensor_id], - ) + @property + def native_value(self) -> str | None: + """Return the value reported by the sensor. + + The Notion API only returns a localized string for temperature (e.g. "70°"); we + simply remove the degree symbol: + """ + if not self.listener.status_localized: + return None + return self.listener.status_localized.state[:-1] diff --git a/requirements_all.txt b/requirements_all.txt index efc89ce66a0..2648aec0b9a 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -223,7 +223,7 @@ aionanoleaf==0.2.1 aionotify==0.2.0 # homeassistant.components.notion -aionotion==2023.05.1 +aionotion==2023.05.4 # homeassistant.components.oncue aiooncue==0.3.4 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 07a71a6a840..5c30dc4da57 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -204,7 +204,7 @@ aiomusiccast==0.14.8 aionanoleaf==0.2.1 # homeassistant.components.notion -aionotion==2023.05.1 +aionotion==2023.05.4 # homeassistant.components.oncue aiooncue==0.3.4 diff --git a/tests/components/notion/conftest.py b/tests/components/notion/conftest.py index 75eeda70300..81d69158e82 100644 --- a/tests/components/notion/conftest.py +++ b/tests/components/notion/conftest.py @@ -3,8 +3,9 @@ from collections.abc import Generator import json from unittest.mock import AsyncMock, Mock, patch -from aionotion.bridge.models import Bridge -from aionotion.sensor.models import Listener, Sensor +from aionotion.bridge.models import BridgeAllResponse +from aionotion.sensor.models import ListenerAllResponse, SensorAllResponse +from aionotion.user.models import UserPreferencesResponse import pytest from homeassistant.components.notion import DOMAIN @@ -27,24 +28,23 @@ def mock_setup_entry() -> Generator[AsyncMock, None, None]: @pytest.fixture(name="client") -def client_fixture(data_bridge, data_listener, data_sensor): +def client_fixture(data_bridge, data_listener, data_sensor, data_user_preferences): """Define a fixture for an aionotion client.""" return Mock( bridge=Mock( - async_all=AsyncMock( - return_value=[Bridge.parse_obj(bridge) for bridge in data_bridge] - ) + async_all=AsyncMock(return_value=BridgeAllResponse.parse_obj(data_bridge)) ), sensor=Mock( - async_all=AsyncMock( - return_value=[Sensor.parse_obj(sensor) for sensor in data_sensor] - ), + async_all=AsyncMock(return_value=SensorAllResponse.parse_obj(data_sensor)), async_listeners=AsyncMock( - return_value=[ - Listener.parse_obj(listener) for listener in data_listener - ] + return_value=ListenerAllResponse.parse_obj(data_listener) ), ), + user=Mock( + async_preferences=AsyncMock( + return_value=UserPreferencesResponse.parse_obj(data_user_preferences) + ) + ), ) @@ -83,6 +83,12 @@ def data_sensor_fixture(): return json.loads(load_fixture("sensor_data.json", "notion")) +@pytest.fixture(name="data_user_preferences", scope="package") +def data_user_preferences_fixture(): + """Define user preferences data.""" + return json.loads(load_fixture("user_preferences_data.json", "notion")) + + @pytest.fixture(name="get_client") def get_client_fixture(client): """Define a fixture to mock the async_get_client method.""" diff --git a/tests/components/notion/fixtures/bridge_data.json b/tests/components/notion/fixtures/bridge_data.json index 008967ece86..05bd8859e7e 100644 --- a/tests/components/notion/fixtures/bridge_data.json +++ b/tests/components/notion/fixtures/bridge_data.json @@ -1,50 +1,52 @@ -[ - { - "id": 12345, - "name": "Bridge 1", - "mode": "home", - "hardware_id": "0x0000000000000000", - "hardware_revision": 4, - "firmware_version": { - "silabs": "1.1.2", - "wifi": "0.121.0", - "wifi_app": "3.3.0" +{ + "base_stations": [ + { + "id": 12345, + "name": "Bridge 1", + "mode": "home", + "hardware_id": "0x0000000000000000", + "hardware_revision": 4, + "firmware_version": { + "silabs": "1.1.2", + "wifi": "0.121.0", + "wifi_app": "3.3.0" + }, + "missing_at": null, + "created_at": "2019-06-27T00:18:44.337Z", + "updated_at": "2023-03-19T03:20:16.061Z", + "system_id": 11111, + "firmware": { + "silabs": "1.1.2", + "wifi": "0.121.0", + "wifi_app": "3.3.0" + }, + "links": { + "system": 11111 + } }, - "missing_at": null, - "created_at": "2019-06-27T00:18:44.337Z", - "updated_at": "2023-03-19T03:20:16.061Z", - "system_id": 11111, - "firmware": { - "silabs": "1.1.2", - "wifi": "0.121.0", - "wifi_app": "3.3.0" - }, - "links": { - "system": 11111 + { + "id": 67890, + "name": "Bridge 2", + "mode": "home", + "hardware_id": "0x0000000000000000", + "hardware_revision": 4, + "firmware_version": { + "wifi": "0.121.0", + "wifi_app": "3.3.0", + "silabs": "1.1.2" + }, + "missing_at": null, + "created_at": "2019-04-30T01:43:50.497Z", + "updated_at": "2023-01-02T19:09:58.251Z", + "system_id": 11111, + "firmware": { + "wifi": "0.121.0", + "wifi_app": "3.3.0", + "silabs": "1.1.2" + }, + "links": { + "system": 11111 + } } - }, - { - "id": 67890, - "name": "Bridge 2", - "mode": "home", - "hardware_id": "0x0000000000000000", - "hardware_revision": 4, - "firmware_version": { - "wifi": "0.121.0", - "wifi_app": "3.3.0", - "silabs": "1.1.2" - }, - "missing_at": null, - "created_at": "2019-04-30T01:43:50.497Z", - "updated_at": "2023-01-02T19:09:58.251Z", - "system_id": 11111, - "firmware": { - "wifi": "0.121.0", - "wifi_app": "3.3.0", - "silabs": "1.1.2" - }, - "links": { - "system": 11111 - } - } -] + ] +} diff --git a/tests/components/notion/fixtures/listener_data.json b/tests/components/notion/fixtures/listener_data.json index bd49aab89db..6d59dde76df 100644 --- a/tests/components/notion/fixtures/listener_data.json +++ b/tests/components/notion/fixtures/listener_data.json @@ -1,55 +1,57 @@ -[ - { - "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "definition_id": 4, - "created_at": "2019-06-28T22:12:49.651Z", - "type": "sensor", - "model_version": "2.1", - "sensor_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "status": { - "trigger_value": "no_leak", - "data_received_at": "2022-03-20T08:00:29.763Z" - }, - "status_localized": { - "state": "No Leak", - "description": "Mar 20 at 2:00am" - }, - "insights": { - "primary": { - "origin": { - "type": "Sensor", - "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" - }, - "value": "no_leak", +{ + "listeners": [ + { + "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "definition_id": 4, + "created_at": "2019-06-28T22:12:49.651Z", + "type": "sensor", + "model_version": "2.1", + "sensor_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "status": { + "trigger_value": "no_leak", "data_received_at": "2022-03-20T08:00:29.763Z" - } + }, + "status_localized": { + "state": "No Leak", + "description": "Mar 20 at 2:00am" + }, + "insights": { + "primary": { + "origin": { + "type": "Sensor", + "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + }, + "value": "no_leak", + "data_received_at": "2022-03-20T08:00:29.763Z" + } + }, + "configuration": {}, + "pro_monitoring_status": "eligible" }, - "configuration": {}, - "pro_monitoring_status": "eligible" - }, - { - "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "definition_id": 7, - "created_at": "2019-07-10T22:40:48.847Z", - "type": "sensor", - "model_version": "3.1", - "sensor_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "status": { - "trigger_value": "no_alarm", - "data_received_at": "2019-06-28T22:12:49.516Z" - }, - "status_localized": { - "state": "No Sound", - "description": "Jun 28 at 4:12pm" - }, - "insights": { - "primary": { - "origin": {}, - "value": "no_alarm", + { + "id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "definition_id": 7, + "created_at": "2019-07-10T22:40:48.847Z", + "type": "sensor", + "model_version": "3.1", + "sensor_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "status": { + "trigger_value": "no_alarm", "data_received_at": "2019-06-28T22:12:49.516Z" - } - }, - "configuration": {}, - "pro_monitoring_status": "eligible" - } -] + }, + "status_localized": { + "state": "No Sound", + "description": "Jun 28 at 4:12pm" + }, + "insights": { + "primary": { + "origin": {}, + "value": "no_alarm", + "data_received_at": "2019-06-28T22:12:49.516Z" + } + }, + "configuration": {}, + "pro_monitoring_status": "eligible" + } + ] +} diff --git a/tests/components/notion/fixtures/sensor_data.json b/tests/components/notion/fixtures/sensor_data.json index e042daf6ddd..9f0d0fe2e03 100644 --- a/tests/components/notion/fixtures/sensor_data.json +++ b/tests/components/notion/fixtures/sensor_data.json @@ -1,34 +1,36 @@ -[ - { - "id": 123456, - "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "user": { - "id": 12345, - "email": "user@email.com" - }, - "bridge": { - "id": 67890, - "hardware_id": "0x0000000000000000" - }, - "last_bridge_hardware_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "name": "Sensor 1", - "location_id": 123456, - "system_id": 12345, - "hardware_id": "0x0000000000000000", - "hardware_revision": 5, - "firmware_version": "1.1.2", - "device_key": "0x0000000000000000", - "encryption_key": true, - "installed_at": "2019-06-28T22:12:51.209Z", - "calibrated_at": "2023-03-07T19:51:56.838Z", - "last_reported_at": "2023-04-19T18:09:40.479Z", - "missing_at": null, - "updated_at": "2023-03-28T13:33:33.801Z", - "created_at": "2019-06-28T22:12:20.256Z", - "signal_strength": 4, - "firmware": { - "status": "valid" - }, - "surface_type": null - } -] +{ + "sensors": [ + { + "id": 123456, + "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "user": { + "id": 12345, + "email": "user@email.com" + }, + "bridge": { + "id": 67890, + "hardware_id": "0x0000000000000000" + }, + "last_bridge_hardware_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + "name": "Sensor 1", + "location_id": 123456, + "system_id": 12345, + "hardware_id": "0x0000000000000000", + "hardware_revision": 5, + "firmware_version": "1.1.2", + "device_key": "0x0000000000000000", + "encryption_key": true, + "installed_at": "2019-06-28T22:12:51.209Z", + "calibrated_at": "2023-03-07T19:51:56.838Z", + "last_reported_at": "2023-04-19T18:09:40.479Z", + "missing_at": null, + "updated_at": "2023-03-28T13:33:33.801Z", + "created_at": "2019-06-28T22:12:20.256Z", + "signal_strength": 4, + "firmware": { + "status": "valid" + }, + "surface_type": null + } + ] +} diff --git a/tests/components/notion/fixtures/user_preferences_data.json b/tests/components/notion/fixtures/user_preferences_data.json new file mode 100644 index 00000000000..6fa603e9d85 --- /dev/null +++ b/tests/components/notion/fixtures/user_preferences_data.json @@ -0,0 +1,10 @@ +{ + "user_preferences": { + "user_id": 12345, + "military_time_enabled": false, + "celsius_enabled": false, + "disconnect_alerts_enabled": true, + "home_away_alerts_enabled": false, + "battery_alerts_enabled": true + } +} diff --git a/tests/components/notion/test_diagnostics.py b/tests/components/notion/test_diagnostics.py index 7062778e812..b59b995b404 100644 --- a/tests/components/notion/test_diagnostics.py +++ b/tests/components/notion/test_diagnostics.py @@ -86,14 +86,6 @@ async def test_entry_diagnostics( "device_type": "sensor", "model_version": "3.1", "sensor_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - "status": { - "trigger_value": "no_alarm", - "data_received_at": "2019-06-28T22:12:49.516000+00:00", - }, - "status_localized": { - "state": "No Sound", - "description": "Jun 28 at 4:12pm", - }, "insights": { "primary": { "origin": {"type": None, "id": None}, @@ -103,6 +95,14 @@ async def test_entry_diagnostics( }, "configuration": {}, "pro_monitoring_status": "eligible", + "status": { + "trigger_value": "no_alarm", + "data_received_at": "2019-06-28T22:12:49.516000+00:00", + }, + "status_localized": { + "state": "No Sound", + "description": "Jun 28 at 4:12pm", + }, } ], "sensors": [ @@ -131,5 +131,13 @@ async def test_entry_diagnostics( "surface_type": None, } ], + "user_preferences": { + "user_id": REDACTED, + "military_time_enabled": False, + "celsius_enabled": False, + "disconnect_alerts_enabled": True, + "home_away_alerts_enabled": False, + "battery_alerts_enabled": True, + }, }, }