from __future__ import annotations from unittest.mock import AsyncMock, MagicMock import pytest from yuxi.channel.domain.service.pipeline import Pipeline from yuxi.channel.domain.service.message_context import MessageContext class TestPipeline: @pytest.fixture def sample_message(self): from yuxi.channel.domain.model.message.unified_message import UnifiedMessage from yuxi.channel.domain.model.message.peer import Peer return UnifiedMessage( message_id="msg123", channel_type="web", sender=Peer(id="user1", name="User"), content="Hello", ) @pytest.mark.asyncio async def test_empty_pipeline(self, sample_message): pipeline = Pipeline() ctx = MessageContext(message=sample_message) result = await pipeline.execute(ctx) assert result.is_aborted is False @pytest.mark.asyncio async def test_single_middleware(self, sample_message): middleware = AsyncMock() middleware.process.return_value = MessageContext(message=sample_message) pipeline = Pipeline(middlewares=[middleware]) ctx = MessageContext(message=sample_message) result = await pipeline.execute(ctx) middleware.process.assert_awaited_once() @pytest.mark.asyncio async def test_middleware_chain(self, sample_message): middleware1 = AsyncMock() middleware1.process.return_value = MessageContext(message=sample_message) middleware2 = AsyncMock() middleware2.process.return_value = MessageContext(message=sample_message) pipeline = Pipeline(middlewares=[middleware1, middleware2]) ctx = MessageContext(message=sample_message) result = await pipeline.execute(ctx) middleware1.process.assert_awaited_once() middleware2.process.assert_awaited_once() @pytest.mark.asyncio async def test_abort_stops_chain(self, sample_message): middleware1 = AsyncMock() aborted_ctx = MessageContext(message=sample_message) aborted_ctx.abort("TEST", "test abort") middleware1.process.return_value = aborted_ctx middleware2 = AsyncMock() pipeline = Pipeline(middlewares=[middleware1, middleware2]) ctx = MessageContext(message=sample_message) result = await pipeline.execute(ctx) middleware1.process.assert_awaited_once() middleware2.process.assert_not_awaited() @pytest.mark.asyncio async def test_skip_stops_chain(self, sample_message): middleware1 = AsyncMock() skipped_ctx = MessageContext(message=sample_message) skipped_ctx.skip("test skip") middleware1.process.return_value = skipped_ctx middleware2 = AsyncMock() pipeline = Pipeline(middlewares=[middleware1, middleware2]) ctx = MessageContext(message=sample_message) result = await pipeline.execute(ctx) middleware1.process.assert_awaited_once() middleware2.process.assert_not_awaited() def test_add_middleware(self, sample_message): pipeline = Pipeline() middleware = MagicMock() pipeline.add(middleware) assert len(pipeline.middlewares) == 1 def test_remove_middleware(self, sample_message): middleware = MagicMock() pipeline = Pipeline(middlewares=[middleware]) pipeline.remove(middleware) assert len(pipeline.middlewares) == 0