Add repairs from issue registry to integration diagnostics (#148498)

This commit is contained in:
G Johansson 2025-07-09 19:52:16 +02:00 committed by GitHub
parent 3045f67ae5
commit 57083d877e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 73 additions and 3 deletions

View File

@ -19,6 +19,7 @@ from homeassistant.helpers import (
config_validation as cv,
device_registry as dr,
integration_platform,
issue_registry as ir,
)
from homeassistant.helpers.device_registry import DeviceEntry
from homeassistant.helpers.json import (
@ -187,6 +188,7 @@ def async_format_manifest(manifest: Manifest) -> Manifest:
async def _async_get_json_file_response(
hass: HomeAssistant,
data: Mapping[str, Any],
data_issues: list[dict[str, Any]] | None,
filename: str,
domain: str,
d_id: str,
@ -213,6 +215,8 @@ async def _async_get_json_file_response(
"setup_times": async_get_domain_setup_times(hass, domain),
"data": data,
}
if data_issues is not None:
payload["issues"] = data_issues
try:
json_data = json.dumps(payload, indent=2, cls=ExtendedJSONEncoder)
except TypeError:
@ -275,6 +279,14 @@ class DownloadDiagnosticsView(http.HomeAssistantView):
filename = f"{config_entry.domain}-{config_entry.entry_id}"
issue_registry = ir.async_get(hass)
issues = issue_registry.issues
data_issues = [
issue_reg.to_json()
for issue_id, issue_reg in issues.items()
if issue_id[0] == config_entry.domain
]
if not device_diagnostics:
# Config entry diagnostics
if info.config_entry_diagnostics is None:
@ -282,7 +294,7 @@ class DownloadDiagnosticsView(http.HomeAssistantView):
data = await info.config_entry_diagnostics(hass, config_entry)
filename = f"{DiagnosticsType.CONFIG_ENTRY}-{filename}"
return await _async_get_json_file_response(
hass, data, filename, config_entry.domain, d_id
hass, data, data_issues, filename, config_entry.domain, d_id
)
# Device diagnostics
@ -300,5 +312,5 @@ class DownloadDiagnosticsView(http.HomeAssistantView):
data = await info.device_diagnostics(hass, config_entry, device)
return await _async_get_json_file_response(
hass, data, filename, config_entry.domain, d_id, sub_id
hass, data, data_issues, filename, config_entry.domain, d_id, sub_id
)

View File

@ -1,13 +1,15 @@
"""Test the Diagnostics integration."""
from datetime import datetime
from http import HTTPStatus
from unittest.mock import AsyncMock, Mock, patch
from freezegun import freeze_time
import pytest
from homeassistant.components.websocket_api import TYPE_RESULT
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers import device_registry as dr, issue_registry as ir
from homeassistant.helpers.system_info import async_get_system_info
from homeassistant.loader import async_get_integration
from homeassistant.setup import async_setup_component
@ -81,10 +83,20 @@ async def test_websocket(
@pytest.mark.usefixtures("enable_custom_integrations")
@pytest.mark.parametrize(
"ignore_missing_translations",
[
[
"component.fake_integration.issues.test_issue.title",
"component.fake_integration.issues.test_issue.description",
]
],
)
async def test_download_diagnostics(
hass: HomeAssistant,
hass_client: ClientSessionGenerator,
device_registry: dr.DeviceRegistry,
issue_registry: ir.IssueRegistry,
) -> None:
"""Test download diagnostics."""
config_entry = MockConfigEntry(domain="fake_integration")
@ -95,6 +107,18 @@ async def test_download_diagnostics(
integration = await async_get_integration(hass, "fake_integration")
original_manifest = integration.manifest.copy()
original_manifest["codeowners"] = ["@test"]
with freeze_time(datetime(2025, 7, 9, 14, 00, 00)):
issue_registry.async_get_or_create(
domain="fake_integration",
issue_id="test_issue",
breaks_in_ha_version="2023.10.0",
severity=ir.IssueSeverity.WARNING,
is_fixable=False,
is_persistent=True,
translation_key="test_issue",
)
with patch.object(integration, "manifest", original_manifest):
response = await _get_diagnostics_for_config_entry(
hass, hass_client, config_entry
@ -179,6 +203,23 @@ async def test_download_diagnostics(
"requirements": [],
},
"data": {"config_entry": "info"},
"issues": [
{
"breaks_in_ha_version": "2023.10.0",
"created": "2025-07-09T14:00:00+00:00",
"data": None,
"dismissed_version": None,
"domain": "fake_integration",
"is_fixable": False,
"is_persistent": True,
"issue_domain": None,
"issue_id": "test_issue",
"learn_more_url": None,
"severity": "warning",
"translation_key": "test_issue",
"translation_placeholders": None,
},
],
}
device = device_registry.async_get_or_create(
@ -266,6 +307,23 @@ async def test_download_diagnostics(
"requirements": [],
},
"data": {"device": "info"},
"issues": [
{
"breaks_in_ha_version": "2023.10.0",
"created": "2025-07-09T14:00:00+00:00",
"data": None,
"dismissed_version": None,
"domain": "fake_integration",
"is_fixable": False,
"is_persistent": True,
"issue_domain": None,
"issue_id": "test_issue",
"learn_more_url": None,
"severity": "warning",
"translation_key": "test_issue",
"translation_placeholders": None,
},
],
"setup_times": {},
}