1
0
mirror of https://github.com/home-assistant/core.git synced 2026-05-28 03:06:30 +01:00
Files
core/tests/components/analytics/test_init.py
2026-05-27 18:07:27 +00:00

226 lines
7.7 KiB
Python

"""The tests for the analytics ."""
from datetime import timedelta
from typing import Any
from unittest.mock import patch
import pytest
from homeassistant.components.analytics import CONF_SNAPSHOTS_URL, LABS_SNAPSHOT_FEATURE
from homeassistant.components.analytics.const import (
BASIC_ENDPOINT_URL,
BASIC_ENDPOINT_URL_DEV,
DOMAIN,
SNAPSHOT_DEFAULT_URL,
SNAPSHOT_URL_PATH,
STORAGE_KEY,
)
from homeassistant.components.hassio import HassioNotReadyError
from homeassistant.components.labs import async_update_preview_feature
from homeassistant.config_entries import ConfigEntryState
from homeassistant.const import EVENT_HOMEASSISTANT_STARTED
from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component
from homeassistant.util import dt as dt_util
from tests.common import async_fire_time_changed
from tests.test_util.aiohttp import AiohttpClientMocker
from tests.typing import WebSocketGenerator
MOCK_VERSION = "1970.1.0"
SNAPSHOT_ENDPOINT_URL = SNAPSHOT_DEFAULT_URL + SNAPSHOT_URL_PATH
async def test_setup(hass: HomeAssistant) -> None:
"""Test setup of the integration."""
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
await hass.async_block_till_done()
assert DOMAIN in hass.data
async def test_setup_with_snapshots_url(
hass: HomeAssistant,
hass_storage: dict[str, Any],
hass_ws_client: WebSocketGenerator,
aioclient_mock: AiohttpClientMocker,
) -> None:
"""Test setup with snapshots_url in YAML config sends snapshots to that URL."""
custom_url = "https://custom-snapshot-endpoint.example.com"
snapshot_endpoint = custom_url + SNAPSHOT_URL_PATH
aioclient_mock.post(snapshot_endpoint, status=200, json={})
with patch(
"homeassistant.components.analytics.analytics._async_snapshot_payload",
return_value={"mock": {}},
):
assert await async_setup_component(hass, "labs", {})
assert await async_setup_component(
hass, DOMAIN, {DOMAIN: {CONF_SNAPSHOTS_URL: custom_url}}
)
await hass.async_block_till_done()
ws_client = await hass_ws_client(hass)
await ws_client.send_json_auto_id(
{"type": "analytics/preferences", "preferences": {"snapshots": True}}
)
assert (await ws_client.receive_json())["success"]
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(hours=25))
await hass.async_block_till_done()
assert any(str(call[1]) == snapshot_endpoint for call in aioclient_mock.mock_calls)
async def test_setup_entry_supervisor_not_ready(hass: HomeAssistant) -> None:
"""Test that HassioNotReadyError raises ConfigEntryNotReady."""
with (
patch(
"homeassistant.components.analytics.analytics.is_hassio",
return_value=True,
),
patch(
"homeassistant.components.hassio.get_supervisor_info",
side_effect=HassioNotReadyError,
),
):
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
await hass.async_block_till_done()
entry = hass.config_entries.async_entries(DOMAIN)[0]
assert entry.state is ConfigEntryState.SETUP_RETRY
async def test_schedule_starts_and_sends_analytics(
hass: HomeAssistant,
hass_storage: dict[str, Any],
hass_ws_client: WebSocketGenerator,
aioclient_mock: AiohttpClientMocker,
) -> None:
"""Test that the analytics schedule fires and sends analytics after time travel."""
aioclient_mock.post(BASIC_ENDPOINT_URL, status=200)
aioclient_mock.post(BASIC_ENDPOINT_URL_DEV, status=200)
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
await hass.async_block_till_done()
ws_client = await hass_ws_client(hass)
with patch("homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION):
await ws_client.send_json_auto_id(
{"type": "analytics/preferences", "preferences": {"base": True}}
)
assert (await ws_client.receive_json())["success"]
assert len(aioclient_mock.mock_calls) == 0
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(seconds=901))
await hass.async_block_till_done()
assert len(aioclient_mock.mock_calls) == 1
@pytest.mark.parametrize(
("ws_type", "ws_options"),
[("analytics", {}), ("analytics/preferences", {"preferences": {"base": True}})],
)
async def test_websocket_not_loaded(
hass: HomeAssistant,
hass_ws_client: WebSocketGenerator,
ws_type: str,
ws_options: dict[str, Any],
) -> None:
"""Test websocket returns error when analytics entry failed to load."""
with (
patch(
"homeassistant.components.analytics.analytics.is_hassio",
return_value=True,
),
patch(
"homeassistant.components.hassio.get_supervisor_info",
side_effect=HassioNotReadyError,
),
):
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
await hass.async_block_till_done()
ws_client = await hass_ws_client(hass)
await ws_client.send_json_auto_id({"type": ws_type} | ws_options)
response = await ws_client.receive_json()
assert not response["success"]
assert response["error"]["code"] == "not_found"
@pytest.mark.usefixtures("mock_snapshot_payload")
async def test_labs_feature_toggle(
hass: HomeAssistant,
hass_storage: dict[str, Any],
aioclient_mock: AiohttpClientMocker,
) -> None:
"""Test that snapshots can be toggled via labs feature."""
aioclient_mock.post(SNAPSHOT_ENDPOINT_URL, status=200, json={})
assert await async_setup_component(hass, "labs", {})
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
hass.bus.async_fire(EVENT_HOMEASSISTANT_STARTED)
await hass.async_block_till_done()
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(hours=25))
await hass.async_block_till_done()
assert len(aioclient_mock.mock_calls) == 0
await async_update_preview_feature(hass, DOMAIN, LABS_SNAPSHOT_FEATURE, True)
assert hass_storage[STORAGE_KEY]["data"]["preferences"]["snapshots"] is True
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(hours=25))
await hass.async_block_till_done()
assert any(
str(call[1]) == SNAPSHOT_ENDPOINT_URL for call in aioclient_mock.mock_calls
)
aioclient_mock.clear_requests()
await async_update_preview_feature(hass, DOMAIN, LABS_SNAPSHOT_FEATURE, False)
assert hass_storage[STORAGE_KEY]["data"]["preferences"]["snapshots"] is False
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(hours=25))
await hass.async_block_till_done()
assert len(aioclient_mock.mock_calls) == 0
@pytest.mark.usefixtures("supervisor_client")
async def test_websocket(
hass: HomeAssistant,
hass_ws_client: WebSocketGenerator,
aioclient_mock: AiohttpClientMocker,
) -> None:
"""Test WebSocket commands."""
aioclient_mock.post(BASIC_ENDPOINT_URL, status=200)
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {}})
await hass.async_block_till_done()
ws_client = await hass_ws_client(hass)
await ws_client.send_json_auto_id({"type": "analytics"})
response = await ws_client.receive_json()
assert response["success"]
with patch("homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION):
await ws_client.send_json_auto_id(
{"type": "analytics/preferences", "preferences": {"base": True}}
)
response = await ws_client.receive_json()
assert response["result"]["preferences"]["base"]
await ws_client.send_json_auto_id({"type": "analytics"})
response = await ws_client.receive_json()
assert response["result"]["preferences"]["base"]