mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 04:07:08 +00:00
Adjust the analytics collector to only report configured integrations (#95246)
This commit is contained in:
parent
90c1263501
commit
4d4e7522f4
@ -21,12 +21,22 @@ from homeassistant.components.recorder import (
|
|||||||
DOMAIN as RECORDER_DOMAIN,
|
DOMAIN as RECORDER_DOMAIN,
|
||||||
get_instance as get_recorder_instance,
|
get_instance as get_recorder_instance,
|
||||||
)
|
)
|
||||||
|
import homeassistant.config as conf_util
|
||||||
|
from homeassistant.config_entries import (
|
||||||
|
SOURCE_IGNORE,
|
||||||
|
)
|
||||||
from homeassistant.const import ATTR_DOMAIN, __version__ as HA_VERSION
|
from homeassistant.const import ATTR_DOMAIN, __version__ as HA_VERSION
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant, callback
|
||||||
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
|
import homeassistant.helpers.entity_registry as er
|
||||||
from homeassistant.helpers.storage import Store
|
from homeassistant.helpers.storage import Store
|
||||||
from homeassistant.helpers.system_info import async_get_system_info
|
from homeassistant.helpers.system_info import async_get_system_info
|
||||||
from homeassistant.loader import IntegrationNotFound, async_get_integrations
|
from homeassistant.loader import (
|
||||||
|
Integration,
|
||||||
|
IntegrationNotFound,
|
||||||
|
async_get_integrations,
|
||||||
|
)
|
||||||
from homeassistant.setup import async_get_loaded_integrations
|
from homeassistant.setup import async_get_loaded_integrations
|
||||||
|
|
||||||
from .const import (
|
from .const import (
|
||||||
@ -206,8 +216,25 @@ class Analytics:
|
|||||||
if self.preferences.get(ATTR_USAGE, False) or self.preferences.get(
|
if self.preferences.get(ATTR_USAGE, False) or self.preferences.get(
|
||||||
ATTR_STATISTICS, False
|
ATTR_STATISTICS, False
|
||||||
):
|
):
|
||||||
|
ent_reg = er.async_get(self.hass)
|
||||||
|
|
||||||
|
try:
|
||||||
|
yaml_configuration = await conf_util.async_hass_config_yaml(self.hass)
|
||||||
|
except HomeAssistantError as err:
|
||||||
|
LOGGER.error(err)
|
||||||
|
return
|
||||||
|
|
||||||
|
configuration_set = set(yaml_configuration)
|
||||||
|
er_platforms = {
|
||||||
|
entity.platform
|
||||||
|
for entity in ent_reg.entities.values()
|
||||||
|
if not entity.disabled
|
||||||
|
}
|
||||||
|
|
||||||
domains = async_get_loaded_integrations(self.hass)
|
domains = async_get_loaded_integrations(self.hass)
|
||||||
configured_integrations = await async_get_integrations(self.hass, domains)
|
configured_integrations = await async_get_integrations(self.hass, domains)
|
||||||
|
enabled_domains = set(configured_integrations)
|
||||||
|
|
||||||
for integration in configured_integrations.values():
|
for integration in configured_integrations.values():
|
||||||
if isinstance(integration, IntegrationNotFound):
|
if isinstance(integration, IntegrationNotFound):
|
||||||
continue
|
continue
|
||||||
@ -215,7 +242,11 @@ class Analytics:
|
|||||||
if isinstance(integration, BaseException):
|
if isinstance(integration, BaseException):
|
||||||
raise integration
|
raise integration
|
||||||
|
|
||||||
if integration.disabled:
|
if not self._async_should_report_integration(
|
||||||
|
integration=integration,
|
||||||
|
yaml_domains=configuration_set,
|
||||||
|
entity_registry_platforms=er_platforms,
|
||||||
|
):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if not integration.is_built_in:
|
if not integration.is_built_in:
|
||||||
@ -253,12 +284,12 @@ class Analytics:
|
|||||||
if supervisor_info is not None:
|
if supervisor_info is not None:
|
||||||
payload[ATTR_ADDONS] = addons
|
payload[ATTR_ADDONS] = addons
|
||||||
|
|
||||||
if ENERGY_DOMAIN in integrations:
|
if ENERGY_DOMAIN in enabled_domains:
|
||||||
payload[ATTR_ENERGY] = {
|
payload[ATTR_ENERGY] = {
|
||||||
ATTR_CONFIGURED: await energy_is_configured(self.hass)
|
ATTR_CONFIGURED: await energy_is_configured(self.hass)
|
||||||
}
|
}
|
||||||
|
|
||||||
if RECORDER_DOMAIN in integrations:
|
if RECORDER_DOMAIN in enabled_domains:
|
||||||
instance = get_recorder_instance(self.hass)
|
instance = get_recorder_instance(self.hass)
|
||||||
engine = instance.database_engine
|
engine = instance.database_engine
|
||||||
if engine and engine.version is not None:
|
if engine and engine.version is not None:
|
||||||
@ -306,3 +337,34 @@ class Analytics:
|
|||||||
LOGGER.error(
|
LOGGER.error(
|
||||||
"Error sending analytics to %s: %r", ANALYTICS_ENDPOINT_URL, err
|
"Error sending analytics to %s: %r", ANALYTICS_ENDPOINT_URL, err
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def _async_should_report_integration(
|
||||||
|
self,
|
||||||
|
integration: Integration,
|
||||||
|
yaml_domains: set[str],
|
||||||
|
entity_registry_platforms: set[str],
|
||||||
|
) -> bool:
|
||||||
|
"""Return a bool to indicate if this integration should be reported."""
|
||||||
|
if integration.disabled:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Check if the integration is defined in YAML or in the entity registry
|
||||||
|
if (
|
||||||
|
integration.domain in yaml_domains
|
||||||
|
or integration.domain in entity_registry_platforms
|
||||||
|
):
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Check if the integration provide a config flow
|
||||||
|
if not integration.config_flow:
|
||||||
|
return False
|
||||||
|
|
||||||
|
entries = self.hass.config_entries.async_entries(integration.domain)
|
||||||
|
|
||||||
|
# Filter out ignored and disabled entries
|
||||||
|
return any(
|
||||||
|
entry
|
||||||
|
for entry in entries
|
||||||
|
if entry.source != SOURCE_IGNORE and entry.disabled_by is None
|
||||||
|
)
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
"""The tests for the analytics ."""
|
"""The tests for the analytics ."""
|
||||||
from unittest.mock import AsyncMock, Mock, PropertyMock, patch
|
import asyncio
|
||||||
|
from typing import Any
|
||||||
|
from unittest.mock import ANY, AsyncMock, Mock, PropertyMock, patch
|
||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
import pytest
|
import pytest
|
||||||
@ -14,11 +16,14 @@ from homeassistant.components.analytics.const import (
|
|||||||
ATTR_USAGE,
|
ATTR_USAGE,
|
||||||
)
|
)
|
||||||
from homeassistant.components.recorder import Recorder
|
from homeassistant.components.recorder import Recorder
|
||||||
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
from homeassistant.const import ATTR_DOMAIN
|
from homeassistant.const import ATTR_DOMAIN
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.loader import IntegrationNotFound
|
from homeassistant.loader import IntegrationNotFound
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry, MockModule, mock_integration
|
||||||
from tests.test_util.aiohttp import AiohttpClientMocker
|
from tests.test_util.aiohttp import AiohttpClientMocker
|
||||||
|
|
||||||
MOCK_UUID = "abcdefg"
|
MOCK_UUID = "abcdefg"
|
||||||
@ -27,6 +32,11 @@ MOCK_VERSION_DEV = "1970.1.0.dev0"
|
|||||||
MOCK_VERSION_NIGHTLY = "1970.1.0.dev19700101"
|
MOCK_VERSION_NIGHTLY = "1970.1.0.dev19700101"
|
||||||
|
|
||||||
|
|
||||||
|
def _last_call_payload(aioclient: AiohttpClientMocker) -> dict[str, Any]:
|
||||||
|
"""Return the payload of the last call."""
|
||||||
|
return aioclient.mock_calls[-1][2]
|
||||||
|
|
||||||
|
|
||||||
async def test_no_send(
|
async def test_no_send(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
caplog: pytest.LogCaptureFixture,
|
caplog: pytest.LogCaptureFixture,
|
||||||
@ -206,18 +216,36 @@ async def test_send_usage(
|
|||||||
assert analytics.preferences[ATTR_USAGE]
|
assert analytics.preferences[ATTR_USAGE]
|
||||||
hass.config.components = ["default_config"]
|
hass.config.components = ["default_config"]
|
||||||
|
|
||||||
with patch("homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION):
|
with patch(
|
||||||
|
"homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION
|
||||||
|
), patch(
|
||||||
|
"homeassistant.config.load_yaml_config_file",
|
||||||
|
return_value={"default_config": {}},
|
||||||
|
), patch(
|
||||||
|
"homeassistant.components.analytics.analytics.async_get_system_info",
|
||||||
|
return_value={"installation_type": "Home Assistant Tests"},
|
||||||
|
):
|
||||||
await analytics.send_analytics()
|
await analytics.send_analytics()
|
||||||
|
|
||||||
assert "'integrations': ['default_config']" in caplog.text
|
assert (
|
||||||
assert "'integration_count':" not in caplog.text
|
"Submitted analytics to Home Assistant servers. Information submitted includes"
|
||||||
assert "'certificate': False" in caplog.text
|
in caplog.text
|
||||||
|
)
|
||||||
|
assert _last_call_payload(aioclient_mock) == {
|
||||||
|
"uuid": ANY,
|
||||||
|
"version": MOCK_VERSION,
|
||||||
|
"installation_type": "Home Assistant Tests",
|
||||||
|
"certificate": False,
|
||||||
|
"integrations": ["default_config"],
|
||||||
|
"custom_integrations": [],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
async def test_send_usage_with_supervisor(
|
async def test_send_usage_with_supervisor(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
caplog: pytest.LogCaptureFixture,
|
caplog: pytest.LogCaptureFixture,
|
||||||
aioclient_mock: AiohttpClientMocker,
|
aioclient_mock: AiohttpClientMocker,
|
||||||
|
mock_hass_config: None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test send usage with supervisor preferences are defined."""
|
"""Test send usage with supervisor preferences are defined."""
|
||||||
aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200)
|
aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200)
|
||||||
@ -284,7 +312,12 @@ async def test_send_statistics(
|
|||||||
assert analytics.preferences[ATTR_STATISTICS]
|
assert analytics.preferences[ATTR_STATISTICS]
|
||||||
hass.config.components = ["default_config"]
|
hass.config.components = ["default_config"]
|
||||||
|
|
||||||
with patch("homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION):
|
with patch(
|
||||||
|
"homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION
|
||||||
|
), patch(
|
||||||
|
"homeassistant.config.load_yaml_config_file",
|
||||||
|
return_value={"default_config": {}},
|
||||||
|
):
|
||||||
await analytics.send_analytics()
|
await analytics.send_analytics()
|
||||||
assert (
|
assert (
|
||||||
"'state_count': 0, 'automation_count': 0, 'integration_count': 1,"
|
"'state_count': 0, 'automation_count': 0, 'integration_count': 1,"
|
||||||
@ -297,6 +330,7 @@ async def test_send_statistics_one_integration_fails(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
caplog: pytest.LogCaptureFixture,
|
caplog: pytest.LogCaptureFixture,
|
||||||
aioclient_mock: AiohttpClientMocker,
|
aioclient_mock: AiohttpClientMocker,
|
||||||
|
mock_hass_config: None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test send statistics preferences are defined."""
|
"""Test send statistics preferences are defined."""
|
||||||
aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200)
|
aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200)
|
||||||
@ -317,10 +351,85 @@ async def test_send_statistics_one_integration_fails(
|
|||||||
assert post_call[2]["integration_count"] == 0
|
assert post_call[2]["integration_count"] == 0
|
||||||
|
|
||||||
|
|
||||||
|
async def test_send_statistics_disabled_integration(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
caplog: pytest.LogCaptureFixture,
|
||||||
|
aioclient_mock: AiohttpClientMocker,
|
||||||
|
mock_hass_config: None,
|
||||||
|
) -> None:
|
||||||
|
"""Test send statistics with disabled integration."""
|
||||||
|
aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200)
|
||||||
|
analytics = Analytics(hass)
|
||||||
|
await analytics.save_preferences({ATTR_BASE: True, ATTR_STATISTICS: True})
|
||||||
|
assert analytics.preferences[ATTR_BASE]
|
||||||
|
assert analytics.preferences[ATTR_STATISTICS]
|
||||||
|
hass.config.components = ["default_config"]
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.analytics.analytics.async_get_integrations",
|
||||||
|
return_value={
|
||||||
|
"disabled_integration_manifest": mock_integration(
|
||||||
|
hass,
|
||||||
|
MockModule(
|
||||||
|
"disabled_integration",
|
||||||
|
async_setup=AsyncMock(return_value=True),
|
||||||
|
partial_manifest={"disabled": "system"},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
), patch("homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION):
|
||||||
|
await analytics.send_analytics()
|
||||||
|
|
||||||
|
payload = _last_call_payload(aioclient_mock)
|
||||||
|
assert "uuid" in payload
|
||||||
|
assert payload["integration_count"] == 0
|
||||||
|
|
||||||
|
|
||||||
|
async def test_send_statistics_ignored_integration(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
caplog: pytest.LogCaptureFixture,
|
||||||
|
aioclient_mock: AiohttpClientMocker,
|
||||||
|
mock_hass_config: None,
|
||||||
|
) -> None:
|
||||||
|
"""Test send statistics with ignored integration."""
|
||||||
|
aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200)
|
||||||
|
analytics = Analytics(hass)
|
||||||
|
await analytics.save_preferences({ATTR_BASE: True, ATTR_STATISTICS: True})
|
||||||
|
assert analytics.preferences[ATTR_BASE]
|
||||||
|
assert analytics.preferences[ATTR_STATISTICS]
|
||||||
|
|
||||||
|
mock_config_entry = MockConfigEntry(
|
||||||
|
domain="ignored_integration",
|
||||||
|
state=ConfigEntryState.LOADED,
|
||||||
|
source="ignore",
|
||||||
|
)
|
||||||
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.analytics.analytics.async_get_integrations",
|
||||||
|
return_value={
|
||||||
|
"ignored_integration": mock_integration(
|
||||||
|
hass,
|
||||||
|
MockModule(
|
||||||
|
"ignored_integration",
|
||||||
|
async_setup=AsyncMock(return_value=True),
|
||||||
|
partial_manifest={"config_flow": True},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
), patch("homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION):
|
||||||
|
await analytics.send_analytics()
|
||||||
|
|
||||||
|
payload = _last_call_payload(aioclient_mock)
|
||||||
|
assert "uuid" in payload
|
||||||
|
assert payload["integration_count"] == 0
|
||||||
|
|
||||||
|
|
||||||
async def test_send_statistics_async_get_integration_unknown_exception(
|
async def test_send_statistics_async_get_integration_unknown_exception(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
caplog: pytest.LogCaptureFixture,
|
caplog: pytest.LogCaptureFixture,
|
||||||
aioclient_mock: AiohttpClientMocker,
|
aioclient_mock: AiohttpClientMocker,
|
||||||
|
mock_hass_config: None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test send statistics preferences are defined."""
|
"""Test send statistics preferences are defined."""
|
||||||
aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200)
|
aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200)
|
||||||
@ -341,6 +450,7 @@ async def test_send_statistics_with_supervisor(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
caplog: pytest.LogCaptureFixture,
|
caplog: pytest.LogCaptureFixture,
|
||||||
aioclient_mock: AiohttpClientMocker,
|
aioclient_mock: AiohttpClientMocker,
|
||||||
|
mock_hass_config: None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test send statistics preferences are defined."""
|
"""Test send statistics preferences are defined."""
|
||||||
aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200)
|
aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200)
|
||||||
@ -421,7 +531,12 @@ async def test_custom_integrations(
|
|||||||
assert await async_setup_component(hass, "test_package", {"test_package": {}})
|
assert await async_setup_component(hass, "test_package", {"test_package": {}})
|
||||||
await analytics.save_preferences({ATTR_BASE: True, ATTR_USAGE: True})
|
await analytics.save_preferences({ATTR_BASE: True, ATTR_USAGE: True})
|
||||||
|
|
||||||
with patch("homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION):
|
with patch(
|
||||||
|
"homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION
|
||||||
|
), patch(
|
||||||
|
"homeassistant.config.load_yaml_config_file",
|
||||||
|
return_value={"test_package": {}},
|
||||||
|
):
|
||||||
await analytics.send_analytics()
|
await analytics.send_analytics()
|
||||||
|
|
||||||
payload = aioclient_mock.mock_calls[0][2]
|
payload = aioclient_mock.mock_calls[0][2]
|
||||||
@ -486,7 +601,9 @@ async def test_nightly_endpoint(
|
|||||||
|
|
||||||
|
|
||||||
async def test_send_with_no_energy(
|
async def test_send_with_no_energy(
|
||||||
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
hass: HomeAssistant,
|
||||||
|
aioclient_mock: AiohttpClientMocker,
|
||||||
|
mock_hass_config: None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test send base preferences are defined."""
|
"""Test send base preferences are defined."""
|
||||||
aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200)
|
aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200)
|
||||||
@ -510,7 +627,10 @@ async def test_send_with_no_energy(
|
|||||||
|
|
||||||
|
|
||||||
async def test_send_with_no_energy_config(
|
async def test_send_with_no_energy_config(
|
||||||
recorder_mock: Recorder, hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
recorder_mock: Recorder,
|
||||||
|
hass: HomeAssistant,
|
||||||
|
aioclient_mock: AiohttpClientMocker,
|
||||||
|
mock_hass_config: None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test send base preferences are defined."""
|
"""Test send base preferences are defined."""
|
||||||
aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200)
|
aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200)
|
||||||
@ -534,7 +654,10 @@ async def test_send_with_no_energy_config(
|
|||||||
|
|
||||||
|
|
||||||
async def test_send_with_energy_config(
|
async def test_send_with_energy_config(
|
||||||
recorder_mock: Recorder, hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
|
recorder_mock: Recorder,
|
||||||
|
hass: HomeAssistant,
|
||||||
|
aioclient_mock: AiohttpClientMocker,
|
||||||
|
mock_hass_config: None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test send base preferences are defined."""
|
"""Test send base preferences are defined."""
|
||||||
aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200)
|
aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200)
|
||||||
@ -561,6 +684,7 @@ async def test_send_usage_with_certificate(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
caplog: pytest.LogCaptureFixture,
|
caplog: pytest.LogCaptureFixture,
|
||||||
aioclient_mock: AiohttpClientMocker,
|
aioclient_mock: AiohttpClientMocker,
|
||||||
|
mock_hass_config: None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test send usage preferences with certificate."""
|
"""Test send usage preferences with certificate."""
|
||||||
aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200)
|
aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200)
|
||||||
@ -570,7 +694,6 @@ async def test_send_usage_with_certificate(
|
|||||||
|
|
||||||
assert analytics.preferences[ATTR_BASE]
|
assert analytics.preferences[ATTR_BASE]
|
||||||
assert analytics.preferences[ATTR_USAGE]
|
assert analytics.preferences[ATTR_USAGE]
|
||||||
hass.config.components = ["default_config"]
|
|
||||||
|
|
||||||
with patch("homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION):
|
with patch("homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION):
|
||||||
await analytics.send_analytics()
|
await analytics.send_analytics()
|
||||||
@ -590,8 +713,101 @@ async def test_send_with_recorder(
|
|||||||
|
|
||||||
await analytics.save_preferences({ATTR_BASE: True, ATTR_USAGE: True})
|
await analytics.save_preferences({ATTR_BASE: True, ATTR_USAGE: True})
|
||||||
|
|
||||||
with patch("homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION):
|
with patch(
|
||||||
|
"homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION
|
||||||
|
), patch(
|
||||||
|
"homeassistant.config.load_yaml_config_file",
|
||||||
|
return_value={"recorder": {}},
|
||||||
|
):
|
||||||
await analytics.send_analytics()
|
await analytics.send_analytics()
|
||||||
|
|
||||||
postdata = aioclient_mock.mock_calls[-1][2]
|
postdata = _last_call_payload(aioclient_mock)
|
||||||
assert postdata["recorder"]["engine"] == "sqlite"
|
assert postdata["recorder"]["engine"] == "sqlite"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_send_with_problems_loading_yaml(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
caplog: pytest.LogCaptureFixture,
|
||||||
|
aioclient_mock: AiohttpClientMocker,
|
||||||
|
) -> None:
|
||||||
|
"""Test error loading YAML configuration."""
|
||||||
|
analytics = Analytics(hass)
|
||||||
|
|
||||||
|
await analytics.save_preferences({ATTR_BASE: True, ATTR_USAGE: True})
|
||||||
|
with patch(
|
||||||
|
"homeassistant.config.load_yaml_config_file",
|
||||||
|
side_effect=HomeAssistantError("Error loading YAML file"),
|
||||||
|
):
|
||||||
|
await analytics.send_analytics()
|
||||||
|
|
||||||
|
assert "Error loading YAML file" in caplog.text
|
||||||
|
assert len(aioclient_mock.mock_calls) == 0
|
||||||
|
|
||||||
|
|
||||||
|
async def test_timeout_while_sending(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
caplog: pytest.LogCaptureFixture,
|
||||||
|
aioclient_mock: AiohttpClientMocker,
|
||||||
|
mock_hass_config: None,
|
||||||
|
) -> None:
|
||||||
|
"""Test timeout error while sending analytics."""
|
||||||
|
analytics = Analytics(hass)
|
||||||
|
aioclient_mock.post(ANALYTICS_ENDPOINT_URL_DEV, exc=asyncio.TimeoutError())
|
||||||
|
|
||||||
|
await analytics.save_preferences({ATTR_BASE: True})
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION_DEV
|
||||||
|
):
|
||||||
|
await analytics.send_analytics()
|
||||||
|
|
||||||
|
assert "Timeout sending analytics" in caplog.text
|
||||||
|
|
||||||
|
|
||||||
|
async def test_not_check_config_entries_if_yaml(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
caplog: pytest.LogCaptureFixture,
|
||||||
|
aioclient_mock: AiohttpClientMocker,
|
||||||
|
) -> None:
|
||||||
|
"""Test skip config entry check if defined in yaml."""
|
||||||
|
aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200)
|
||||||
|
analytics = Analytics(hass)
|
||||||
|
hass.http = Mock(ssl_certificate="/some/path/to/cert.pem")
|
||||||
|
|
||||||
|
await analytics.save_preferences(
|
||||||
|
{ATTR_BASE: True, ATTR_STATISTICS: True, ATTR_USAGE: True}
|
||||||
|
)
|
||||||
|
assert analytics.preferences[ATTR_BASE]
|
||||||
|
assert analytics.preferences[ATTR_STATISTICS]
|
||||||
|
hass.config.components = ["default_config"]
|
||||||
|
|
||||||
|
mock_config_entry = MockConfigEntry(
|
||||||
|
domain="ignored_integration",
|
||||||
|
state=ConfigEntryState.LOADED,
|
||||||
|
source="ignore",
|
||||||
|
disabled_by="user",
|
||||||
|
)
|
||||||
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.analytics.analytics.async_get_integrations",
|
||||||
|
return_value={
|
||||||
|
"default_config": mock_integration(
|
||||||
|
hass,
|
||||||
|
MockModule(
|
||||||
|
"default_config",
|
||||||
|
async_setup=AsyncMock(return_value=True),
|
||||||
|
partial_manifest={"config_flow": True},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
), patch(
|
||||||
|
"homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION
|
||||||
|
), patch(
|
||||||
|
"homeassistant.config.load_yaml_config_file",
|
||||||
|
return_value={"default_config": {}},
|
||||||
|
):
|
||||||
|
await analytics.send_analytics()
|
||||||
|
|
||||||
|
payload = _last_call_payload(aioclient_mock)
|
||||||
|
assert payload["integration_count"] == 1
|
||||||
|
assert payload["integrations"] == ["default_config"]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user