111 lines
3.5 KiB
Python
111 lines
3.5 KiB
Python
import pytest
|
|
from unittest.mock import patch, AsyncMock, MagicMock, PropertyMock
|
|
import logging
|
|
import uuid
|
|
|
|
from app.api.lifecycle import project_stats
|
|
|
|
|
|
class TestLifecycleExceptionHandling:
|
|
"""测试 lifecycle.py 中的异常处理行为"""
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_project_stats_handles_content_query_failure(self, caplog):
|
|
"""测试 project_stats 当 Content 查询失败时的处理"""
|
|
from app.models.user import User
|
|
|
|
org_id = uuid.uuid4()
|
|
user_id = uuid.uuid4()
|
|
|
|
user = User(
|
|
id=user_id,
|
|
email="test@example.com",
|
|
password_hash="hash",
|
|
name="Test User",
|
|
plan="free",
|
|
organization_id=org_id,
|
|
)
|
|
|
|
execute_results = [
|
|
MagicMock(one=MagicMock(total=0, active=0)),
|
|
MagicMock(),
|
|
MagicMock(),
|
|
MagicMock(),
|
|
MagicMock(),
|
|
]
|
|
execute_results[1].all.return_value = []
|
|
execute_results[2].scalar.return_value = 0
|
|
execute_results[3].all.return_value = []
|
|
execute_results[4].all.return_value = []
|
|
execute_count = [0]
|
|
|
|
def execute_side_effect(*args, **kwargs):
|
|
idx = execute_count[0]
|
|
execute_count[0] += 1
|
|
if idx == 2:
|
|
raise RuntimeError("Content table not available")
|
|
return execute_results[idx]
|
|
|
|
mock_session = AsyncMock()
|
|
mock_session.execute.side_effect = execute_side_effect
|
|
|
|
with caplog.at_level(logging.WARNING):
|
|
result = await project_stats(
|
|
db=mock_session,
|
|
current_user=user
|
|
)
|
|
|
|
assert result.contents_produced == 0
|
|
assert any("Failed to count contents" in record.message for record in caplog.records)
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_project_stats_handles_citation_query_failure(self, caplog):
|
|
"""测试 project_stats 当 CitationRecord 查询失败时的处理"""
|
|
from app.models.user import User
|
|
|
|
org_id = uuid.uuid4()
|
|
user_id = uuid.uuid4()
|
|
|
|
user = User(
|
|
id=user_id,
|
|
email="test@example.com",
|
|
password_hash="hash",
|
|
name="Test User",
|
|
plan="free",
|
|
organization_id=org_id,
|
|
)
|
|
|
|
execute_results = [
|
|
MagicMock(one=MagicMock(total=0, active=0)),
|
|
MagicMock(),
|
|
MagicMock(),
|
|
MagicMock(),
|
|
MagicMock(),
|
|
MagicMock(),
|
|
]
|
|
execute_results[1].all.return_value = []
|
|
execute_results[2].scalar.return_value = 0
|
|
execute_results[3].all.return_value = []
|
|
execute_results[4].one.return_value = MagicMock(total_citations=0, cited_count=0)
|
|
execute_results[5].all.return_value = []
|
|
execute_count = [0]
|
|
|
|
def execute_side_effect(*args, **kwargs):
|
|
idx = execute_count[0]
|
|
execute_count[0] += 1
|
|
if idx == 4:
|
|
raise RuntimeError("CitationRecord table not available")
|
|
return execute_results[idx]
|
|
|
|
mock_session = AsyncMock()
|
|
mock_session.execute.side_effect = execute_side_effect
|
|
|
|
with caplog.at_level(logging.WARNING):
|
|
result = await project_stats(
|
|
db=mock_session,
|
|
current_user=user
|
|
)
|
|
|
|
assert result.avg_ai_citation_rate is None
|
|
assert any("Failed to calculate AI citation rate" in record.message for record in caplog.records)
|