diff --git a/apps/api/app/api/routes/generation_cover.py b/apps/api/app/api/routes/generation_cover.py index 540aaefd2..3d5a5a72d 100644 --- a/apps/api/app/api/routes/generation_cover.py +++ b/apps/api/app/api/routes/generation_cover.py @@ -15,6 +15,7 @@ from typing import Any, Optional from urllib.parse import urlparse from app.auth import AuthenticatedUser, get_current_user +from packages.middleware.points_gate import points_gate from app.dependencies import get_db_session, get_generated_video_repository from app.services.edit_plan_service import EditPlanService from app.services.edit_template_service import EditTemplateService @@ -331,6 +332,7 @@ def _is_trusted_media_url(url: str) -> bool: @router.post("/generate-cover", response_model=GenerateCoverResponse) +@points_gate("ai_cover") def generate_cover( body: GenerateCoverRequest, template_id: str = Query(..., description="模板 ID"), diff --git a/tests/unit/test_generation_cover.py b/tests/unit/test_generation_cover.py index 96f5c260f..dfecca6d7 100644 --- a/tests/unit/test_generation_cover.py +++ b/tests/unit/test_generation_cover.py @@ -5,6 +5,16 @@ from __future__ import annotations import pytest from pydantic import ValidationError +import packages.middleware.points_gate as _pg_module + + +@pytest.fixture(autouse=True) +def _disable_points_gate(monkeypatch): + """默认关闭积分闸门,避免影响既有用例。""" + monkeypatch.setattr(_pg_module, "_points_gate_enabled", lambda: False) + yield + + def test_generation_cover_router_importable(): """新路由模块可以正确导入""" diff --git a/tests/unit/test_generation_cover_points.py b/tests/unit/test_generation_cover_points.py new file mode 100644 index 000000000..34a8d9c2b --- /dev/null +++ b/tests/unit/test_generation_cover_points.py @@ -0,0 +1,25 @@ +"""AI封面生成 积分扣点单元测试 (#1895 P2 step 2.7)""" +from __future__ import annotations + +from unittest.mock import MagicMock, patch + +import pytest + +import packages.middleware.points_gate as _pg_module + + +@pytest.fixture(autouse=True) +def _enable(monkeypatch): + monkeypatch.setattr(_pg_module, "_points_gate_enabled", lambda: True) + yield + + +class TestGenerationCoverPoints: + def test_ai_cover_cost(self): + from packages.domain.points_rules import calculate_points_cost + assert calculate_points_cost("ai_cover", is_member=False) == 2 + assert calculate_points_cost("ai_cover", is_member=True, member_type="yearly") >= 0 + + def test_decorator_attached(self): + from app.api.routes.generation_cover import generate_cover + assert hasattr(generate_cover, "__wrapped__"), "missing @points_gate"