mirror of
https://github.com/home-assistant/core.git
synced 2026-08-07 22:05:35 +01:00
221 lines
6.1 KiB
Python
221 lines
6.1 KiB
Python
"""Tests for the Point component."""
|
|
|
|
import time
|
|
from typing import Any
|
|
from unittest.mock import AsyncMock, patch
|
|
|
|
import pytest
|
|
|
|
from homeassistant.components.application_credentials import (
|
|
DOMAIN as APPLICATION_CREDENTIALS_DOMAIN,
|
|
ClientCredential,
|
|
async_import_client_credential,
|
|
)
|
|
from homeassistant.components.point import DOMAIN
|
|
from homeassistant.config_entries import ConfigEntryState
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers import device_registry as dr
|
|
from homeassistant.helpers.config_entry_oauth2_flow import (
|
|
ImplementationUnavailableError,
|
|
)
|
|
from homeassistant.setup import async_setup_component
|
|
|
|
from tests.common import MockConfigEntry
|
|
|
|
HOME_ID = "home_1"
|
|
DEVICE_ID = "device_1"
|
|
|
|
DEVICE_RAW: dict[str, Any] = {
|
|
"device_id": DEVICE_ID,
|
|
"device_mac": "00:11:22:33:44:55",
|
|
"description": "Kitchen",
|
|
"hardware_version": "1",
|
|
"firmware": {"installed": "2.0.0"},
|
|
"home": HOME_ID,
|
|
"last_heard_from_at": "2023-01-01T00:00:00+00:00",
|
|
"active": True,
|
|
"offline": False,
|
|
"battery": {"percent": 100},
|
|
"ongoing_events": [],
|
|
}
|
|
|
|
HOME_RAW: dict[str, Any] = {
|
|
"home_id": HOME_ID,
|
|
"name": "My Home",
|
|
"devices": [DEVICE_ID],
|
|
"alarm_status": "off",
|
|
}
|
|
|
|
|
|
class FakeDevice:
|
|
"""Minimal fake of pypoint.Device."""
|
|
|
|
def __init__(self, raw: dict[str, Any]) -> None:
|
|
"""Initialize."""
|
|
self._raw = raw
|
|
|
|
@property
|
|
def device_id(self) -> str:
|
|
"""Return the device id."""
|
|
return self._raw["device_id"]
|
|
|
|
@property
|
|
def device(self) -> dict[str, Any]:
|
|
"""Return the raw representation."""
|
|
return self._raw
|
|
|
|
@property
|
|
def name(self) -> str:
|
|
"""Return the device name."""
|
|
return self._raw["description"]
|
|
|
|
@property
|
|
def last_update(self) -> str:
|
|
"""Return the last update timestamp."""
|
|
return self._raw["last_heard_from_at"]
|
|
|
|
@property
|
|
def ongoing_events(self) -> list[str]:
|
|
"""Return ongoing events."""
|
|
return self._raw["ongoing_events"]
|
|
|
|
@property
|
|
def webhook(self) -> str:
|
|
"""Return the webhook."""
|
|
return "webhook"
|
|
|
|
@property
|
|
def device_status(self) -> dict[str, Any]:
|
|
"""Return the device status."""
|
|
return {
|
|
"active": self._raw["active"],
|
|
"offline": self._raw["offline"],
|
|
"last_update": self.last_update,
|
|
"battery_level": self._raw["battery"]["percent"],
|
|
}
|
|
|
|
async def sensor(self, sensor_type: str) -> float:
|
|
"""Return a sensor value."""
|
|
return 1.0
|
|
|
|
|
|
class FakePointSession:
|
|
"""Minimal fake of pypoint.PointSession."""
|
|
|
|
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
"""Initialize."""
|
|
self._devices = {DEVICE_ID: DEVICE_RAW}
|
|
self._homes = {HOME_ID: HOME_RAW}
|
|
self.webhook = "webhook"
|
|
|
|
async def update(self) -> bool:
|
|
"""Update the session."""
|
|
return True
|
|
|
|
@property
|
|
def homes(self) -> dict[str, dict[str, Any]]:
|
|
"""Return known homes."""
|
|
return self._homes
|
|
|
|
@property
|
|
def device_ids(self) -> Any:
|
|
"""Return known device ids."""
|
|
return self._devices.keys()
|
|
|
|
@property
|
|
def devices(self) -> Any:
|
|
"""Return device representations."""
|
|
return (FakeDevice(raw) for raw in self._devices.values())
|
|
|
|
def device(self, device_id: str) -> FakeDevice:
|
|
"""Return a single device."""
|
|
return FakeDevice(self._devices[device_id])
|
|
|
|
|
|
@pytest.fixture
|
|
async def setup_credentials(hass: HomeAssistant) -> None:
|
|
"""Fixture to set up application credentials."""
|
|
assert await async_setup_component(hass, APPLICATION_CREDENTIALS_DOMAIN, {})
|
|
await async_import_client_credential(
|
|
hass,
|
|
DOMAIN,
|
|
ClientCredential("1234", "5678"),
|
|
)
|
|
|
|
|
|
async def test_oauth_implementation_not_available(
|
|
hass: HomeAssistant,
|
|
) -> None:
|
|
"""Test that unavailable OAuth implementation raises ConfigEntryNotReady."""
|
|
config_entry = MockConfigEntry(
|
|
domain=DOMAIN,
|
|
data={
|
|
"auth_implementation": DOMAIN,
|
|
"token": {
|
|
"refresh_token": "mock-refresh-token",
|
|
"access_token": "mock-access-token",
|
|
"type": "Bearer",
|
|
"expires_in": 60,
|
|
},
|
|
},
|
|
)
|
|
config_entry.add_to_hass(hass)
|
|
|
|
with patch(
|
|
"homeassistant.components.point.async_get_config_entry_implementation",
|
|
side_effect=ImplementationUnavailableError,
|
|
):
|
|
await hass.config_entries.async_setup(config_entry.entry_id)
|
|
await hass.async_block_till_done()
|
|
|
|
assert config_entry.state is ConfigEntryState.SETUP_RETRY
|
|
|
|
|
|
@pytest.mark.usefixtures("setup_credentials")
|
|
async def test_device_via_device_link(
|
|
hass: HomeAssistant,
|
|
device_registry: dr.DeviceRegistry,
|
|
) -> None:
|
|
"""Test that a Point device is linked to its home via_device."""
|
|
config_entry = MockConfigEntry(
|
|
domain=DOMAIN,
|
|
unique_id="abcd",
|
|
data={
|
|
"auth_implementation": DOMAIN,
|
|
"token": {
|
|
"refresh_token": "mock-refresh-token",
|
|
"access_token": "mock-access-token",
|
|
"type": "Bearer",
|
|
"expires_in": 60,
|
|
"expires_at": time.time() + 3600,
|
|
},
|
|
},
|
|
)
|
|
config_entry.add_to_hass(hass)
|
|
|
|
with (
|
|
patch(
|
|
"homeassistant.components.point.PointSession",
|
|
FakePointSession,
|
|
),
|
|
patch(
|
|
"homeassistant.components.point.async_setup_webhook",
|
|
new=AsyncMock(),
|
|
),
|
|
):
|
|
await hass.config_entries.async_setup(config_entry.entry_id)
|
|
await hass.async_block_till_done()
|
|
|
|
assert config_entry.state is ConfigEntryState.LOADED
|
|
|
|
home_device = device_registry.async_get_device_by_identifier(
|
|
(DOMAIN, HOME_ID), config_entry.entry_id
|
|
)
|
|
assert home_device is not None
|
|
|
|
point_device = device_registry.async_get_device_by_identifier(
|
|
(DOMAIN, DEVICE_ID), config_entry.entry_id
|
|
)
|
|
assert point_device is not None
|
|
assert point_device.via_device_id == home_device.id
|