From bbcbb2e3222ee0a489b41d189473506f36fdcc12 Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Tue, 12 Sep 2023 21:07:32 +0200 Subject: [PATCH] Improve Entity._suggest_report_issue (#100204) --- homeassistant/helpers/entity.py | 22 ++++++++++- tests/components/sensor/test_init.py | 2 +- tests/helpers/test_entity.py | 58 +++++++++++++++++++++++++++- 3 files changed, 78 insertions(+), 4 deletions(-) diff --git a/homeassistant/helpers/entity.py b/homeassistant/helpers/entity.py index 99c71e2cc86..5ed16408388 100644 --- a/homeassistant/helpers/entity.py +++ b/homeassistant/helpers/entity.py @@ -4,6 +4,7 @@ from __future__ import annotations from abc import ABC import asyncio from collections.abc import Coroutine, Iterable, Mapping, MutableMapping +from contextlib import suppress from dataclasses import dataclass from datetime import timedelta from enum import Enum, auto @@ -49,7 +50,11 @@ from homeassistant.exceptions import ( InvalidStateError, NoEntitySpecifiedError, ) -from homeassistant.loader import bind_hass +from homeassistant.loader import ( + IntegrationNotLoaded, + async_get_loaded_integration, + bind_hass, +) from homeassistant.util import ensure_unique_string, slugify from . import device_registry as dr, entity_registry as er @@ -1215,8 +1220,21 @@ class Entity(ABC): def _suggest_report_issue(self) -> str: """Suggest to report an issue.""" report_issue = "" + + integration = None + # The check for self.platform guards against integrations not using an + # EntityComponent and can be removed in HA Core 2024.1 + if self.platform: + with suppress(IntegrationNotLoaded): + integration = async_get_loaded_integration( + self.hass, self.platform.platform_name + ) + if "custom_components" in type(self).__module__: - report_issue = "report it to the custom integration author." + if integration and integration.issue_tracker: + report_issue = f"create a bug report at {integration.issue_tracker}" + else: + report_issue = "report it to the custom integration author" else: report_issue = ( "create a bug report at " diff --git a/tests/components/sensor/test_init.py b/tests/components/sensor/test_init.py index 1f836ad9095..b7682eb2ec2 100644 --- a/tests/components/sensor/test_init.py +++ b/tests/components/sensor/test_init.py @@ -164,7 +164,7 @@ async def test_deprecated_last_reset( f"with state_class {state_class} has set last_reset. Setting last_reset for " "entities with state_class other than 'total' is not supported. Please update " "your configuration if state_class is manually configured, otherwise report it " - "to the custom integration author." + "to the custom integration author" ) in caplog.text state = hass.states.get("sensor.test") diff --git a/tests/helpers/test_entity.py b/tests/helpers/test_entity.py index 68eed5b6e32..61ee38a66a7 100644 --- a/tests/helpers/test_entity.py +++ b/tests/helpers/test_entity.py @@ -27,8 +27,10 @@ from tests.common import ( MockConfigEntry, MockEntity, MockEntityPlatform, + MockModule, MockPlatform, get_test_home_assistant, + mock_integration, mock_registry, ) @@ -776,7 +778,7 @@ async def test_warn_slow_write_state_custom_component( assert ( "Updating state for comp_test.test_entity " "(.CustomComponentEntity'>) " - "took 10.000 seconds. Please report it to the custom integration author." + "took 10.000 seconds. Please report it to the custom integration author" ) in caplog.text @@ -1503,3 +1505,57 @@ async def test_invalid_state( ent._attr_state = "x" * 255 ent.async_write_ha_state() assert hass.states.get("test.test").state == "x" * 255 + + +async def test_suggest_report_issue_built_in( + hass: HomeAssistant, caplog: pytest.LogCaptureFixture +) -> None: + """Test _suggest_report_issue for an entity from a built-in integration.""" + mock_entity = entity.Entity() + mock_entity.entity_id = "comp_test.test_entity" + + suggestion = mock_entity._suggest_report_issue() + assert suggestion == ( + "create a bug report at https://github.com/home-assistant/core/issues" + "?q=is%3Aopen+is%3Aissue" + ) + + mock_integration(hass, MockModule(domain="test"), built_in=True) + platform = MockEntityPlatform(hass, domain="comp_test", platform_name="test") + await platform.async_add_entities([mock_entity]) + + suggestion = mock_entity._suggest_report_issue() + assert suggestion == ( + "create a bug report at https://github.com/home-assistant/core/issues" + "?q=is%3Aopen+is%3Aissue+label%3A%22integration%3A+test%22" + ) + + +async def test_suggest_report_issue_custom_component( + hass: HomeAssistant, caplog: pytest.LogCaptureFixture +) -> None: + """Test _suggest_report_issue for an entity from a custom component.""" + + class CustomComponentEntity(entity.Entity): + """Custom component entity.""" + + __module__ = "custom_components.bla.sensor" + + mock_entity = CustomComponentEntity() + mock_entity.entity_id = "comp_test.test_entity" + + suggestion = mock_entity._suggest_report_issue() + assert suggestion == "report it to the custom integration author" + + mock_integration( + hass, + MockModule( + domain="test", partial_manifest={"issue_tracker": "httpts://some_url"} + ), + built_in=False, + ) + platform = MockEntityPlatform(hass, domain="comp_test", platform_name="test") + await platform.async_add_entities([mock_entity]) + + suggestion = mock_entity._suggest_report_issue() + assert suggestion == "create a bug report at httpts://some_url"