geo/backend/tests/test_services/test_quota_service.py

333 lines
12 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.

import pytest
from app.services.quota_service import (
QuotaService,
QuotaUsage,
QuotaWarning,
QuotaType,
QUOTA_LIMITS,
WARNING_THRESHOLDS,
)
class TestQuotaUsage:
"""额度使用数据结构测试"""
def test_quota_usage_creation(self):
"""测试QuotaUsage数据创建"""
usage = QuotaUsage(
quota_type="api_calls",
used=800,
limit=1000,
usage_percentage=80.0,
status="warning",
remaining=200,
)
assert usage.quota_type == "api_calls"
assert usage.used == 800
assert usage.limit == 1000
assert usage.usage_percentage == 80.0
assert usage.status == "warning"
assert usage.remaining == 200
def test_quota_usage_unlimited(self):
"""测试无限额度QuotaUsage"""
usage = QuotaUsage(
quota_type="api_calls",
used=5000,
limit=-1,
usage_percentage=0.0,
status="unlimited",
remaining=-1,
)
assert usage.limit == -1
assert usage.status == "unlimited"
assert usage.remaining == -1
class TestQuotaWarning:
"""预警数据结构测试"""
def test_quota_warning_creation(self):
"""测试QuotaWarning数据创建"""
warning = QuotaWarning(
quota_type="api_calls",
status="warning",
usage_percentage=80.0,
message="API调用额度已使用80%",
recommended_action="请关注使用情况,考虑升级套餐",
)
assert warning.quota_type == "api_calls"
assert warning.status == "warning"
assert warning.usage_percentage == 80.0
assert "80%" in warning.message
class TestQuotaService:
"""额度预警服务测试"""
@pytest.fixture
def quota_service(self):
"""创建额度服务实例"""
return QuotaService()
def test_calculate_usage_percentage_basic(self, quota_service):
"""测试基础使用率计算"""
percentage = quota_service.calculate_usage_percentage(used=800, limit=1000)
assert percentage == 80.0
def test_calculate_usage_percentage_zero(self, quota_service):
"""测试0%使用率"""
percentage = quota_service.calculate_usage_percentage(used=0, limit=1000)
assert percentage == 0.0
def test_calculate_usage_percentage_full(self, quota_service):
"""测试100%使用率"""
percentage = quota_service.calculate_usage_percentage(used=1000, limit=1000)
assert percentage == 100.0
def test_calculate_usage_percentage_half(self, quota_service):
"""测试50%使用率"""
percentage = quota_service.calculate_usage_percentage(used=500, limit=1000)
assert percentage == 50.0
def test_calculate_usage_percentage_unlimited(self, quota_service):
"""测试无限额度使用率"""
percentage = quota_service.calculate_usage_percentage(used=5000, limit=-1)
assert percentage == 0.0
def test_get_quota_status_ok(self, quota_service):
"""测试正常状态低于80%"""
status = quota_service.get_quota_status(usage_percentage=50.0)
assert status == "ok"
def test_get_quota_status_warning(self, quota_service):
"""测试警告状态80%"""
status = quota_service.get_quota_status(usage_percentage=80.0)
assert status == "warning"
def test_get_quota_status_critical(self, quota_service):
"""测试严重状态90%"""
status = quota_service.get_quota_status(usage_percentage=90.0)
assert status == "critical"
def test_get_quota_status_exhausted(self, quota_service):
"""测试耗尽状态100%"""
status = quota_service.get_quota_status(usage_percentage=100.0)
assert status == "exhausted"
def test_get_quota_status_unlimited(self, quota_service):
"""测试无限状态"""
status = quota_service.get_quota_status(usage_percentage=0.0, limit=-1)
assert status == "unlimited"
def test_get_quota_limit_free_plan(self, quota_service):
"""测试免费套餐额度"""
limit = quota_service.get_quota_limit("free", QuotaType.API_CALLS)
assert limit == 1000
def test_get_quota_limit_basic_plan(self, quota_service):
"""测试基础套餐额度"""
limit = quota_service.get_quota_limit("basic", QuotaType.QUERIES)
assert limit == 500
def test_get_quota_limit_pro_plan(self, quota_service):
"""测试专业套餐额度"""
limit = quota_service.get_quota_limit("pro", QuotaType.CONTENT_GENERATION)
assert limit == 1000
def test_get_quota_limit_unlimited_plan(self, quota_service):
"""测试无限套餐额度"""
limit = quota_service.get_quota_limit("unlimited", QuotaType.API_CALLS)
assert limit == -1
def test_get_remaining_quota(self, quota_service):
"""测试剩余额度计算"""
remaining = quota_service.get_remaining(used=800, limit=1000)
assert remaining == 200
def test_get_remaining_quota_exhausted(self, quota_service):
"""测试额度耗尽"""
remaining = quota_service.get_remaining(used=1000, limit=1000)
assert remaining == 0
def test_get_remaining_quota_unlimited(self, quota_service):
"""测试无限额度"""
remaining = quota_service.get_remaining(used=5000, limit=-1)
assert remaining == -1
def test_get_remaining_quota_overuse(self, quota_service):
"""测试超额使用"""
remaining = quota_service.get_remaining(used=1200, limit=1000)
assert remaining == -200
def test_generate_warning_message_warning(self, quota_service):
"""测试生成警告消息"""
warning = quota_service.generate_warning(
quota_type=QuotaType.API_CALLS,
status="warning",
usage_percentage=80.0,
)
assert warning.quota_type == QuotaType.API_CALLS
assert warning.status == "warning"
assert warning.usage_percentage == 80.0
assert "80%" in warning.message
assert warning.recommended_action != ""
def test_generate_warning_message_critical(self, quota_service):
"""测试生成严重警告消息"""
warning = quota_service.generate_warning(
quota_type=QuotaType.QUERIES,
status="critical",
usage_percentage=90.0,
)
assert warning.status == "critical"
assert "90%" in warning.message
def test_generate_warning_message_exhausted(self, quota_service):
"""测试生成耗尽警告消息"""
warning = quota_service.generate_warning(
quota_type=QuotaType.CONTENT_GENERATION,
status="exhausted",
usage_percentage=100.0,
)
assert warning.status == "exhausted"
assert "100%" in warning.message
def test_check_quota_free_plan(self, quota_service):
"""测试检查免费套餐额度"""
usage = quota_service.check_quota(
plan="free",
quota_type=QuotaType.API_CALLS,
used=800,
)
assert usage.quota_type == QuotaType.API_CALLS
assert usage.limit == 1000
assert usage.used == 800
assert usage.remaining == 200
assert usage.usage_percentage == 80.0
assert usage.status == "warning"
def test_check_quota_pro_plan_warning(self, quota_service):
"""测试专业套餐警告状态"""
usage = quota_service.check_quota(
plan="pro",
quota_type=QuotaType.QUERIES,
used=4500,
)
assert usage.limit == 5000
assert usage.usage_percentage == 90.0
assert usage.status == "critical"
def test_check_quota_unlimited_plan(self, quota_service):
"""测试无限套餐"""
usage = quota_service.check_quota(
plan="unlimited",
quota_type=QuotaType.API_CALLS,
used=100000,
)
assert usage.limit == -1
assert usage.status == "unlimited"
assert usage.usage_percentage == 0.0
assert usage.remaining == -1
def test_check_quota_exhausted(self, quota_service):
"""测试额度耗尽"""
usage = quota_service.check_quota(
plan="free",
quota_type=QuotaType.QUERIES,
used=50,
)
assert usage.limit == 50
assert usage.used == 50
assert usage.remaining == 0
assert usage.usage_percentage == 100.0
assert usage.status == "exhausted"
def test_check_quota_ok(self, quota_service):
"""测试额度正常"""
usage = quota_service.check_quota(
plan="basic",
quota_type=QuotaType.STORAGE,
used=500,
)
assert usage.limit == 1000
assert usage.usage_percentage == 50.0
assert usage.status == "ok"
def test_reset_quota_usage(self, quota_service):
"""测试额度重置"""
usage = quota_service.check_quota(
plan="free",
quota_type=QuotaType.API_CALLS,
used=800,
)
assert usage.used == 800
reset_usage = quota_service.reset_quota(used=800)
assert reset_usage == 0
def test_reset_quota_to_specific_value(self, quota_service):
"""测试重置到特定值"""
reset_usage = quota_service.reset_quota(used=500, reset_to=100)
assert reset_usage == 100
def test_get_all_quota_usage(self, quota_service):
"""测试获取所有额度使用情况"""
all_usage = quota_service.get_all_quota_usage(
plan="free",
api_calls_used=800,
queries_used=40,
content_generation_used=8,
storage_used=50,
)
assert len(all_usage) == 4
assert any(u.quota_type == QuotaType.API_CALLS and u.used == 800 for u in all_usage)
assert any(u.quota_type == QuotaType.QUERIES and u.used == 40 for u in all_usage)
def test_get_warnings_from_usage(self, quota_service):
"""测试从使用情况生成预警"""
all_usage = quota_service.get_all_quota_usage(
plan="free",
api_calls_used=800,
queries_used=45,
content_generation_used=5,
storage_used=20,
)
warnings = quota_service.get_warnings(all_usage)
assert len(warnings) >= 1
assert any(w.status in ["warning", "critical", "exhausted"] for w in warnings)
def test_boundary_value_0_percent(self, quota_service):
"""测试边界值0%"""
usage = quota_service.check_quota(
plan="free",
quota_type=QuotaType.API_CALLS,
used=0,
)
assert usage.usage_percentage == 0.0
assert usage.status == "ok"
def test_boundary_value_100_percent(self, quota_service):
"""测试边界值100%"""
usage = quota_service.check_quota(
plan="free",
quota_type=QuotaType.API_CALLS,
used=1000,
)
assert usage.usage_percentage == 100.0
assert usage.status == "exhausted"
def test_warning_thresholds_constants(self):
"""测试预警阈值常量"""
assert WARNING_THRESHOLDS["warning"] == 0.80
assert WARNING_THRESHOLDS["critical"] == 0.90
assert WARNING_THRESHOLDS["exhausted"] == 1.00
def test_quota_limits_constants(self):
"""测试套餐额度常量"""
assert QUOTA_LIMITS["free"]["api_calls"] == 1000
assert QUOTA_LIMITS["free"]["queries"] == 50
assert QUOTA_LIMITS["basic"]["api_calls"] == 10000
assert QUOTA_LIMITS["pro"]["api_calls"] == 100000
assert QUOTA_LIMITS["unlimited"]["api_calls"] == -1