Improve myuplink tests to reach full coverage for all modules (#131937)

This commit is contained in:
Åke Strandberg 2024-12-10 12:20:21 +01:00 committed by GitHub
parent 03c6dab143
commit f6621023c2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 5390 additions and 69 deletions

View File

@ -1024,6 +1024,23 @@
"scaleValue": "1",
"zoneId": null
},
{
"category": "F730 CU 3x400V",
"parameterId": "148072r",
"parameterName": "r start diff additional heat",
"parameterUnit": "DM",
"writable": false,
"timestamp": "2024-10-18T09:51:39+00:00",
"value": 700,
"strVal": "700DM",
"smartHomeCategories": [],
"minValue": 100,
"maxValue": 2000,
"stepValue": 10,
"enumValues": [],
"scaleValue": "1",
"zoneId": null
},
{
"category": "F730 CU 3x400V",
"parameterId": "47011",
@ -1040,5 +1057,39 @@
"enumValues": [],
"scaleValue": "1",
"zoneId": null
},
{
"category": "F730 CU 3x400V",
"parameterId": "47007",
"parameterName": "Excluded",
"parameterUnit": "",
"writable": true,
"timestamp": "2024-10-18T09:51:39+00:00",
"value": 1,
"strVal": "1",
"smartHomeCategories": ["sh-indoorSpOffsHeat"],
"minValue": -10,
"maxValue": 10,
"stepValue": 1,
"enumValues": [],
"scaleValue": "1",
"zoneId": null
},
{
"category": "F730 CU 3x400V",
"parameterId": "99000",
"parameterName": "Excluded 2",
"parameterUnit": "",
"writable": true,
"timestamp": "2024-10-18T09:51:39+00:00",
"value": "Hello",
"strVal": "Hello",
"smartHomeCategories": [],
"minValue": "",
"maxValue": "",
"stepValue": 1,
"enumValues": [],
"scaleValue": "1",
"zoneId": null
}
]

View File

@ -0,0 +1,326 @@
# serializer version: 1
# name: test_binary_sensor_states[binary_sensor.gotham_city_alarm-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'binary_sensor',
'entity_category': None,
'entity_id': 'binary_sensor.gotham_city_alarm',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <BinarySensorDeviceClass.PROBLEM: 'problem'>,
'original_icon': None,
'original_name': 'Alarm',
'platform': 'myuplink',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'alarm',
'unique_id': '123456-7890-1234-has_alarm',
'unit_of_measurement': None,
})
# ---
# name: test_binary_sensor_states[binary_sensor.gotham_city_alarm-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'problem',
'friendly_name': 'Gotham City Alarm',
}),
'context': <ANY>,
'entity_id': 'binary_sensor.gotham_city_alarm',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'off',
})
# ---
# name: test_binary_sensor_states[binary_sensor.gotham_city_connectivity-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'binary_sensor',
'entity_category': None,
'entity_id': 'binary_sensor.gotham_city_connectivity',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <BinarySensorDeviceClass.CONNECTIVITY: 'connectivity'>,
'original_icon': None,
'original_name': 'Connectivity',
'platform': 'myuplink',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'robin-r-1234-20240201-123456-aa-bb-cc-dd-ee-ff-connection_state',
'unit_of_measurement': None,
})
# ---
# name: test_binary_sensor_states[binary_sensor.gotham_city_connectivity-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'connectivity',
'friendly_name': 'Gotham City Connectivity',
}),
'context': <ANY>,
'entity_id': 'binary_sensor.gotham_city_connectivity',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'on',
})
# ---
# name: test_binary_sensor_states[binary_sensor.gotham_city_connectivity_2-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'binary_sensor',
'entity_category': None,
'entity_id': 'binary_sensor.gotham_city_connectivity_2',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': <BinarySensorDeviceClass.CONNECTIVITY: 'connectivity'>,
'original_icon': None,
'original_name': 'Connectivity',
'platform': 'myuplink',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'batman-r-1234-20240201-123456-aa-bb-cc-dd-ee-ff-connection_state',
'unit_of_measurement': None,
})
# ---
# name: test_binary_sensor_states[binary_sensor.gotham_city_connectivity_2-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'connectivity',
'friendly_name': 'Gotham City Connectivity',
}),
'context': <ANY>,
'entity_id': 'binary_sensor.gotham_city_connectivity_2',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'on',
})
# ---
# name: test_binary_sensor_states[binary_sensor.gotham_city_extern_adjustment_climate_system_1-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'binary_sensor',
'entity_category': None,
'entity_id': 'binary_sensor.gotham_city_extern_adjustment_climate_system_1',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Extern. adjust\xadment climate system 1',
'platform': 'myuplink',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'elect_add',
'unique_id': 'robin-r-1234-20240201-123456-aa-bb-cc-dd-ee-ff-43161',
'unit_of_measurement': None,
})
# ---
# name: test_binary_sensor_states[binary_sensor.gotham_city_extern_adjustment_climate_system_1-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Gotham City Extern. adjust\xadment climate system 1',
}),
'context': <ANY>,
'entity_id': 'binary_sensor.gotham_city_extern_adjustment_climate_system_1',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'off',
})
# ---
# name: test_binary_sensor_states[binary_sensor.gotham_city_extern_adjustment_climate_system_1_2-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'binary_sensor',
'entity_category': None,
'entity_id': 'binary_sensor.gotham_city_extern_adjustment_climate_system_1_2',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Extern. adjust\xadment climate system 1',
'platform': 'myuplink',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'elect_add',
'unique_id': 'batman-r-1234-20240201-123456-aa-bb-cc-dd-ee-ff-43161',
'unit_of_measurement': None,
})
# ---
# name: test_binary_sensor_states[binary_sensor.gotham_city_extern_adjustment_climate_system_1_2-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Gotham City Extern. adjust\xadment climate system 1',
}),
'context': <ANY>,
'entity_id': 'binary_sensor.gotham_city_extern_adjustment_climate_system_1_2',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'off',
})
# ---
# name: test_binary_sensor_states[binary_sensor.gotham_city_pump_heating_medium_gp1-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'binary_sensor',
'entity_category': None,
'entity_id': 'binary_sensor.gotham_city_pump_heating_medium_gp1',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Pump: Heating medium (GP1)',
'platform': 'myuplink',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'robin-r-1234-20240201-123456-aa-bb-cc-dd-ee-ff-49995',
'unit_of_measurement': None,
})
# ---
# name: test_binary_sensor_states[binary_sensor.gotham_city_pump_heating_medium_gp1-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Gotham City Pump: Heating medium (GP1)',
}),
'context': <ANY>,
'entity_id': 'binary_sensor.gotham_city_pump_heating_medium_gp1',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'on',
})
# ---
# name: test_binary_sensor_states[binary_sensor.gotham_city_pump_heating_medium_gp1_2-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'binary_sensor',
'entity_category': None,
'entity_id': 'binary_sensor.gotham_city_pump_heating_medium_gp1_2',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Pump: Heating medium (GP1)',
'platform': 'myuplink',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': None,
'unique_id': 'batman-r-1234-20240201-123456-aa-bb-cc-dd-ee-ff-49995',
'unit_of_measurement': None,
})
# ---
# name: test_binary_sensor_states[binary_sensor.gotham_city_pump_heating_medium_gp1_2-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Gotham City Pump: Heating medium (GP1)',
}),
'context': <ANY>,
'entity_id': 'binary_sensor.gotham_city_pump_heating_medium_gp1_2',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'on',
})
# ---

View File

@ -1085,6 +1085,23 @@
"scaleValue": "1",
"zoneId": null
},
{
"category": "F730 CU 3x400V",
"parameterId": "148072r",
"parameterName": "r start diff additional heat",
"parameterUnit": "DM",
"writable": false,
"timestamp": "2024-10-18T09:51:39+00:00",
"value": 700,
"strVal": "700DM",
"smartHomeCategories": [],
"minValue": 100,
"maxValue": 2000,
"stepValue": 10,
"enumValues": [],
"scaleValue": "1",
"zoneId": null
},
{
"category": "F730 CU 3x400V",
"parameterId": "47011",
@ -1101,6 +1118,40 @@
"enumValues": [],
"scaleValue": "1",
"zoneId": null
},
{
"category": "F730 CU 3x400V",
"parameterId": "47007",
"parameterName": "Excluded",
"parameterUnit": "",
"writable": true,
"timestamp": "2024-10-18T09:51:39+00:00",
"value": 1,
"strVal": "1",
"smartHomeCategories": ["sh-indoorSpOffsHeat"],
"minValue": -10,
"maxValue": 10,
"stepValue": 1,
"enumValues": [],
"scaleValue": "1",
"zoneId": null
},
{
"category": "F730 CU 3x400V",
"parameterId": "99000",
"parameterName": "Excluded 2",
"parameterUnit": "",
"writable": true,
"timestamp": "2024-10-18T09:51:39+00:00",
"value": "Hello",
"strVal": "Hello",
"smartHomeCategories": [],
"minValue": "",
"maxValue": "",
"stepValue": 1,
"enumValues": [],
"scaleValue": "1",
"zoneId": null
}
]
@ -2179,6 +2230,23 @@
"scaleValue": "1",
"zoneId": null
},
{
"category": "F730 CU 3x400V",
"parameterId": "148072r",
"parameterName": "r start diff additional heat",
"parameterUnit": "DM",
"writable": false,
"timestamp": "2024-10-18T09:51:39+00:00",
"value": 700,
"strVal": "700DM",
"smartHomeCategories": [],
"minValue": 100,
"maxValue": 2000,
"stepValue": 10,
"enumValues": [],
"scaleValue": "1",
"zoneId": null
},
{
"category": "F730 CU 3x400V",
"parameterId": "47011",
@ -2195,6 +2263,40 @@
"enumValues": [],
"scaleValue": "1",
"zoneId": null
},
{
"category": "F730 CU 3x400V",
"parameterId": "47007",
"parameterName": "Excluded",
"parameterUnit": "",
"writable": true,
"timestamp": "2024-10-18T09:51:39+00:00",
"value": 1,
"strVal": "1",
"smartHomeCategories": ["sh-indoorSpOffsHeat"],
"minValue": -10,
"maxValue": 10,
"stepValue": 1,
"enumValues": [],
"scaleValue": "1",
"zoneId": null
},
{
"category": "F730 CU 3x400V",
"parameterId": "99000",
"parameterName": "Excluded 2",
"parameterUnit": "",
"writable": true,
"timestamp": "2024-10-18T09:51:39+00:00",
"value": "Hello",
"strVal": "Hello",
"smartHomeCategories": [],
"minValue": "",
"maxValue": "",
"stepValue": 1,
"enumValues": [],
"scaleValue": "1",
"zoneId": null
}
]

File diff suppressed because it is too large Load Diff

View File

@ -1,57 +1,28 @@
"""Tests for myuplink sensor module."""
"""Tests for myuplink binary sensor module."""
from unittest.mock import MagicMock
from unittest.mock import MagicMock, patch
import pytest
from syrupy import SnapshotAssertion
from homeassistant.const import STATE_OFF, STATE_ON
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from . import setup_integration
from tests.common import MockConfigEntry
from tests.common import MockConfigEntry, snapshot_platform
# Test one entity from each of binary_sensor classes.
@pytest.mark.parametrize(
("entity_id", "friendly_name", "test_attributes", "expected_state"),
[
(
"binary_sensor.gotham_city_pump_heating_medium_gp1",
"Gotham City Pump: Heating medium (GP1)",
True,
STATE_ON,
),
(
"binary_sensor.gotham_city_connectivity",
"Gotham City Connectivity",
False,
STATE_ON,
),
(
"binary_sensor.gotham_city_alarm",
"Gotham City Pump: Alarm",
False,
STATE_OFF,
),
],
)
async def test_sensor_states(
async def test_binary_sensor_states(
hass: HomeAssistant,
mock_myuplink_client: MagicMock,
mock_config_entry: MockConfigEntry,
entity_id: str,
friendly_name: str,
test_attributes: bool,
expected_state: str,
snapshot: SnapshotAssertion,
entity_registry: er.EntityRegistry,
) -> None:
"""Test sensor state."""
await setup_integration(hass, mock_config_entry)
"""Test binary sensor state."""
state = hass.states.get(entity_id)
assert state is not None
assert state.state == expected_state
if test_attributes:
assert state.attributes == {
"friendly_name": friendly_name,
}
with patch("homeassistant.components.myuplink.PLATFORMS", [Platform.BINARY_SENSOR]):
await setup_integration(hass, mock_config_entry)
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)

View File

@ -14,7 +14,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType
from homeassistant.helpers import config_entry_oauth2_flow
from .const import CLIENT_ID
from .const import CLIENT_ID, UNIQUE_ID
from tests.common import MockConfigEntry
from tests.test_util.aiohttp import AiohttpClientMocker
@ -76,7 +76,28 @@ async def test_full_flow(
@pytest.mark.usefixtures("current_request_with_host")
async def test_flow_reauth(
@pytest.mark.parametrize(
("unique_id", "scope", "expected_reason"),
[
(
UNIQUE_ID,
CURRENT_SCOPE,
"reauth_successful",
),
(
"wrong_uid",
CURRENT_SCOPE,
"account_mismatch",
),
(
UNIQUE_ID,
"READSYSTEM offline_access",
"reauth_successful",
),
],
ids=["reauth_only", "account_mismatch", "wrong_scope"],
)
async def test_flow_reauth_abort(
hass: HomeAssistant,
hass_client_no_auth: ClientSessionGenerator,
aioclient_mock: AiohttpClientMocker,
@ -84,27 +105,26 @@ async def test_flow_reauth(
mock_config_entry: MockConfigEntry,
access_token: str,
expires_at: float,
unique_id: str,
scope: str,
expected_reason: str,
) -> None:
"""Test reauth step."""
"""Test reauth step with correct params and mismatches."""
OLD_SCOPE = "READSYSTEM offline_access"
OLD_SCOPE_TOKEN = {
CURRENT_TOKEN = {
"auth_implementation": DOMAIN,
"token": {
"access_token": access_token,
"scope": OLD_SCOPE,
"scope": scope,
"expires_in": 86399,
"refresh_token": "3012bc9f-7a65-4240-b817-9154ffdcc30f",
"token_type": "Bearer",
"expires_at": expires_at,
},
}
assert mock_config_entry.data["token"]["scope"] == CURRENT_SCOPE
assert hass.config_entries.async_update_entry(
mock_config_entry, data=OLD_SCOPE_TOKEN
mock_config_entry, data=CURRENT_TOKEN, unique_id=unique_id
)
assert mock_config_entry.data["token"]["scope"] == OLD_SCOPE
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
result = await mock_config_entry.start_reauth_flow(hass)
@ -148,13 +168,11 @@ async def test_flow_reauth(
with patch(
f"homeassistant.components.{DOMAIN}.async_setup_entry", return_value=True
) as mock_setup:
):
result = await hass.config_entries.flow.async_configure(result["flow_id"])
await hass.async_block_till_done()
assert result.get("type") is FlowResultType.ABORT
assert result.get("reason") == "reauth_successful"
assert result.get("reason") == expected_reason
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
assert len(mock_setup.mock_calls) == 1
assert mock_config_entry.data["token"]["scope"] == CURRENT_SCOPE

View File

@ -4,18 +4,21 @@ import http
import time
from unittest.mock import MagicMock
from aiohttp import ClientConnectionError
import pytest
from homeassistant.components.myuplink.const import DOMAIN, OAUTH2_TOKEN
from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr
from homeassistant.setup import async_setup_component
from . import setup_integration
from .const import UNIQUE_ID
from tests.common import MockConfigEntry, load_fixture
from tests.test_util.aiohttp import AiohttpClientMocker
from tests.typing import WebSocketGenerator
async def test_load_unload_entry(
@ -71,6 +74,37 @@ async def test_expired_token_refresh_failure(
assert mock_config_entry.state is expected_state
@pytest.mark.parametrize(
("expires_at", "expected_state"),
[
(
time.time() - 3600,
ConfigEntryState.SETUP_RETRY,
),
],
ids=[
"client_connection_error",
],
)
async def test_expired_token_refresh_connection_failure(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
aioclient_mock: AiohttpClientMocker,
expected_state: ConfigEntryState,
) -> None:
"""Test failure while refreshing token with a ClientError."""
aioclient_mock.clear_requests()
aioclient_mock.post(
OAUTH2_TOKEN,
exc=ClientConnectionError(),
)
await setup_integration(hass, mock_config_entry)
assert mock_config_entry.state is expected_state
@pytest.mark.parametrize(
"load_systems_file",
[load_fixture("systems.json", DOMAIN)],
@ -130,3 +164,53 @@ async def test_migrate_config_entry(
assert mock_entry_v1_1.version == 1
assert mock_entry_v1_1.minor_version == 2
assert mock_entry_v1_1.unique_id == UNIQUE_ID
async def test_oaut2_scope_failure(
hass: HomeAssistant,
mock_myuplink_client: MagicMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test that an incorrect OAuth2 scope fails."""
mock_config_entry.data["token"]["scope"] = "wrong_scope"
await setup_integration(hass, mock_config_entry)
assert mock_config_entry.state is ConfigEntryState.SETUP_ERROR
async def test_device_remove_devices(
hass: HomeAssistant,
hass_ws_client: WebSocketGenerator,
mock_config_entry: MockConfigEntry,
mock_myuplink_client: MagicMock,
device_registry: dr.DeviceRegistry,
) -> None:
"""Test we can only remove a device that no longer exists."""
assert await async_setup_component(hass, "config", {})
mock_config_entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
device_entry = device_registry.async_get_device(
identifiers={
(
DOMAIN,
"batman-r-1234-20240201-123456-aa-bb-cc-dd-ee-ff",
)
},
)
client = await hass_ws_client(hass)
response = await client.remove_device(device_entry.id, mock_config_entry.entry_id)
assert not response["success"]
old_device_entry = device_registry.async_get_or_create(
config_entry_id=mock_config_entry.entry_id,
identifiers={(DOMAIN, "OLD-DEVICE-UUID")},
)
response = await client.remove_device(
old_device_entry.id, mock_config_entry.entry_id
)
assert response["success"]

View File

@ -1,28 +1,30 @@
"""Tests for myuplink sensor module."""
from unittest.mock import MagicMock
from unittest.mock import MagicMock, patch
import pytest
from syrupy import SnapshotAssertion
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from . import setup_integration
from tests.common import MockConfigEntry
from tests.common import MockConfigEntry, snapshot_platform
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
async def test_sensor_states(
hass: HomeAssistant,
mock_myuplink_client: MagicMock,
mock_config_entry: MockConfigEntry,
snapshot: SnapshotAssertion,
entity_registry: er.EntityRegistry,
) -> None:
"""Test sensor state."""
await setup_integration(hass, mock_config_entry)
state = hass.states.get("sensor.gotham_city_average_outdoor_temp_bt1")
assert state is not None
assert state.state == "-12.2"
assert state.attributes == {
"friendly_name": "Gotham City Average outdoor temp (BT1)",
"device_class": "temperature",
"state_class": "measurement",
"unit_of_measurement": "°C",
}
with patch("homeassistant.components.myuplink.PLATFORMS", [Platform.SENSOR]):
await setup_integration(hass, mock_config_entry)
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)