From 5975eca2c0bdc6810f016d9665f2512d929838a6 Mon Sep 17 00:00:00 2001 From: Tsvi Mostovicz Date: Mon, 19 May 2025 07:35:28 +0000 Subject: [PATCH 1/3] Implement diagnostics --- .../components/jewish_calendar/diagnostics.py | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 homeassistant/components/jewish_calendar/diagnostics.py diff --git a/homeassistant/components/jewish_calendar/diagnostics.py b/homeassistant/components/jewish_calendar/diagnostics.py new file mode 100644 index 0000000000000..cc02ca10fa509 --- /dev/null +++ b/homeassistant/components/jewish_calendar/diagnostics.py @@ -0,0 +1,26 @@ +"""Diagnostics support for Jewish Calendar integration.""" + +from typing import Any + +from homeassistant.components.diagnostics import async_redact_data +from homeassistant.const import CONF_ELEVATION, CONF_LATITUDE, CONF_LONGITUDE +from homeassistant.core import HomeAssistant + +from .entity import JewishCalendarConfigEntry + +TO_REDACT = [ + CONF_ELEVATION, + CONF_LATITUDE, + CONF_LONGITUDE, +] + + +async def async_get_config_entry_diagnostics( + hass: HomeAssistant, entry: JewishCalendarConfigEntry +) -> dict[str, Any]: + """Return diagnostics for a config entry.""" + + return { + "entry_data": async_redact_data(entry.data, TO_REDACT), + "data": entry.runtime_data, + } From 6159f00e2aea4c0945eb9b6934be9630e8b17fa1 Mon Sep 17 00:00:00 2001 From: Tsvi Mostovicz Date: Mon, 19 May 2025 16:36:38 +0000 Subject: [PATCH 2/3] Add testing --- .../components/jewish_calendar/const.py | 1 + .../components/jewish_calendar/diagnostics.py | 8 +- tests/components/jewish_calendar/conftest.py | 2 +- .../snapshots/test_diagnostics.ambr | 77 +++++++++++++++++++ .../jewish_calendar/test_diagnostics.py | 47 +++++++++++ 5 files changed, 131 insertions(+), 4 deletions(-) create mode 100644 tests/components/jewish_calendar/snapshots/test_diagnostics.ambr create mode 100644 tests/components/jewish_calendar/test_diagnostics.py diff --git a/homeassistant/components/jewish_calendar/const.py b/homeassistant/components/jewish_calendar/const.py index 3c5b754fee482..b3a0dea5da0a9 100644 --- a/homeassistant/components/jewish_calendar/const.py +++ b/homeassistant/components/jewish_calendar/const.py @@ -6,6 +6,7 @@ ATTR_DATE = "date" ATTR_NUSACH = "nusach" +CONF_ALTITUDE = "altitude" # The name used by the hdate library for elevation CONF_DIASPORA = "diaspora" CONF_CANDLE_LIGHT_MINUTES = "candle_lighting_minutes_before_sunset" CONF_HAVDALAH_OFFSET_MINUTES = "havdalah_minutes_after_sunset" diff --git a/homeassistant/components/jewish_calendar/diagnostics.py b/homeassistant/components/jewish_calendar/diagnostics.py index cc02ca10fa509..27415282b6df5 100644 --- a/homeassistant/components/jewish_calendar/diagnostics.py +++ b/homeassistant/components/jewish_calendar/diagnostics.py @@ -1,15 +1,17 @@ """Diagnostics support for Jewish Calendar integration.""" +from dataclasses import asdict from typing import Any from homeassistant.components.diagnostics import async_redact_data -from homeassistant.const import CONF_ELEVATION, CONF_LATITUDE, CONF_LONGITUDE +from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE from homeassistant.core import HomeAssistant +from .const import CONF_ALTITUDE from .entity import JewishCalendarConfigEntry TO_REDACT = [ - CONF_ELEVATION, + CONF_ALTITUDE, CONF_LATITUDE, CONF_LONGITUDE, ] @@ -22,5 +24,5 @@ async def async_get_config_entry_diagnostics( return { "entry_data": async_redact_data(entry.data, TO_REDACT), - "data": entry.runtime_data, + "data": async_redact_data(asdict(entry.runtime_data), TO_REDACT), } diff --git a/tests/components/jewish_calendar/conftest.py b/tests/components/jewish_calendar/conftest.py index 5cd7ad3408536..568affb9ab6ba 100644 --- a/tests/components/jewish_calendar/conftest.py +++ b/tests/components/jewish_calendar/conftest.py @@ -49,7 +49,7 @@ def mock_setup_entry() -> Generator[AsyncMock]: @pytest.fixture def location_data(request: pytest.FixtureRequest) -> _LocationData | None: """Return data based on location name.""" - if not hasattr(request, "param"): + if not hasattr(request, "param") or request.param is None: return None return LOCATIONS[request.param] diff --git a/tests/components/jewish_calendar/snapshots/test_diagnostics.ambr b/tests/components/jewish_calendar/snapshots/test_diagnostics.ambr new file mode 100644 index 0000000000000..8dfd04afc08c8 --- /dev/null +++ b/tests/components/jewish_calendar/snapshots/test_diagnostics.ambr @@ -0,0 +1,77 @@ +# serializer version: 1 +# name: test_diagnostics[Jerusalem] + dict({ + 'data': dict({ + 'candle_lighting_offset': 40, + 'diaspora': False, + 'havdalah_offset': 0, + 'language': 'en', + 'location': dict({ + 'altitude': '**REDACTED**', + 'diaspora': False, + 'latitude': '**REDACTED**', + 'longitude': '**REDACTED**', + 'name': 'test home', + 'timezone': dict({ + '__type': "", + 'repr': "zoneinfo.ZoneInfo(key='Asia/Jerusalem')", + }), + }), + }), + 'entry_data': dict({ + 'diaspora': False, + 'language': 'en', + 'time_zone': 'Asia/Jerusalem', + }), + }) +# --- +# name: test_diagnostics[New York] + dict({ + 'data': dict({ + 'candle_lighting_offset': 18, + 'diaspora': True, + 'havdalah_offset': 0, + 'language': 'en', + 'location': dict({ + 'altitude': '**REDACTED**', + 'diaspora': True, + 'latitude': '**REDACTED**', + 'longitude': '**REDACTED**', + 'name': 'test home', + 'timezone': dict({ + '__type': "", + 'repr': "zoneinfo.ZoneInfo(key='America/New_York')", + }), + }), + }), + 'entry_data': dict({ + 'diaspora': True, + 'language': 'en', + 'time_zone': 'America/New_York', + }), + }) +# --- +# name: test_diagnostics[None] + dict({ + 'data': dict({ + 'candle_lighting_offset': 18, + 'diaspora': False, + 'havdalah_offset': 0, + 'language': 'en', + 'location': dict({ + 'altitude': '**REDACTED**', + 'diaspora': False, + 'latitude': '**REDACTED**', + 'longitude': '**REDACTED**', + 'name': 'test home', + 'timezone': dict({ + '__type': "", + 'repr': "zoneinfo.ZoneInfo(key='US/Pacific')", + }), + }), + }), + 'entry_data': dict({ + 'language': 'en', + }), + }) +# --- diff --git a/tests/components/jewish_calendar/test_diagnostics.py b/tests/components/jewish_calendar/test_diagnostics.py new file mode 100644 index 0000000000000..4754257fa5abf --- /dev/null +++ b/tests/components/jewish_calendar/test_diagnostics.py @@ -0,0 +1,47 @@ +"""Tests for the diagnostics data provided by the Jewish Calendar integration.""" + +import pytest +from syrupy.assertion import SnapshotAssertion + +from homeassistant.components.jewish_calendar.diagnostics import TO_REDACT +from homeassistant.core import HomeAssistant + +from tests.common import MockConfigEntry +from tests.components.diagnostics import get_diagnostics_for_config_entry +from tests.typing import ClientSessionGenerator + + +@pytest.mark.parametrize( + ("location_data"), + ["Jerusalem", "New York", None], + indirect=True, +) +async def test_diagnostics( + hass: HomeAssistant, + config_entry: MockConfigEntry, + hass_client: ClientSessionGenerator, + snapshot: SnapshotAssertion, +) -> None: + """Test diagnostics with different locations.""" + config_entry.add_to_hass(hass) + await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + diagnostics_data = await get_diagnostics_for_config_entry( + hass, hass_client, config_entry + ) + + # Verify that location data is redacted in entry_data + for key in TO_REDACT: + if key in diagnostics_data["entry_data"]: + assert diagnostics_data["entry_data"][key] == "**REDACTED**" + + # Verify the runtime_data is included and location properties are redacted + assert "data" in diagnostics_data + if "location" in diagnostics_data["data"]: + for key in TO_REDACT: + assert key in diagnostics_data["data"]["location"] + assert diagnostics_data["data"]["location"][key] == "**REDACTED**" + + # Complete snapshot test + assert diagnostics_data == snapshot From a27bc1110bd92ab1cc9f6e72e29a6da76b8eb226 Mon Sep 17 00:00:00 2001 From: Tsvi Mostovicz Date: Mon, 19 May 2025 16:49:07 +0000 Subject: [PATCH 3/3] Remove implicitly tested code --- .../jewish_calendar/test_diagnostics.py | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/tests/components/jewish_calendar/test_diagnostics.py b/tests/components/jewish_calendar/test_diagnostics.py index 4754257fa5abf..cd3ace24c8c4f 100644 --- a/tests/components/jewish_calendar/test_diagnostics.py +++ b/tests/components/jewish_calendar/test_diagnostics.py @@ -3,7 +3,6 @@ import pytest from syrupy.assertion import SnapshotAssertion -from homeassistant.components.jewish_calendar.diagnostics import TO_REDACT from homeassistant.core import HomeAssistant from tests.common import MockConfigEntry @@ -12,9 +11,7 @@ @pytest.mark.parametrize( - ("location_data"), - ["Jerusalem", "New York", None], - indirect=True, + ("location_data"), ["Jerusalem", "New York", None], indirect=True ) async def test_diagnostics( hass: HomeAssistant, @@ -31,17 +28,4 @@ async def test_diagnostics( hass, hass_client, config_entry ) - # Verify that location data is redacted in entry_data - for key in TO_REDACT: - if key in diagnostics_data["entry_data"]: - assert diagnostics_data["entry_data"][key] == "**REDACTED**" - - # Verify the runtime_data is included and location properties are redacted - assert "data" in diagnostics_data - if "location" in diagnostics_data["data"]: - for key in TO_REDACT: - assert key in diagnostics_data["data"]["location"] - assert diagnostics_data["data"]["location"][key] == "**REDACTED**" - - # Complete snapshot test assert diagnostics_data == snapshot