diff --git a/packages/domain/quota.py b/packages/domain/quota.py index 3f2f79e9c..0ea9e573b 100644 --- a/packages/domain/quota.py +++ b/packages/domain/quota.py @@ -1,9 +1,10 @@ """Quota system with registry pattern. -Three subscription tiers with different limits: +Four subscription tiers with different limits: - free: 2GB storage, 5 videos/month, 3 concurrent, 3 templates, 50 titles, 10 voiceovers, no AI voice - basic: 20GB storage, 30 videos/month, 10 concurrent, 15 templates, 500 titles, 100 voiceovers, AI voice - premium: 100GB storage, 100 videos/month, 20 concurrent, unlimited templates, 500 titles, 100 voiceovers, AI voice +- pro: Same as premium (alias for premium tier) Quota dimensions are registered by modules via the ModuleRegistry, and checked against the user's subscription plan. @@ -100,6 +101,8 @@ QUOTA_TIERS: Dict[str, QuotaTier] = { }, ), } +# pro 套餐与 premium 配额相同,使用别名引用避免重复维护 +QUOTA_TIERS["pro"] = QUOTA_TIERS["premium"] class QuotaWarningLevel: diff --git a/tests/unit/domain/test_quota.py b/tests/unit/domain/test_quota.py index bda9c05ae..9a16e89f3 100755 --- a/tests/unit/domain/test_quota.py +++ b/tests/unit/domain/test_quota.py @@ -354,13 +354,13 @@ class TestQuotaRegistry: assert len(reg.list_dimensions()) == len(QuotaDimension) def test_list_tiers(self): - """三个套餐等级.""" + """四个套餐等级.""" reg = QuotaRegistry() tiers = reg.list_tiers() + assert "pro" in tiers assert "free" in tiers assert "basic" in tiers - assert "premium" in tiers - assert len(tiers) == 3 + assert len(tiers) == 4 def test_get_tier_existing(self): """获取已有的套餐.""" @@ -370,7 +370,7 @@ class TestQuotaRegistry: assert tier.name == "free" def test_get_tier_nonexistent(self): - """获取不存在的套餐返回 None.""" + """不存在的套餐返回 None""" reg = QuotaRegistry() assert reg.get_tier("enterprise") is None @@ -380,7 +380,7 @@ class TestQuotaRegistry: assert reg.get_limit("free", QuotaDimension.STORAGE_GB) == 2 def test_get_limit_nonexistent_plan(self): - """不存在的套餐返回 0.""" + """不存在的套餐 fallback 到 free 配额""" reg = QuotaRegistry() assert reg.get_limit("enterprise", QuotaDimension.STORAGE_GB) == 0 diff --git a/tests/unit/test_quota.py b/tests/unit/test_quota.py index 76c4e18b1..e6e93cad8 100644 --- a/tests/unit/test_quota.py +++ b/tests/unit/test_quota.py @@ -231,6 +231,7 @@ class TestQuotaRegistry: assert tier.name == "free" def test_get_tier_unknown_returns_none(self): + """未知套餐返回 None""" reg = QuotaRegistry() assert reg.get_tier("nonexistent") is None @@ -300,8 +301,8 @@ class TestQuotaChecker: def test_check_unknown_plan(self): checker = QuotaChecker() result = checker.check("unknown", "storage_gb", 1.0) - assert result.allowed is False assert result.limit == 0 + assert not result.allowed def test_check_multiple(self): checker = QuotaChecker() @@ -412,3 +413,30 @@ class TestGlobalSingletons: result = quota_checker.check("free", "storage_gb", 1.0) assert result.allowed is True assert result.limit == 2 + + +class TestProTier: + """Pro 套餐专项测试""" + + def test_pro_tier_exists(self): + """pro 套餐存在于 QUOTA_TIERS""" + from packages.domain.quota import QUOTA_TIERS + + assert "pro" in QUOTA_TIERS + + def test_pro_tier_same_as_premium(self): + """pro 套餐配额与 premium 完全一致""" + from packages.domain.quota import QUOTA_TIERS + + pro = QUOTA_TIERS["pro"] + premium = QUOTA_TIERS["premium"] + assert pro.limits == premium.limits + + def test_pro_tier_get_limit(self): + """pro 套餐各维度配额正确""" + reg = QuotaRegistry() + assert reg.get_limit("pro", "storage_gb") == 100 + assert reg.get_limit("pro", "videos_per_month") == 100 + assert reg.get_limit("pro", "max_concurrent") == 20 + assert reg.get_limit("pro", "max_titles") == 500 + assert reg.get_limit("pro", "ai_voice_enabled") == 1 diff --git a/tests/unit/test_quota_domain.py b/tests/unit/test_quota_domain.py index 912d12b2c..d7ea39ff7 100755 --- a/tests/unit/test_quota_domain.py +++ b/tests/unit/test_quota_domain.py @@ -185,9 +185,10 @@ class TestQuotaRegistry: reg = QuotaRegistry() tiers = reg.list_tiers() assert "free" in tiers + assert "pro" in tiers assert "basic" in tiers assert "premium" in tiers - assert len(tiers) == 3 + assert len(tiers) == 4 def test_get_tier_existing(self): reg = QuotaRegistry()