mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-05 10:17:17 +08:00
Fixes NousResearch/hermes-agent#11768 Root cause: target.strip().lower() was lowercasing the entire target string, corrupting case-sensitive chat IDs like Slack C123ABC and Matrix !RoomABC. Fix: Only lowercase the platform prefix for case-insensitive matching; preserve the original case for chat_id and thread_id values.
127 lines
4.9 KiB
Python
127 lines
4.9 KiB
Python
"""Tests for the delivery routing module."""
|
|
|
|
from gateway.config import Platform
|
|
from gateway.delivery import DeliveryTarget
|
|
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", thread_id="42")
|
|
target = DeliveryTarget.parse("origin", origin=origin)
|
|
assert target.platform == Platform.TELEGRAM
|
|
assert target.chat_id == "789"
|
|
assert target.thread_id == "42"
|
|
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 TestTargetToStringRoundtrip:
|
|
def test_origin_roundtrip(self):
|
|
origin = SessionSource(platform=Platform.TELEGRAM, chat_id="111", thread_id="42")
|
|
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"
|
|
|
|
|
|
class TestCaseSensitiveChatIdParsing:
|
|
"""Test that chat IDs preserve their original case (issue #11768)."""
|
|
|
|
def test_slack_uppercase_chat_id_preserved(self):
|
|
"""Slack channel IDs like C123ABC should preserve case."""
|
|
target = DeliveryTarget.parse("slack:C123ABC")
|
|
assert target.platform == Platform.SLACK
|
|
assert target.chat_id == "C123ABC" # Should NOT be lowercased to c123abc
|
|
assert target.is_explicit is True
|
|
|
|
def test_slack_chat_id_with_thread_preserved(self):
|
|
"""Slack channel:thread IDs should preserve case."""
|
|
target = DeliveryTarget.parse("slack:C123ABC:thread123")
|
|
assert target.platform == Platform.SLACK
|
|
assert target.chat_id == "C123ABC"
|
|
assert target.thread_id == "thread123"
|
|
|
|
def test_matrix_room_id_preserved(self):
|
|
"""Matrix room IDs like !RoomABC:example.org should preserve case.
|
|
|
|
Note: Matrix room IDs contain colons (e.g., !RoomABC:example.org).
|
|
Due to the platform:chat_id:thread_id format, these are parsed as
|
|
chat_id=!RoomABC and thread_id=example.org. This is a known limitation
|
|
of the current format. The fix preserves case but doesn't change the
|
|
parsing structure.
|
|
"""
|
|
target = DeliveryTarget.parse("matrix:!RoomABC:example.org")
|
|
assert target.platform == Platform.MATRIX
|
|
# The room ID is split at the first colon after the platform prefix
|
|
# This is a format limitation - the case is preserved but the structure is split
|
|
assert target.chat_id == "!RoomABC"
|
|
assert target.thread_id == "example.org"
|
|
|
|
def test_mixed_case_chat_id_roundtrip(self):
|
|
"""Mixed-case chat IDs should survive parse-to_string roundtrip."""
|
|
original = "telegram:ChatId123ABC"
|
|
target = DeliveryTarget.parse(original)
|
|
s = target.to_string()
|
|
reparsed = DeliveryTarget.parse(s)
|
|
assert reparsed.chat_id == "ChatId123ABC"
|
|
|
|
|
|
class TestPlatformNameCaseInsensitivity:
|
|
"""Test that platform names are case-insensitive."""
|
|
|
|
def test_uppercase_platform_name(self):
|
|
"""Platform names should be case-insensitive."""
|
|
target = DeliveryTarget.parse("TELEGRAM:12345")
|
|
assert target.platform == Platform.TELEGRAM
|
|
assert target.chat_id == "12345"
|
|
|
|
def test_mixed_case_platform_name(self):
|
|
"""Mixed-case platform names should work."""
|
|
target = DeliveryTarget.parse("TeleGram:12345")
|
|
assert target.platform == Platform.TELEGRAM
|
|
assert target.chat_id == "12345"
|
|
|
|
|
|
|