mirror of
https://github.com/esphome/esphome.git
synced 2026-10-09 04:16:01 +00:00
[sendspin] Add an unpaired access switch (#20350)
This commit is contained in:
@@ -1,24 +1,42 @@
|
||||
"""Validation tests for the hub's unpaired access policy."""
|
||||
"""Validation tests for the unpaired access policy.
|
||||
|
||||
The hub's `unpaired_access` key and an `unpaired_access` switch both set the
|
||||
policy, so the switch platform rejects a config that has both.
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
import pytest
|
||||
|
||||
from esphome import config_validation as cv
|
||||
from esphome.components.sendspin import (
|
||||
CONF_UNPAIRED_ACCESS,
|
||||
CONFIG_SCHEMA as HUB_CONFIG_SCHEMA,
|
||||
DOMAIN,
|
||||
FINAL_VALIDATE_SCHEMA as HUB_FINAL_VALIDATE_SCHEMA,
|
||||
_get_data,
|
||||
request_pairing_code_display_support,
|
||||
)
|
||||
from esphome.components.sendspin.switch import (
|
||||
CONFIG_SCHEMA as SWITCH_CONFIG_SCHEMA,
|
||||
FINAL_VALIDATE_SCHEMA as SWITCH_FINAL_VALIDATE_SCHEMA,
|
||||
)
|
||||
from esphome.const import PlatformFramework
|
||||
from esphome.types import ConfigType
|
||||
from tests.component_tests.types import SetCoreConfigCallable
|
||||
|
||||
HUB_ID = "sendspin_hub_id"
|
||||
NO_PAIRING_WARNING = "nothing lets a server pair"
|
||||
NO_PAIRING_WARNING = "no new server can pair with this device"
|
||||
|
||||
|
||||
def _switch_config(switch_type: str) -> ConfigType:
|
||||
return SWITCH_CONFIG_SCHEMA(
|
||||
{"name": "Sendspin Switch", "type": switch_type, "sendspin_id": HUB_ID}
|
||||
)
|
||||
|
||||
|
||||
def test_hub_key_absent_by_default(set_core_config: SetCoreConfigCallable) -> None:
|
||||
"""Codegen leaves the hub's built-in default of on in place when the key is not set."""
|
||||
"""With no default in the schema, the switch can tell whether the key was set."""
|
||||
set_core_config(PlatformFramework.ESP32_IDF)
|
||||
|
||||
assert CONF_UNPAIRED_ACCESS not in HUB_CONFIG_SCHEMA({"id": HUB_ID})
|
||||
@@ -36,7 +54,7 @@ def test_hub_key_accepted(set_core_config: SetCoreConfigCallable, value: bool) -
|
||||
def test_off_without_pairing_method_warns(
|
||||
set_core_config: SetCoreConfigCallable, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
"""With unpaired access off and no way to pair, no server could ever play."""
|
||||
"""With unpaired access off and no way to pair, no new server could pair."""
|
||||
set_core_config(PlatformFramework.ESP32_IDF)
|
||||
config = HUB_CONFIG_SCHEMA({"id": HUB_ID, CONF_UNPAIRED_ACCESS: False})
|
||||
|
||||
@@ -76,3 +94,92 @@ def test_on_does_not_warn(
|
||||
HUB_FINAL_VALIDATE_SCHEMA(config)
|
||||
|
||||
assert NO_PAIRING_WARNING not in caplog.text
|
||||
|
||||
|
||||
def test_switch_with_hub_key_rejected(set_core_config: SetCoreConfigCallable) -> None:
|
||||
"""Both would set the policy, and the hub's value would be silently ignored."""
|
||||
set_core_config(
|
||||
PlatformFramework.ESP32_IDF,
|
||||
full_config={DOMAIN: {"id": HUB_ID, CONF_UNPAIRED_ACCESS: False}},
|
||||
)
|
||||
config = _switch_config(CONF_UNPAIRED_ACCESS)
|
||||
|
||||
with pytest.raises(cv.Invalid, match="set the switch's restore_mode instead"):
|
||||
SWITCH_FINAL_VALIDATE_SCHEMA(config)
|
||||
|
||||
|
||||
def test_switch_without_hub_key_accepted(
|
||||
set_core_config: SetCoreConfigCallable,
|
||||
) -> None:
|
||||
set_core_config(PlatformFramework.ESP32_IDF, full_config={DOMAIN: {"id": HUB_ID}})
|
||||
config = _switch_config(CONF_UNPAIRED_ACCESS)
|
||||
|
||||
assert SWITCH_FINAL_VALIDATE_SCHEMA(config) is config
|
||||
|
||||
|
||||
def test_switch_without_pairing_method_warns(
|
||||
set_core_config: SetCoreConfigCallable, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
"""Turning the switch off would leave no way for a new server to pair."""
|
||||
set_core_config(PlatformFramework.ESP32_IDF, full_config={DOMAIN: {"id": HUB_ID}})
|
||||
config = _switch_config(CONF_UNPAIRED_ACCESS)
|
||||
|
||||
with caplog.at_level(logging.WARNING):
|
||||
SWITCH_FINAL_VALIDATE_SCHEMA(config)
|
||||
|
||||
assert NO_PAIRING_WARNING in caplog.text
|
||||
|
||||
|
||||
def test_switch_with_pairing_method_does_not_warn(
|
||||
set_core_config: SetCoreConfigCallable, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
set_core_config(
|
||||
PlatformFramework.ESP32_IDF,
|
||||
full_config={DOMAIN: {"id": HUB_ID, "static_pairing_code": "01234567"}},
|
||||
)
|
||||
config = _switch_config(CONF_UNPAIRED_ACCESS)
|
||||
|
||||
with caplog.at_level(logging.WARNING):
|
||||
SWITCH_FINAL_VALIDATE_SCHEMA(config)
|
||||
|
||||
assert NO_PAIRING_WARNING not in caplog.text
|
||||
|
||||
|
||||
def test_enabled_switch_ignores_hub_key(set_core_config: SetCoreConfigCallable) -> None:
|
||||
"""Only the unpaired access switch competes with the hub key."""
|
||||
set_core_config(
|
||||
PlatformFramework.ESP32_IDF,
|
||||
full_config={DOMAIN: {"id": HUB_ID, CONF_UNPAIRED_ACCESS: False}},
|
||||
)
|
||||
config = _switch_config("enabled")
|
||||
|
||||
assert SWITCH_FINAL_VALIDATE_SCHEMA(config) is config
|
||||
|
||||
|
||||
@pytest.mark.parametrize("switch_type", ["enabled", CONF_UNPAIRED_ACCESS])
|
||||
def test_duplicate_switch_type_rejected(
|
||||
set_core_config: SetCoreConfigCallable, switch_type: str
|
||||
) -> None:
|
||||
"""Two switches of one type would fight over the same hub setting."""
|
||||
entry = {"platform": DOMAIN, "type": switch_type}
|
||||
set_core_config(
|
||||
PlatformFramework.ESP32_IDF,
|
||||
full_config={DOMAIN: {"id": HUB_ID}, "switch": [entry, dict(entry)]},
|
||||
)
|
||||
config = _switch_config(switch_type)
|
||||
|
||||
with pytest.raises(cv.Invalid, match="Only one sendspin"):
|
||||
SWITCH_FINAL_VALIDATE_SCHEMA(config)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("switch_type", ["enabled", CONF_UNPAIRED_ACCESS])
|
||||
def test_switch_requests_its_type(
|
||||
set_core_config: SetCoreConfigCallable, switch_type: str
|
||||
) -> None:
|
||||
"""The hub skips the codegen value for a setting a switch drives, so the client
|
||||
waits for that switch to restore before its first start."""
|
||||
set_core_config(PlatformFramework.ESP32_IDF)
|
||||
|
||||
_switch_config(switch_type)
|
||||
|
||||
assert _get_data().switch_types == {switch_type}
|
||||
|
||||
@@ -10,5 +10,5 @@ wifi:
|
||||
sendspin:
|
||||
id: sendspin_hub_id
|
||||
static_pairing_code: "01234567"
|
||||
# Covers the hub's unpaired access option.
|
||||
# Covers the hub's unpaired access option, which is only valid without an unpaired access switch.
|
||||
unpaired_access: false
|
||||
|
||||
@@ -5,3 +5,6 @@ switch:
|
||||
- platform: sendspin
|
||||
name: "Sendspin Enabled"
|
||||
type: enabled
|
||||
- platform: sendspin
|
||||
name: "Sendspin Unpaired Access"
|
||||
type: unpaired_access
|
||||
|
||||
Reference in New Issue
Block a user