[sendspin] Add the dynamic pairing code (#20349)

This commit is contained in:
Kevin Ahrendt
2026-10-08 13:36:12 -04:00
committed by GitHub
parent 4b2f8122e3
commit 9c79fa7430
13 changed files with 271 additions and 19 deletions
+19 -1
View File
@@ -9,7 +9,12 @@ from typing import Any
import pytest
from esphome import config_validation as cv
from esphome.components.sendspin import CONF_STATIC_PAIRING_CODE, CONFIG_SCHEMA
from esphome.components.sendspin import (
CONF_STATIC_PAIRING_CODE,
CONFIG_SCHEMA,
FINAL_VALIDATE_SCHEMA,
request_pairing_code_display_support,
)
from esphome.const import PlatformFramework
from esphome.types import ConfigType
from tests.component_tests.types import SetCoreConfigCallable
@@ -75,3 +80,16 @@ def test_unquoted_static_pairing_code_rejected(
with pytest.raises(cv.Invalid):
CONFIG_SCHEMA(_hub_config(static_pairing_code=1234567))
def test_static_code_with_dynamic_code_rejected(
set_core_config: SetCoreConfigCallable,
) -> None:
"""Only one pairing code method can be offered, so a static code next to the dynamic
code would be silently ignored."""
set_core_config(PlatformFramework.ESP32_IDF)
request_pairing_code_display_support()
config = CONFIG_SCHEMA(_hub_config(static_pairing_code="01234567"))
with pytest.raises(cv.Invalid, match="cannot be used with a dynamic pairing code"):
FINAL_VALIDATE_SCHEMA(config)
@@ -0,0 +1,60 @@
"""Validation tests for the sendspin text sensor platform.
These cover behavior a compile test cannot observe: which roles a sensor type requests.
"""
from typing import Any
import pytest
from esphome import config_validation as cv
from esphome.components.sendspin import _get_data
from esphome.components.sendspin.text_sensor import (
CONF_PAIRING_CODE,
CONFIG_SCHEMA,
SENDSPIN_TEXT_METADATA_TYPES,
)
from esphome.const import PlatformFramework
from esphome.types import ConfigType
from tests.component_tests.types import SetCoreConfigCallable
def _sensor_config(**overrides: Any) -> ConfigType:
"""Build a minimal valid text sensor config, allowing field overrides."""
config: ConfigType = {"name": "Sendspin Text", "type": "title"}
config.update(overrides)
return config
@pytest.mark.parametrize("sensor_type", sorted(SENDSPIN_TEXT_METADATA_TYPES))
def test_metadata_types_request_metadata_role(
set_core_config: SetCoreConfigCallable, sensor_type: str
) -> None:
"""Metadata sensors need the metadata role, and say nothing about pairing codes."""
set_core_config(PlatformFramework.ESP32_IDF)
CONFIG_SCHEMA(_sensor_config(type=sensor_type))
assert _get_data().metadata_support is True
assert _get_data().pairing_code_display_support is False
def test_pairing_code_requests_code_display(
set_core_config: SetCoreConfigCallable,
) -> None:
"""A pairing_code sensor is a way to show the dynamic code, so it alone makes the
hub offer it. It needs no role, so a pairing-only config builds without metadata."""
set_core_config(PlatformFramework.ESP32_IDF)
CONFIG_SCHEMA(_sensor_config(type=CONF_PAIRING_CODE))
assert _get_data().pairing_code_display_support is True
assert _get_data().metadata_support is False
def test_unknown_type_rejected(set_core_config: SetCoreConfigCallable) -> None:
"""A misspelled type must fail rather than fall through to a default."""
set_core_config(PlatformFramework.ESP32_IDF)
with pytest.raises(cv.Invalid):
CONFIG_SCHEMA(_sensor_config(type="pairing_secret"))
@@ -8,6 +8,7 @@ from esphome.components.sendspin import (
CONF_UNPAIRED_ACCESS,
CONFIG_SCHEMA as HUB_CONFIG_SCHEMA,
FINAL_VALIDATE_SCHEMA as HUB_FINAL_VALIDATE_SCHEMA,
request_pairing_code_display_support,
)
from esphome.const import PlatformFramework
from tests.component_tests.types import SetCoreConfigCallable
@@ -45,7 +46,7 @@ def test_off_without_pairing_method_warns(
assert NO_PAIRING_WARNING in caplog.text
@pytest.mark.parametrize("method", ["static_pairing_code"])
@pytest.mark.parametrize("method", ["static_pairing_code", "pairing_code"])
def test_off_with_pairing_method_does_not_warn(
set_core_config: SetCoreConfigCallable,
caplog: pytest.LogCaptureFixture,
@@ -55,6 +56,8 @@ def test_off_with_pairing_method_does_not_warn(
hub_config = {"id": HUB_ID, CONF_UNPAIRED_ACCESS: False}
if method == "static_pairing_code":
hub_config["static_pairing_code"] = "01234567"
else:
request_pairing_code_display_support()
config = HUB_CONFIG_SCHEMA(hub_config)
with caplog.at_level(logging.WARNING):