Initial commit
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import unittest
|
||||
from types import SimpleNamespace
|
||||
|
||||
from opc.channels.manager import ChannelManager
|
||||
from opc.channels.provider_base import PollingChannel, SocketChannel
|
||||
from opc.channels.provider_registry import PROVIDER_SPECS, ordered_provider_specs
|
||||
from opc.core.config import OPCConfig
|
||||
from opc.layer0_interaction.message_bus import MessageBus
|
||||
|
||||
|
||||
class _PollingProbe(PollingChannel):
|
||||
name = "poll-probe"
|
||||
required_package = None
|
||||
|
||||
def __init__(self, config, bus):
|
||||
super().__init__(config, bus)
|
||||
self.calls = 0
|
||||
|
||||
def get_poll_interval_seconds(self) -> float:
|
||||
return 0.01
|
||||
|
||||
async def poll_once(self) -> None:
|
||||
self.calls += 1
|
||||
if self.calls >= 2:
|
||||
self.mark_stopped()
|
||||
|
||||
|
||||
class _SocketProbe(SocketChannel):
|
||||
name = "socket-probe"
|
||||
required_package = None
|
||||
|
||||
def __init__(self, config, bus):
|
||||
super().__init__(config, bus)
|
||||
self.calls = 0
|
||||
|
||||
async def run_socket_forever(self) -> None:
|
||||
self.calls += 1
|
||||
if self.calls == 1:
|
||||
raise RuntimeError("boom")
|
||||
self.mark_stopped()
|
||||
|
||||
|
||||
class ChannelProviderRegistryTests(unittest.TestCase):
|
||||
def test_provider_registry_covers_all_builtin_channels(self) -> None:
|
||||
self.assertEqual(
|
||||
[spec.name for spec in ordered_provider_specs()],
|
||||
["telegram", "whatsapp", "discord", "feishu", "mochat", "dingtalk", "email", "slack", "qq", "matrix"],
|
||||
)
|
||||
self.assertTrue(PROVIDER_SPECS["whatsapp"].bridge_required)
|
||||
self.assertEqual(PROVIDER_SPECS["slack"].extra_name, "channels-slack")
|
||||
|
||||
|
||||
class ChannelRuntimeScaffoldTests(unittest.IsolatedAsyncioTestCase):
|
||||
async def test_polling_channel_runs_loop_until_stopped(self) -> None:
|
||||
channel = _PollingProbe(SimpleNamespace(allow_from=["*"]), MessageBus())
|
||||
await channel.start()
|
||||
await asyncio.sleep(0.05)
|
||||
await channel.stop()
|
||||
self.assertGreaterEqual(channel.calls, 2)
|
||||
|
||||
async def test_socket_channel_retries_after_failure(self) -> None:
|
||||
channel = _SocketProbe(SimpleNamespace(allow_from=["*"]), MessageBus())
|
||||
channel.reconnect_delay_seconds = 0.01
|
||||
await channel.start()
|
||||
await asyncio.sleep(0.05)
|
||||
await channel.stop()
|
||||
self.assertGreaterEqual(channel.calls, 2)
|
||||
self.assertEqual(channel.last_error, "boom")
|
||||
|
||||
async def test_manager_status_reports_bridge_and_missing_config(self) -> None:
|
||||
config = OPCConfig()
|
||||
config.channels.slack.enabled = True
|
||||
config.channels.slack.allow_from = ["*"]
|
||||
config.channels.whatsapp.enabled = True
|
||||
manager = ChannelManager(config, MessageBus())
|
||||
slack_status = manager.get_status("slack")
|
||||
whatsapp_status = manager.get_status("whatsapp")
|
||||
self.assertTrue(slack_status["enabled"])
|
||||
self.assertFalse(slack_status["configured"])
|
||||
self.assertIn("bot_token", slack_status["missing_config"])
|
||||
self.assertTrue(whatsapp_status["bridge_required"])
|
||||
self.assertTrue(whatsapp_status["enabled"])
|
||||
self.assertTrue(whatsapp_status["configured"])
|
||||
Reference in New Issue
Block a user