mirror of
https://github.com/home-assistant/frontend.git
synced 2026-04-17 15:45:43 +01:00
172 lines
4.9 KiB
TypeScript
172 lines
4.9 KiB
TypeScript
import { assert, describe, it, vi, afterEach } from "vitest";
|
|
import type { HomeAssistant } from "../../src/types";
|
|
import {
|
|
addBrandsAuth,
|
|
brandsUrl,
|
|
clearBrandsTokenRefresh,
|
|
fetchBrandsAccessToken,
|
|
scheduleBrandsTokenRefresh,
|
|
} from "../../src/util/brands-url";
|
|
|
|
describe("Generate brands Url", () => {
|
|
it("Generate logo brands url for cloud component", () => {
|
|
assert.strictEqual(
|
|
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" },
|
|
"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 },
|
|
"http://homeassistant.local:8123"
|
|
),
|
|
"http://homeassistant.local:8123/api/brands/integration/cloud/dark_logo.png"
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("addBrandsAuth", () => {
|
|
it("Returns non-brands URLs unchanged", () => {
|
|
assert.strictEqual(
|
|
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",
|
|
"http://homeassistant.local:8123"
|
|
),
|
|
"/api/brands/integration/demo/icon.png"
|
|
);
|
|
});
|
|
|
|
it("Appends token to brands URL when token is available", async () => {
|
|
const mockHass = {
|
|
callWS: async () => ({ token: "test-token-123" }),
|
|
} as unknown as HomeAssistant;
|
|
await fetchBrandsAccessToken(mockHass);
|
|
|
|
assert.strictEqual(
|
|
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"
|
|
);
|
|
});
|
|
|
|
it("Replaces existing token param instead of duplicating", async () => {
|
|
const mockHass = {
|
|
callWS: async () => ({ token: "new-token" }),
|
|
} as unknown as HomeAssistant;
|
|
await fetchBrandsAccessToken(mockHass);
|
|
|
|
assert.strictEqual(
|
|
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"
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("scheduleBrandsTokenRefresh", () => {
|
|
afterEach(() => {
|
|
clearBrandsTokenRefresh();
|
|
vi.restoreAllMocks();
|
|
vi.useRealTimers();
|
|
});
|
|
|
|
it("Refreshes the token after 30 minutes", async () => {
|
|
vi.useFakeTimers();
|
|
let callCount = 0;
|
|
const mockHass = {
|
|
callWS: async () => {
|
|
callCount++;
|
|
return { token: `token-${callCount}` };
|
|
},
|
|
} as unknown as HomeAssistant;
|
|
|
|
await fetchBrandsAccessToken(mockHass);
|
|
assert.strictEqual(callCount, 1);
|
|
assert.strictEqual(
|
|
brandsUrl(
|
|
{ domain: "test", type: "icon" },
|
|
"http://homeassistant.local:8123"
|
|
),
|
|
"http://homeassistant.local:8123/api/brands/integration/test/icon.png?token=token-1"
|
|
);
|
|
|
|
scheduleBrandsTokenRefresh(mockHass);
|
|
|
|
// Advance 30 minutes
|
|
await vi.advanceTimersByTimeAsync(30 * 60 * 1000);
|
|
assert.strictEqual(callCount, 2);
|
|
assert.strictEqual(
|
|
brandsUrl(
|
|
{ domain: "test", type: "icon" },
|
|
"http://homeassistant.local:8123"
|
|
),
|
|
"http://homeassistant.local:8123/api/brands/integration/test/icon.png?token=token-2"
|
|
);
|
|
});
|
|
|
|
it("Does not refresh before 30 minutes", async () => {
|
|
vi.useFakeTimers();
|
|
let callCount = 0;
|
|
const mockHass = {
|
|
callWS: async () => {
|
|
callCount++;
|
|
return { token: `token-${callCount}` };
|
|
},
|
|
} as unknown as HomeAssistant;
|
|
|
|
await fetchBrandsAccessToken(mockHass);
|
|
scheduleBrandsTokenRefresh(mockHass);
|
|
|
|
// Advance 29 minutes — should not have refreshed
|
|
await vi.advanceTimersByTimeAsync(29 * 60 * 1000);
|
|
assert.strictEqual(callCount, 1);
|
|
});
|
|
|
|
it("clearBrandsTokenRefresh stops the interval", async () => {
|
|
vi.useFakeTimers();
|
|
let callCount = 0;
|
|
const mockHass = {
|
|
callWS: async () => {
|
|
callCount++;
|
|
return { token: `token-${callCount}` };
|
|
},
|
|
} as unknown as HomeAssistant;
|
|
|
|
await fetchBrandsAccessToken(mockHass);
|
|
scheduleBrandsTokenRefresh(mockHass);
|
|
clearBrandsTokenRefresh();
|
|
|
|
// Advance 30 minutes — should not have refreshed because we cleared
|
|
await vi.advanceTimersByTimeAsync(30 * 60 * 1000);
|
|
assert.strictEqual(callCount, 1);
|
|
});
|
|
});
|