From 76aef60c05de3a39aea2faf477699c5efb24a71c Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 3 Mar 2026 21:00:43 +0100 Subject: [PATCH] Add hass url to brand images (#29961) --- src/components/device/ha-device-picker.ts | 26 ++++---- src/components/entity/state-badge.ts | 2 +- src/components/ha-domain-icon.ts | 13 ++-- src/components/ha-related-items.ts | 26 ++++---- .../ha-selector/ha-selector-media.ts | 13 ++-- src/components/ha-target-picker.ts | 13 ++-- .../media-player/ha-media-player-browse.ts | 13 ++-- .../ha-target-picker-item-row.ts | 13 ++-- .../ha-target-picker-value-chip.ts | 13 ++-- src/components/voice-assistant-brand-icon.ts | 13 ++-- .../config-flow/step-flow-create-entry.ts | 14 +++-- src/onboarding/integration-badge.ts | 13 ++-- .../ha-automation-add-from-target.ts | 13 ++-- .../config/ha-backup-config-agents.ts | 13 ++-- .../components/ha-backup-agents-picker.ts | 13 ++-- .../config/backup/ha-config-backup-backups.ts | 13 ++-- .../config/backup/ha-config-backup-details.ts | 15 +++-- .../backup/ha-config-backup-settings.ts | 13 ++-- src/panels/config/core/ai-task-pref.ts | 13 ++-- .../config/devices/ha-config-device-page.ts | 26 ++++---- .../devices/ha-config-devices-dashboard.ts | 13 ++-- .../components/ha-energy-grid-settings.ts | 13 ++-- .../dialogs/dialog-energy-solar-settings.ts | 13 ++-- .../config/hardware/ha-config-hardware.ts | 15 +++-- .../config/helpers/dialog-helper-detail.ts | 13 ++-- .../ha-config-integration-page.ts | 13 ++-- .../integrations/ha-domain-integrations.ts | 39 +++++++----- .../ha-integration-action-card.ts | 13 ++-- .../integrations/ha-integration-header.ts | 13 ++-- .../integrations/ha-integration-list-item.ts | 13 ++-- ...dialog-matter-open-commissioning-window.ts | 13 ++-- .../thread/thread-config-panel.ts | 13 ++-- src/panels/config/labs/ha-config-labs.ts | 13 ++-- .../config/repairs/ha-config-repairs.ts | 13 ++-- .../repairs/integrations-startup-time.ts | 13 ++-- src/panels/logbook/ha-logbook-renderer.ts | 13 ++-- .../lovelace/badges/hui-entity-badge.ts | 5 +- src/panels/lovelace/cards/hui-tile-card.ts | 5 +- src/util/brands-url.ts | 60 +++++++++++++------ test/util/generate-brands-url.test.ts | 59 +++++++++++++----- 40 files changed, 418 insertions(+), 238 deletions(-) diff --git a/src/components/device/ha-device-picker.ts b/src/components/device/ha-device-picker.ts index a68d73b165..451762c2c6 100644 --- a/src/components/device/ha-device-picker.ts +++ b/src/components/device/ha-device-picker.ts @@ -173,11 +173,14 @@ export class HaDevicePicker extends LitElement { alt="" crossorigin="anonymous" referrerpolicy="no-referrer" - src=${brandsUrl({ - domain: configEntry.domain, - type: "icon", - darkOptimized: this.hass.themes?.darkMode, - })} + src=${brandsUrl( + { + domain: configEntry.domain, + type: "icon", + darkOptimized: this.hass.themes?.darkMode, + }, + this.hass.auth.data.hassUrl + )} />` : nothing} ${primary} @@ -195,11 +198,14 @@ export class HaDevicePicker extends LitElement { alt="" crossorigin="anonymous" referrerpolicy="no-referrer" - src=${brandsUrl({ - domain: item.domain, - type: "icon", - darkOptimized: this.hass.themes.darkMode, - })} + src=${brandsUrl( + { + domain: item.domain, + type: "icon", + darkOptimized: this.hass.themes.darkMode, + }, + this.hass.auth.data.hassUrl + )} /> ` : nothing} diff --git a/src/components/entity/state-badge.ts b/src/components/entity/state-badge.ts index 71b6a7d74e..d1233c72e0 100644 --- a/src/components/entity/state-badge.ts +++ b/src/components/entity/state-badge.ts @@ -138,10 +138,10 @@ export class StateBadge extends LitElement { let imageUrl = stateObj.attributes.entity_picture_local || stateObj.attributes.entity_picture; - imageUrl = addBrandsAuth(imageUrl); if (this.hass) { imageUrl = this.hass.hassUrl(imageUrl); } + imageUrl = addBrandsAuth(imageUrl, this.hass?.auth.data.hassUrl); if (domain === "camera") { imageUrl = cameraUrlWithWidthHeight(imageUrl, 80, 80); } diff --git a/src/components/ha-domain-icon.ts b/src/components/ha-domain-icon.ts index d41a0799de..48a81284db 100644 --- a/src/components/ha-domain-icon.ts +++ b/src/components/ha-domain-icon.ts @@ -61,11 +61,14 @@ export class HaDomainIcon extends LitElement { `; } if (this.brandFallback) { - const image = brandsUrl({ - domain: this.domain!, - type: "icon", - darkOptimized: this.hass.themes?.darkMode, - }); + const image = brandsUrl( + { + domain: this.domain!, + type: "icon", + darkOptimized: this.hass.themes?.darkMode, + }, + this.hass.auth.data.hassUrl + ); return html` ${entry.domain} ${integration} ` : type === "floor" diff --git a/src/components/media-player/ha-media-player-browse.ts b/src/components/media-player/ha-media-player-browse.ts index d60ec2cabf..26077cc187 100644 --- a/src/components/media-player/ha-media-player-browse.ts +++ b/src/components/media-player/ha-media-player-browse.ts @@ -768,11 +768,14 @@ export class HaMediaPlayerBrowse extends LitElement { if (isBrandUrl(thumbnailUrl)) { // The backend is not aware of the theme used by the users, // so we rewrite the URL to show a proper icon - return brandsUrl({ - domain: extractDomainFromBrandUrl(thumbnailUrl), - type: "icon", - darkOptimized: this.hass.themes?.darkMode, - }); + return brandsUrl( + { + domain: extractDomainFromBrandUrl(thumbnailUrl), + type: "icon", + darkOptimized: this.hass.themes?.darkMode, + }, + this.hass.auth.data.hassUrl + ); } if (thumbnailUrl.startsWith("/")) { diff --git a/src/components/target-picker/ha-target-picker-item-row.ts b/src/components/target-picker/ha-target-picker-item-row.ts index b52bbb13b3..4c6db12d03 100644 --- a/src/components/target-picker/ha-target-picker-item-row.ts +++ b/src/components/target-picker/ha-target-picker-item-row.ts @@ -577,11 +577,14 @@ export class HaTargetPickerItemRow extends LitElement { try { const data = await getConfigEntry(this.hass, configEntryId); const domain = data.config_entry.domain; - this._iconImg = brandsUrl({ - domain: domain, - type: "icon", - darkOptimized: this.hass.themes?.darkMode, - }); + this._iconImg = brandsUrl( + { + domain: domain, + type: "icon", + darkOptimized: this.hass.themes?.darkMode, + }, + this.hass.auth.data.hassUrl + ); this._setDomainName(domain); } catch { diff --git a/src/components/target-picker/ha-target-picker-value-chip.ts b/src/components/target-picker/ha-target-picker-value-chip.ts index 4c58c28502..b25a385fdf 100644 --- a/src/components/target-picker/ha-target-picker-value-chip.ts +++ b/src/components/target-picker/ha-target-picker-value-chip.ts @@ -203,11 +203,14 @@ export class HaTargetPickerValueChip extends LitElement { try { const data = await getConfigEntry(this.hass, configEntryId); const domain = data.config_entry.domain; - this._iconImg = brandsUrl({ - domain: domain, - type: "icon", - darkOptimized: this.hass.themes?.darkMode, - }); + this._iconImg = brandsUrl( + { + domain: domain, + type: "icon", + darkOptimized: this.hass.themes?.darkMode, + }, + this.hass.auth.data.hassUrl + ); this._setDomainName(domain); } catch { diff --git a/src/components/voice-assistant-brand-icon.ts b/src/components/voice-assistant-brand-icon.ts index c40ad9d64e..6a4032f401 100644 --- a/src/components/voice-assistant-brand-icon.ts +++ b/src/components/voice-assistant-brand-icon.ts @@ -17,11 +17,14 @@ export class VoiceAssistantBrandicon extends LitElement { diff --git a/src/dialogs/config-flow/step-flow-create-entry.ts b/src/dialogs/config-flow/step-flow-create-entry.ts index 79a8e73725..c4ea0982b8 100644 --- a/src/dialogs/config-flow/step-flow-create-entry.ts +++ b/src/dialogs/config-flow/step-flow-create-entry.ts @@ -140,11 +140,15 @@ class StepFlowCreateEntry extends LitElement { this.hass.localize, domains[device.primary_config_entry] )} - src=${brandsUrl({ - domain: domains[device.primary_config_entry], - type: "icon", - darkOptimized: this.hass.themes?.darkMode, - })} + src=${brandsUrl( + { + domain: + domains[device.primary_config_entry], + type: "icon", + darkOptimized: this.hass.themes?.darkMode, + }, + this.hass.auth.data.hassUrl + )} crossorigin="anonymous" referrerpolicy="no-referrer" />` diff --git a/src/onboarding/integration-badge.ts b/src/onboarding/integration-badge.ts index 8112e4b900..0edf2538be 100644 --- a/src/onboarding/integration-badge.ts +++ b/src/onboarding/integration-badge.ts @@ -21,11 +21,14 @@ class IntegrationBadge extends LitElement {
diff --git a/src/panels/config/automation/add-automation-element/ha-automation-add-from-target.ts b/src/panels/config/automation/add-automation-element/ha-automation-add-from-target.ts index e2cf97b4a2..b7f6cf1c12 100644 --- a/src/panels/config/automation/add-automation-element/ha-automation-add-from-target.ts +++ b/src/panels/config/automation/add-automation-element/ha-automation-add-from-target.ts @@ -769,11 +769,14 @@ export default class HaAutomationAddFromTarget extends LitElement { alt="" crossorigin="anonymous" referrerpolicy="no-referrer" - src=${brandsUrl({ - domain, - type: "icon", - darkOptimized: this.hass.themes?.darkMode, - })} + src=${brandsUrl( + { + domain, + type: "icon", + darkOptimized: this.hass.themes?.darkMode, + }, + this.hass.auth.data.hassUrl + )} /> `; diff --git a/src/panels/config/backup/components/config/ha-backup-config-agents.ts b/src/panels/config/backup/components/config/ha-backup-config-agents.ts index 8e44f4695f..e587321abe 100644 --- a/src/panels/config/backup/components/config/ha-backup-config-agents.ts +++ b/src/panels/config/backup/components/config/ha-backup-config-agents.ts @@ -149,11 +149,14 @@ class HaBackupConfigAgents extends LitElement { return html` ` : html`
Nabu Casa logo ${this.hass.localize("ui.panel.config.ai_task.header")} diff --git a/src/panels/config/devices/ha-config-device-page.ts b/src/panels/config/devices/ha-config-device-page.ts index 74cf314320..f353b0b82b 100644 --- a/src/panels/config/devices/ha-config-device-page.ts +++ b/src/panels/config/devices/ha-config-device-page.ts @@ -364,11 +364,14 @@ export class HaConfigDevicePage extends LitElement { ${domainToName(this.hass.localize,` : "", }, diff --git a/src/panels/config/energy/components/ha-energy-grid-settings.ts b/src/panels/config/energy/components/ha-energy-grid-settings.ts index 4a272ba489..e37cb6a7b4 100644 --- a/src/panels/config/energy/components/ha-energy-grid-settings.ts +++ b/src/panels/config/energy/components/ha-energy-grid-settings.ts @@ -186,11 +186,14 @@ export class EnergyGridSettings extends LitElement { alt="" crossorigin="anonymous" referrerpolicy="no-referrer" - src=${brandsUrl({ - domain: "co2signal", - type: "icon", - darkOptimized: this.hass.themes?.darkMode, - })} + src=${brandsUrl( + { + domain: "co2signal", + type: "icon", + darkOptimized: this.hass.themes?.darkMode, + }, + this.hass.auth.data.hassUrl + )} /> ${this._co2ConfigEntry.title} ${entry.title}
`} > diff --git a/src/panels/config/hardware/ha-config-hardware.ts b/src/panels/config/hardware/ha-config-hardware.ts index 7562c51c2d..8d37d9b871 100644 --- a/src/panels/config/hardware/ha-config-hardware.ts +++ b/src/panels/config/hardware/ha-config-hardware.ts @@ -229,12 +229,15 @@ class HaConfigHardware extends SubscribeMixin(LitElement) { boardId = boardData.board!.hassio_board_id; boardName = boardData.name; documentationURL = boardData.url; - imageURL = hardwareBrandsUrl({ - category: "boards", - manufacturer: boardData.board!.manufacturer, - model: boardData.board!.model, - darkOptimized: this.hass.themes?.darkMode, - }); + imageURL = hardwareBrandsUrl( + { + category: "boards", + manufacturer: boardData.board!.manufacturer, + model: boardData.board!.model, + darkOptimized: this.hass.themes?.darkMode, + }, + this.hass.auth.data.hassUrl + ); } else if (this._OSData?.board) { boardId = this._OSData.board; boardName = BOARD_NAMES[this._OSData.board]; diff --git a/src/panels/config/helpers/dialog-helper-detail.ts b/src/panels/config/helpers/dialog-helper-detail.ts index 3b3e2b2525..85bec0e9b4 100644 --- a/src/panels/config/helpers/dialog-helper-detail.ts +++ b/src/panels/config/helpers/dialog-helper-detail.ts @@ -252,11 +252,14 @@ export class DialogHelperDetail extends LitElement { slot="graphic" loading="lazy" alt="" - src=${brandsUrl({ - domain, - type: "icon", - darkOptimized: this.hass.themes?.darkMode, - })} + src=${brandsUrl( + { + domain, + type: "icon", + darkOptimized: this.hass.themes?.darkMode, + }, + this.hass.auth.data.hassUrl + )} crossorigin="anonymous" referrerpolicy="no-referrer" /> diff --git a/src/panels/config/integrations/ha-config-integration-page.ts b/src/panels/config/integrations/ha-config-integration-page.ts index 6ff3aedf7a..a8bc30620e 100644 --- a/src/panels/config/integrations/ha-config-integration-page.ts +++ b/src/panels/config/integrations/ha-config-integration-page.ts @@ -376,11 +376,14 @@ class HaConfigIntegrationPage extends SubscribeMixin(LitElement) {
${domainToName(this.hass.localize, @@ -112,11 +115,14 @@ class HaDomainIntegrations extends LitElement { slot="graphic" loading="lazy" alt="" - src=${brandsUrl({ - domain, - type: "icon", - darkOptimized: this.hass.themes?.darkMode, - })} + src=${brandsUrl( + { + domain, + type: "icon", + darkOptimized: this.hass.themes?.darkMode, + }, + this.hass.auth.data.hassUrl + )} crossorigin="anonymous" referrerpolicy="no-referrer" /> @@ -175,11 +181,14 @@ class HaDomainIntegrations extends LitElement { slot="graphic" loading="lazy" alt="" - src=${brandsUrl({ - domain: this.domain, - type: "icon", - darkOptimized: this.hass.themes?.darkMode, - })} + src=${brandsUrl( + { + domain: this.domain, + type: "icon", + darkOptimized: this.hass.themes?.darkMode, + }, + this.hass.auth.data.hassUrl + )} crossorigin="anonymous" referrerpolicy="no-referrer" /> diff --git a/src/panels/config/integrations/ha-integration-action-card.ts b/src/panels/config/integrations/ha-integration-action-card.ts index ae7302ad17..81430bcb02 100644 --- a/src/panels/config/integrations/ha-integration-action-card.ts +++ b/src/panels/config/integrations/ha-integration-action-card.ts @@ -31,11 +31,14 @@ export class HaIntegrationActionCard extends LitElement {
`} diff --git a/src/panels/config/integrations/integration-panels/matter/dialog-matter-open-commissioning-window.ts b/src/panels/config/integrations/integration-panels/matter/dialog-matter-open-commissioning-window.ts index a416a3e13e..bc92c6c1de 100644 --- a/src/panels/config/integrations/integration-panels/matter/dialog-matter-open-commissioning-window.ts +++ b/src/panels/config/integrations/integration-panels/matter/dialog-matter-open-commissioning-window.ts @@ -67,11 +67,14 @@ class DialogMatterOpenCommissioningWindow extends LitElement { crossorigin="anonymous" referrerpolicy="no-referrer" alt=${domainToName(this.hass.localize, "matter")} - src=${brandsUrl({ - domain: "matter", - type: "logo", - darkOptimized: this.hass.themes?.darkMode, - })} + src=${brandsUrl( + { + domain: "matter", + type: "logo", + darkOptimized: this.hass.themes?.darkMode, + }, + this.hass.auth.data.hassUrl + )} /> ${router.brand} diff --git a/src/panels/config/repairs/ha-config-repairs.ts b/src/panels/config/repairs/ha-config-repairs.ts index 778ec31955..c856368974 100644 --- a/src/panels/config/repairs/ha-config-repairs.ts +++ b/src/panels/config/repairs/ha-config-repairs.ts @@ -74,11 +74,14 @@ class HaConfigRepairs extends LitElement { slot="start" alt=${domainName} loading="lazy" - src=${brandsUrl({ - domain: issue.issue_domain || issue.domain, - type: "icon", - darkOptimized: this.hass.themes?.darkMode, - })} + src=${brandsUrl( + { + domain: issue.issue_domain || issue.domain, + type: "icon", + darkOptimized: this.hass.themes?.darkMode, + }, + this.hass.auth.data.hassUrl + )} .title=${domainName} crossorigin="anonymous" referrerpolicy="no-referrer" diff --git a/src/panels/config/repairs/integrations-startup-time.ts b/src/panels/config/repairs/integrations-startup-time.ts index f737804bef..6946b74096 100644 --- a/src/panels/config/repairs/integrations-startup-time.ts +++ b/src/panels/config/repairs/integrations-startup-time.ts @@ -55,11 +55,14 @@ class IntegrationsStartupTime extends LitElement { { } }; -export const brandsUrl = (options: BrandsOptions): string => { +export const brandsUrl = (options: BrandsOptions, hassUrl?: string): string => { + hassUrl = hassUrl ?? location.origin; const base = `/api/brands/integration/${options.domain}/${ options.darkOptimized ? "dark_" : "" }${options.type}.png`; + + const url = new URL(base, hassUrl); if (_brandsAccessToken) { - return `${base}?token=${_brandsAccessToken}`; + url.searchParams.set("token", _brandsAccessToken); } - return base; + return url.toString(); }; -export const hardwareBrandsUrl = (options: HardwareBrandsOptions): string => { +export const hardwareBrandsUrl = ( + options: HardwareBrandsOptions, + hassUrl?: string +): string => { + hassUrl = hassUrl ?? location.origin; const base = `/api/brands/hardware/${options.category}/${ options.darkOptimized ? "dark_" : "" }${options.manufacturer}${options.model ? `_${options.model}` : ""}.png`; + + const url = new URL(base, hassUrl); if (_brandsAccessToken) { - return `${base}?token=${_brandsAccessToken}`; + url.searchParams.set("token", _brandsAccessToken); } - return base; + return url.toString(); }; -export const addBrandsAuth = (url: string): string => { - if (!_brandsAccessToken || !url.startsWith("/api/brands/")) { +export const addBrandsAuth = (url: string, hassUrl?: string): string => { + hassUrl = hassUrl ?? location.origin; + if (!_brandsAccessToken) { + return url; + } + + try { + const parsedUrl = new URL(url, hassUrl); + if (!parsedUrl.pathname.startsWith("/api/brands/")) { + return url; + } + parsedUrl.searchParams.set("token", _brandsAccessToken); + return parsedUrl.toString(); + } catch { return url; } - const fullUrl = new URL(url, location.origin); - fullUrl.searchParams.set("token", _brandsAccessToken); - return `${fullUrl.pathname}${fullUrl.search}`; }; export const extractDomainFromBrandUrl = (url: string): string => { // Handle both new local API paths (/api/brands/integration/{domain}/...) // and legacy CDN URLs (https://brands.home-assistant.io/_/{domain}/...) - if (url.startsWith("/api/brands/")) { + const parsed = new URL(url, location.origin); + if (parsed.pathname.startsWith("/api/brands/")) { // /api/brands/integration/{domain}/... -> ["" ,"api", "brands", "integration", "{domain}", ...] - return url.split("/")[4]; + return parsed.pathname.split("/")[4]; } // https://brands.home-assistant.io/_/{domain}/... -> ["", "_", "{domain}", ...] - const parsed = new URL(url); const segments = parsed.pathname.split("/").filter((s) => s.length > 0); const underscoreIdx = segments.indexOf("_"); if (underscoreIdx !== -1 && underscoreIdx + 1 < segments.length) { @@ -101,6 +119,14 @@ export const extractDomainFromBrandUrl = (url: string): string => { return segments[1] ?? ""; }; -export const isBrandUrl = (thumbnail: string | ""): boolean => - thumbnail.startsWith("/api/brands/") || - thumbnail.startsWith("https://brands.home-assistant.io/"); +export const isBrandUrl = (thumbnail: string | ""): boolean => { + try { + const url = new URL(thumbnail, location.origin); + return ( + url.pathname.startsWith("/api/brands/") || + thumbnail.startsWith("https://brands.home-assistant.io/") + ); + } catch { + return false; + } +}; diff --git a/test/util/generate-brands-url.test.ts b/test/util/generate-brands-url.test.ts index 527bded700..9aa89d8d5b 100644 --- a/test/util/generate-brands-url.test.ts +++ b/test/util/generate-brands-url.test.ts @@ -11,21 +11,30 @@ import { describe("Generate brands Url", () => { it("Generate logo brands url for cloud component", () => { assert.strictEqual( - brandsUrl({ domain: "cloud", type: "logo" }), - "/api/brands/integration/cloud/logo.png" + brandsUrl( + { domain: "cloud", type: "logo" }, + "http://homeassistant.local:8123" + ), + "http://homeassistant.local:8123/api/brands/integration/cloud/logo.png" ); }); it("Generate icon brands url for cloud component", () => { assert.strictEqual( - brandsUrl({ domain: "cloud", type: "icon" }), - "/api/brands/integration/cloud/icon.png" + brandsUrl( + { domain: "cloud", type: "icon" }, + "http://homeassistant.local:8123" + ), + "http://homeassistant.local:8123/api/brands/integration/cloud/icon.png" ); }); it("Generate dark theme optimized logo brands url for cloud component", () => { assert.strictEqual( - brandsUrl({ domain: "cloud", type: "logo", darkOptimized: true }), - "/api/brands/integration/cloud/dark_logo.png" + brandsUrl( + { domain: "cloud", type: "logo", darkOptimized: true }, + "http://homeassistant.local:8123" + ), + "http://homeassistant.local:8123/api/brands/integration/cloud/dark_logo.png" ); }); }); @@ -33,14 +42,20 @@ describe("Generate brands Url", () => { describe("addBrandsAuth", () => { it("Returns non-brands URLs unchanged", () => { assert.strictEqual( - addBrandsAuth("/api/camera_proxy/camera.foo?token=abc"), + addBrandsAuth( + "/api/camera_proxy/camera.foo?token=abc", + "http://homeassistant.local:8123" + ), "/api/camera_proxy/camera.foo?token=abc" ); }); it("Returns brands URL unchanged when no token is available", () => { assert.strictEqual( - addBrandsAuth("/api/brands/integration/demo/icon.png"), + addBrandsAuth( + "/api/brands/integration/demo/icon.png", + "http://homeassistant.local:8123" + ), "/api/brands/integration/demo/icon.png" ); }); @@ -52,8 +67,11 @@ describe("addBrandsAuth", () => { await fetchBrandsAccessToken(mockHass); assert.strictEqual( - addBrandsAuth("/api/brands/integration/demo/icon.png"), - "/api/brands/integration/demo/icon.png?token=test-token-123" + addBrandsAuth( + "/api/brands/integration/demo/icon.png", + "http://homeassistant.local:8123" + ), + "http://homeassistant.local:8123/api/brands/integration/demo/icon.png?token=test-token-123" ); }); @@ -64,8 +82,11 @@ describe("addBrandsAuth", () => { await fetchBrandsAccessToken(mockHass); assert.strictEqual( - addBrandsAuth("/api/brands/integration/demo/icon.png?token=old-token"), - "/api/brands/integration/demo/icon.png?token=new-token" + addBrandsAuth( + "/api/brands/integration/demo/icon.png?token=old-token", + "http://homeassistant.local:8123" + ), + "http://homeassistant.local:8123/api/brands/integration/demo/icon.png?token=new-token" ); }); }); @@ -90,8 +111,11 @@ describe("scheduleBrandsTokenRefresh", () => { await fetchBrandsAccessToken(mockHass); assert.strictEqual(callCount, 1); assert.strictEqual( - brandsUrl({ domain: "test", type: "icon" }), - "/api/brands/integration/test/icon.png?token=token-1" + brandsUrl( + { domain: "test", type: "icon" }, + "http://homeassistant.local:8123" + ), + "http://homeassistant.local:8123/api/brands/integration/test/icon.png?token=token-1" ); scheduleBrandsTokenRefresh(mockHass); @@ -100,8 +124,11 @@ describe("scheduleBrandsTokenRefresh", () => { await vi.advanceTimersByTimeAsync(30 * 60 * 1000); assert.strictEqual(callCount, 2); assert.strictEqual( - brandsUrl({ domain: "test", type: "icon" }), - "/api/brands/integration/test/icon.png?token=token-2" + brandsUrl( + { domain: "test", type: "icon" }, + "http://homeassistant.local:8123" + ), + "http://homeassistant.local:8123/api/brands/integration/test/icon.png?token=token-2" ); });