Add some myuplink tests (#110521)

* Add some myuplink tests

* Update fixtures for api endpoints

* Adjust according to review

* Update snapshot file

* Remove unneded fixtures and improve typing

* More cleanup

* One last session scope removed

* Fix typing

---------

Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
Åke Strandberg 2024-02-15 13:44:45 +01:00 committed by GitHub
parent 57d3f3f9f7
commit fd0f093299
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 1178 additions and 1108 deletions

View File

@ -1,11 +1,10 @@
"""Test helpers for myuplink."""
from collections.abc import Generator
import json
import time
from typing import Any
from unittest.mock import MagicMock, patch
from myuplink import Device, System
from myuplink import Device, DevicePoint, System
import pytest
from homeassistant.components.application_credentials import (
@ -15,10 +14,11 @@ from homeassistant.components.application_credentials import (
from homeassistant.components.myuplink.const import DOMAIN
from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component
from homeassistant.util.json import json_loads
from .const import CLIENT_ID, CLIENT_SECRET
from tests.common import MockConfigEntry, load_fixture, load_json_value_fixture
from tests.common import MockConfigEntry, load_fixture
@pytest.fixture(name="expires_at")
@ -64,34 +64,91 @@ async def setup_credentials(hass: HomeAssistant) -> None:
)
@pytest.fixture
def mock_myuplink_client() -> Generator[MagicMock, None, None]:
"""Mock a myuplink client."""
# Fixture group for device API endpoint.
def process_json_system(data: dict[str, Any]) -> System:
array = json.loads(data)
return [System(system_data) for system_data in array["systems"]]
@pytest.fixture(scope="session")
def load_device_file() -> str:
"""Fixture for loading device file."""
return load_fixture("device.json", DOMAIN)
@pytest.fixture
def device_fixture(load_device_file: str) -> Device:
"""Fixture for device."""
return Device(json_loads(load_device_file))
# Fixture group for systems API endpoint.
@pytest.fixture
def load_systems_jv_file(load_systems_file: str) -> dict[str, Any]:
"""Load fixture file for systems endpoint."""
return json_loads(load_systems_file)
@pytest.fixture(scope="session")
def load_systems_file() -> str:
"""Load fixture file for systems."""
return load_fixture("systems.json", DOMAIN)
@pytest.fixture
def system_fixture(load_systems_file: str) -> list[System]:
"""Fixture for systems."""
data = json_loads(load_systems_file)
return [System(system_data) for system_data in data["systems"]]
# Fixture group for device points API endpoint.
@pytest.fixture(scope="session")
def load_device_points_file() -> str:
"""Load fixture file for device-points endpoint."""
return load_fixture("device_points_nibe_f730.json", DOMAIN)
@pytest.fixture
def load_device_points_jv_file():
"""Load fixture file for device_points."""
return json_loads(load_device_points_file)
@pytest.fixture
def device_points_fixture(load_device_points_file: str) -> list[DevicePoint]:
"""Fixture for devce_points."""
data = json_loads(load_device_points_file)
return [DevicePoint(point_data) for point_data in data]
@pytest.fixture
def mock_myuplink_client(
load_device_file,
device_fixture,
load_device_points_file,
device_points_fixture,
system_fixture,
load_systems_jv_file,
) -> Generator[MagicMock, None, None]:
"""Mock a myuplink client."""
with patch(
"homeassistant.components.myuplink.MyUplinkAPI",
autospec=True,
) as mock_client:
client = mock_client.return_value
client.async_get_device_points_json.return_value = load_json_value_fixture(
"device_points_nibe_f730.json", DOMAIN
)
client.async_get_systems.return_value = process_json_system(
load_fixture("systems.json", DOMAIN)
)
client.async_get_device.return_value = Device(
load_json_value_fixture("device.json", DOMAIN)
)
client.async_get_device_json.return_value = load_json_value_fixture(
"device.json", DOMAIN
)
client.async_get_systems_json.return_value = load_json_value_fixture(
"systems.json", DOMAIN
)
client.async_get_systems.return_value = system_fixture
client.async_get_systems_json.return_value = load_systems_jv_file
client.async_get_device.return_value = device_fixture
client.async_get_device_json.return_value = load_device_file
client.async_get_device_points.return_value = device_points_fixture
client.async_get_device_points_json.return_value = load_device_points_file
yield client

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,68 @@
"""Tests for init module."""
import http
import time
from unittest.mock import MagicMock
import pytest
from homeassistant.components.myuplink.const import DOMAIN, OAUTH2_TOKEN
from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant
from . import setup_integration
from tests.common import MockConfigEntry
from tests.test_util.aiohttp import AiohttpClientMocker
async def test_load_unload_entry(
hass: HomeAssistant,
mock_myuplink_client: MagicMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test load and unload entry."""
await setup_integration(hass, mock_config_entry)
entry = hass.config_entries.async_entries(DOMAIN)[0]
assert entry.state == ConfigEntryState.LOADED
await hass.config_entries.async_remove(entry.entry_id)
await hass.async_block_till_done()
assert entry.state == ConfigEntryState.NOT_LOADED
@pytest.mark.parametrize(
("expires_at", "status", "expected_state"),
[
(
time.time() - 3600,
http.HTTPStatus.UNAUTHORIZED,
ConfigEntryState.SETUP_RETRY, # Will trigger reauth in the future
),
(
time.time() - 3600,
http.HTTPStatus.INTERNAL_SERVER_ERROR,
ConfigEntryState.SETUP_RETRY,
),
],
ids=["unauthorized", "internal_server_error"],
)
async def test_expired_token_refresh_failure(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
aioclient_mock: AiohttpClientMocker,
status: http.HTTPStatus,
expected_state: ConfigEntryState,
) -> None:
"""Test failure while refreshing token with a transient error."""
aioclient_mock.clear_requests()
aioclient_mock.post(
OAUTH2_TOKEN,
status=status,
)
await setup_integration(hass, mock_config_entry)
assert mock_config_entry.state is expected_state

View File

@ -0,0 +1,28 @@
"""Tests for myuplink sensor module."""
from unittest.mock import MagicMock
from homeassistant.core import HomeAssistant
from . import setup_integration
from tests.common import MockConfigEntry
async def test_sensor_states(
hass: HomeAssistant,
mock_myuplink_client: MagicMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test sensor state."""
await setup_integration(hass, mock_config_entry)
state = hass.states.get("sensor.f730_cu_3x400v_average_outdoor_temp_bt1")
assert state is not None
assert state.state == "-12.2"
assert state.attributes == {
"friendly_name": "F730 CU 3x400V Average outdoor temp (BT1)",
"device_class": "temperature",
"state_class": "measurement",
"unit_of_measurement": "°C",
}