diff --git a/custom_components/hacs/update.py b/custom_components/hacs/update.py index ec4014302db..65526b132a3 100644 --- a/custom_components/hacs/update.py +++ b/custom_components/hacs/update.py @@ -76,6 +76,12 @@ def entity_picture(self) -> str | None: ): return None + if "brands" in self.hass.config.components: + # Home Assistant 2026.3+ proxies brand images locally, which also serves + # the assets custom integrations ship in their own brand/ directory. + # The frontend adds the required access token to /api/brands/ paths. + return f"/api/brands/integration/{self.repository.data.domain}/icon.png" + return f"https://brands.home-assistant.io/_/{self.repository.data.domain}/icon.png" async def async_install(self, version: str | None, backup: bool, **kwargs: Any) -> None: diff --git a/tests/snapshots/api-usage/tests/test_updatetest-update-entity-picture-brands-proxy-hacs-test-org-integration-basic.json b/tests/snapshots/api-usage/tests/test_updatetest-update-entity-picture-brands-proxy-hacs-test-org-integration-basic.json new file mode 100644 index 00000000000..c28939ca8e9 --- /dev/null +++ b/tests/snapshots/api-usage/tests/test_updatetest-update-entity-picture-brands-proxy-hacs-test-org-integration-basic.json @@ -0,0 +1,17 @@ +{ + "tests/test_update.py::test_update_entity_picture[brands_proxy-hacs-test-org/integration-basic]": { + "https://api.github.com/repos/hacs/integration": 1, + "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, + "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, + "https://api.github.com/repos/hacs/integration/git/trees/main": 1, + "https://api.github.com/repos/hacs/integration/releases": 1, + "https://data-v2.hacs.xyz/appdaemon/data.json": 1, + "https://data-v2.hacs.xyz/critical/data.json": 1, + "https://data-v2.hacs.xyz/integration/data.json": 1, + "https://data-v2.hacs.xyz/plugin/data.json": 1, + "https://data-v2.hacs.xyz/python_script/data.json": 1, + "https://data-v2.hacs.xyz/removed/data.json": 1, + "https://data-v2.hacs.xyz/template/data.json": 1, + "https://data-v2.hacs.xyz/theme/data.json": 1 + } +} \ No newline at end of file diff --git a/tests/snapshots/api-usage/tests/test_updatetest-update-entity-picture-cdn-hacs-test-org-integration-basic.json b/tests/snapshots/api-usage/tests/test_updatetest-update-entity-picture-cdn-hacs-test-org-integration-basic.json new file mode 100644 index 00000000000..29ede252dc1 --- /dev/null +++ b/tests/snapshots/api-usage/tests/test_updatetest-update-entity-picture-cdn-hacs-test-org-integration-basic.json @@ -0,0 +1,17 @@ +{ + "tests/test_update.py::test_update_entity_picture[cdn-hacs-test-org/integration-basic]": { + "https://api.github.com/repos/hacs/integration": 1, + "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, + "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, + "https://api.github.com/repos/hacs/integration/git/trees/main": 1, + "https://api.github.com/repos/hacs/integration/releases": 1, + "https://data-v2.hacs.xyz/appdaemon/data.json": 1, + "https://data-v2.hacs.xyz/critical/data.json": 1, + "https://data-v2.hacs.xyz/integration/data.json": 1, + "https://data-v2.hacs.xyz/plugin/data.json": 1, + "https://data-v2.hacs.xyz/python_script/data.json": 1, + "https://data-v2.hacs.xyz/removed/data.json": 1, + "https://data-v2.hacs.xyz/template/data.json": 1, + "https://data-v2.hacs.xyz/theme/data.json": 1 + } +} \ No newline at end of file diff --git a/tests/test_update.py b/tests/test_update.py index 7896ca107d5..8261f58f342 100644 --- a/tests/test_update.py +++ b/tests/test_update.py @@ -10,6 +10,7 @@ import pytest from custom_components.hacs.const import DOMAIN +from custom_components.hacs.enums import HacsCategory from tests.common import ( CategoryTestData, @@ -96,3 +97,40 @@ async def test_update_entity_state( "updated_state": updated_state}), f"{category_test_data['repository']}/test_update_entity_state.json", ) + + +@pytest.mark.parametrize( + "category_test_data", + category_test_data_parametrized(categories=[HacsCategory.INTEGRATION]), +) +@pytest.mark.parametrize("brands_loaded", [False, True], ids=["cdn", "brands_proxy"]) +async def test_update_entity_picture( + hass: HomeAssistant, + setup_integration: Generator, + category_test_data: CategoryTestData, + brands_loaded: bool, +): + """Test the entity picture follows the availability of the brands proxy.""" + hacs = get_hacs(hass) + repo = hacs.repositories.get_by_full_name(category_test_data["repository"]) + + assert repo is not None + + repo.data.installed = True + repo.data.installed_version = category_test_data["version_base"] + + if brands_loaded: + hass.config.components.add("brands") + + await hass.config_entries.async_reload(hacs.configuration.config_entry.entry_id) + await hass.async_block_till_done() + + er = async_get_entity_registry(hass) + entity_id = er.async_get_entity_id("update", DOMAIN, repo.data.id) + state = hass.states.get(entity_id) + + assert state.attributes["entity_picture"] == ( + f"/api/brands/integration/{repo.data.domain}/icon.png" + if brands_loaded + else f"https://brands.home-assistant.io/_/{repo.data.domain}/icon.png" + )