Files
life-echo/api/tests/test_conversation_list_fallback_title.py

121 lines
3.7 KiB
Python
Raw Permalink Normal View History

"""ConversationService.list_for_user 兜底标题随用户语言切换zh→岁月知己 / en→Life Echo"""
from __future__ import annotations
import uuid
from datetime import datetime, timezone
from types import SimpleNamespace
from unittest.mock import AsyncMock, MagicMock
import pytest
# 预加载所有 feature 模型,触发 SQLAlchemy 关系解析
from app.features.asset import models as _asset_models # noqa: F401
from app.features.auth import models as _auth_models # noqa: F401
from app.features.conversation import models as _conv_models # noqa: F401
from app.features.memoir import models as _memoir_models # noqa: F401
from app.features.memory import models as _memory_models # noqa: F401
from app.features.payment import models as _payment_models # noqa: F401
from app.features.story import models as _story_models # noqa: F401
from app.features.user import models as _user_models # noqa: F401
from app.features.conversation import service as conv_service_mod
from app.features.conversation.service import ConversationService
from app.features.user.models import User
def _make_conv(user_id: str, summary: str | None) -> SimpleNamespace:
now = datetime.now(timezone.utc)
return SimpleNamespace(
id=str(uuid.uuid4()),
user_id=user_id,
summary=summary,
started_at=now,
last_message_at=now,
)
def _build_user(language: str) -> User:
return User(
id=str(uuid.uuid4()),
phone=f"138{uuid.uuid4().int % 100_000_000:08d}",
password_hash="x",
nickname="t",
subscription_type="free",
created_at=datetime.now(timezone.utc),
language_preference=language,
)
@pytest.mark.asyncio
async def test_list_for_user_zh_fallback_title(monkeypatch) -> None:
user = _build_user("zh")
convs = [_make_conv(user.id, summary=None), _make_conv(user.id, summary="夏日记忆")]
db = MagicMock()
db.get = AsyncMock(return_value=user)
svc = ConversationService(db, MagicMock())
monkeypatch.setattr(
conv_service_mod.repo,
"get_user_conversations",
AsyncMock(return_value=convs),
)
monkeypatch.setattr(
ConversationService,
"ensure_redis_history_from_db",
AsyncMock(return_value=[]),
)
rows = await svc.list_for_user(user.id)
assert rows[0]["title"] == "岁月知己"
assert rows[1]["title"] == "夏日记忆"
@pytest.mark.asyncio
async def test_list_for_user_en_fallback_title(monkeypatch) -> None:
user = _build_user("en")
convs = [_make_conv(user.id, summary=None)]
db = MagicMock()
db.get = AsyncMock(return_value=user)
svc = ConversationService(db, MagicMock())
monkeypatch.setattr(
conv_service_mod.repo,
"get_user_conversations",
AsyncMock(return_value=convs),
)
monkeypatch.setattr(
ConversationService,
"ensure_redis_history_from_db",
AsyncMock(return_value=[]),
)
rows = await svc.list_for_user(user.id)
assert rows[0]["title"] == "Life Echo"
@pytest.mark.asyncio
async def test_list_for_user_missing_user_falls_back_to_zh(monkeypatch) -> None:
"""安全兜底:如果 DB 查不到 user 行(极端情况),用 zh 默认。"""
convs = [_make_conv("uid", summary=None)]
db = MagicMock()
db.get = AsyncMock(return_value=None)
svc = ConversationService(db, MagicMock())
monkeypatch.setattr(
conv_service_mod.repo,
"get_user_conversations",
AsyncMock(return_value=convs),
)
monkeypatch.setattr(
ConversationService,
"ensure_redis_history_from_db",
AsyncMock(return_value=[]),
)
rows = await svc.list_for_user("uid")
assert rows[0]["title"] == "岁月知己"