Initial commit
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import contextlib
|
||||
import shutil
|
||||
import unittest
|
||||
import uuid
|
||||
from pathlib import Path
|
||||
|
||||
from opc.channels.email import EmailChannel
|
||||
from opc.channels.slack import SlackChannel
|
||||
from opc.channels.telegram import TelegramChannel
|
||||
from opc.channels.whatsapp import WhatsAppChannel
|
||||
from opc.core.config import OPCConfig
|
||||
from opc.core.models import SystemMessage
|
||||
from opc.layer0_interaction.message_bus import MessageBus
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def _workspace_tempdir() -> Path:
|
||||
base = Path.cwd() / ".tmp-test" / f"channel-runtime-{uuid.uuid4().hex}"
|
||||
base.mkdir(parents=True, exist_ok=True)
|
||||
try:
|
||||
yield base
|
||||
finally:
|
||||
shutil.rmtree(base, ignore_errors=True)
|
||||
|
||||
|
||||
class ChannelProviderRuntimeTests(unittest.IsolatedAsyncioTestCase):
|
||||
async def test_email_send_sets_reply_headers(self) -> None:
|
||||
config = OPCConfig()
|
||||
config.channels.email.consent_granted = True
|
||||
config.channels.email.imap_host = "imap.example.com"
|
||||
config.channels.email.imap_username = "bot@example.com"
|
||||
config.channels.email.imap_password = "secret"
|
||||
config.channels.email.smtp_host = "smtp.example.com"
|
||||
config.channels.email.smtp_username = "bot@example.com"
|
||||
config.channels.email.smtp_password = "secret"
|
||||
channel = EmailChannel(config.channels.email, MessageBus())
|
||||
channel._last_subject_by_chat["user@example.com"] = "Original subject"
|
||||
channel._last_message_id_by_chat["user@example.com"] = "<abc@example.com>"
|
||||
sent = {}
|
||||
|
||||
def fake_smtp_send(message):
|
||||
sent["message"] = message
|
||||
|
||||
channel._smtp_send = fake_smtp_send # type: ignore[method-assign]
|
||||
await channel.send(
|
||||
SystemMessage(
|
||||
channel="email",
|
||||
user_id="u",
|
||||
session_id="sess",
|
||||
content="hello",
|
||||
metadata={"chat_id": "user@example.com"},
|
||||
)
|
||||
)
|
||||
|
||||
message = sent["message"]
|
||||
self.assertEqual(message["To"], "user@example.com")
|
||||
self.assertEqual(message["In-Reply-To"], "<abc@example.com>")
|
||||
self.assertEqual(message["References"], "<abc@example.com>")
|
||||
|
||||
async def test_telegram_send_splits_messages_and_uses_reply(self) -> None:
|
||||
config = OPCConfig()
|
||||
config.channels.telegram.reply_to_message = True
|
||||
channel = TelegramChannel(config.channels.telegram, MessageBus())
|
||||
calls = []
|
||||
|
||||
class _Bot:
|
||||
async def send_message(self, **kwargs):
|
||||
calls.append(("message", kwargs))
|
||||
|
||||
async def send_document(self, **kwargs):
|
||||
calls.append(("document", kwargs))
|
||||
|
||||
channel._bot = _Bot()
|
||||
with _workspace_tempdir() as tmpdir:
|
||||
attachment = tmpdir / "a.txt"
|
||||
attachment.write_text("demo")
|
||||
await channel.send(
|
||||
SystemMessage(
|
||||
channel="telegram",
|
||||
user_id="u",
|
||||
session_id="7",
|
||||
content="x" * 4500,
|
||||
metadata={"chat_id": "7", "reply_to": "11", "attachments": [str(attachment)]},
|
||||
)
|
||||
)
|
||||
|
||||
self.assertEqual(calls[0][0], "message")
|
||||
self.assertEqual(calls[0][1]["reply_to_message_id"], 11)
|
||||
self.assertEqual(calls[-1][0], "document")
|
||||
|
||||
async def test_slack_socket_event_produces_thread_scoped_session(self) -> None:
|
||||
config = OPCConfig()
|
||||
config.channels.slack.allow_from = ["*"]
|
||||
bus = MessageBus()
|
||||
channel = SlackChannel(config.channels.slack, bus)
|
||||
channel._bot_user_id = "bot-1"
|
||||
|
||||
class _Client:
|
||||
async def send_socket_mode_response(self, response):
|
||||
return response
|
||||
|
||||
class _Req:
|
||||
type = "events_api"
|
||||
envelope_id = "env-1"
|
||||
payload = {
|
||||
"event": {
|
||||
"type": "app_mention",
|
||||
"user": "u1",
|
||||
"channel": "c1",
|
||||
"text": "<@bot-1> hi",
|
||||
"thread_ts": "th-1",
|
||||
"ts": "msg-1",
|
||||
"channel_type": "channel",
|
||||
}
|
||||
}
|
||||
|
||||
await channel._on_socket_request(_Client(), _Req())
|
||||
message = await bus._inbound_queue.get()
|
||||
self.assertEqual(message.session_id, "slack:c1:th-1")
|
||||
self.assertEqual(message.content, "hi")
|
||||
|
||||
async def test_whatsapp_bridge_message_publishes_inbound(self) -> None:
|
||||
config = OPCConfig()
|
||||
config.channels.whatsapp.allow_from = ["*"]
|
||||
bus = MessageBus()
|
||||
channel = WhatsAppChannel(config.channels.whatsapp, bus)
|
||||
|
||||
await channel._handle_bridge_message(
|
||||
'{"type":"message","id":"m1","sender":"12345@s.whatsapp.net","message":{"chat_id":"12345@s.whatsapp.net","text":"hello"}}'
|
||||
)
|
||||
|
||||
message = await bus._inbound_queue.get()
|
||||
self.assertEqual(message.user_id, "12345")
|
||||
self.assertEqual(message.metadata["chat_id"], "12345@s.whatsapp.net")
|
||||
Reference in New Issue
Block a user