""" Unit tests for TemplateEngine. [AC-IDS-06, AC-IDS-11] Test template variable filling. """ import pytest from app.services.flow.template_engine import TemplateEngine class MockLLMClient: """Mock LLM client for testing.""" def __init__(self, response: str = "先生"): self._response = response async def generate_text(self, prompt: str) -> str: return self._response async def generate(self, messages: list) -> "MockResponse": return MockResponse(self._response) class MockResponse: """Mock LLM response.""" def __init__(self, content: str): self.content = content class TestTemplateEngine: """[AC-IDS-06, AC-IDS-11] Test cases for TemplateEngine.""" @pytest.mark.asyncio async def test_fill_template_no_variables(self): """Test template without variables returns as-is.""" engine = TemplateEngine(llm_client=None) result = await engine.fill_template( template="您好,请问有什么可以帮您?", context=None, history=None, ) assert result == "您好,请问有什么可以帮您?" @pytest.mark.asyncio async def test_fill_template_from_context(self): """Test filling variables from context.""" engine = TemplateEngine(llm_client=None) result = await engine.fill_template( template="您好{user_name},请问有什么可以帮您?", context={"user_name": "张先生"}, history=None, ) assert result == "您好张先生,请问有什么可以帮您?" @pytest.mark.asyncio async def test_fill_template_from_inputs(self): """Test filling variables from context inputs.""" engine = TemplateEngine(llm_client=None) result = await engine.fill_template( template="您好,您咨询的是{product}相关的问题吗?", context={ "inputs": [ {"variable": "product", "input": "手机"}, ] }, history=None, ) assert result == "您好,您咨询的是手机相关的问题吗?" @pytest.mark.asyncio async def test_fill_template_with_llm(self): """Test filling variables using LLM generation.""" llm_client = MockLLMClient(response="先生") engine = TemplateEngine(llm_client=llm_client) result = await engine.fill_template( template="您好{greeting_style},请问您{inquiry_style}?", context=None, history=[{"role": "user", "content": "你好"}], ) assert "先生" in result @pytest.mark.asyncio async def test_fill_template_multiple_variables(self): """Test filling multiple variables.""" engine = TemplateEngine(llm_client=None) result = await engine.fill_template( template="您好{name},您订购的{product}已发货,预计{date}送达。", context={ "name": "李女士", "product": "iPhone 15", "date": "明天", }, history=None, ) assert result == "您好李女士,您订购的iPhone 15已发货,预计明天送达。" @pytest.mark.asyncio async def test_fill_template_missing_variable(self): """Test handling missing variables with placeholder.""" engine = TemplateEngine(llm_client=None) result = await engine.fill_template( template="您好{unknown_var},请问有什么可以帮您?", context=None, history=None, ) assert result == "您好[unknown_var],请问有什么可以帮您?" def test_extract_variables(self): """Test extracting variable names from template.""" engine = TemplateEngine(llm_client=None) variables = engine.extract_variables( "您好{name},您订购的{product}预计{date}送达。" ) assert variables == ["name", "product", "date"] def test_extract_variables_empty(self): """Test extracting from template without variables.""" engine = TemplateEngine(llm_client=None) variables = engine.extract_variables("您好,请问有什么可以帮您?") assert variables == [] def test_extract_variables_adjacent(self): """Test extracting adjacent variables.""" engine = TemplateEngine(llm_client=None) variables = engine.extract_variables("{a}{b}{c}") assert variables == ["a", "b", "c"] @pytest.mark.asyncio async def test_fill_template_with_history_context(self): """Test that history is used for LLM prompt.""" llm_client = MockLLMClient(response="贵姓") engine = TemplateEngine(llm_client=llm_client) result = await engine.fill_template( template="您好,请问您{inquiry_style}?", context=None, history=[ {"role": "user", "content": "我想咨询一下"}, {"role": "assistant", "content": "好的,请问您想咨询什么?"}, ], ) assert "贵姓" in result @pytest.mark.asyncio async def test_fill_template_exception_handling(self): """Test that exceptions are handled gracefully.""" class FailingLLMClient: async def generate_text(self, prompt: str) -> str: raise RuntimeError("LLM service unavailable") engine = TemplateEngine(llm_client=FailingLLMClient()) result = await engine.fill_template( template="您好{greeting},请问有什么可以帮您?", context=None, history=None, ) assert result == "您好[greeting],请问有什么可以帮您?"