ForcePilot/backend/test/unit/channels/test_channels_imessage_config.py

175 lines
5.9 KiB
Python
Raw Normal View History

from __future__ import annotations
import pytest
from pydantic import ValidationError
from yuxi.channels.adapters.imessage.config_schema import (
DmPolicyEnum,
GroupOverrideConfig,
GroupPolicyEnum,
IMessageAccountConfig,
IMessageConnectionConfig,
IMessageFullConfig,
IMessageSecurityConfigSchema,
validate_config,
)
class TestDmPolicyEnum:
def test_values(self):
assert DmPolicyEnum.PAIRING.value == "pairing"
assert DmPolicyEnum.ALLOWLIST.value == "allowlist"
assert DmPolicyEnum.OPEN.value == "open"
assert DmPolicyEnum.DISABLED.value == "disabled"
def test_coercion(self):
schema = IMessageSecurityConfigSchema(dm_policy="open")
assert schema.dm_policy == DmPolicyEnum.OPEN
def test_coercion_invalid(self):
schema = IMessageSecurityConfigSchema(dm_policy="invalid_policy")
assert schema.dm_policy == DmPolicyEnum.PAIRING
class TestGroupPolicyEnum:
def test_values(self):
assert GroupPolicyEnum.OPEN.value == "open"
assert GroupPolicyEnum.ALLOWLIST.value == "allowlist"
assert GroupPolicyEnum.DISABLED.value == "disabled"
def test_coercion_invalid(self):
schema = IMessageSecurityConfigSchema(group_policy="invalid")
assert schema.group_policy == GroupPolicyEnum.ALLOWLIST
class TestIMessageConnectionConfig:
def test_defaults(self):
cfg = IMessageConnectionConfig()
assert cfg.server_url == "http://localhost:1234"
assert cfg.password == ""
assert cfg.probe_timeout_ms == 10000
assert cfg.max_retries == 3
assert cfg.http_timeout_s == 30.0
def test_custom_values(self):
cfg = IMessageConnectionConfig(
server_url="http://mac.local:4321",
password="secret",
probe_timeout_ms=5000,
max_retries=5,
http_timeout_s=60.0,
)
assert cfg.server_url == "http://mac.local:4321"
assert cfg.password == "secret"
assert cfg.probe_timeout_ms == 5000
assert cfg.max_retries == 5
assert cfg.http_timeout_s == 60.0
def test_probe_timeout_out_of_range(self):
with pytest.raises(ValidationError):
IMessageConnectionConfig(probe_timeout_ms=500)
def test_max_retries_out_of_range(self):
with pytest.raises(ValidationError):
IMessageConnectionConfig(max_retries=0)
class TestIMessageSecurityConfigSchema:
def test_defaults(self):
cfg = IMessageSecurityConfigSchema()
assert cfg.dm_policy == DmPolicyEnum.PAIRING
assert cfg.group_policy == GroupPolicyEnum.ALLOWLIST
assert cfg.allow_from == []
assert cfg.group_allow_from == []
assert cfg.require_mention is False
def test_custom_values(self):
cfg = IMessageSecurityConfigSchema(
dm_policy=DmPolicyEnum.OPEN,
group_policy=GroupPolicyEnum.OPEN,
allow_from=["+8613800138000"],
group_allow_from=["iMessage;-;group001"],
require_mention=True,
)
assert cfg.dm_policy == DmPolicyEnum.OPEN
assert cfg.group_policy == GroupPolicyEnum.OPEN
assert "+8613800138000" in cfg.allow_from
assert "iMessage;-;group001" in cfg.group_allow_from
assert cfg.require_mention is True
class TestIMessageFullConfig:
def test_defaults(self):
cfg = IMessageFullConfig()
assert cfg.name == "iMessage"
assert cfg.block_streaming is False
assert cfg.text_chunk_limit == 4096
assert cfg.media_max_mb == 100
assert cfg.history_limit == 20
assert cfg.include_attachments is False
assert cfg.accounts == {}
assert cfg.groups == {}
assert cfg.loop_rate_limit == 5
def test_text_chunk_limit_out_of_range(self):
with pytest.raises(ValidationError):
IMessageFullConfig(text_chunk_limit=50)
def test_accounts_from_list(self):
cfg = IMessageFullConfig(
accounts=[
IMessageAccountConfig(account_id="acct1"),
IMessageAccountConfig(account_id="acct2"),
]
)
assert len(cfg.accounts) == 2
assert "acct1" in cfg.accounts
assert "acct2" in cfg.accounts
def test_accounts_none_coerced_to_dict(self):
cfg = IMessageFullConfig(accounts=None)
assert cfg.accounts == {}
class TestGroupOverrideConfig:
def test_defaults(self):
cfg = GroupOverrideConfig()
assert cfg.enabled is None
assert cfg.require_mention is None
assert cfg.tools is None
def test_custom_values(self):
cfg = GroupOverrideConfig(enabled=True, require_mention=True, tools=["calc", "weather"])
assert cfg.enabled is True
assert cfg.require_mention is True
assert cfg.tools == ["calc", "weather"]
class TestValidateConfig:
def test_basic_valid_config(self):
result = validate_config({"server_url": "http://localhost:1234", "password": "test"})
assert isinstance(result, IMessageFullConfig)
def test_empty_config(self):
result = validate_config({})
assert isinstance(result, IMessageFullConfig)
def test_dm_policy_string(self):
result = validate_config({"security": {"dm_policy": "open"}})
assert result.security.dm_policy == DmPolicyEnum.OPEN
def test_block_streaming(self):
result = validate_config({"block_streaming": True})
assert result.block_streaming is True
def test_ws_reconnect_params(self):
result = validate_config({"ws_reconnect_initial_delay": 10.0})
assert result.ws_reconnect_initial_delay == 10.0
def test_loop_rate_params(self):
result = validate_config(
{"loop_rate_limit": 10, "loop_rate_window_s": 120.0, "loop_cooldown_s": 300.0}
)
assert result.loop_rate_limit == 10
assert result.loop_rate_window_s == 120.0
assert result.loop_cooldown_s == 300.0