test: reorganize test structure and add missing unit tests
Reorganize flat tests/ directory to mirror source code structure (tools/, gateway/, hermes_cli/, integration/). Add 11 new test files covering previously untested modules: registry, patch_parser, fuzzy_match, todo_tool, approval, file_tools, gateway session/config/ delivery, and hermes_cli config/models. Total: 147 unit tests passing, 9 integration tests gated behind pytest marker.
This commit is contained in:
parent
3c5bf5b9d8
commit
8fc28c34ce
24 changed files with 1066 additions and 16 deletions
0
tests/gateway/__init__.py
Normal file
0
tests/gateway/__init__.py
Normal file
103
tests/gateway/test_config.py
Normal file
103
tests/gateway/test_config.py
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
"""Tests for gateway configuration management."""
|
||||
|
||||
from gateway.config import (
|
||||
GatewayConfig,
|
||||
HomeChannel,
|
||||
Platform,
|
||||
PlatformConfig,
|
||||
SessionResetPolicy,
|
||||
)
|
||||
|
||||
|
||||
class TestHomeChannelRoundtrip:
|
||||
def test_to_dict_from_dict(self):
|
||||
hc = HomeChannel(platform=Platform.DISCORD, chat_id="999", name="general")
|
||||
d = hc.to_dict()
|
||||
restored = HomeChannel.from_dict(d)
|
||||
|
||||
assert restored.platform == Platform.DISCORD
|
||||
assert restored.chat_id == "999"
|
||||
assert restored.name == "general"
|
||||
|
||||
|
||||
class TestPlatformConfigRoundtrip:
|
||||
def test_to_dict_from_dict(self):
|
||||
pc = PlatformConfig(
|
||||
enabled=True,
|
||||
token="tok_123",
|
||||
home_channel=HomeChannel(
|
||||
platform=Platform.TELEGRAM,
|
||||
chat_id="555",
|
||||
name="Home",
|
||||
),
|
||||
extra={"foo": "bar"},
|
||||
)
|
||||
d = pc.to_dict()
|
||||
restored = PlatformConfig.from_dict(d)
|
||||
|
||||
assert restored.enabled is True
|
||||
assert restored.token == "tok_123"
|
||||
assert restored.home_channel.chat_id == "555"
|
||||
assert restored.extra == {"foo": "bar"}
|
||||
|
||||
def test_disabled_no_token(self):
|
||||
pc = PlatformConfig()
|
||||
d = pc.to_dict()
|
||||
restored = PlatformConfig.from_dict(d)
|
||||
assert restored.enabled is False
|
||||
assert restored.token is None
|
||||
|
||||
|
||||
class TestGetConnectedPlatforms:
|
||||
def test_returns_enabled_with_token(self):
|
||||
config = GatewayConfig(
|
||||
platforms={
|
||||
Platform.TELEGRAM: PlatformConfig(enabled=True, token="t"),
|
||||
Platform.DISCORD: PlatformConfig(enabled=False, token="d"),
|
||||
Platform.SLACK: PlatformConfig(enabled=True), # no token
|
||||
},
|
||||
)
|
||||
connected = config.get_connected_platforms()
|
||||
assert Platform.TELEGRAM in connected
|
||||
assert Platform.DISCORD not in connected
|
||||
assert Platform.SLACK not in connected
|
||||
|
||||
def test_empty_platforms(self):
|
||||
config = GatewayConfig()
|
||||
assert config.get_connected_platforms() == []
|
||||
|
||||
|
||||
class TestSessionResetPolicy:
|
||||
def test_roundtrip(self):
|
||||
policy = SessionResetPolicy(mode="idle", at_hour=6, idle_minutes=120)
|
||||
d = policy.to_dict()
|
||||
restored = SessionResetPolicy.from_dict(d)
|
||||
assert restored.mode == "idle"
|
||||
assert restored.at_hour == 6
|
||||
assert restored.idle_minutes == 120
|
||||
|
||||
def test_defaults(self):
|
||||
policy = SessionResetPolicy()
|
||||
assert policy.mode == "both"
|
||||
assert policy.at_hour == 4
|
||||
assert policy.idle_minutes == 1440
|
||||
|
||||
|
||||
class TestGatewayConfigRoundtrip:
|
||||
def test_full_roundtrip(self):
|
||||
config = GatewayConfig(
|
||||
platforms={
|
||||
Platform.TELEGRAM: PlatformConfig(
|
||||
enabled=True,
|
||||
token="tok",
|
||||
home_channel=HomeChannel(Platform.TELEGRAM, "123", "Home"),
|
||||
),
|
||||
},
|
||||
reset_triggers=["/new"],
|
||||
)
|
||||
d = config.to_dict()
|
||||
restored = GatewayConfig.from_dict(d)
|
||||
|
||||
assert Platform.TELEGRAM in restored.platforms
|
||||
assert restored.platforms[Platform.TELEGRAM].token == "tok"
|
||||
assert restored.reset_triggers == ["/new"]
|
||||
86
tests/gateway/test_delivery.py
Normal file
86
tests/gateway/test_delivery.py
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
"""Tests for the delivery routing module."""
|
||||
|
||||
from gateway.config import Platform, GatewayConfig, PlatformConfig, HomeChannel
|
||||
from gateway.delivery import DeliveryTarget, parse_deliver_spec
|
||||
from gateway.session import SessionSource
|
||||
|
||||
|
||||
class TestParseTargetPlatformChat:
|
||||
def test_explicit_telegram_chat(self):
|
||||
target = DeliveryTarget.parse("telegram:12345")
|
||||
assert target.platform == Platform.TELEGRAM
|
||||
assert target.chat_id == "12345"
|
||||
assert target.is_explicit is True
|
||||
|
||||
def test_platform_only_no_chat_id(self):
|
||||
target = DeliveryTarget.parse("discord")
|
||||
assert target.platform == Platform.DISCORD
|
||||
assert target.chat_id is None
|
||||
assert target.is_explicit is False
|
||||
|
||||
def test_local_target(self):
|
||||
target = DeliveryTarget.parse("local")
|
||||
assert target.platform == Platform.LOCAL
|
||||
assert target.chat_id is None
|
||||
|
||||
def test_origin_with_source(self):
|
||||
origin = SessionSource(platform=Platform.TELEGRAM, chat_id="789")
|
||||
target = DeliveryTarget.parse("origin", origin=origin)
|
||||
assert target.platform == Platform.TELEGRAM
|
||||
assert target.chat_id == "789"
|
||||
assert target.is_origin is True
|
||||
|
||||
def test_origin_without_source(self):
|
||||
target = DeliveryTarget.parse("origin")
|
||||
assert target.platform == Platform.LOCAL
|
||||
assert target.is_origin is True
|
||||
|
||||
def test_unknown_platform(self):
|
||||
target = DeliveryTarget.parse("unknown_platform")
|
||||
assert target.platform == Platform.LOCAL
|
||||
|
||||
|
||||
class TestParseDeliverSpec:
|
||||
def test_none_returns_default(self):
|
||||
result = parse_deliver_spec(None)
|
||||
assert result == "origin"
|
||||
|
||||
def test_empty_string_returns_default(self):
|
||||
result = parse_deliver_spec("")
|
||||
assert result == "origin"
|
||||
|
||||
def test_custom_default(self):
|
||||
result = parse_deliver_spec(None, default="local")
|
||||
assert result == "local"
|
||||
|
||||
def test_passthrough_string(self):
|
||||
result = parse_deliver_spec("telegram")
|
||||
assert result == "telegram"
|
||||
|
||||
def test_passthrough_list(self):
|
||||
result = parse_deliver_spec(["local", "telegram"])
|
||||
assert result == ["local", "telegram"]
|
||||
|
||||
|
||||
class TestTargetToStringRoundtrip:
|
||||
def test_origin_roundtrip(self):
|
||||
origin = SessionSource(platform=Platform.TELEGRAM, chat_id="111")
|
||||
target = DeliveryTarget.parse("origin", origin=origin)
|
||||
assert target.to_string() == "origin"
|
||||
|
||||
def test_local_roundtrip(self):
|
||||
target = DeliveryTarget.parse("local")
|
||||
assert target.to_string() == "local"
|
||||
|
||||
def test_platform_only_roundtrip(self):
|
||||
target = DeliveryTarget.parse("discord")
|
||||
assert target.to_string() == "discord"
|
||||
|
||||
def test_explicit_chat_roundtrip(self):
|
||||
target = DeliveryTarget.parse("telegram:999")
|
||||
s = target.to_string()
|
||||
assert s == "telegram:999"
|
||||
|
||||
reparsed = DeliveryTarget.parse(s)
|
||||
assert reparsed.platform == Platform.TELEGRAM
|
||||
assert reparsed.chat_id == "999"
|
||||
88
tests/gateway/test_session.py
Normal file
88
tests/gateway/test_session.py
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
"""Tests for gateway session management."""
|
||||
|
||||
from gateway.config import Platform, HomeChannel, GatewayConfig, PlatformConfig
|
||||
from gateway.session import (
|
||||
SessionSource,
|
||||
build_session_context,
|
||||
build_session_context_prompt,
|
||||
)
|
||||
|
||||
|
||||
class TestSessionSourceRoundtrip:
|
||||
def test_to_dict_from_dict(self):
|
||||
source = SessionSource(
|
||||
platform=Platform.TELEGRAM,
|
||||
chat_id="12345",
|
||||
chat_name="My Group",
|
||||
chat_type="group",
|
||||
user_id="99",
|
||||
user_name="alice",
|
||||
thread_id="t1",
|
||||
)
|
||||
d = source.to_dict()
|
||||
restored = SessionSource.from_dict(d)
|
||||
|
||||
assert restored.platform == Platform.TELEGRAM
|
||||
assert restored.chat_id == "12345"
|
||||
assert restored.chat_name == "My Group"
|
||||
assert restored.chat_type == "group"
|
||||
assert restored.user_id == "99"
|
||||
assert restored.user_name == "alice"
|
||||
assert restored.thread_id == "t1"
|
||||
|
||||
def test_minimal_roundtrip(self):
|
||||
source = SessionSource(platform=Platform.LOCAL, chat_id="cli")
|
||||
d = source.to_dict()
|
||||
restored = SessionSource.from_dict(d)
|
||||
assert restored.platform == Platform.LOCAL
|
||||
assert restored.chat_id == "cli"
|
||||
|
||||
|
||||
class TestLocalCliSource:
|
||||
def test_local_cli(self):
|
||||
source = SessionSource.local_cli()
|
||||
assert source.platform == Platform.LOCAL
|
||||
assert source.chat_id == "cli"
|
||||
assert source.chat_type == "dm"
|
||||
|
||||
def test_description_local(self):
|
||||
source = SessionSource.local_cli()
|
||||
assert source.description == "CLI terminal"
|
||||
|
||||
|
||||
class TestBuildSessionContextPrompt:
|
||||
def test_contains_platform_info(self):
|
||||
config = GatewayConfig(
|
||||
platforms={
|
||||
Platform.TELEGRAM: PlatformConfig(
|
||||
enabled=True,
|
||||
token="fake-token",
|
||||
home_channel=HomeChannel(
|
||||
platform=Platform.TELEGRAM,
|
||||
chat_id="111",
|
||||
name="Home Chat",
|
||||
),
|
||||
),
|
||||
},
|
||||
)
|
||||
source = SessionSource(
|
||||
platform=Platform.TELEGRAM,
|
||||
chat_id="111",
|
||||
chat_name="Home Chat",
|
||||
chat_type="dm",
|
||||
)
|
||||
ctx = build_session_context(source, config)
|
||||
prompt = build_session_context_prompt(ctx)
|
||||
|
||||
assert "Telegram" in prompt
|
||||
assert "Home Chat" in prompt
|
||||
assert "Session Context" in prompt
|
||||
|
||||
def test_local_source_prompt(self):
|
||||
config = GatewayConfig()
|
||||
source = SessionSource.local_cli()
|
||||
ctx = build_session_context(source, config)
|
||||
prompt = build_session_context_prompt(ctx)
|
||||
|
||||
assert "Local" in prompt
|
||||
assert "machine running this agent" in prompt
|
||||
Loading…
Add table
Add a link
Reference in a new issue