from datetime import UTC, datetime from app.models.entities import Conversation, ConversationMessage from app.services.conversations import ConversationService def test_conversation_message_data_reads_persisted_risk_result() -> None: message = ConversationMessage( id=10, conversation_id=3, role="assistant", content="已完成风险预估。", structured_data={ "riskResult": { "subjectId": "软管新品", "score": 82, "level": "low", "modelVersion": "baseline-safety-v2", "factors": [], } }, created_at=datetime.now(UTC), ) result = ConversationService._message(message) assert result.role == "assistant" assert result.risk_result is not None assert result.risk_result.score == 82 assert result.risk_result.level.value == "low" def test_conversation_data_includes_all_messages() -> None: conversation = Conversation( id=3, user_id=1, title="软管新品评估", created_at=datetime.now(UTC), updated_at=datetime.now(UTC), messages=[ ConversationMessage( id=1, conversation_id=3, role="user", content="评估软管新品", created_at=datetime.now(UTC), ), ConversationMessage( id=2, conversation_id=3, role="assistant", content="已完成分析", created_at=datetime.now(UTC), ), ], ) result = ConversationService._data(conversation) assert result.message_count == 2 assert [message.role for message in result.messages] == ["user", "assistant"] def test_only_explicit_risk_requests_generate_risk_cards() -> None: assert ConversationService._is_risk_request( "你好", {"intent": "greet", "risk_requested": False}, ) is False assert ConversationService._is_risk_request( "请只回复:AI 连通成功。", {"intent": "general", "risk_requested": False}, ) is False assert ConversationService._is_risk_request( "请评估这个产品的风险", {"intent": "assessment", "risk_requested": True}, ) is True def test_legacy_general_semantics_hide_old_risk_card() -> None: messages = [ ConversationMessage( id=1, conversation_id=1, role="user", content="你好", created_at=datetime.now(UTC), ), ConversationMessage( id=2, conversation_id=1, role="assistant", content="你好,我可以帮你做什么?", structured_data={ "semantic": {"intent": "general"}, "riskResult": { "subjectId": "误判", "score": 61, "level": "moderately_low", "modelVersion": "baseline-safety-v2", "factors": [], }, }, created_at=datetime.now(UTC), ), ] assert ConversationService._risk_result_for_message(messages, 1) is None assert ConversationService._is_risk_request( "我要做一款脱毛膏新品,100g,PE软管包装,加工厂准备使用瑞沣", {"intent": "general", "risk_requested": False}, ) is True def test_product_assessment_semantics_override_nlu_miss() -> None: normalized = ConversationService._normalize_semantics( "我要做一款脱毛膏新品,100g,PE软管包装,加工厂准备使用瑞沣", {"intent": "general", "risk_requested": False, "category": "脱毛膏"}, ) assert normalized["intent"] == "assessment" assert normalized["risk_requested"] is True