import asyncio import pytest from libs.events.base import EventPayload from libs.events.nats_bus import NATSEventBus from libs.schemas.events import DocumentIngestedEventData @pytest.mark.asyncio async def test_nats_bus_class(): """Test NATSEventBus class within pytest.""" import time unique_suffix = int(time.time()) stream_name = f"PYTEST_DEBUG_STREAM_{unique_suffix}" print(f"\nStarting NATSEventBus with stream {stream_name}...") bus = NATSEventBus( servers="nats://localhost:4222", stream_name=stream_name, consumer_group="test-debug-group", ) await bus.start() print("Bus started.") # Clean up (just in case) try: await bus.js.delete_stream(stream_name) except Exception: pass await bus._ensure_stream_exists() # Wait for stream to be ready await asyncio.sleep(2) try: info = await bus.js.stream_info(stream_name) print(f"Stream info: {info.config.subjects}") except Exception as e: print(f"Failed to get stream info: {e}") # Setup subscriber received_event = asyncio.Future() async def handler(topic, event): print(f"Handler received event: {event.event_id}") if not received_event.done(): received_event.set_result(event) await bus.subscribe("doc.ingested", handler) print("Publishing message...") data = DocumentIngestedEventData( doc_id="test-doc-123", filename="test.pdf", mime_type="application/pdf", size_bytes=1024, source="upload", kind="invoice", storage_path="s3://test-bucket/test.pdf", checksum_sha256="a" * 64, ) payload = EventPayload( data=data.model_dump(mode="json"), actor="tester", tenant_id="tenant-1", schema_version="1.0", ) payload.event_id = "evt-debug-1" success = await bus.publish("doc.ingested", payload) print(f"Published: {success}") try: result = await asyncio.wait_for(received_event, timeout=5.0) print(f"Received event: {result.event_id}") assert result.event_id == "evt-debug-1" assert result.data["doc_id"] == "test-doc-123" except TimeoutError: print("Timeout waiting for event") raise await bus.stop() print("Bus stopped.") # Cleanup stream try: nc = await nats.connect("nats://localhost:4222") js = nc.jetstream() await js.delete_stream(stream_name) await nc.close() except Exception: pass