mirror of
https://github.com/esphome/esphome.git
synced 2026-09-12 15:57:33 +00:00
84 lines
2.9 KiB
Python
84 lines
2.9 KiB
Python
"""Tests for the device information the sendspin hub reports to the server."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from collections.abc import Callable
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from esphome import config_validation as cv
|
|
from esphome.components.sendspin import (
|
|
CONF_FIRMWARE_VERSION,
|
|
CONF_MANUFACTURER,
|
|
CONFIG_SCHEMA,
|
|
)
|
|
from esphome.const import CONF_MODEL, PlatformFramework
|
|
from tests.component_tests.types import SetCoreConfigCallable
|
|
|
|
|
|
def test_explicit_device_info_wins_over_project(
|
|
generate_main: Callable[[str | Path], str],
|
|
component_config_path: Callable[[str], Path],
|
|
) -> None:
|
|
"""Configured values take precedence over the project information."""
|
|
main_cpp = generate_main(component_config_path("device_info_explicit.yaml"))
|
|
|
|
assert 'set_manufacturer("Explicit Manufacturer")' in main_cpp
|
|
assert 'set_model("Explicit Model")' in main_cpp
|
|
assert 'set_firmware_version("1.2.3")' in main_cpp
|
|
|
|
|
|
def test_project_supplies_device_info(
|
|
generate_main: Callable[[str | Path], str],
|
|
component_config_path: Callable[[str], Path],
|
|
) -> None:
|
|
"""Without configured values, the project name splits into manufacturer and model."""
|
|
main_cpp = generate_main(component_config_path("device_info_project.yaml"))
|
|
|
|
assert 'set_manufacturer("project_manufacturer")' in main_cpp
|
|
assert 'set_model("project_model")' in main_cpp
|
|
assert 'set_firmware_version("9.9.9")' in main_cpp
|
|
|
|
|
|
def test_no_device_info_leaves_hub_defaults(
|
|
generate_main: Callable[[str | Path], str],
|
|
component_config_path: Callable[[str], Path],
|
|
) -> None:
|
|
"""With neither source, nothing is emitted and the hub keeps its own defaults."""
|
|
main_cpp = generate_main(component_config_path("device_info_default.yaml"))
|
|
|
|
assert "set_manufacturer(" not in main_cpp
|
|
assert "set_model(" not in main_cpp
|
|
assert "set_firmware_version(" not in main_cpp
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"conf_key", [CONF_MANUFACTURER, CONF_MODEL, CONF_FIRMWARE_VERSION]
|
|
)
|
|
def test_empty_device_info_rejected(
|
|
set_core_config: SetCoreConfigCallable, conf_key: str
|
|
) -> None:
|
|
"""An empty string would be sent to the server as an empty value, so it is not accepted."""
|
|
set_core_config(PlatformFramework.ESP32_IDF)
|
|
|
|
with pytest.raises(cv.Invalid):
|
|
CONFIG_SCHEMA({conf_key: ""})
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"conf_key", [CONF_MANUFACTURER, CONF_MODEL, CONF_FIRMWARE_VERSION]
|
|
)
|
|
def test_device_info_capped_at_127_bytes(
|
|
set_core_config: SetCoreConfigCallable, conf_key: str
|
|
) -> None:
|
|
"""The cap is in bytes so the protobuf length prefix stays a single byte."""
|
|
set_core_config(PlatformFramework.ESP32_IDF)
|
|
|
|
CONFIG_SCHEMA({conf_key: "a" * 127})
|
|
with pytest.raises(cv.Invalid):
|
|
CONFIG_SCHEMA({conf_key: "a" * 128})
|
|
# 64 two-byte characters is 128 bytes.
|
|
with pytest.raises(cv.Invalid):
|
|
CONFIG_SCHEMA({conf_key: "é" * 64})
|