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", "scaleValue": "1",
"zoneId": null "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", "category": "F730 CU 3x400V",
"parameterId": "47011", "parameterId": "47011",
@ -1040,5 +1057,39 @@
"enumValues": [], "enumValues": [],
"scaleValue": "1", "scaleValue": "1",
"zoneId": null "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", "scaleValue": "1",
"zoneId": null "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", "category": "F730 CU 3x400V",
"parameterId": "47011", "parameterId": "47011",
@ -1101,6 +1118,40 @@
"enumValues": [], "enumValues": [],
"scaleValue": "1", "scaleValue": "1",
"zoneId": null "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", "scaleValue": "1",
"zoneId": null "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", "category": "F730 CU 3x400V",
"parameterId": "47011", "parameterId": "47011",
@ -2195,6 +2263,40 @@
"enumValues": [], "enumValues": [],
"scaleValue": "1", "scaleValue": "1",
"zoneId": null "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.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from . import setup_integration 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. async def test_binary_sensor_states(
@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(
hass: HomeAssistant, hass: HomeAssistant,
mock_myuplink_client: MagicMock, mock_myuplink_client: MagicMock,
mock_config_entry: MockConfigEntry, mock_config_entry: MockConfigEntry,
entity_id: str, snapshot: SnapshotAssertion,
friendly_name: str, entity_registry: er.EntityRegistry,
test_attributes: bool,
expected_state: str,
) -> None: ) -> None:
"""Test sensor state.""" """Test binary sensor state."""
await setup_integration(hass, mock_config_entry)
state = hass.states.get(entity_id) with patch("homeassistant.components.myuplink.PLATFORMS", [Platform.BINARY_SENSOR]):
assert state is not None await setup_integration(hass, mock_config_entry)
assert state.state == expected_state
if test_attributes: await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
assert state.attributes == {
"friendly_name": friendly_name,
}

View File

@ -14,7 +14,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType from homeassistant.data_entry_flow import FlowResultType
from homeassistant.helpers import config_entry_oauth2_flow 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.common import MockConfigEntry
from tests.test_util.aiohttp import AiohttpClientMocker from tests.test_util.aiohttp import AiohttpClientMocker
@ -76,7 +76,28 @@ async def test_full_flow(
@pytest.mark.usefixtures("current_request_with_host") @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: HomeAssistant,
hass_client_no_auth: ClientSessionGenerator, hass_client_no_auth: ClientSessionGenerator,
aioclient_mock: AiohttpClientMocker, aioclient_mock: AiohttpClientMocker,
@ -84,27 +105,26 @@ async def test_flow_reauth(
mock_config_entry: MockConfigEntry, mock_config_entry: MockConfigEntry,
access_token: str, access_token: str,
expires_at: float, expires_at: float,
unique_id: str,
scope: str,
expected_reason: str,
) -> None: ) -> None:
"""Test reauth step.""" """Test reauth step with correct params and mismatches."""
OLD_SCOPE = "READSYSTEM offline_access" CURRENT_TOKEN = {
OLD_SCOPE_TOKEN = {
"auth_implementation": DOMAIN, "auth_implementation": DOMAIN,
"token": { "token": {
"access_token": access_token, "access_token": access_token,
"scope": OLD_SCOPE, "scope": scope,
"expires_in": 86399, "expires_in": 86399,
"refresh_token": "3012bc9f-7a65-4240-b817-9154ffdcc30f", "refresh_token": "3012bc9f-7a65-4240-b817-9154ffdcc30f",
"token_type": "Bearer", "token_type": "Bearer",
"expires_at": expires_at, "expires_at": expires_at,
}, },
} }
assert mock_config_entry.data["token"]["scope"] == CURRENT_SCOPE
assert hass.config_entries.async_update_entry( 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 assert len(hass.config_entries.async_entries(DOMAIN)) == 1
result = await mock_config_entry.start_reauth_flow(hass) result = await mock_config_entry.start_reauth_flow(hass)
@ -148,13 +168,11 @@ async def test_flow_reauth(
with patch( with patch(
f"homeassistant.components.{DOMAIN}.async_setup_entry", return_value=True f"homeassistant.components.{DOMAIN}.async_setup_entry", return_value=True
) as mock_setup: ):
result = await hass.config_entries.flow.async_configure(result["flow_id"]) result = await hass.config_entries.flow.async_configure(result["flow_id"])
await hass.async_block_till_done() await hass.async_block_till_done()
assert result.get("type") is FlowResultType.ABORT 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(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 import time
from unittest.mock import MagicMock from unittest.mock import MagicMock
from aiohttp import ClientConnectionError
import pytest import pytest
from homeassistant.components.myuplink.const import DOMAIN, OAUTH2_TOKEN from homeassistant.components.myuplink.const import DOMAIN, OAUTH2_TOKEN
from homeassistant.config_entries import ConfigEntryState from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr from homeassistant.helpers import device_registry as dr
from homeassistant.setup import async_setup_component
from . import setup_integration from . import setup_integration
from .const import UNIQUE_ID from .const import UNIQUE_ID
from tests.common import MockConfigEntry, load_fixture from tests.common import MockConfigEntry, load_fixture
from tests.test_util.aiohttp import AiohttpClientMocker from tests.test_util.aiohttp import AiohttpClientMocker
from tests.typing import WebSocketGenerator
async def test_load_unload_entry( 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 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( @pytest.mark.parametrize(
"load_systems_file", "load_systems_file",
[load_fixture("systems.json", DOMAIN)], [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.version == 1
assert mock_entry_v1_1.minor_version == 2 assert mock_entry_v1_1.minor_version == 2
assert mock_entry_v1_1.unique_id == UNIQUE_ID 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.""" """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.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from . import setup_integration 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( async def test_sensor_states(
hass: HomeAssistant, hass: HomeAssistant,
mock_myuplink_client: MagicMock, mock_myuplink_client: MagicMock,
mock_config_entry: MockConfigEntry, mock_config_entry: MockConfigEntry,
snapshot: SnapshotAssertion,
entity_registry: er.EntityRegistry,
) -> None: ) -> None:
"""Test sensor state.""" """Test sensor state."""
await setup_integration(hass, mock_config_entry)
state = hass.states.get("sensor.gotham_city_average_outdoor_temp_bt1") with patch("homeassistant.components.myuplink.PLATFORMS", [Platform.SENSOR]):
assert state is not None await setup_integration(hass, mock_config_entry)
assert state.state == "-12.2"
assert state.attributes == { await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
"friendly_name": "Gotham City Average outdoor temp (BT1)",
"device_class": "temperature",
"state_class": "measurement",
"unit_of_measurement": "°C",
}