from __future__ import annotations from typing import Any import pytest from yuxi.channel.application.pipeline.builder import build_inbound_pipeline from yuxi.channel.application.service.auth_service import AuthService from yuxi.channel.domain.service.pipeline import Pipeline class _FakeRateLimiter: async def check_and_incr( self, key: str, *, max_attempts: int, window_seconds: int, lockout_seconds: int = 0 ) -> bool: return True async def is_locked(self, key: str) -> tuple[bool, int]: return False, 0 async def reset(self, key: str) -> None: pass class _FakeCache: async def get(self, key: str) -> str | None: return None async def set(self, key: str, value: str, *, ex: int | None = None, nx: bool = False) -> bool: return True async def delete(self, key: str) -> None: pass async def incr(self, key: str) -> int: return 1 async def expire(self, key: str, seconds: int) -> None: pass async def ttl(self, key: str) -> int: return 0 async def eval(self, script: str, keys: list[str], args: list[str | int]) -> tuple: return () class _FakeQueue: async def enqueue(self, payload: dict) -> str: return "msg-id" async def dequeue(self, *, count: int = 1, block: int = 5000, consumer_name: str = "") -> list[dict]: return [] async def ack(self, message_id: str) -> None: pass async def pending_count(self) -> int: return 0 class _FakeKeywordMatcher: def match(self, content: str) -> str | None: return None def update_keywords(self, keywords: set[str]) -> None: pass class _FakeSignatureVerifier: async def verify(self, payload: dict, signature: str, timestamp: str) -> bool: return True class _FakeMetrics: async def record_middleware_duration(self, middleware: str, channel_type: str, duration_s: float) -> None: pass async def record_pipeline_duration(self, channel_type: str, duration_s: float) -> None: pass async def record_pipeline_total(self, channel_type: str) -> None: pass async def record_pipeline_aborted(self, channel_type: str, reason: str) -> None: pass async def record_worker_dispatch_duration(self, channel_type: str, duration_s: float) -> None: pass async def record_worker_dispatch_total(self, channel_type: str, result: str) -> None: pass async def record_worker_step_duration(self, step: str, channel_type: str, duration_s: float) -> None: pass async def set_outbox_pending(self, count: int) -> None: pass async def record_outbox_enqueued(self, channel_type: str) -> None: pass async def set_sse_connections(self, count: int) -> None: pass async def record_auth_attempts(self, result: str) -> None: pass async def record_bot_loop_blocked(self, channel_type: str, context: str) -> None: pass async def record_access_policy_blocked(self, channel_type: str, policy: str) -> None: pass async def record_mention_gate_skipped(self, channel_type: str) -> None: pass async def record_hooks_received(self, match_path: str) -> None: pass async def record_content_filter_blocked(self, channel_type: str) -> None: pass async def set_circuit_breaker_state(self, agent_config_id: int, state: int) -> None: pass async def record_circuit_breaker_rejected(self, agent_config_id: int) -> None: pass @pytest.fixture def auth_service() -> AuthService: return AuthService(rate_limit_port=_FakeRateLimiter(), token="token") @pytest.fixture def base_kwargs(auth_service: AuthService) -> dict: return { "auth_service": auth_service, "cache_port": _FakeCache(), "rate_limit_port": _FakeRateLimiter(), "queue_port": _FakeQueue(), } def test_build_inbound_pipeline_returns_pipeline(base_kwargs: dict) -> None: pipeline = build_inbound_pipeline(**base_kwargs) assert isinstance(pipeline, Pipeline) assert len(pipeline.middlewares) == 7 def test_build_inbound_pipeline_with_bot_id(base_kwargs: dict) -> None: pipeline = build_inbound_pipeline(**base_kwargs, bot_id="bot-123") assert isinstance(pipeline, Pipeline) def test_build_inbound_pipeline_with_custom_matcher(base_kwargs: dict) -> None: pipeline = build_inbound_pipeline(**base_kwargs, keyword_matcher=_FakeKeywordMatcher()) assert isinstance(pipeline, Pipeline) def test_build_inbound_pipeline_with_signature_verifier(base_kwargs: dict) -> None: pipeline = build_inbound_pipeline(**base_kwargs, signature_verifier=_FakeSignatureVerifier()) assert isinstance(pipeline, Pipeline) def test_build_inbound_pipeline_with_metrics(base_kwargs: dict) -> None: pipeline = build_inbound_pipeline(**base_kwargs, metrics=_FakeMetrics()) assert isinstance(pipeline, Pipeline) def test_build_inbound_pipeline_with_channel_config(base_kwargs: dict) -> None: config = { "keyword_blocklist": ["bad"], "allow_from": {"web": ["user-1"]}, "access_policies": {"web": {"dm_policy": "disabled"}}, } pipeline = build_inbound_pipeline(**base_kwargs, channel_config=config) assert isinstance(pipeline, Pipeline)