1
0
mirror of https://github.com/home-assistant/frontend.git synced 2026-07-04 21:15:09 +01:00
Files
frontend/test/components/chart/lit-tooltip-formatter.test.ts
Petar Petrov b8c201b6d3 Render echarts tooltips with Lit templates (#52235)
* Render echarts tooltips with Lit templates

Replace raw HTML string interpolation in echarts tooltip formatters with Lit templates so user-controlled fields (entity friendly_name, device names, node labels) are auto-escaped instead of relying on per-string filterXSS. ha-chart-base now wraps any function tooltip.formatter into a stable per-formatter container and handles Lit TemplateResult / nothing / null returns; the public HaECOption type lets charts express Lit-returning formatters without per-callsite casts.

* Simplify

* Refactor _getSeries

* Small fix

* Fix merge mistake

* Marker component and wrapper test
2026-05-28 14:27:47 +02:00

39 lines
1.5 KiB
TypeScript

import { html, nothing } from "lit";
import { describe, expect, it } from "vitest";
import type { LitTooltipFormatter } from "../../../src/resources/echarts/echarts";
import { wrapLitTooltipFormatter } from "../../../src/components/chart/lit-tooltip-formatter";
describe("wrapLitTooltipFormatter", () => {
it("renders TemplateResult into a stable container", () => {
const formatter = () => html`<b>Hello</b>`;
const wrapped = wrapLitTooltipFormatter(formatter);
const first = wrapped({});
const second = wrapped({});
expect(first).toBe(second);
expect(first?.tagName).toBe("DIV");
expect(first?.style.display).toBe("contents");
expect(first?.textContent).toContain("Hello");
});
it("returns null for nothing, null, and undefined", () => {
const returnNothing: LitTooltipFormatter = () => nothing;
expect(wrapLitTooltipFormatter(returnNothing)({})).toBeNull();
expect(wrapLitTooltipFormatter(() => null)({})).toBeNull();
expect(wrapLitTooltipFormatter(() => undefined)({})).toBeNull();
});
it("returns the same wrapped function for the same formatter", () => {
const formatter = () => html`x`;
expect(wrapLitTooltipFormatter(formatter)).toBe(
wrapLitTooltipFormatter(formatter)
);
});
it("does not double-wrap an already wrapped formatter", () => {
const formatter = () => html`x`;
const wrapped = wrapLitTooltipFormatter(formatter);
expect(wrapLitTooltipFormatter(wrapped)).toBe(wrapped);
});
});