legco_ai_assistant/backend/app/test/conftest.py

71 lines
2.0 KiB
Python

"""Shared pytest fixtures for backend tests.
All external LLM/ASR calls must be mocked. Use tmp_path for ChromaDB instances.
"""
import pytest
from unittest.mock import AsyncMock, MagicMock
@pytest.fixture
def mock_llm_client(monkeypatch):
"""Mock LLM client to avoid hitting live APIs."""
class _Mock:
async def complete(self, prompt: str, temperature: float = 0.7) -> str: # type: ignore
return "{\"choices\": [{\"message\": {\"content\": \"mock response\"}}]}"
return _Mock()
@pytest.fixture
def mock_asr_client(monkeypatch):
"""Mock ASR client to avoid hitting live APIs."""
class _Mock:
async def transcribe(self, audio_bytes): # type: ignore
return ""
return _Mock()
@pytest.fixture
def chroma_test_dir(tmp_path):
"""Provide a temporary directory for isolated ChromaDB instances."""
return tmp_path / "chroma_test"
@pytest.fixture
def mock_prompt_service():
"""Mock PromptService for tests that don't need real DB."""
class _MockPromptService:
def __init__(self):
self._template = "Test template: {question}"
def get_active_profile_name(self) -> str:
return "A"
def get_prompt_template(self, step: str) -> str:
return self._template
def list_profiles(self) -> list[dict]:
return [
{"name": "A", "is_active": True},
{"name": "B", "is_active": False},
{"name": "C", "is_active": False},
]
def activate_profile(self, name: str) -> None:
pass
def get_profile_prompts(self, name: str) -> dict:
return {"decompose": self._template, "filter": self._template, "generate": self._template}
def update_prompt(self, name: str, step: str, template: str) -> None:
pass
def update_all_prompts(self, name: str, prompts: dict[str, str]) -> None:
pass
def reset_to_defaults(self, name: str, step: str | None = None) -> None:
pass
return _MockPromptService()