chore/ 删除无用文件

This commit is contained in:
Kevin
2026-03-19 14:36:14 +08:00
parent 2f60858c9c
commit c6e07ce5ca
135 changed files with 2111 additions and 4510 deletions

View File

@@ -89,7 +89,9 @@ class _FakeAsyncDB:
async def execute(self, stmt):
stmt_str = str(stmt)
if "MemoirState" in stmt_str or "memoir_state" in stmt_str:
return _ExecuteResult([self.state_result] if self.state_result is not None else [])
return _ExecuteResult(
[self.state_result] if self.state_result is not None else []
)
return _ExecuteResult(self.segments)
@@ -116,7 +118,9 @@ class _FakeManager:
self.active_connections.pop(conversation_id, None)
async def send_message(self, conversation_id, message):
self.sent_messages.append({"conversation_id": conversation_id, "message": message})
self.sent_messages.append(
{"conversation_id": conversation_id, "message": message}
)
def get_or_create_segment_state(self, conversation_id, voice_session_id):
state_key = (conversation_id, voice_session_id)
@@ -149,13 +153,16 @@ def _make_user():
def _db_provider(db):
"""返回可被 patch 到 get_async_db 的异步生成器(旧用法)。"""
async def _provider():
yield db
return _provider
class _FakeSessionCM:
"""模拟 async with AsyncSessionLocal() as db 的上下文管理器。"""
def __init__(self, db):
self._db = db
@@ -168,8 +175,10 @@ class _FakeSessionCM:
def _session_local_factory(fake_db):
"""返回可 patch 到 AsyncSessionLocal 的工厂,使 async with AsyncSessionLocal() as db 得到 fake_db。"""
def _factory():
return _FakeSessionCM(fake_db)
return _factory
@@ -215,7 +224,9 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
)
)
stack.enter_context(
patch.object(ws_router, "AsyncSessionLocal", _session_local_factory(fake_db))
patch.object(
ws_router, "AsyncSessionLocal", _session_local_factory(fake_db)
)
)
stack.enter_context(
patch(
@@ -228,13 +239,22 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
stack.enter_context(
patch("app.features.conversation.ws.pipeline.manager", fake_manager)
)
stack.enter_context(patch.object(ws_router, "background_runner", fake_manager.background_runner))
stack.enter_context(
patch.object(
ws_router, "background_runner", fake_manager.background_runner
)
)
stack.enter_context(_redis_empty_history_patch())
stack.enter_context(
patch("app.features.conversation.ws.router.check_ws_quota", new=AsyncMock(return_value=(True, "")))
patch(
"app.features.conversation.ws.router.check_ws_quota",
new=AsyncMock(return_value=(True, "")),
)
)
stack.enter_context(
patch.object(ws_router, "process_user_message", process_user_message_mock)
patch.object(
ws_router, "process_user_message", process_user_message_mock
)
)
await ws_router.websocket_endpoint(fake_websocket, "conv-1")
@@ -277,7 +297,9 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
)
)
stack.enter_context(
patch.object(ws_router, "AsyncSessionLocal", _session_local_factory(fake_db))
patch.object(
ws_router, "AsyncSessionLocal", _session_local_factory(fake_db)
)
)
stack.enter_context(
patch(
@@ -290,13 +312,22 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
stack.enter_context(
patch("app.features.conversation.ws.pipeline.manager", fake_manager)
)
stack.enter_context(patch.object(ws_router, "background_runner", fake_manager.background_runner))
stack.enter_context(
patch.object(
ws_router, "background_runner", fake_manager.background_runner
)
)
stack.enter_context(_redis_empty_history_patch())
stack.enter_context(
patch("app.features.conversation.ws.router.check_ws_quota", new=AsyncMock(return_value=(True, "")))
patch(
"app.features.conversation.ws.router.check_ws_quota",
new=AsyncMock(return_value=(True, "")),
)
)
stack.enter_context(
patch.object(ws_router, "process_user_message", process_user_message_mock)
patch.object(
ws_router, "process_user_message", process_user_message_mock
)
)
stack.enter_context(
patch(
@@ -364,7 +395,9 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
)
)
stack.enter_context(
patch.object(ws_router, "AsyncSessionLocal", _session_local_factory(fake_db))
patch.object(
ws_router, "AsyncSessionLocal", _session_local_factory(fake_db)
)
)
stack.enter_context(
patch(
@@ -377,10 +410,16 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
stack.enter_context(
patch("app.features.conversation.ws.pipeline.manager", fake_manager)
)
stack.enter_context(patch.object(ws_router, "background_runner", fake_manager.background_runner))
stack.enter_context(
patch.object(
ws_router, "background_runner", fake_manager.background_runner
)
)
stack.enter_context(_redis_empty_history_patch())
stack.enter_context(
patch.object(ws_router, "process_user_message", process_user_message_mock)
patch.object(
ws_router, "process_user_message", process_user_message_mock
)
)
stack.enter_context(
patch(
@@ -406,7 +445,9 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
transcribe_mock.assert_awaited_once_with(b"fake-audio-b64", "m4a")
process_user_message_mock.assert_not_awaited()
self.assertEqual(len([obj for obj in fake_db.added if isinstance(obj, Segment)]), 0)
self.assertEqual(
len([obj for obj in fake_db.added if isinstance(obj, Segment)]), 0
)
transcript_msgs = [
item["message"]
@@ -435,7 +476,9 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
)
)
stack.enter_context(
patch.object(ws_router, "AsyncSessionLocal", _session_local_factory(fake_db))
patch.object(
ws_router, "AsyncSessionLocal", _session_local_factory(fake_db)
)
)
stack.enter_context(
patch(
@@ -448,7 +491,11 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
stack.enter_context(
patch("app.features.conversation.ws.pipeline.manager", fake_manager)
)
stack.enter_context(patch.object(ws_router, "background_runner", fake_manager.background_runner))
stack.enter_context(
patch.object(
ws_router, "background_runner", fake_manager.background_runner
)
)
stack.enter_context(_redis_empty_history_patch())
stack.enter_context(
patch.object(
@@ -491,7 +538,9 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
)
)
stack.enter_context(
patch.object(ws_router, "AsyncSessionLocal", _session_local_factory(fake_db))
patch.object(
ws_router, "AsyncSessionLocal", _session_local_factory(fake_db)
)
)
stack.enter_context(
patch(
@@ -504,7 +553,11 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
stack.enter_context(
patch("app.features.conversation.ws.pipeline.manager", fake_manager)
)
stack.enter_context(patch.object(ws_router, "background_runner", fake_manager.background_runner))
stack.enter_context(
patch.object(
ws_router, "background_runner", fake_manager.background_runner
)
)
stack.enter_context(_redis_empty_history_patch())
stack.enter_context(
patch.object(
@@ -558,7 +611,9 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
)
)
stack.enter_context(
patch.object(ws_router, "AsyncSessionLocal", _session_local_factory(fake_db))
patch.object(
ws_router, "AsyncSessionLocal", _session_local_factory(fake_db)
)
)
stack.enter_context(
patch(
@@ -571,13 +626,22 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
stack.enter_context(
patch("app.features.conversation.ws.pipeline.manager", fake_manager)
)
stack.enter_context(patch.object(ws_router, "background_runner", fake_manager.background_runner))
stack.enter_context(
patch.object(
ws_router, "background_runner", fake_manager.background_runner
)
)
stack.enter_context(_redis_empty_history_patch())
stack.enter_context(
patch("app.features.conversation.ws.router.check_ws_quota", new=AsyncMock(return_value=(True, "")))
patch(
"app.features.conversation.ws.router.check_ws_quota",
new=AsyncMock(return_value=(True, "")),
)
)
stack.enter_context(
patch.object(ws_router, "process_user_message", process_user_message_mock)
patch.object(
ws_router, "process_user_message", process_user_message_mock
)
)
stack.enter_context(
patch(
@@ -608,7 +672,9 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
if item["message"]["type"] == ws_router.MessageType.ERROR
]
self.assertEqual(len(error_msgs), 1)
self.assertEqual(error_msgs[0]["data"]["message"], "语音转写失败,请重试或使用文字输入")
self.assertEqual(
error_msgs[0]["data"]["message"], "语音转写失败,请重试或使用文字输入"
)
async def test_audio_segment_out_of_order_is_aggregated_by_segment_index(self):
user = _make_user()
@@ -642,9 +708,7 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
)
process_user_message_mock = AsyncMock()
transcribe_mock = AsyncMock(
side_effect=["这是第 1 段", "这是第 0 段"]
)
transcribe_mock = AsyncMock(side_effect=["这是第 1 段", "这是第 0 段"])
with ExitStack() as stack:
stack.enter_context(
@@ -655,7 +719,9 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
)
)
stack.enter_context(
patch.object(ws_router, "AsyncSessionLocal", _session_local_factory(fake_db))
patch.object(
ws_router, "AsyncSessionLocal", _session_local_factory(fake_db)
)
)
stack.enter_context(
patch(
@@ -668,13 +734,22 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
stack.enter_context(
patch("app.features.conversation.ws.pipeline.manager", fake_manager)
)
stack.enter_context(patch.object(ws_router, "background_runner", fake_manager.background_runner))
stack.enter_context(
patch.object(
ws_router, "background_runner", fake_manager.background_runner
)
)
stack.enter_context(_redis_empty_history_patch())
stack.enter_context(
patch("app.features.conversation.ws.router.check_ws_quota", new=AsyncMock(return_value=(True, "")))
patch(
"app.features.conversation.ws.router.check_ws_quota",
new=AsyncMock(return_value=(True, "")),
)
)
stack.enter_context(
patch.object(ws_router, "process_user_message", process_user_message_mock)
patch.object(
ws_router, "process_user_message", process_user_message_mock
)
)
stack.enter_context(
patch(
@@ -701,10 +776,13 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
self.assertEqual(transcribe_mock.await_count, 2)
ordered_messages = [
call.kwargs["user_message"] for call in process_user_message_mock.await_args_list
call.kwargs["user_message"]
for call in process_user_message_mock.await_args_list
]
self.assertEqual(ordered_messages, ["这是第 0 段", "这是第 1 段"])
self.assertEqual(len([obj for obj in fake_db.added if isinstance(obj, Segment)]), 2)
self.assertEqual(
len([obj for obj in fake_db.added if isinstance(obj, Segment)]), 2
)
transcript_msgs = [
item["message"]
for item in fake_manager.sent_messages
@@ -756,7 +834,9 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
)
)
stack.enter_context(
patch.object(ws_router, "AsyncSessionLocal", _session_local_factory(fake_db))
patch.object(
ws_router, "AsyncSessionLocal", _session_local_factory(fake_db)
)
)
stack.enter_context(
patch(
@@ -769,13 +849,22 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
stack.enter_context(
patch("app.features.conversation.ws.pipeline.manager", fake_manager)
)
stack.enter_context(patch.object(ws_router, "background_runner", fake_manager.background_runner))
stack.enter_context(
patch.object(
ws_router, "background_runner", fake_manager.background_runner
)
)
stack.enter_context(_redis_empty_history_patch())
stack.enter_context(
patch("app.features.conversation.ws.router.check_ws_quota", new=AsyncMock(return_value=(True, "")))
patch(
"app.features.conversation.ws.router.check_ws_quota",
new=AsyncMock(return_value=(True, "")),
)
)
stack.enter_context(
patch.object(ws_router, "process_user_message", process_user_message_mock)
patch.object(
ws_router, "process_user_message", process_user_message_mock
)
)
stack.enter_context(
patch(
@@ -802,9 +891,13 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
self.assertEqual(transcribe_mock.await_count, 1)
process_user_message_mock.assert_awaited_once()
self.assertEqual(len([obj for obj in fake_db.added if isinstance(obj, Segment)]), 1)
self.assertEqual(
len([obj for obj in fake_db.added if isinstance(obj, Segment)]), 1
)
async def test_audio_segment_same_index_is_allowed_for_different_voice_sessions(self):
async def test_audio_segment_same_index_is_allowed_for_different_voice_sessions(
self,
):
user = _make_user()
conversation = Conversation(id="conv-1", user_id=user.id, status="active")
fake_db = _FakeAsyncDB(user=user, conversation=conversation)
@@ -838,9 +931,7 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
)
process_user_message_mock = AsyncMock()
transcribe_mock = AsyncMock(
side_effect=["第一轮第 0 段", "第二轮第 0 段"]
)
transcribe_mock = AsyncMock(side_effect=["第一轮第 0 段", "第二轮第 0 段"])
with ExitStack() as stack:
stack.enter_context(
@@ -851,7 +942,9 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
)
)
stack.enter_context(
patch.object(ws_router, "AsyncSessionLocal", _session_local_factory(fake_db))
patch.object(
ws_router, "AsyncSessionLocal", _session_local_factory(fake_db)
)
)
stack.enter_context(
patch(
@@ -864,13 +957,22 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
stack.enter_context(
patch("app.features.conversation.ws.pipeline.manager", fake_manager)
)
stack.enter_context(patch.object(ws_router, "background_runner", fake_manager.background_runner))
stack.enter_context(
patch.object(
ws_router, "background_runner", fake_manager.background_runner
)
)
stack.enter_context(_redis_empty_history_patch())
stack.enter_context(
patch("app.features.conversation.ws.router.check_ws_quota", new=AsyncMock(return_value=(True, "")))
patch(
"app.features.conversation.ws.router.check_ws_quota",
new=AsyncMock(return_value=(True, "")),
)
)
stack.enter_context(
patch.object(ws_router, "process_user_message", process_user_message_mock)
patch.object(
ws_router, "process_user_message", process_user_message_mock
)
)
stack.enter_context(
patch(
@@ -896,11 +998,14 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
await asyncio.sleep(0.05)
ordered_messages = [
call.kwargs["user_message"] for call in process_user_message_mock.await_args_list
call.kwargs["user_message"]
for call in process_user_message_mock.await_args_list
]
self.assertEqual(ordered_messages, ["第一轮第 0 段", "第二轮第 0 段"])
self.assertEqual(transcribe_mock.await_count, 2)
self.assertEqual(len([obj for obj in fake_db.added if isinstance(obj, Segment)]), 2)
self.assertEqual(
len([obj for obj in fake_db.added if isinstance(obj, Segment)]), 2
)
async def test_audio_segment_sends_transition_feedback_while_processing(self):
user = _make_user()
@@ -938,7 +1043,9 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
)
)
stack.enter_context(
patch.object(ws_router, "AsyncSessionLocal", _session_local_factory(fake_db))
patch.object(
ws_router, "AsyncSessionLocal", _session_local_factory(fake_db)
)
)
stack.enter_context(
patch(
@@ -951,13 +1058,22 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
stack.enter_context(
patch("app.features.conversation.ws.pipeline.manager", fake_manager)
)
stack.enter_context(patch.object(ws_router, "background_runner", fake_manager.background_runner))
stack.enter_context(
patch.object(
ws_router, "background_runner", fake_manager.background_runner
)
)
stack.enter_context(_redis_empty_history_patch())
stack.enter_context(
patch("app.features.conversation.ws.router.check_ws_quota", new=AsyncMock(return_value=(True, "")))
patch(
"app.features.conversation.ws.router.check_ws_quota",
new=AsyncMock(return_value=(True, "")),
)
)
stack.enter_context(
patch.object(ws_router, "process_user_message", process_user_message_mock)
patch.object(
ws_router, "process_user_message", process_user_message_mock
)
)
stack.enter_context(
patch(
@@ -999,7 +1115,10 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
fake_manager = _FakeManager()
fake_websocket = _FakeWebSocket(
messages=[
{"type": "recording_started", "data": {"voice_session_id": "session-1"}},
{
"type": "recording_started",
"data": {"voice_session_id": "session-1"},
},
WebSocketDisconnect(),
]
)
@@ -1013,7 +1132,9 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
)
)
stack.enter_context(
patch.object(ws_router, "AsyncSessionLocal", _session_local_factory(fake_db))
patch.object(
ws_router, "AsyncSessionLocal", _session_local_factory(fake_db)
)
)
stack.enter_context(
patch(
@@ -1025,10 +1146,17 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
stack.enter_context(
patch("app.features.conversation.ws.pipeline.manager", fake_manager)
)
stack.enter_context(patch.object(ws_router, "background_runner", fake_manager.background_runner))
stack.enter_context(
patch.object(
ws_router, "background_runner", fake_manager.background_runner
)
)
stack.enter_context(_redis_empty_history_patch())
stack.enter_context(
patch("app.features.conversation.ws.pipeline.LISTENING_FEEDBACK_DELAY_SEC", 0.05)
patch(
"app.features.conversation.ws.pipeline.LISTENING_FEEDBACK_DELAY_SEC",
0.05,
)
)
await ws_router.websocket_endpoint(fake_websocket, "conv-1")
@@ -1077,7 +1205,9 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
)
)
stack.enter_context(
patch.object(ws_router, "AsyncSessionLocal", _session_local_factory(fake_db))
patch.object(
ws_router, "AsyncSessionLocal", _session_local_factory(fake_db)
)
)
stack.enter_context(
patch(
@@ -1090,13 +1220,22 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
stack.enter_context(
patch("app.features.conversation.ws.pipeline.manager", fake_manager)
)
stack.enter_context(patch.object(ws_router, "background_runner", fake_manager.background_runner))
stack.enter_context(
patch.object(
ws_router, "background_runner", fake_manager.background_runner
)
)
stack.enter_context(_redis_empty_history_patch())
stack.enter_context(
patch("app.features.conversation.ws.router.check_ws_quota", new=AsyncMock(return_value=(True, "")))
patch(
"app.features.conversation.ws.router.check_ws_quota",
new=AsyncMock(return_value=(True, "")),
)
)
stack.enter_context(
patch.object(ws_router, "process_user_message", process_user_message_mock)
patch.object(
ws_router, "process_user_message", process_user_message_mock
)
)
stack.enter_context(
patch(
@@ -1130,7 +1269,9 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
]
self.assertEqual(len(transition_msgs), 0)
async def test_audio_segment_continues_after_reconnect_with_existing_previous_segment(self):
async def test_audio_segment_continues_after_reconnect_with_existing_previous_segment(
self,
):
user = _make_user()
conversation = Conversation(id="conv-1", user_id=user.id, status="active")
existing_segment = Segment(
@@ -1175,7 +1316,9 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
)
)
stack.enter_context(
patch.object(ws_router, "AsyncSessionLocal", _session_local_factory(fake_db))
patch.object(
ws_router, "AsyncSessionLocal", _session_local_factory(fake_db)
)
)
stack.enter_context(
patch(
@@ -1188,13 +1331,22 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
stack.enter_context(
patch("app.features.conversation.ws.pipeline.manager", fake_manager)
)
stack.enter_context(patch.object(ws_router, "background_runner", fake_manager.background_runner))
stack.enter_context(
patch.object(
ws_router, "background_runner", fake_manager.background_runner
)
)
stack.enter_context(_redis_empty_history_patch())
stack.enter_context(
patch("app.features.conversation.ws.router.check_ws_quota", new=AsyncMock(return_value=(True, "")))
patch(
"app.features.conversation.ws.router.check_ws_quota",
new=AsyncMock(return_value=(True, "")),
)
)
stack.enter_context(
patch.object(ws_router, "process_user_message", process_user_message_mock)
patch.object(
ws_router, "process_user_message", process_user_message_mock
)
)
stack.enter_context(
patch(
@@ -1279,7 +1431,9 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
)
)
stack.enter_context(
patch.object(ws_router, "AsyncSessionLocal", _session_local_factory(fake_db))
patch.object(
ws_router, "AsyncSessionLocal", _session_local_factory(fake_db)
)
)
stack.enter_context(
patch(
@@ -1292,13 +1446,22 @@ class WebSocketBaselineTest(unittest.IsolatedAsyncioTestCase):
stack.enter_context(
patch("app.features.conversation.ws.pipeline.manager", fake_manager)
)
stack.enter_context(patch.object(ws_router, "background_runner", fake_manager.background_runner))
stack.enter_context(
patch.object(
ws_router, "background_runner", fake_manager.background_runner
)
)
stack.enter_context(_redis_empty_history_patch())
stack.enter_context(
patch("app.features.conversation.ws.router.check_ws_quota", new=AsyncMock(return_value=(True, "")))
patch(
"app.features.conversation.ws.router.check_ws_quota",
new=AsyncMock(return_value=(True, "")),
)
)
stack.enter_context(
patch.object(ws_router, "process_user_message", process_user_message_mock)
patch.object(
ws_router, "process_user_message", process_user_message_mock
)
)
stack.enter_context(
patch(