mirror of
https://github.com/home-assistant/core.git
synced 2026-07-07 14:56:25 +01:00
175 lines
5.8 KiB
Python
175 lines
5.8 KiB
Python
"""Fixtures for WaterFurnace integration tests."""
|
|
|
|
from collections.abc import Generator
|
|
from datetime import timedelta
|
|
from unittest.mock import AsyncMock, Mock, patch
|
|
|
|
import pytest
|
|
from waterfurnace.waterfurnace import WaterFurnace, WFGateway, WFNoDataError, WFReading
|
|
|
|
from homeassistant.components.recorder import Recorder
|
|
from homeassistant.components.recorder.models import StatisticMeanType
|
|
from homeassistant.components.recorder.models.statistics import (
|
|
StatisticData,
|
|
StatisticMetaData,
|
|
)
|
|
from homeassistant.components.recorder.statistics import async_add_external_statistics
|
|
from homeassistant.components.waterfurnace.const import DOMAIN
|
|
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform, UnitOfEnergy
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.util import dt as dt_util
|
|
from homeassistant.util.unit_conversion import EnergyConverter
|
|
|
|
from tests.common import MockConfigEntry, load_json_object_fixture
|
|
from tests.components.recorder.common import async_wait_recording_done
|
|
|
|
SEED_STATISTIC_METADATA = StatisticMetaData(
|
|
has_sum=True,
|
|
mean_type=StatisticMeanType.NONE,
|
|
name="WaterFurnace Energy",
|
|
source=DOMAIN,
|
|
statistic_id=f"{DOMAIN}:test_gwid_12345_energy",
|
|
unit_class=EnergyConverter.UNIT_CLASS,
|
|
unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_setup_entry() -> Generator[AsyncMock]:
|
|
"""Mock setting up a config entry."""
|
|
with patch(
|
|
"homeassistant.components.waterfurnace.async_setup_entry", return_value=True
|
|
) as mock_setup:
|
|
yield mock_setup
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_waterfurnace_client() -> Generator[Mock]:
|
|
"""Mock WaterFurnace client."""
|
|
with (
|
|
patch(
|
|
"homeassistant.components.waterfurnace.config_flow.WaterFurnace",
|
|
autospec=True,
|
|
) as mock_client,
|
|
patch(
|
|
"homeassistant.components.waterfurnace.WaterFurnace",
|
|
new=mock_client,
|
|
),
|
|
):
|
|
client = mock_client.return_value
|
|
client.gwid = "TEST_GWID_12345"
|
|
client.account_id = "test_account_id"
|
|
|
|
gateway_data = {
|
|
"gwid": "TEST_GWID_12345",
|
|
"description": "Test WaterFurnace Device",
|
|
"awlabctypedesc": "Test ABC Type",
|
|
}
|
|
client.devices = [WFGateway(gateway_data)]
|
|
|
|
device_data = WFReading(load_json_object_fixture("device_data.json", DOMAIN))
|
|
client.read.return_value = device_data
|
|
client.read_with_retry.return_value = device_data
|
|
client.get_energy_data.side_effect = WFNoDataError("No data")
|
|
|
|
yield client
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_waterfurnace_client_multi_device() -> Generator[Mock]:
|
|
"""Mock WaterFurnace client with multiple devices."""
|
|
gateway_data_1 = {
|
|
"gwid": "TEST_GWID_12345",
|
|
"description": "Test WaterFurnace Device 1",
|
|
"awlabctypedesc": "Test ABC Type 1",
|
|
}
|
|
gateway_data_2 = {
|
|
"gwid": "TEST_GWID_67890",
|
|
"description": "Test WaterFurnace Device 2",
|
|
"awlabctypedesc": "Test ABC Type 2",
|
|
}
|
|
|
|
device_data = WFReading(load_json_object_fixture("device_data.json", DOMAIN))
|
|
|
|
with (
|
|
patch(
|
|
"homeassistant.components.waterfurnace.config_flow.WaterFurnace",
|
|
autospec=True,
|
|
) as mock_client,
|
|
patch(
|
|
"homeassistant.components.waterfurnace.WaterFurnace",
|
|
new=mock_client,
|
|
),
|
|
):
|
|
instances: list[Mock] = []
|
|
for gwid_data in (gateway_data_1, gateway_data_2):
|
|
client = Mock(spec=WaterFurnace)
|
|
client.gwid = gwid_data["gwid"]
|
|
client.account_id = "test_account_id"
|
|
client.devices = [WFGateway(gateway_data_1), WFGateway(gateway_data_2)]
|
|
client.read.return_value = device_data
|
|
client.read_with_retry.return_value = device_data
|
|
client.get_energy_data.side_effect = WFNoDataError("No data")
|
|
instances.append(client)
|
|
|
|
mock_client.side_effect = lambda username, password, device=0: instances[device]
|
|
yield instances[0]
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_config_entry() -> MockConfigEntry:
|
|
"""Return a mock config entry."""
|
|
return MockConfigEntry(
|
|
domain=DOMAIN,
|
|
title="WaterFurnace test_user",
|
|
data={
|
|
CONF_USERNAME: "test_user",
|
|
CONF_PASSWORD: "test_password",
|
|
},
|
|
unique_id="test_account_id",
|
|
version=1,
|
|
minor_version=2,
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
async def seed_statistics(
|
|
recorder_mock: Recorder,
|
|
hass: HomeAssistant,
|
|
) -> None:
|
|
"""Seed a recent energy statistic so the coordinator uses the normal poll path.
|
|
|
|
Without this, the energy coordinator sees no prior statistics and triggers
|
|
a reverse backfill on first refresh.
|
|
"""
|
|
now = dt_util.utcnow()
|
|
# Place the seed 90 minutes back so it doesn't collide with test readings
|
|
start = (now - timedelta(minutes=90)).replace(minute=0, second=0, microsecond=0)
|
|
async_add_external_statistics(
|
|
hass, SEED_STATISTIC_METADATA, [StatisticData(start=start, state=0.0, sum=0.0)]
|
|
)
|
|
await async_wait_recording_done(hass)
|
|
|
|
|
|
@pytest.fixture
|
|
def platforms() -> list[Platform]:
|
|
"""Fixture to specify platforms to test."""
|
|
return [Platform.CLIMATE, Platform.SENSOR]
|
|
|
|
|
|
@pytest.fixture
|
|
async def init_integration(
|
|
recorder_mock: Recorder,
|
|
hass: HomeAssistant,
|
|
mock_config_entry: MockConfigEntry,
|
|
mock_waterfurnace_client: Mock,
|
|
platforms: list[Platform],
|
|
) -> MockConfigEntry:
|
|
"""Set up the WaterFurnace integration for testing."""
|
|
with patch("homeassistant.components.waterfurnace.PLATFORMS", platforms):
|
|
mock_config_entry.add_to_hass(hass)
|
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
|
await hass.async_block_till_done()
|
|
|
|
return mock_config_entry
|