Files
2026-07-05 16:39:15 -05:00

176 lines
4.6 KiB
Python

"""TOML config loading: namespaced sections per device class."""
import textwrap
import pytest
from tuya_re.config import (
GatewayFingerbot,
SwitchCredentials,
load_fingerbots,
load_gateway,
load_ir_blasters,
load_switches,
select_devices,
)
FULL = textwrap.dedent("""
[fingerbots]
default = "robot2"
[fingerbots.devices.robot1]
device_id = "testdevice000000000001"
uuid = "uuidTESTtest0000"
local_key = "abcdef0123456789"
product_id = "mknd4lci"
[fingerbots.devices.robot2]
device_id = "testdevice000000000002"
uuid = "uuidTESTtest0002"
local_key = "abcdef0123456789"
product_id = "mknd4lci"
[switches]
default = "plug"
[switches.devices.plug]
device_id = "testdevice000000000003"
local_key = "abcdef0123456789"
product_id = "o7ve1lp3gfjvsvyo"
version = "3.4"
ip = "192.0.2.10"
[ir_blasters]
default = "blaster"
[ir_blasters.devices.blaster]
device_id = "testdevice000000000004"
uuid = "uuidTESTtest0004"
local_key = "abcdef0123456789"
product_id = "xgahj3gjk3ftaejt"
[gateway]
device_id = "testdevice000000000005"
ip = "192.0.2.20"
local_key = "abcdef0123456789"
version = "3.4"
[gateway.fingerbots]
default = "robot1"
[gateway.fingerbots.devices.robot1]
device_id = "testdevice000000000001"
node_id = "uuidTESTtest0000"
""")
@pytest.fixture
def cfg_path(tmp_path):
p = tmp_path / "config.toml"
p.write_text(FULL)
return p
def test_load_fingerbots_default_selection(cfg_path):
cfg = load_fingerbots(cfg_path)
[creds] = select_devices(cfg, None)
assert creds.name == "robot2"
assert creds.device_id == "testdevice000000000002"
def test_select_by_name_and_all(cfg_path):
cfg = load_fingerbots(cfg_path)
assert select_devices(cfg, "robot1")[0].uuid == "uuidTESTtest0000"
assert {c.name for c in select_devices(cfg, "all")} == {"robot1", "robot2"}
def test_unknown_device_raises(cfg_path):
with pytest.raises(ValueError, match="unknown device"):
select_devices(load_fingerbots(cfg_path), "nope")
def test_load_switches(cfg_path):
[sw] = select_devices(load_switches(cfg_path), None)
assert sw == SwitchCredentials(
device_id="testdevice000000000003",
local_key="abcdef0123456789",
product_id="o7ve1lp3gfjvsvyo",
name="plug",
version="3.4",
ip="192.0.2.10",
)
def test_switch_optional_fields_default_none(tmp_path):
p = tmp_path / "config.toml"
p.write_text(
textwrap.dedent("""
[switches.devices.plug]
device_id = "testdevice000000000003"
local_key = "abcdef0123456789"
product_id = "o7ve1lp3gfjvsvyo"
""")
)
[sw] = select_devices(load_switches(p), None)
assert sw.version is None and sw.ip is None
def test_switch_numeric_version_coerced_to_str(tmp_path):
p = tmp_path / "config.toml"
p.write_text(
textwrap.dedent("""
[switches.devices.plug]
device_id = "testdevice000000000003"
local_key = "abcdef0123456789"
product_id = "o7ve1lp3gfjvsvyo"
version = 3.4
""")
)
[sw] = select_devices(load_switches(p), None)
assert sw.version == "3.4"
def test_load_ir_blasters(cfg_path):
[blaster] = select_devices(load_ir_blasters(cfg_path), None)
assert blaster.product_id == "xgahj3gjk3ftaejt"
def test_missing_section_gives_empty_config(tmp_path):
p = tmp_path / "config.toml"
p.write_text(
'[fingerbots.devices.r]\ndevice_id = "x"\nuuid = "u"\n'
'local_key = "k"\nproduct_id = "p"\n'
)
with pytest.raises(ValueError, match="no .* devices configured"):
select_devices(load_ir_blasters(p), None)
def test_multiple_devices_without_default_raises(tmp_path):
p = tmp_path / "config.toml"
p.write_text(
textwrap.dedent("""
[fingerbots.devices.a]
device_id = "x"
uuid = "u"
local_key = "k"
product_id = "p"
[fingerbots.devices.b]
device_id = "y"
uuid = "u2"
local_key = "k"
product_id = "p"
""")
)
with pytest.raises(ValueError, match="multiple devices"):
select_devices(load_fingerbots(p), None)
def test_load_gateway(cfg_path):
gw = load_gateway(cfg_path)
assert gw.ip == "192.0.2.20"
assert gw.version == "3.4"
[fb] = select_devices(gw.fingerbots, None)
assert fb == GatewayFingerbot(
device_id="testdevice000000000001", node_id="uuidTESTtest0000", name="robot1"
)
def test_load_gateway_absent_returns_none(tmp_path):
p = tmp_path / "config.toml"
p.write_text("[fingerbots]\n")
assert load_gateway(p) is None