Files
xiaoxia-saas/tests/unit/test_helpers_get_user_plan.py
T
xiaoxia d855fc30ba
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker 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 / Check if frontend-only change (pull_request) Successful in 26s
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m28s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 1m23s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 2m3s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m11s
AI Code Review / AI Code Review (pull_request) Successful in 6m49s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 10m42s
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (pull_request) Failing after 14m49s
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m30s
CI/CD Pipeline / Unit Tests (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
CI/CD Pipeline / Validate - Style (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Security (pull_request) Has been cancelled
CI/CD Pipeline / Validate - Python (mypy + alembic) (pull_request) Has been cancelled
fix(scripts): #1894/#1968 抖音 yt-dlp cookies 支持 + 旧档位归一化补测 + CI 覆盖率修复
- scripts_ai.py: 支持通过 DOUYIN_COOKIES_FILE 指定 Netscape cookies 文件;
  cookies 缺失/过期类错误('fresh cookies' 等)返回 503 + 友好文案
  ('抖音链接解析暂时不可用,请稍后重试或手动输入文案'),
  不再暴露 yt-dlp 原始错误;普通下载失败统一文案,不带内部异常文本
- ci_staging_deploy.sh: API 容器挂载 /var/lib/xiaoxia-saas-staging/configs/douyin_cookies.txt
  到 /app/configs/douyin_cookies.txt;自动 mkdir + 空占位兜底
- infra/docker/compose.yml: API 服务挂载 ../../deploy/configs:/app/configs:ro
- deploy/configs/.env.{staging,production}: 新增 DOUYIN_COOKIES_FILE 环境变量
- deploy/configs/douyin_cookies.txt: Netscape 格式占位文件(真实 cookies 部署时替换)
- 新增 test_helpers_get_user_plan.py 覆盖 _helpers.get_user_plan 旧档位归一化分支
- 新增 test_subscription_routes_legacy.py 覆盖 _build_subscription_info 旧档位归一化/
  cancel_subscription 免费用户分支/change_plan 参数校验/toggle-auto-renew 等
- 扩展 test_extract_from_douyin_errors.py: 新增 5 个 cookies 场景测试(503 友好文案/
  cookiefile 注入/错误信息脱敏等)
- 增量覆盖率从 59% 提升到 60%+,解决 CI Gate 阻塞
2026-09-16 18:28:23 +08:00

73 lines
2.0 KiB
Python
Raw 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.
"""验证 _helpers.get_user_plan 档位归一化逻辑(#1894 旧档位兼容)"""
from __future__ import annotations
from unittest import mock
import pytest
from app.api.routes import _helpers
class _FakeUser:
def __init__(self, plan):
self.subscription_plan = plan
class _FakeUserNoPlan:
pass
class _FakeRepo:
def __init__(self, user=None):
self._user = user
def find_by_id(self, uid):
return self._user
def test_user_not_found_returns_free():
"""用户不存在时返回 free(覆盖 _helpers.py 第 41 行 user is None 分支)"""
repo = _FakeRepo(user=None)
assert _helpers.get_user_plan("u-missing", repo) == "free"
def test_user_plan_none_returns_free():
"""用户 plan 属性为 None 时返回 free"""
repo = _FakeRepo(user=_FakeUser(None))
assert _helpers.get_user_plan("u1", repo) == "free"
@pytest.mark.parametrize(
"legacy,expected",
[
("standard", "monthly"),
("basic", "monthly"),
("pro", "quarterly"),
("premium", "quarterly"),
("enterprise", "quarterly"),
],
)
def test_legacy_plans_normalized(legacy, expected):
"""旧档位值正确归一化到新体系"""
repo = _FakeRepo(user=_FakeUser(legacy))
assert _helpers.get_user_plan("u1", repo) == expected
def test_unknown_plan_returns_free():
"""未知 plan 值(非新旧任一档位)→ 回落到 free(覆盖第 47 行)"""
repo = _FakeRepo(user=_FakeUser("totally_unknown_plan_xyz"))
assert _helpers.get_user_plan("u1", repo) == "free"
def test_user_without_subscription_plan_attr_returns_free():
"""user 对象没有 subscription_plan 属性时返回 free(getattr 默认值分支)"""
repo = _FakeRepo(user=_FakeUserNoPlan())
assert _helpers.get_user_plan("u1", repo) == "free"
@pytest.mark.parametrize("plan", ["free", "monthly", "quarterly", "yearly"])
def test_valid_new_plans_passthrough(plan):
"""新档位直接透传"""
repo = _FakeRepo(user=_FakeUser(plan))
assert _helpers.get_user_plan("u1", repo) == plan