Files
life-echo/api/tests/test_conversation_messages_history.py
Kevin 8af37e5e8e 修复:CI 部署环境与 ref 错配、迁移碎片化、图片意图 source_span、章节物化脏版式、会话历史与本地语音不一致
新增:TTS 上传 COS 与分片、章节 reading_segments 物化与快照、markdown 清洗、会话消息 repository、语音 store 重构与相关测试
2026-03-20 16:43:02 +08:00

147 lines
5.1 KiB
Python

import unittest
from datetime import datetime, timezone
from app.features.conversation.models import Conversation
from app.features.conversation.service import (
_build_messages_from_history,
_latest_message_time_ms,
_message_timestamp_ms,
)
class ConversationMessagesHistoryTest(unittest.TestCase):
def test_build_messages_collapses_audio_segments_from_same_voice_session(self):
history = [
{
"role": "human",
"content": "第一段",
"messageType": "audio",
"voiceSessionId": "voice-1",
"timestamp": "2026-03-14T12:00:01+00:00",
},
{
"role": "ai",
"content": "继续说",
"messageType": "text",
"timestamp": "2026-03-14T12:00:02+00:00",
},
{
"role": "human",
"content": "第二段",
"messageType": "audio",
"voiceSessionId": "voice-1",
"timestamp": "2026-03-14T12:00:03+00:00",
},
{
"role": "ai",
"content": "我记住了",
"messageType": "text",
"timestamp": "2026-03-14T12:00:04+00:00",
},
]
messages = _build_messages_from_history(
conversation_id="conv-1",
history=history,
fallback_timestamp=datetime(2026, 3, 14, 12, 0, 0, tzinfo=timezone.utc),
)
self.assertEqual(
[
(msg["senderType"], msg["messageType"], msg["content"])
for msg in messages
],
[
("user", "audio", "第一段"),
("assistant", "text", "继续说"),
("assistant", "text", "我记住了"),
],
)
self.assertEqual(messages[0]["timestamp"], 1773489601000)
self.assertEqual(messages[0]["voiceSessionId"], "voice-1")
self.assertEqual(messages[1]["timestamp"], 1773489602000)
self.assertEqual(messages[2]["timestamp"], 1773489604000)
def test_build_messages_keeps_distinct_voice_sessions_separate(self):
history = [
{
"role": "human",
"content": "第一次录音",
"messageType": "audio",
"voiceSessionId": "voice-1",
"timestamp": "2026-03-14T12:00:01+00:00",
},
{
"role": "human",
"content": "第二次录音",
"messageType": "audio",
"voiceSessionId": "voice-2",
"timestamp": "2026-03-14T12:00:02+00:00",
},
]
messages = _build_messages_from_history(
conversation_id="conv-1",
history=history,
fallback_timestamp=datetime(2026, 3, 14, 12, 0, 0, tzinfo=timezone.utc),
)
self.assertEqual(len(messages), 2)
self.assertEqual(messages[0]["messageType"], "audio")
self.assertEqual(messages[0]["content"], "第一次录音")
self.assertEqual(messages[0]["voiceSessionId"], "voice-1")
self.assertEqual(messages[1]["messageType"], "audio")
self.assertEqual(messages[1]["content"], "第二次录音")
self.assertEqual(messages[1]["voiceSessionId"], "voice-2")
def test_build_messages_includes_duration_seconds_from_history(self):
history = [
{
"role": "human",
"content": "你好",
"messageType": "audio",
"voiceSessionId": "vs-a",
"durationSeconds": 8,
"timestamp": "2026-03-14T12:00:01+00:00",
},
]
messages = _build_messages_from_history(
conversation_id="conv-1",
history=history,
fallback_timestamp=datetime(2026, 3, 14, 12, 0, 0, tzinfo=timezone.utc),
)
self.assertEqual(len(messages), 1)
self.assertEqual(messages[0]["durationSeconds"], 8)
def test_latest_message_time_prefers_conversation_last_message_at(self):
conversation = Conversation(
id="conv-1",
user_id="user-1",
started_at=datetime(2026, 3, 9, 12, 0, 0, tzinfo=timezone.utc),
last_message_at=datetime(2026, 3, 14, 12, 0, 5, tzinfo=timezone.utc),
)
history = [
{
"role": "human",
"content": "旧消息",
"messageType": "text",
"timestamp": "2026-03-10T12:00:00+00:00",
}
]
latest_message_time = _latest_message_time_ms(conversation, history)
self.assertEqual(latest_message_time, 1773489605000)
def test_message_timestamp_falls_back_to_started_at_for_legacy_history(self):
conversation = Conversation(
id="conv-1",
user_id="user-1",
started_at=datetime(2026, 3, 14, 12, 0, 0, tzinfo=timezone.utc),
)
timestamp = _message_timestamp_ms({}, conversation.started_at)
self.assertEqual(timestamp, 1773489600000)