179 lines
5.7 KiB
Python
179 lines
5.7 KiB
Python
"""
|
||
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],请问有什么可以帮您?"
|