Files
esphome/tests/unit_tests/test_web_server_helpers.py
J. Nick Koston a97f9e7cda [core] Add esphome logs over web_server HTTP SSE
Stream device logs over the web_server /events Server-Sent Events feed so
'esphome logs' works on devices that have web_server: but no api:. This is
the logging counterpart to web_server OTA. Priority stays API, then MQTT,
then web_server. Reconnects automatically when the stream drops.

Factor the resolve-to-URLs step and the web_server port/auth lookup shared
with web_server OTA into a new web_server_helpers module (resolve_web_server_urls
and get_web_server_connection), with helpers.format_ip_url for IPv4/IPv6 URL
formatting, and broaden the missing-transport log error to suggest web_server:
alongside api:/MQTT/USB.
2026-06-21 10:50:49 -05:00

65 lines
1.9 KiB
Python

"""Unit tests for esphome.web_server_helpers module."""
from __future__ import annotations
import socket
import pytest
from esphome.const import (
CONF_AUTH,
CONF_PASSWORD,
CONF_PORT,
CONF_USERNAME,
CONF_WEB_SERVER,
)
from esphome.core import EsphomeError
from esphome.web_server_helpers import (
get_web_server_connection,
resolve_web_server_urls,
)
def test_resolve_web_server_urls_maps_ipv4_and_ipv6(
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""Each resolved address becomes an (ip, url) pair with IPv6 bracketing."""
addr_infos = [
(socket.AF_INET, socket.SOCK_STREAM, 0, "", ("192.168.1.5", 80)),
(socket.AF_INET6, socket.SOCK_STREAM, 0, "", ("fe80::1", 80, 0, 7)),
]
monkeypatch.setattr(
"esphome.web_server_helpers.resolve_ip_address",
lambda *args, **kwargs: addr_infos,
)
assert resolve_web_server_urls("dev.local", 80, "/events") == [
("192.168.1.5", "http://192.168.1.5:80/events"),
("fe80::1", "http://[fe80::1%257]:80/events"),
]
def test_get_web_server_connection_without_auth() -> None:
"""Port is returned and credentials are None when no auth is configured."""
config = {CONF_WEB_SERVER: {CONF_PORT: 80}}
assert get_web_server_connection(config) == (80, None, None)
def test_get_web_server_connection_with_auth() -> None:
"""Port and HTTP Basic credentials are returned when auth is configured."""
config = {
CONF_WEB_SERVER: {
CONF_PORT: 8080,
CONF_AUTH: {CONF_USERNAME: "admin", CONF_PASSWORD: "secret"},
}
}
assert get_web_server_connection(config) == (8080, "admin", "secret")
def test_get_web_server_connection_missing_component() -> None:
"""A config without web_server raises a clear error."""
with pytest.raises(EsphomeError, match="web_server.*not configured"):
get_web_server_connection({})