fix: 清理删除旧路径后的 unused imports/variables 和孤儿测试
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 33s
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 44s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 1m58s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 2m7s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 2m9s
AI Code Review / AI Code Review (pull_request) Successful in 2m18s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m36s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 2m6s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m51s
CI/CD Pipeline / Validate - Code Quality (pull_request) Failing after 4m24s
CI/CD Pipeline / Unit Tests (pull_request) Has been cancelled
CI/CD Pipeline / Integration Tests (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

- generation.py: 移除 9 个 unused import (json, tempfile, Any, VirtualClip 等)
- generation.py: 注释 3 个 unused variable (asset_library_id, voice_library_id, output_name)
- generation_preview.py: 移除 unused import json
- test_oneclick_gen_p0_fixes.py: 删除 TestTemplateClipEffectMapping (10个测试)
  测试的 _apply_template_clip_effects/_extract_intro_outro_from_clip_configs 已随旧路径删除

单测 13637 passed, 0 failed
This commit is contained in:
xiaoxia
2026-08-24 14:00:11 +08:00
parent e8c3d181b1
commit 70c822e54e
3 changed files with 3 additions and 203 deletions
@@ -5,7 +5,6 @@
from __future__ import annotations
import json
import logging
from app.auth import AuthenticatedUser, get_current_user
+3 -13
View File
@@ -13,25 +13,15 @@
from __future__ import annotations
import json
import logging
import tempfile
import time
from pathlib import Path
from typing import Any
from video_processing.ffmpeg_utils import probe_duration
from worker_app.celery_app import celery_app
from worker_app.db import SessionLocal
from worker_app.tasks.generation_plan_builder import VirtualClip as _VirtualClip
from worker_app.tasks.generation_plan_builder import VirtualPlan as _VirtualPlan
from worker_app.tasks.generation_plan_builder import apply_template_clip_effects as _apply_template_clip_effects
from worker_app.tasks.generation_plan_builder import build_error_info as _build_error_info
from worker_app.tasks.generation_plan_builder import (
extract_intro_outro_from_clip_configs as _extract_intro_outro_from_clip_configs,
)
from packages.domain.bgm_utils import merge_bgm_config
OUTPUT_WIDTH = 1280
OUTPUT_HEIGHT = 720
@@ -644,8 +634,8 @@ def generate_video(self, task_id: str) -> dict:
return {"status": "failed", "error": f"generation task {task_id} not found"}
project_id = task_info["project_id"]
asset_library_id = task_info["asset_library_id"]
voice_library_id = task_info["voice_library_id"]
# asset_library_id, voice_library_id 已在 _render_from_edit_plan 内部重新获取
# (不再需要在 generate_video 顶层解包)
template_id = task_info["template_id"]
task_asset_ids = task_info["task_asset_ids"]
batch_id = task_info["batch_id"]
@@ -679,7 +669,7 @@ def generate_video(self, task_id: str) -> dict:
except ValueError:
editing_mode = EditingMode.ONE_TAKE
output_name = f"generated-{task_id}.mp4"
# output_name 不再使用,渲染路径内部自行处理文件名
try:
if template_id:
-189
View File
@@ -167,192 +167,3 @@ class TestP1Validations:
# ── P1: 一键生成 clip 级效果层映射 ───────────────────────────────────────────
class TestTemplateClipEffectMapping:
"""P1: 模板 clip 级效果层映射到一键生成素材 clips."""
def _make_virtual_clip(self, idx: int, clip_type: str = "main", config: dict | None = None):
from dataclasses import dataclass, field
_clip_type_val = clip_type
@dataclass
class FakeClip:
id: str = f"vc_{idx:03d}"
plan_id: str = "task_001"
clip_type: str = _clip_type_val
order: int = idx
asset_id: str = f"asset_{idx}"
duration: float = 5.0
transition_effect: str = "cut"
transition_duration: float = 0.0
playback_speed: float = 1.0
config: dict = field(default_factory=dict)
return FakeClip(config=config or {})
def _make_template_clip_config(self, clip_type: str = "main", transition: str = "cut", config: dict | None = None):
mock = MagicMock()
mock.clip_type = clip_type
mock.transition_effect = transition
mock.config = config or {}
mock.default_duration = 3.0
mock.text_template = ""
return mock
def test_transition_effect_mapped(self):
"""转场效果正确映射到素材 clips."""
from worker_app.tasks.generation import _apply_template_clip_effects
clips = [self._make_virtual_clip(i) for i in range(3)]
clip_configs = [
self._make_template_clip_config("main", transition="fade"),
self._make_template_clip_config("main", transition="dissolve"),
]
_apply_template_clip_effects(clips, clip_configs, "one_take")
# 前两个按顺序映射,第三个用最后一个模板配置
assert clips[0].transition_effect == "fade"
assert clips[1].transition_effect == "dissolve"
assert clips[2].transition_effect == "dissolve" # 复用最后一个
def test_color_grade_mapped(self):
"""滤镜配置正确映射到 clip.config.color_grade."""
from worker_app.tasks.generation import _apply_template_clip_effects
clips = [self._make_virtual_clip(i) for i in range(2)]
clip_configs = [
self._make_template_clip_config(
"main", config={"color_grade": {"enabled": True, "filter": "vintage", "brightness": 0.1}}
),
]
_apply_template_clip_effects(clips, clip_configs, "one_take")
assert clips[0].config["color_grade"]["filter"] == "vintage"
assert clips[0].config["color_grade"]["brightness"] == 0.1
# 第二个素材复用第一个模板配置
assert clips[1].config["color_grade"]["filter"] == "vintage"
def test_existing_config_preserved(self):
"""已有 clip.config 内容(如 role)被保留."""
from worker_app.tasks.generation import _apply_template_clip_effects
clips = [self._make_virtual_clip(0, config={"role": "b_roll"})]
clip_configs = [
self._make_template_clip_config("main", config={"color_grade": {"enabled": True, "filter": "warm"}}),
]
_apply_template_clip_effects(clips, clip_configs, "voice_over")
assert clips[0].config["role"] == "b_roll" # 保留原有配置
assert clips[0].config["color_grade"]["filter"] == "warm" # 新增滤镜配置
def test_empty_clip_configs_no_change(self):
"""空模板配置时 clips 保持不变."""
from worker_app.tasks.generation import _apply_template_clip_effects
clips = [self._make_virtual_clip(i) for i in range(2)]
_apply_template_clip_effects(clips, [], "one_take")
assert clips[0].transition_effect == "cut"
assert clips[1].transition_effect == "cut"
def test_cut_transition_not_overwritten(self):
"""模板转场为 cut 时不覆盖(保持默认)."""
from worker_app.tasks.generation import _apply_template_clip_effects
clips = [self._make_virtual_clip(0)]
clips[0].transition_effect = "fade" # 已有非默认值
clip_configs = [
self._make_template_clip_config("main", transition="cut"),
]
_apply_template_clip_effects(clips, clip_configs, "one_take")
# 模板是 cut 时,保留原有值(避免无意义覆盖)
assert clips[0].transition_effect == "fade"
def test_transition_duration_mapped(self):
"""转场时长(transition_duration)从模板 config 正确映射到 clip."""
from worker_app.tasks.generation import _apply_template_clip_effects
clips = [self._make_virtual_clip(i) for i in range(3)]
clip_configs = [
self._make_template_clip_config("main", transition="fade", config={"transition_duration": 0.8}),
self._make_template_clip_config("main", transition="dissolve", config={"transition_duration": 1.2}),
]
_apply_template_clip_effects(clips, clip_configs, "one_take")
# 前两个按顺序映射,第三个复用最后一个
assert clips[0].transition_effect == "fade"
assert clips[0].transition_duration == 0.8
assert clips[1].transition_effect == "dissolve"
assert clips[1].transition_duration == 1.2
assert clips[2].transition_effect == "dissolve"
assert clips[2].transition_duration == 1.2
def test_transition_duration_ignored_for_cut(self):
"""模板转场为 cut 时,transition_duration 不生效(保持默认0."""
from worker_app.tasks.generation import _apply_template_clip_effects
clips = [self._make_virtual_clip(0)]
clip_configs = [
self._make_template_clip_config("main", transition="cut", config={"transition_duration": 0.5}),
]
_apply_template_clip_effects(clips, clip_configs, "one_take")
# cut 转场不映射,transition_duration 也不应用
assert clips[0].transition_duration == 0.0
def test_transition_duration_invalid_value_skipped(self):
"""transition_duration 为无效值时安全跳过."""
from worker_app.tasks.generation import _apply_template_clip_effects
clips = [self._make_virtual_clip(0)]
clip_configs = [
self._make_template_clip_config("main", transition="fade", config={"transition_duration": "abc"}),
]
_apply_template_clip_effects(clips, clip_configs, "one_take")
assert clips[0].transition_effect == "fade"
assert clips[0].transition_duration == 0.0 # 无效值保持默认
def test_intro_outro_extracted(self):
"""intro/outro 类型 clip_config 正确提取为 plan 级 intro_outro 配置."""
from worker_app.tasks.generation import _extract_intro_outro_from_clip_configs
clip_configs = [
self._make_template_clip_config("intro", config={"intro_type": "text", "intro_text_color": "#ffffff"}),
self._make_template_clip_config("main"),
self._make_template_clip_config("outro", config={"outro_type": "follow", "outro_follow_text": "关注我们"}),
]
# 设置 intro/outro 的 text_template
clip_configs[0].text_template = "精彩视频"
clip_configs[0].default_duration = 2.5
result = _extract_intro_outro_from_clip_configs(clip_configs)
assert result["has_intro"] is True
assert result["intro_type"] == "text"
assert result["intro_text"] == "精彩视频"
assert result["intro_duration"] == 2.5
assert result["intro_text_color"] == "#ffffff"
assert result["has_outro"] is True
assert result["outro_type"] == "follow"
assert result["outro_follow_text"] == "关注我们"
def test_intro_outro_empty_when_none(self):
"""没有 intro/outro 时返回空 dict."""
from worker_app.tasks.generation import _extract_intro_outro_from_clip_configs
clip_configs = [
self._make_template_clip_config("main"),
self._make_template_clip_config("main"),
]
result = _extract_intro_outro_from_clip_configs(clip_configs)
assert result == {}