67a1ed6430
CI/CD Pipeline / Check if frontend-only change (push) Has been skipped
CI/CD Pipeline / Check push changed paths (push) Successful in 2s
CI/CD Pipeline / PR Build API Image (push) Has been skipped
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (push) Successful in 2s
CI/CD Pipeline / PR Build Web Image (push) Has been skipped
CI/CD Pipeline / PR Build Worker Image (push) Has been skipped
CI/CD Pipeline / Frontend Lint (push) Has been skipped
CI/CD Pipeline / Build Staging Web Image (push) Has been skipped
CI/CD Pipeline / Build Staging API Image (push) Successful in 37s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 38s
CI/CD Pipeline / Retag skipped Staging API Image (push) Has been skipped
CI/CD Pipeline / Retag skipped Staging Worker Image (push) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (push) Successful in 20s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 43s
CI/CD Pipeline / Validate - Python (mypy + alembic) (push) Successful in 3m3s
CI/CD Pipeline / Integration Tests (push) Successful in 3m7s
CI/CD Pipeline / Staging E2E Tests (push) Successful in 1m40s
CI/CD Pipeline / Validate - Style (push) Successful in 3m52s
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 4m17s
CI/CD Pipeline / ACR Image Cleanup (push) Successful in 3m6s
CI/CD Pipeline / Validate - Security (push) Successful in 7m14s
CI/CD Pipeline / Unit Tests (push) Successful in 9m33s
CI/CD Pipeline / Build Production API Image (push) Has been skipped
CI/CD Pipeline / Build Production Web Image (push) Has been skipped
CI/CD Pipeline / Build Production Worker Image (push) Has been skipped
CI/CD Pipeline / CI Gate (push) Has been skipped
CI/CD Pipeline / Deploy Production (push) Has been skipped
CI/CD Pipeline / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (push) Successful in 35m54s
CI/CD Pipeline / Canary Release to Production (push) Has been skipped
Co-authored-by: xiaoxia <dev@xiaoxiajianji.com> Co-committed-by: xiaoxia <dev@xiaoxiajianji.com>
73 lines
2.0 KiB
Python
73 lines
2.0 KiB
Python
"""验证 _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
|