Files
life-echo/api/tests/test_conversation_list_fallback_title.py
Kevin ccdc4e4277 feat(i18n): persist language preference and thread through chat, memoir, TTS
- Add users.language_preference (Alembic 0018, default zh); capture at signup/SMS
  only; expose on auth and profile APIs
- Lite English prompts for chat and memoir; localized stage labels and agent
  names (Life Echo / 岁月知己)
- Tencent TTS: language-aware synthesis, ModelType=1 for 501004, English chunking
- WebSocket pipeline: emit all AGENT_RESPONSE segments when TTS cancels; INFO logs
  for tts_this_turn and TTS decisions; on-demand TTS logging
- Expo: device language on auth, i18n tiers/agent name, [SPLIT] streaming UX fixes
- Tests for migration, prompts, pipeline, router tts_this_turn, reply segments

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 16:16:49 +08:00

121 lines
3.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""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"] == "岁月知己"