Issues template function (#95206)

* Add 'issues' template function for listing active issues.

* Add issue template function test

* Add 'issue' template function for getting specific issue by domain and issue_id

* Remove comment

* Fix function description

* Remove reduntant function,
Fix tests

* remove pass_context

* remove issues filter

Co-authored-by: Erik Montnemery <erik@montnemery.com>

---------

Co-authored-by: Erik Montnemery <erik@montnemery.com>
pull/112198/head
RoboMagus 2024-03-04 14:22:14 +01:00 committed by GitHub
parent c2a991625d
commit b381922a20
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 89 additions and 1 deletions

View File

@ -78,7 +78,13 @@ from homeassistant.util.json import JSON_DECODE_EXCEPTIONS, json_loads
from homeassistant.util.read_only_dict import ReadOnlyDict from homeassistant.util.read_only_dict import ReadOnlyDict
from homeassistant.util.thread import ThreadWithException from homeassistant.util.thread import ThreadWithException
from . import area_registry, device_registry, entity_registry, location as loc_helper from . import (
area_registry,
device_registry,
entity_registry,
issue_registry,
location as loc_helper,
)
from .singleton import singleton from .singleton import singleton
from .translation import async_translate_state from .translation import async_translate_state
from .typing import TemplateVarsType from .typing import TemplateVarsType
@ -1357,6 +1363,21 @@ def is_device_attr(
return bool(device_attr(hass, device_or_entity_id, attr_name) == attr_value) return bool(device_attr(hass, device_or_entity_id, attr_name) == attr_value)
def issues(hass: HomeAssistant) -> dict[tuple[str, str], dict[str, Any]]:
"""Return all open issues."""
current_issues = issue_registry.async_get(hass).issues
# Use JSON for safe representation
return {k: v.to_json() for (k, v) in current_issues.items()}
def issue(hass: HomeAssistant, domain: str, issue_id: str) -> dict[str, Any] | None:
"""Get issue by domain and issue_id."""
result = issue_registry.async_get(hass).async_get_issue(domain, issue_id)
if result:
return result.to_json()
return None
def areas(hass: HomeAssistant) -> Iterable[str | None]: def areas(hass: HomeAssistant) -> Iterable[str | None]:
"""Return all areas.""" """Return all areas."""
area_reg = area_registry.async_get(hass) area_reg = area_registry.async_get(hass)
@ -2619,6 +2640,11 @@ class TemplateEnvironment(ImmutableSandboxedEnvironment):
self.globals["device_id"] = hassfunction(device_id) self.globals["device_id"] = hassfunction(device_id)
self.filters["device_id"] = self.globals["device_id"] self.filters["device_id"] = self.globals["device_id"]
self.globals["issues"] = hassfunction(issues)
self.globals["issue"] = hassfunction(issue)
self.filters["issue"] = self.globals["issue"]
self.globals["areas"] = hassfunction(areas) self.globals["areas"] = hassfunction(areas)
self.globals["area_id"] = hassfunction(area_id) self.globals["area_id"] = hassfunction(area_id)

View File

@ -37,6 +37,7 @@ from homeassistant.helpers import (
device_registry as dr, device_registry as dr,
entity, entity,
entity_registry as er, entity_registry as er,
issue_registry as ir,
template, template,
translation, translation,
) )
@ -3512,6 +3513,67 @@ async def test_device_attr(
assert info.rate_limit is None assert info.rate_limit is None
async def test_issues(hass: HomeAssistant, issue_registry: ir.IssueRegistry) -> None:
"""Test issues function."""
# Test no issues
info = render_to_info(hass, "{{ issues() }}")
assert_result_info(info, {})
assert info.rate_limit is None
# Test persistent issue
ir.async_create_issue(
hass,
"test",
"issue 1",
breaks_in_ha_version="2023.7",
is_fixable=True,
is_persistent=True,
learn_more_url="https://theuselessweb.com",
severity="error",
translation_key="abc_1234",
translation_placeholders={"abc": "123"},
)
await hass.async_block_till_done()
created_issue = issue_registry.async_get_issue("test", "issue 1")
info = render_to_info(hass, "{{ issues()['test', 'issue 1'] }}")
assert_result_info(info, created_issue.to_json())
assert info.rate_limit is None
# Test fixed issue
ir.async_delete_issue(hass, "test", "issue 1")
await hass.async_block_till_done()
info = render_to_info(hass, "{{ issues() }}")
assert_result_info(info, {})
assert info.rate_limit is None
async def test_issue(hass: HomeAssistant, issue_registry: ir.IssueRegistry) -> None:
"""Test issue function."""
# Test non existent issue
info = render_to_info(hass, "{{ issue('non_existent', 'issue') }}")
assert_result_info(info, None)
assert info.rate_limit is None
# Test existing issue
ir.async_create_issue(
hass,
"test",
"issue 1",
breaks_in_ha_version="2023.7",
is_fixable=True,
is_persistent=True,
learn_more_url="https://theuselessweb.com",
severity="error",
translation_key="abc_1234",
translation_placeholders={"abc": "123"},
)
await hass.async_block_till_done()
created_issue = issue_registry.async_get_issue("test", "issue 1")
info = render_to_info(hass, "{{ issue('test', 'issue 1') }}")
assert_result_info(info, created_issue.to_json())
assert info.rate_limit is None
async def test_areas(hass: HomeAssistant, area_registry: ar.AreaRegistry) -> None: async def test_areas(hass: HomeAssistant, area_registry: ar.AreaRegistry) -> None:
"""Test areas function.""" """Test areas function."""
# Test no areas # Test no areas