mirror of
https://github.com/home-assistant/core.git
synced 2026-04-02 16:36:08 +01:00
156 lines
5.7 KiB
Python
156 lines
5.7 KiB
Python
"""Test the Fresh-r sensor platform."""
|
|
|
|
from unittest.mock import MagicMock
|
|
|
|
from aiohttp import ClientError
|
|
from freezegun.api import FrozenDateTimeFactory
|
|
from pyfreshr.exceptions import ApiResponseError
|
|
from pyfreshr.models import DeviceReadings, DeviceSummary
|
|
import pytest
|
|
from syrupy.assertion import SnapshotAssertion
|
|
|
|
from homeassistant.components.freshr.const import DOMAIN
|
|
from homeassistant.components.freshr.coordinator import (
|
|
DEVICES_SCAN_INTERVAL,
|
|
READINGS_SCAN_INTERVAL,
|
|
)
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
|
|
|
from .conftest import DEVICE_ID, MOCK_DEVICE_CURRENT
|
|
|
|
from tests.common import MockConfigEntry, async_fire_time_changed, snapshot_platform
|
|
|
|
|
|
@pytest.mark.usefixtures("entity_registry_enabled_by_default", "init_integration")
|
|
async def test_entities(
|
|
hass: HomeAssistant,
|
|
snapshot: SnapshotAssertion,
|
|
entity_registry: er.EntityRegistry,
|
|
device_registry: dr.DeviceRegistry,
|
|
mock_config_entry: MockConfigEntry,
|
|
) -> None:
|
|
"""Test the sensor entities."""
|
|
await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id)
|
|
|
|
device_entry = device_registry.async_get_device(identifiers={(DOMAIN, DEVICE_ID)})
|
|
assert device_entry
|
|
entity_entries = er.async_entries_for_config_entry(
|
|
entity_registry, mock_config_entry.entry_id
|
|
)
|
|
for entity_entry in entity_entries:
|
|
assert entity_entry.device_id == device_entry.id
|
|
|
|
|
|
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
|
async def test_sensor_none_values(
|
|
hass: HomeAssistant,
|
|
entity_registry: er.EntityRegistry,
|
|
mock_config_entry: MockConfigEntry,
|
|
mock_freshr_client: MagicMock,
|
|
) -> None:
|
|
"""Test sensors return unknown when all readings are None."""
|
|
mock_freshr_client.fetch_device_current.return_value = DeviceReadings(
|
|
t1=None, t2=None, co2=None, hum=None, flow=None, dp=None
|
|
)
|
|
mock_config_entry.add_to_hass(hass)
|
|
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
|
await hass.async_block_till_done()
|
|
|
|
for key in ("t1", "t2", "co2", "hum", "flow", "dp"):
|
|
entity_id = entity_registry.async_get_entity_id(
|
|
"sensor", DOMAIN, f"{DEVICE_ID}_{key}"
|
|
)
|
|
assert entity_id is not None
|
|
assert hass.states.get(entity_id).state == "unknown"
|
|
|
|
|
|
@pytest.mark.usefixtures("entity_registry_enabled_by_default", "init_integration")
|
|
@pytest.mark.parametrize(
|
|
"error",
|
|
[ApiResponseError("api error"), ClientError("network error")],
|
|
)
|
|
async def test_readings_connection_error_makes_unavailable(
|
|
hass: HomeAssistant,
|
|
mock_freshr_client: MagicMock,
|
|
freezer: FrozenDateTimeFactory,
|
|
error: Exception,
|
|
) -> None:
|
|
"""Test that connection errors during readings refresh mark entities unavailable."""
|
|
mock_freshr_client.fetch_device_current.side_effect = error
|
|
freezer.tick(READINGS_SCAN_INTERVAL)
|
|
async_fire_time_changed(hass)
|
|
await hass.async_block_till_done()
|
|
|
|
state = hass.states.get("sensor.fresh_r_inside_temperature")
|
|
assert state is not None
|
|
assert state.state == "unavailable"
|
|
|
|
|
|
DEVICE_ID_2 = "SN002"
|
|
|
|
|
|
@pytest.mark.usefixtures("entity_registry_enabled_by_default", "init_integration")
|
|
async def test_device_reappears_after_removal(
|
|
hass: HomeAssistant,
|
|
mock_config_entry: MockConfigEntry,
|
|
mock_freshr_client: MagicMock,
|
|
device_registry: dr.DeviceRegistry,
|
|
entity_registry: er.EntityRegistry,
|
|
freezer: FrozenDateTimeFactory,
|
|
) -> None:
|
|
"""Test that entities are re-created when a previously removed device reappears."""
|
|
assert device_registry.async_get_device(identifiers={(DOMAIN, DEVICE_ID)})
|
|
|
|
# Device disappears from the account
|
|
mock_freshr_client.fetch_devices.return_value = []
|
|
freezer.tick(DEVICES_SCAN_INTERVAL)
|
|
async_fire_time_changed(hass)
|
|
await hass.async_block_till_done()
|
|
|
|
assert device_registry.async_get_device(identifiers={(DOMAIN, DEVICE_ID)}) is None
|
|
|
|
# Device reappears
|
|
mock_freshr_client.fetch_devices.return_value = [DeviceSummary(id=DEVICE_ID)]
|
|
mock_freshr_client.fetch_device_current.return_value = MOCK_DEVICE_CURRENT
|
|
freezer.tick(DEVICES_SCAN_INTERVAL)
|
|
async_fire_time_changed(hass)
|
|
await hass.async_block_till_done()
|
|
|
|
assert device_registry.async_get_device(identifiers={(DOMAIN, DEVICE_ID)})
|
|
t1_entity_id = entity_registry.async_get_entity_id(
|
|
"sensor", DOMAIN, f"{DEVICE_ID}_t1"
|
|
)
|
|
assert t1_entity_id
|
|
assert hass.states.get(t1_entity_id).state != "unavailable"
|
|
|
|
|
|
@pytest.mark.usefixtures("entity_registry_enabled_by_default", "init_integration")
|
|
async def test_dynamic_device_added(
|
|
hass: HomeAssistant,
|
|
mock_config_entry: MockConfigEntry,
|
|
mock_freshr_client: MagicMock,
|
|
device_registry: dr.DeviceRegistry,
|
|
entity_registry: er.EntityRegistry,
|
|
freezer: FrozenDateTimeFactory,
|
|
) -> None:
|
|
"""Test that sensors are created for a device that appears after initial setup."""
|
|
assert device_registry.async_get_device(identifiers={(DOMAIN, DEVICE_ID_2)}) is None
|
|
|
|
mock_freshr_client.fetch_devices.return_value = [
|
|
DeviceSummary(id=DEVICE_ID),
|
|
DeviceSummary(id=DEVICE_ID_2),
|
|
]
|
|
mock_freshr_client.fetch_device_current.return_value = MOCK_DEVICE_CURRENT
|
|
freezer.tick(DEVICES_SCAN_INTERVAL)
|
|
async_fire_time_changed(hass)
|
|
await hass.async_block_till_done()
|
|
|
|
assert device_registry.async_get_device(identifiers={(DOMAIN, DEVICE_ID_2)})
|
|
t1_entity_id = entity_registry.async_get_entity_id(
|
|
"sensor", DOMAIN, f"{DEVICE_ID_2}_t1"
|
|
)
|
|
assert t1_entity_id
|
|
assert entity_registry.async_get_entity_id("sensor", DOMAIN, f"{DEVICE_ID_2}_co2")
|
|
assert hass.states.get(t1_entity_id).state != "unavailable"
|