diff --git a/homeassistant/components/esphome/diagnostics.py b/homeassistant/components/esphome/diagnostics.py new file mode 100644 index 00000000000..4d9b769791c --- /dev/null +++ b/homeassistant/components/esphome/diagnostics.py @@ -0,0 +1,32 @@ +"""Diahgnostics support for ESPHome.""" +from __future__ import annotations + +from typing import Any, cast + +from homeassistant.components.diagnostics import async_redact_data +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import CONF_PASSWORD +from homeassistant.core import HomeAssistant + +from . import CONF_NOISE_PSK, DomainData + +CONF_MAC_ADDRESS = "mac_address" + +REDACT_KEYS = {CONF_NOISE_PSK, CONF_PASSWORD, CONF_MAC_ADDRESS} + + +async def async_get_config_entry_diagnostics( + hass: HomeAssistant, config_entry: ConfigEntry +) -> dict[str, Any]: + """Return diagnostics for a config entry.""" + diag: dict[str, Any] = {} + + diag["config"] = config_entry.as_dict() + + entry_data = DomainData.get(hass).get_entry_data(config_entry) + + if (storage_data := await entry_data.store.async_load()) is not None: + storage_data = cast("dict[str, Any]", storage_data) + diag["storage_data"] = storage_data + + return async_redact_data(diag, REDACT_KEYS) diff --git a/tests/components/esphome/conftest.py b/tests/components/esphome/conftest.py index 91368044723..7cf25f13015 100644 --- a/tests/components/esphome/conftest.py +++ b/tests/components/esphome/conftest.py @@ -1,8 +1,42 @@ """esphome session fixtures.""" - import pytest +from homeassistant.components.esphome import CONF_NOISE_PSK, DOMAIN +from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_PORT +from homeassistant.core import HomeAssistant + +from tests.common import MockConfigEntry + @pytest.fixture(autouse=True) def esphome_mock_async_zeroconf(mock_async_zeroconf): """Auto mock zeroconf.""" + + +@pytest.fixture +def mock_config_entry() -> MockConfigEntry: + """Return the default mocked config entry.""" + return MockConfigEntry( + title="ESPHome Device", + domain=DOMAIN, + data={ + CONF_HOST: "192.168.1.2", + CONF_PORT: 6053, + CONF_PASSWORD: "", + CONF_NOISE_PSK: "12345678123456781234567812345678", + }, + unique_id="esphome-device", + ) + + +@pytest.fixture +async def init_integration( + hass: HomeAssistant, mock_config_entry: MockConfigEntry +) -> MockConfigEntry: + """Set up the ESPHome integration for testing.""" + mock_config_entry.add_to_hass(hass) + + await hass.config_entries.async_setup(mock_config_entry.entry_id) + await hass.async_block_till_done() + + return mock_config_entry diff --git a/tests/components/esphome/test_diagnostics.py b/tests/components/esphome/test_diagnostics.py new file mode 100644 index 00000000000..319bc2602e1 --- /dev/null +++ b/tests/components/esphome/test_diagnostics.py @@ -0,0 +1,26 @@ +"""Tests for the diagnostics data provided by the ESPHome integration.""" + +from aiohttp import ClientSession + +from homeassistant.components.esphome import CONF_NOISE_PSK +from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_PORT +from homeassistant.core import HomeAssistant + +from tests.common import MockConfigEntry +from tests.components.diagnostics import get_diagnostics_for_config_entry + + +async def test_diagnostics( + hass: HomeAssistant, hass_client: ClientSession, init_integration: MockConfigEntry +): + """Test diagnostics for config entry.""" + result = await get_diagnostics_for_config_entry(hass, hass_client, init_integration) + + assert isinstance(result, dict) + assert result["config"]["data"] == { + CONF_HOST: "192.168.1.2", + CONF_PORT: 6053, + CONF_PASSWORD: "**REDACTED**", + CONF_NOISE_PSK: "**REDACTED**", + } + assert result["config"]["unique_id"] == "esphome-device"