test: 补充 _resolve_strategy_id_from_template 单元测试
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 41s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 48s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m5s
AI Code Review / AI Code Review (pull_request) Successful in 1m14s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 1m26s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m44s
CI/CD Pipeline / Validate - Code Quality (pull_request) Failing after 1m47s
CI/CD Pipeline / Unit Tests (pull_request) Has been cancelled
CI/CD Pipeline / Integration Tests (pull_request) Has been cancelled
CI/CD Pipeline / PR Build API Image (pull_request) Has been cancelled
CI/CD Pipeline / PR Build Worker Image (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
PR Automation / Auto Approve on CI Green (pull_request) Has been cancelled
CI/CD Pipeline / PR Build Web Image (pull_request) Failing after 1032h52m50s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Failing after 1032h52m51s
CI/CD Pipeline / Staging E2E Tests (pull_request) Failing after 1032h53m31s
CI/CD Pipeline / Frontend Lint (pull_request) Failing after 1032h52m52s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Failing after 1032h53m33s
CI/CD Pipeline / Build Staging API Image (pull_request) Failing after 1032h53m35s
CI/CD Pipeline / ACR Image Cleanup (pull_request) Failing after 1032h53m30s
CI/CD Pipeline / Build Staging Worker Image (pull_request) Failing after 1032h53m34s
CI/CD Pipeline / Staging API Integration Tests (pull_request) Failing after 1033h26m47s
CI/CD Pipeline / Build Staging Web Image (pull_request) Failing after 1033h26m51s

- 新增 TestResolveStrategyIdFromTemplate (8个用例)
- 新增 TestPreviewRoutePassesStrategyId (2个用例)
- 修复已有 test_auto_infer_pip_resolution 适配新 import
This commit is contained in:
2026-08-04 14:33:36 +08:00
parent 34188881b3
commit 33a1485e28
+224 -4
View File
@@ -1264,8 +1264,182 @@ class TestPreviewRouteAutoInfersVideoRatio:
bgm_config={},
)
with patch("app.api.routes.generation_preview.SQLAlchemyTemplateRepository") as MockRepo:
MockRepo.return_value.get.return_value = mock_template
with patch("app.api.routes.generation_preview.SQLAlchemyEditTemplateRepository") as MockNewRepo:
MockNewRepo.return_value.get.return_value = None # 新模板系统无数据,fallback 旧系统
with patch("app.api.routes.generation_preview.SQLAlchemyTemplateRepository") as MockRepo:
MockRepo.return_value.get.return_value = mock_template
with patch("app.api.routes.generation_preview.CreateGenerationTaskUseCase") as MockUC:
MockUC.return_value.execute.return_value = task
with patch(
"app.api.routes.generation_preview.safe_enqueue_generation_task",
return_value=True,
):
resp = create_preview_generation_task(
request,
authenticated_user=_make_user(),
generation_task_repository=repo,
db=mock_db,
)
# Verify the resolution passed to CreateGenerationTaskCommand
call_args = MockUC.return_value.execute.call_args
cmd = call_args[0][0]
assert cmd.resolution == "480x854", f"Expected 480x854, got {cmd.resolution}"
# ═══════════════════════════════════════════════════════════════════════════════
# _resolve_strategy_id_from_template 单元测试
# ═══════════════════════════════════════════════════════════════════════════════
class TestResolveStrategyIdFromTemplate:
"""_resolve_strategy_id_from_template 单元测试:预览生成从模板读取 editing_mode。"""
def test_new_template_found_returns_editing_mode(self):
"""新模板系统找到模板 → 返回 editing_mode。"""
from app.api.routes.generation_preview import _resolve_strategy_id_from_template
mock_new_template = MagicMock()
mock_new_template.editing_mode = "pip"
mock_db = MagicMock()
with patch("app.api.routes.generation_preview.SQLAlchemyEditTemplateRepository") as MockNewRepo:
MockNewRepo.return_value.get.return_value = mock_new_template
result = _resolve_strategy_id_from_template("tpl_001", mock_db, "user_1")
assert result == "pip"
def test_new_template_not_found_fallback_to_old(self):
"""新模板系统未找到 → fallback 旧模板系统返回 mode。"""
from app.api.routes.generation_preview import _resolve_strategy_id_from_template
mock_old_template = MagicMock()
mock_old_template.mode = "standard"
mock_db = MagicMock()
with patch("app.api.routes.generation_preview.SQLAlchemyEditTemplateRepository") as MockNewRepo:
MockNewRepo.return_value.get.return_value = None
with patch("app.api.routes.generation_preview.SQLAlchemyTemplateRepository") as MockOldRepo:
MockOldRepo.return_value.get.return_value = mock_old_template
result = _resolve_strategy_id_from_template("tpl_001", mock_db, "user_1")
assert result == "standard"
def test_both_not_found_returns_empty(self):
"""新旧模板系统都未找到 → 返回空字符串。"""
from app.api.routes.generation_preview import _resolve_strategy_id_from_template
mock_db = MagicMock()
with patch("app.api.routes.generation_preview.SQLAlchemyEditTemplateRepository") as MockNewRepo:
MockNewRepo.return_value.get.return_value = None
with patch("app.api.routes.generation_preview.SQLAlchemyTemplateRepository") as MockOldRepo:
MockOldRepo.return_value.get.return_value = None
result = _resolve_strategy_id_from_template("tpl_nonexistent", mock_db, "user_1")
assert result == ""
def test_empty_template_id_returns_empty(self):
"""空 template_id → 直接返回空字符串。"""
from app.api.routes.generation_preview import _resolve_strategy_id_from_template
mock_db = MagicMock()
result = _resolve_strategy_id_from_template("", mock_db, "user_1")
assert result == ""
def test_new_template_exception_fallback_to_old(self):
"""新模板系统异常 → 降级到旧模板系统。"""
from app.api.routes.generation_preview import _resolve_strategy_id_from_template
mock_old_template = MagicMock()
mock_old_template.mode = "voice_over"
mock_db = MagicMock()
with patch("app.api.routes.generation_preview.SQLAlchemyEditTemplateRepository") as MockNewRepo:
MockNewRepo.side_effect = RuntimeError("db error")
with patch("app.api.routes.generation_preview.SQLAlchemyTemplateRepository") as MockOldRepo:
MockOldRepo.return_value.get.return_value = mock_old_template
result = _resolve_strategy_id_from_template("tpl_001", mock_db, "user_1")
assert result == "voice_over"
def test_both_exception_returns_empty(self):
"""新旧模板系统都异常 → 返回空字符串。"""
from app.api.routes.generation_preview import _resolve_strategy_id_from_template
mock_db = MagicMock()
with patch("app.api.routes.generation_preview.SQLAlchemyEditTemplateRepository") as MockNewRepo:
MockNewRepo.side_effect = RuntimeError("new db error")
with patch("app.api.routes.generation_preview.SQLAlchemyTemplateRepository") as MockOldRepo:
MockOldRepo.side_effect = RuntimeError("old db error")
result = _resolve_strategy_id_from_template("tpl_001", mock_db, "user_1")
assert result == ""
def test_new_template_empty_editing_mode_fallback(self):
"""新模板找到但 editing_mode 为空 → fallback 旧模板。"""
from app.api.routes.generation_preview import _resolve_strategy_id_from_template
mock_new_template = MagicMock()
mock_new_template.editing_mode = ""
mock_old_template = MagicMock()
mock_old_template.mode = "one_take"
mock_db = MagicMock()
with patch("app.api.routes.generation_preview.SQLAlchemyEditTemplateRepository") as MockNewRepo:
MockNewRepo.return_value.get.return_value = mock_new_template
with patch("app.api.routes.generation_preview.SQLAlchemyTemplateRepository") as MockOldRepo:
MockOldRepo.return_value.get.return_value = mock_old_template
result = _resolve_strategy_id_from_template("tpl_001", mock_db, "user_1")
assert result == "one_take"
def test_voice_pip_mode(self):
"""模板 editing_mode=voice_pip → 返回 'voice_pip'。"""
from app.api.routes.generation_preview import _resolve_strategy_id_from_template
mock_new_template = MagicMock()
mock_new_template.editing_mode = "voice_pip"
mock_db = MagicMock()
with patch("app.api.routes.generation_preview.SQLAlchemyEditTemplateRepository") as MockNewRepo:
MockNewRepo.return_value.get.return_value = mock_new_template
result = _resolve_strategy_id_from_template("tpl_voice", mock_db, "user_1")
assert result == "voice_pip"
class TestPreviewRoutePassesStrategyId:
"""验证预览路由正确传递 strategy_id 到 CreateGenerationTaskCommand。"""
def test_strategy_id_from_new_template(self):
"""预览路由从新模板读取 strategy_id=pip。"""
from app.api.routes.generation_preview import create_preview_generation_task
from app.schemas.generation_task import CreatePreviewGenerationTaskRequest
repo = MagicMock()
repo.count_pending_by_user.return_value = 0
repo.count_pending_total.return_value = 0
mock_db = MagicMock()
mock_new_template = MagicMock()
mock_new_template.editing_mode = "pip"
task = _make_task()
request = CreatePreviewGenerationTaskRequest(
template_id="tpl_pip",
asset_ids=["a1"],
title_ids=[],
voice_ids=[],
video_title="test",
duration=0.0,
video_ratio="",
bgm_config={},
)
with patch("app.api.routes.generation_preview.SQLAlchemyEditTemplateRepository") as MockNewRepo:
MockNewRepo.return_value.get.return_value = mock_new_template
with patch("app.api.routes.generation_preview.CreateGenerationTaskUseCase") as MockUC:
MockUC.return_value.execute.return_value = task
with patch(
@@ -1279,7 +1453,53 @@ class TestPreviewRouteAutoInfersVideoRatio:
db=mock_db,
)
# Verify the resolution passed to CreateGenerationTaskCommand
call_args = MockUC.return_value.execute.call_args
cmd = call_args[0][0]
assert cmd.resolution == "480x854", f"Expected 480x854, got {cmd.resolution}"
assert cmd.strategy_id == "pip", f"Expected strategy_id='pip', got '{cmd.strategy_id}'"
def test_strategy_id_fallback_to_old_template(self):
"""新模板无数据时,从旧模板读取 strategy_id=standard。"""
from app.api.routes.generation_preview import create_preview_generation_task
from app.schemas.generation_task import CreatePreviewGenerationTaskRequest
repo = MagicMock()
repo.count_pending_by_user.return_value = 0
repo.count_pending_total.return_value = 0
mock_db = MagicMock()
mock_old_template = MagicMock()
mock_old_template.mode = "standard"
task = _make_task()
request = CreatePreviewGenerationTaskRequest(
template_id="tpl_standard",
asset_ids=["a1"],
title_ids=[],
voice_ids=[],
video_title="test",
duration=0.0,
video_ratio="",
bgm_config={},
)
with patch("app.api.routes.generation_preview.SQLAlchemyEditTemplateRepository") as MockNewRepo:
MockNewRepo.return_value.get.return_value = None
with patch("app.api.routes.generation_preview.SQLAlchemyTemplateRepository") as MockOldRepo:
MockOldRepo.return_value.get.return_value = mock_old_template
with patch("app.api.routes.generation_preview.CreateGenerationTaskUseCase") as MockUC:
MockUC.return_value.execute.return_value = task
with patch(
"app.api.routes.generation_preview.safe_enqueue_generation_task",
return_value=True,
):
resp = create_preview_generation_task(
request,
authenticated_user=_make_user(),
generation_task_repository=repo,
db=mock_db,
)
call_args = MockUC.return_value.execute.call_args
cmd = call_args[0][0]
assert cmd.strategy_id == "standard", f"Expected strategy_id='standard', got '{cmd.strategy_id}'"