test(auth): 新增昵称规则单测——存量用户昵称登录不覆盖、默认昵称、中文昵称全链路无乱码 (update b19d212)
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 2s
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Successful in 3s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 30s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 48s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 41s
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Successful in 1m12s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 1m37s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 1m38s
AI Code Review / AI Code Review (pull_request) Successful in 2m3s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 2m45s
CI/CD Pipeline / Validate - Style (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Security (pull_request) Has been cancelled
CI/CD Pipeline / Build Production API Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Web Image (pull_request) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been cancelled
CI/CD Pipeline / Deploy Production (pull_request) Has been cancelled
CI/CD Pipeline / Production Browser E2E (pull_request) Has been cancelled
CI/CD Pipeline / Canary Release to Production (pull_request) Has been cancelled
CI/CD Pipeline / CI Gate (pull_request) Has been cancelled
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been cancelled

This commit is contained in:
2026-09-06 18:16:21 +08:00
parent fd711be0be
commit 25ca33dbaa
+83 -1
View File
@@ -60,7 +60,8 @@ class TestWechatSyncRequest:
assert WechatSyncRequest(openid="o1", unionid=" unionid_456 ").unionid == "unionid_456"
def test_default_nickname(self):
assert WechatSyncRequest(openid="o1").nickname == "微信用户"
# 微信新规拿不到真实昵称,新用户统一默认"小虾同学"
assert WechatSyncRequest(openid="o1").nickname == "小虾同学"
def test_default_source(self):
assert WechatSyncRequest(openid="o1").source == "miniapp"
@@ -319,3 +320,84 @@ class TestWechatSyncSession:
assert kw["user_id"] == "user_001"
assert "wechat_miniapp" in kw["device_info"]
assert kw["expires_in_seconds"] == 30 * 24 * 3600
class TestWechatSyncNicknameRules:
"""昵称规则:默认昵称、登录不覆盖存量昵称、中文昵称全链路无损。"""
def test_existing_user_display_name_never_overwritten_on_login(
self, mock_user_repo, mock_session_store
):
"""守护规则:已存在用户登录时,即使请求带了别的 nickname,
其 display_name 也绝不能被覆盖(只有建号时写入)。"""
user = User(
id="user_custom",
email="c@wechat.local",
username="wx_custom",
display_name="我的专属昵称",
password_hash="h",
email_verified=True,
wechat_openid="openid_123",
wechat_unionid="unionid_456",
)
mock_user_repo.find_by_wechat_openid.return_value = user
mock_user_repo.find_by_wechat_unionid.return_value = user
resp, err = make_use_case(mock_user_repo, mock_session_store).execute(
WechatSyncRequest(
openid="openid_123",
unionid="unionid_456",
nickname="小虾同学", # 请求里带的任何昵称都不准覆盖
)
)
assert err is None
assert resp.is_new_user is False
# 数据层用户昵称不变
assert user.display_name == "我的专属昵称"
# 返回给调用方的昵称也是存量昵称
assert resp.nickname == "我的专属昵称"
# save 的都是同一个用户对象,且 display_name 未被改写
for call in mock_user_repo.save.call_args_list:
assert call.args[0].display_name == "我的专属昵称"
def test_new_user_gets_default_nickname_when_nickname_empty(
self, mock_user_repo, mock_session_store
):
"""新用户且请求未带昵称(微信新规场景)→ 默认昵称小虾同学。"""
saved = {}
mock_user_repo.save.side_effect = lambda u: saved.update({u.id: u})
resp, err = make_use_case(mock_user_repo, mock_session_store).execute(
WechatSyncRequest(openid="new_oid_default", unionid="new_uid_default", nickname="")
)
assert err is None
assert resp.is_new_user is True
u = saved[resp.user_id]
assert u.display_name == "小虾同学"
assert resp.nickname == "小虾同学"
def test_chinese_nickname_full_chain_no_mojibake(
self, mock_user_repo, mock_session_store
):
"""中文昵称全链路无损:建号写入 → 仓储对象 → 响应返回,
不允许出现 latin-1/utf-8 双重编码乱码(如 \u00e8\u0080\u0081 一类)。"""
chinese_name = "老字号🏮肩腰腿🏮御众堂永康店"
saved = {}
mock_user_repo.save.side_effect = lambda u: saved.update({u.id: u})
resp, err = make_use_case(mock_user_repo, mock_session_store).execute(
WechatSyncRequest(
openid="new_oid_cn",
unionid="new_uid_cn",
nickname=chinese_name,
)
)
assert err is None
u = saved[resp.user_id]
# 写入仓储对象的昵称必须与原文完全一致
assert u.display_name == chinese_name
assert resp.nickname == chinese_name
assert resp.to_dict()["user"]["display_name"] == chinese_name
assert resp.to_dict()["user_info"]["display_name"] == chinese_name
# 乱码特征:双重编码后必然出现Ã/\u00c2 拼音字母或控制字符
assert "\u00c3" not in u.display_name and "\u00c2" not in u.display_name
assert "\u00e8" not in u.display_name