test: add unit tests for plugin registry and event bus

This commit is contained in:
agatha 2026-03-14 15:20:11 -04:00
parent f34c805b84
commit a1659531c7

View File

@ -0,0 +1,139 @@
import pytest
from proxy_pool.plugins.protocols import CheckContext, CheckResult, DiscoveredProxy, Event
from proxy_pool.plugins.registry import PluginConflictError, PluginNotFoundError, PluginRegistry, PluginValidationError
class FakeParser:
name = "fake"
def supports(self, url: str) -> bool:
return "fake" in url
async def parse(self, raw, source_url, source_id, default_protocol):
return [DiscoveredProxy(ip="1.2.3.4", port=8080, protocol="http")]
def default_schedule(self):
return None
class FakeChecker:
name = "fake_check"
stage = 1
priority = 0
timeout = 5.0
async def check(self, proxy_ip, proxy_port, proxy_protocol, context):
return CheckResult(passed=True, detail="ok")
def should_skip(self, proxy_protocol):
return False
class FakeNotifier:
name = "fake_notify"
subscribes_to = ["test.*"]
notified_events: list[Event]
def __init__(self):
self.notified_events = []
async def notify(self, event):
self.notified_events.append(event)
async def health_check(self):
return True
class TestParserRegistration:
def test_register_and_retrieve(self):
registry = PluginRegistry()
parser = FakeParser()
registry.register_parser(parser)
assert registry.get_parser("fake") is parser
def test_duplicate_name_raises_conflict(self):
registry = PluginRegistry()
registry.register_parser(FakeParser())
with pytest.raises(PluginConflictError):
registry.register_parser(FakeParser())
def test_get_missing_parser_raises(self):
registry = PluginRegistry()
with pytest.raises(PluginNotFoundError):
registry.get_parser("nonexistent")
def test_get_parser_for_url(self):
registry = PluginRegistry()
parser = FakeParser()
registry.register_parser(parser)
assert registry.get_parser_for_url("http://fake.com/list") is parser
assert registry.get_parser_for_url("http://other.com/list") is None
def test_invalid_plugin_raises_validation_error(self):
registry = PluginRegistry()
with pytest.raises(PluginValidationError):
registry.register_parser("not a plugin")
class TestCheckerRegistration:
def test_checkers_sorted_by_stage_and_priority(self):
registry = PluginRegistry()
class Late(FakeChecker):
name = "late"
stage = 2
priority = 0
class Early(FakeChecker):
name = "early"
stage = 1
priority = 0
class EarlyLow(FakeChecker):
name = "early_low"
stage = 1
priority = 10
registry.register_checker(Late())
registry.register_checker(EarlyLow())
registry.register_checker(Early())
pipeline = registry.get_checker_pipeline()
names = [c.name for c in pipeline]
assert names == ["early", "early_low", "late"]
class TestEventBus:
async def test_emit_notifies_matching_subscribers(self):
registry = PluginRegistry()
notifier = FakeNotifier()
registry.register_notifier(notifier)
event = Event(type="test.something", payload={"key": "value"})
await registry.emit(event)
# Give the fire-and-forget task a moment to run
import asyncio
await asyncio.sleep(0.05)
assert len(notifier.notified_events) == 1
assert notifier.notified_events[0].type == "test.something"
async def test_emit_skips_non_matching(self):
registry = PluginRegistry()
notifier = FakeNotifier()
notifier.subscribes_to = ["other.*"]
registry.register_notifier(notifier)
await registry.emit(Event(type="test.something", payload={}))
import asyncio
await asyncio.sleep(0.05)
assert len(notifier.notified_events) == 0