feat: auto committed
This commit is contained in:
65
services/ai/tests/test_action_state.py
Normal file
65
services/ai/tests/test_action_state.py
Normal file
@@ -0,0 +1,65 @@
|
||||
"""ActionState 统一响应信封测试."""
|
||||
|
||||
from src.ai.models.action_state import ActionState, ErrorDetail
|
||||
from src.ai.models.chat import ChatData, ChatResponse, Usage
|
||||
|
||||
|
||||
class TestActionState:
|
||||
"""ActionState 信封测试."""
|
||||
|
||||
def test_ok_success(self) -> None:
|
||||
"""ok() 返回成功响应."""
|
||||
data = ChatData(content="hello", model="gpt-4o", usage=Usage())
|
||||
resp = ActionState.ok(data)
|
||||
assert resp.success is True
|
||||
assert resp.data is not None
|
||||
assert resp.data.content == "hello"
|
||||
assert resp.error is None
|
||||
|
||||
def test_error_response(self) -> None:
|
||||
"""error_response() 返回错误响应."""
|
||||
resp = ActionState.error_response(
|
||||
code="AI_LLM_UNAVAILABLE",
|
||||
message="all providers failed",
|
||||
details={"tried": ["openai"]},
|
||||
trace_id="req-123",
|
||||
)
|
||||
assert resp.success is False
|
||||
assert resp.data is None
|
||||
assert resp.error is not None
|
||||
assert resp.error.code == "AI_LLM_UNAVAILABLE"
|
||||
assert resp.error.message == "all providers failed"
|
||||
assert resp.error.details == {"tried": ["openai"]}
|
||||
assert resp.error.trace_id == "req-123"
|
||||
|
||||
def test_degraded_sets_flags(self) -> None:
|
||||
"""degraded() 在 data 上设置 degraded + degraded_reason."""
|
||||
data = ChatData(content="fallback", model="gpt-4o", usage=Usage())
|
||||
resp = ActionState.degraded(data, "llm unavailable")
|
||||
assert resp.success is True
|
||||
assert resp.error is None
|
||||
assert resp.data is not None
|
||||
assert resp.data.degraded is True
|
||||
assert resp.data.degraded_reason == "llm unavailable"
|
||||
|
||||
def test_error_detail_alias(self) -> None:
|
||||
"""ErrorDetail 支持 traceId alias."""
|
||||
err = ErrorDetail(code="AI_INTERNAL_ERROR", message="boom", trace_id="t-1")
|
||||
assert err.trace_id == "t-1"
|
||||
# 序列化使用 alias
|
||||
dumped = err.model_dump(by_alias=True)
|
||||
assert dumped["traceId"] == "t-1"
|
||||
|
||||
def test_chat_response_inherits_action_state(self) -> None:
|
||||
"""ChatResponse 继承 ActionState[ChatData]."""
|
||||
data = ChatData(content="hi", model="m", usage=Usage())
|
||||
resp = ChatResponse.ok(data)
|
||||
assert resp.success is True
|
||||
assert resp.data.content == "hi"
|
||||
|
||||
def test_error_response_without_optional_fields(self) -> None:
|
||||
"""error_response() 可选字段缺省."""
|
||||
resp = ActionState.error_response("AI_INTERNAL_ERROR", "fail")
|
||||
assert resp.error is not None
|
||||
assert resp.error.details is None
|
||||
assert resp.error.trace_id is None
|
||||
Reference in New Issue
Block a user