"""The tests for the analytics .""" from typing import Any from unittest.mock import ANY, AsyncMock, Mock, PropertyMock, patch import aiohttp import pytest from homeassistant.components.analytics.analytics import Analytics from homeassistant.components.analytics.const import ( ANALYTICS_ENDPOINT_URL, ANALYTICS_ENDPOINT_URL_DEV, ATTR_BASE, ATTR_DIAGNOSTICS, ATTR_STATISTICS, ATTR_USAGE, ) from homeassistant.components.recorder import Recorder from homeassistant.config_entries import ConfigEntryState from homeassistant.const import ATTR_DOMAIN from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.loader import IntegrationNotFound from homeassistant.setup import async_setup_component from tests.common import MockConfigEntry, MockModule, mock_integration from tests.test_util.aiohttp import AiohttpClientMocker MOCK_UUID = "abcdefg" MOCK_VERSION = "1970.1.0" MOCK_VERSION_DEV = "1970.1.0.dev0" 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( hass: HomeAssistant, caplog: pytest.LogCaptureFixture, aioclient_mock: AiohttpClientMocker, ) -> None: """Test send when no preferences are defined.""" analytics = Analytics(hass) with patch( "homeassistant.components.hassio.is_hassio", side_effect=Mock(return_value=False), ): assert not analytics.preferences[ATTR_BASE] await analytics.send_analytics() assert "Nothing to submit" in caplog.text assert len(aioclient_mock.mock_calls) == 0 async def test_load_with_supervisor_diagnostics(hass: HomeAssistant) -> None: """Test loading with a supervisor that has diagnostics enabled.""" analytics = Analytics(hass) assert not analytics.preferences[ATTR_DIAGNOSTICS] with patch( "homeassistant.components.hassio.get_supervisor_info", side_effect=Mock(return_value={"diagnostics": True}), ), patch( "homeassistant.components.hassio.is_hassio", side_effect=Mock(return_value=True), ): await analytics.load() assert analytics.preferences[ATTR_DIAGNOSTICS] async def test_load_with_supervisor_without_diagnostics(hass: HomeAssistant) -> None: """Test loading with a supervisor that has not diagnostics enabled.""" analytics = Analytics(hass) analytics._data.preferences[ATTR_DIAGNOSTICS] = True assert analytics.preferences[ATTR_DIAGNOSTICS] with patch( "homeassistant.components.hassio.get_supervisor_info", side_effect=Mock(return_value={"diagnostics": False}), ), patch( "homeassistant.components.hassio.is_hassio", side_effect=Mock(return_value=True), ): await analytics.load() assert not analytics.preferences[ATTR_DIAGNOSTICS] async def test_failed_to_send( hass: HomeAssistant, caplog: pytest.LogCaptureFixture, aioclient_mock: AiohttpClientMocker, ) -> None: """Test failed to send payload.""" aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=400) analytics = Analytics(hass) await analytics.save_preferences({ATTR_BASE: True}) assert analytics.preferences[ATTR_BASE] with patch("homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION): await analytics.send_analytics() assert ( f"Sending analytics failed with statuscode 400 from {ANALYTICS_ENDPOINT_URL}" in caplog.text ) async def test_failed_to_send_raises( hass: HomeAssistant, caplog: pytest.LogCaptureFixture, aioclient_mock: AiohttpClientMocker, ) -> None: """Test raises when failed to send payload.""" aioclient_mock.post(ANALYTICS_ENDPOINT_URL, exc=aiohttp.ClientError()) analytics = Analytics(hass) await analytics.save_preferences({ATTR_BASE: True}) assert analytics.preferences[ATTR_BASE] with patch("homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION): await analytics.send_analytics() assert "Error sending analytics" in caplog.text async def test_send_base( hass: HomeAssistant, caplog: pytest.LogCaptureFixture, aioclient_mock: AiohttpClientMocker, ) -> None: """Test send base preferences are defined.""" aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200) analytics = Analytics(hass) await analytics.save_preferences({ATTR_BASE: True}) assert analytics.preferences[ATTR_BASE] with patch("uuid.UUID.hex", new_callable=PropertyMock) as hex, patch( "homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION ): hex.return_value = MOCK_UUID await analytics.send_analytics() assert f"'uuid': '{MOCK_UUID}'" in caplog.text assert f"'version': '{MOCK_VERSION}'" in caplog.text assert "'installation_type':" in caplog.text assert "'integration_count':" not in caplog.text assert "'integrations':" not in caplog.text async def test_send_base_with_supervisor( hass: HomeAssistant, caplog: pytest.LogCaptureFixture, aioclient_mock: AiohttpClientMocker, ) -> None: """Test send base preferences are defined.""" aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200) analytics = Analytics(hass) await analytics.save_preferences({ATTR_BASE: True}) assert analytics.preferences[ATTR_BASE] with patch( "homeassistant.components.hassio.get_supervisor_info", side_effect=Mock( return_value={"supported": True, "healthy": True, "arch": "amd64"} ), ), patch( "homeassistant.components.hassio.get_os_info", side_effect=Mock(return_value={"board": "blue", "version": "123"}), ), patch( "homeassistant.components.hassio.get_info", side_effect=Mock(return_value={}), ), patch( "homeassistant.components.hassio.get_host_info", side_effect=Mock(return_value={}), ), patch( "homeassistant.components.hassio.is_hassio", side_effect=Mock(return_value=True), ), patch( "uuid.UUID.hex", new_callable=PropertyMock, ) as hex, patch( "homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION, ): hex.return_value = MOCK_UUID await analytics.load() await analytics.send_analytics() assert f"'uuid': '{MOCK_UUID}'" in caplog.text assert f"'version': '{MOCK_VERSION}'" in caplog.text assert ( "'supervisor': {'healthy': True, 'supported': True, 'arch': 'amd64'}" in caplog.text ) assert "'operating_system': {'board': 'blue', 'version': '123'}" in caplog.text assert "'installation_type':" in caplog.text assert "'integration_count':" not in caplog.text assert "'integrations':" not in caplog.text async def test_send_usage( hass: HomeAssistant, caplog: pytest.LogCaptureFixture, aioclient_mock: AiohttpClientMocker, ) -> None: """Test send usage preferences are defined.""" aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200) analytics = Analytics(hass) hass.http = Mock(ssl_certificate=None) await analytics.save_preferences({ATTR_BASE: True, ATTR_USAGE: True}) assert analytics.preferences[ATTR_BASE] assert analytics.preferences[ATTR_USAGE] hass.config.components = ["default_config"] 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() assert ( "Submitted analytics to Home Assistant servers. Information submitted includes" 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( hass: HomeAssistant, caplog: pytest.LogCaptureFixture, aioclient_mock: AiohttpClientMocker, mock_hass_config: None, ) -> None: """Test send usage with supervisor preferences are defined.""" aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200) analytics = Analytics(hass) hass.http = Mock(ssl_certificate=None) await analytics.save_preferences({ATTR_BASE: True, ATTR_USAGE: True}) assert analytics.preferences[ATTR_BASE] assert analytics.preferences[ATTR_USAGE] hass.config.components = ["default_config"] with patch( "homeassistant.components.hassio.get_supervisor_info", side_effect=Mock( return_value={ "healthy": True, "supported": True, "arch": "amd64", "addons": [{"slug": "test_addon"}], } ), ), patch( "homeassistant.components.hassio.get_os_info", side_effect=Mock(return_value={}), ), patch( "homeassistant.components.hassio.get_info", side_effect=Mock(return_value={}), ), patch( "homeassistant.components.hassio.get_host_info", side_effect=Mock(return_value={}), ), patch( "homeassistant.components.hassio.async_get_addon_info", side_effect=AsyncMock( return_value={ "slug": "test_addon", "protected": True, "version": "1", "auto_update": False, } ), ), patch( "homeassistant.components.hassio.is_hassio", side_effect=Mock(return_value=True), ), patch( "homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION, ): await analytics.send_analytics() assert ( "'addons': [{'slug': 'test_addon', 'protected': True, 'version': '1'," " 'auto_update': False}]" ) in caplog.text assert "'addon_count':" not in caplog.text async def test_send_statistics( hass: HomeAssistant, caplog: pytest.LogCaptureFixture, aioclient_mock: AiohttpClientMocker, ) -> None: """Test send statistics preferences are defined.""" 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.HA_VERSION", MOCK_VERSION ), patch( "homeassistant.config.load_yaml_config_file", return_value={"default_config": {}}, ): await analytics.send_analytics() assert ( "'state_count': 0, 'automation_count': 0, 'integration_count': 1," " 'user_count': 0" ) in caplog.text assert "'integrations':" not in caplog.text async def test_send_statistics_one_integration_fails( hass: HomeAssistant, caplog: pytest.LogCaptureFixture, aioclient_mock: AiohttpClientMocker, mock_hass_config: None, ) -> None: """Test send statistics preferences are defined.""" 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={"any": IntegrationNotFound("any")}, ), patch("homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION): await analytics.send_analytics() post_call = aioclient_mock.mock_calls[0] assert "uuid" in post_call[2] 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( hass: HomeAssistant, caplog: pytest.LogCaptureFixture, aioclient_mock: AiohttpClientMocker, mock_hass_config: None, ) -> None: """Test send statistics preferences are defined.""" 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 pytest.raises(ValueError), patch( "homeassistant.components.analytics.analytics.async_get_integrations", return_value={"any": ValueError()}, ), patch("homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION): await analytics.send_analytics() async def test_send_statistics_with_supervisor( hass: HomeAssistant, caplog: pytest.LogCaptureFixture, aioclient_mock: AiohttpClientMocker, mock_hass_config: None, ) -> None: """Test send statistics preferences are defined.""" 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] with patch( "homeassistant.components.hassio.get_supervisor_info", side_effect=Mock( return_value={ "healthy": True, "supported": True, "arch": "amd64", "addons": [{"slug": "test_addon"}], } ), ), patch( "homeassistant.components.hassio.get_os_info", side_effect=Mock(return_value={}), ), patch( "homeassistant.components.hassio.get_info", side_effect=Mock(return_value={}), ), patch( "homeassistant.components.hassio.get_host_info", side_effect=Mock(return_value={}), ), patch( "homeassistant.components.hassio.async_get_addon_info", side_effect=AsyncMock( return_value={ "slug": "test_addon", "protected": True, "version": "1", "auto_update": False, } ), ), patch( "homeassistant.components.hassio.is_hassio", side_effect=Mock(return_value=True), ), patch( "homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION, ): await analytics.send_analytics() assert "'addon_count': 1" in caplog.text assert "'integrations':" not in caplog.text async def test_reusing_uuid( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker ) -> None: """Test reusing the stored UUID.""" aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200) analytics = Analytics(hass) analytics._data.uuid = "NOT_MOCK_UUID" await analytics.save_preferences({ATTR_BASE: True}) with patch("uuid.UUID.hex", new_callable=PropertyMock) as hex, patch( "homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION ): # This is not actually called but that in itself prove the test hex.return_value = MOCK_UUID await analytics.send_analytics() assert analytics.uuid == "NOT_MOCK_UUID" async def test_custom_integrations( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, enable_custom_integrations: None, ) -> None: """Test sending custom integrations.""" aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200) analytics = Analytics(hass) hass.http = Mock(ssl_certificate=None) assert await async_setup_component(hass, "test_package", {"test_package": {}}) await analytics.save_preferences({ATTR_BASE: True, ATTR_USAGE: True}) 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() payload = aioclient_mock.mock_calls[0][2] assert payload["custom_integrations"][0][ATTR_DOMAIN] == "test_package" async def test_dev_url( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker ) -> None: """Test sending payload to dev url.""" aioclient_mock.post(ANALYTICS_ENDPOINT_URL_DEV, status=200) analytics = Analytics(hass) await analytics.save_preferences({ATTR_BASE: True}) with patch( "homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION_DEV ): await analytics.send_analytics() payload = aioclient_mock.mock_calls[0] assert str(payload[1]) == ANALYTICS_ENDPOINT_URL_DEV async def test_dev_url_error( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, caplog: pytest.LogCaptureFixture, ) -> None: """Test sending payload to dev url that returns error.""" aioclient_mock.post(ANALYTICS_ENDPOINT_URL_DEV, status=400) analytics = Analytics(hass) await analytics.save_preferences({ATTR_BASE: True}) with patch( "homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION_DEV ): await analytics.send_analytics() payload = aioclient_mock.mock_calls[0] assert str(payload[1]) == ANALYTICS_ENDPOINT_URL_DEV assert ( "Sending analytics failed with statuscode 400 from" f" {ANALYTICS_ENDPOINT_URL_DEV}" ) in caplog.text async def test_nightly_endpoint( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker ) -> None: """Test sending payload to production url when running nightly.""" aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200) analytics = Analytics(hass) await analytics.save_preferences({ATTR_BASE: True}) with patch( "homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION_NIGHTLY ): await analytics.send_analytics() payload = aioclient_mock.mock_calls[0] assert str(payload[1]) == ANALYTICS_ENDPOINT_URL async def test_send_with_no_energy( hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, mock_hass_config: None, ) -> None: """Test send base preferences are defined.""" aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200) analytics = Analytics(hass) hass.http = Mock(ssl_certificate=None) await analytics.save_preferences({ATTR_BASE: True, ATTR_USAGE: True}) with patch("uuid.UUID.hex", new_callable=PropertyMock) as hex, patch( "homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION ), patch( "homeassistant.components.analytics.analytics.energy_is_configured", AsyncMock() ) as energy_is_configured: energy_is_configured.return_value = False hex.return_value = MOCK_UUID await analytics.send_analytics() postdata = aioclient_mock.mock_calls[-1][2] assert "energy" not in postdata async def test_send_with_no_energy_config( recorder_mock: Recorder, hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, mock_hass_config: None, ) -> None: """Test send base preferences are defined.""" aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200) analytics = Analytics(hass) await analytics.save_preferences({ATTR_BASE: True, ATTR_USAGE: True}) assert await async_setup_component(hass, "energy", {}) with patch("uuid.UUID.hex", new_callable=PropertyMock) as hex, patch( "homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION ), patch( "homeassistant.components.analytics.analytics.energy_is_configured", AsyncMock() ) as energy_is_configured: energy_is_configured.return_value = False hex.return_value = MOCK_UUID await analytics.send_analytics() postdata = aioclient_mock.mock_calls[-1][2] assert not postdata["energy"]["configured"] async def test_send_with_energy_config( recorder_mock: Recorder, hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, mock_hass_config: None, ) -> None: """Test send base preferences are defined.""" aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200) analytics = Analytics(hass) await analytics.save_preferences({ATTR_BASE: True, ATTR_USAGE: True}) assert await async_setup_component(hass, "energy", {}) with patch("uuid.UUID.hex", new_callable=PropertyMock) as hex, patch( "homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION ), patch( "homeassistant.components.analytics.analytics.energy_is_configured", AsyncMock() ) as energy_is_configured: energy_is_configured.return_value = True hex.return_value = MOCK_UUID await analytics.send_analytics() postdata = aioclient_mock.mock_calls[-1][2] assert postdata["energy"]["configured"] async def test_send_usage_with_certificate( hass: HomeAssistant, caplog: pytest.LogCaptureFixture, aioclient_mock: AiohttpClientMocker, mock_hass_config: None, ) -> None: """Test send usage preferences with certificate.""" 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_USAGE: True}) assert analytics.preferences[ATTR_BASE] assert analytics.preferences[ATTR_USAGE] with patch("homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION): await analytics.send_analytics() assert "'certificate': True" in caplog.text async def test_send_with_recorder( recorder_mock: Recorder, hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, ) -> None: """Test recorder information.""" 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_USAGE: True}) with patch( "homeassistant.components.analytics.analytics.HA_VERSION", MOCK_VERSION ), patch( "homeassistant.config.load_yaml_config_file", return_value={"recorder": {}}, ): await analytics.send_analytics() postdata = _last_call_payload(aioclient_mock) 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=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"]