from __future__ import annotations from unittest.mock import AsyncMock, MagicMock import pytest from yuxi.channel.infrastructure.messaging.redis_pubsub_publisher import RedisPubSubPublisher from yuxi.channel.infrastructure.messaging.redis_pubsub_subscriber import RedisPubSubSubscriber class TestRedisPubSubPublisher: @pytest.fixture def mock_redis(self): return AsyncMock() @pytest.fixture def publisher(self, mock_redis): return RedisPubSubPublisher(redis=mock_redis) @pytest.mark.asyncio async def test_publish(self, publisher, mock_redis): await publisher.publish("test_event", {"data": "test"}) mock_redis.publish.assert_awaited_once() @pytest.mark.asyncio async def test_publish_with_channel(self, publisher, mock_redis): await publisher.publish("test_event", {"data": "test"}, channel="custom_channel") mock_redis.publish.assert_awaited_once_with("custom_channel", '{"event_type": "test_event", "payload": {"data": "test"}}') class TestRedisPubSubSubscriber: @pytest.fixture def mock_redis(self): redis = AsyncMock() pubsub = AsyncMock() redis.pubsub.return_value = pubsub return redis @pytest.fixture def subscriber(self, mock_redis): return RedisPubSubSubscriber(redis=mock_redis) @pytest.mark.asyncio async def test_subscribe(self, subscriber, mock_redis): mock_redis.pubsub.return_value = AsyncMock() await subscriber.subscribe("test_channel") mock_redis.pubsub.return_value.subscribe.assert_awaited_once_with("test_channel") @pytest.mark.asyncio async def test_unsubscribe(self, subscriber, mock_redis): pubsub = AsyncMock() subscriber._pubsub = pubsub await subscriber.unsubscribe("test_channel") pubsub.unsubscribe.assert_awaited_once_with("test_channel") @pytest.mark.asyncio async def test_listen(self, subscriber, mock_redis): pubsub = AsyncMock() pubsub.listen.return_value = [ {"type": "message", "data": b'{"event_type": "test", "payload": {"data": "test"}}'} ] subscriber._pubsub = pubsub messages = [] async for msg in subscriber.listen(): messages.append(msg) break assert len(messages) == 1 assert messages[0]["event_type"] == "test" @pytest.mark.asyncio async def test_listen_ignore_non_message(self, subscriber, mock_redis): pubsub = AsyncMock() pubsub.listen.return_value = [ {"type": "subscribe", "data": 1} ] subscriber._pubsub = pubsub messages = [] async for msg in subscriber.listen(): messages.append(msg) break assert len(messages) == 0 @pytest.mark.asyncio async def test_stop(self, subscriber, mock_redis): pubsub = AsyncMock() subscriber._pubsub = pubsub await subscriber.stop() pubsub.close.assert_awaited_once() assert subscriber._running is False