diff --git a/apps/worker/video_processing/render_adapter.py b/apps/worker/video_processing/render_adapter.py index 52d2bd718..c6611d814 100755 --- a/apps/worker/video_processing/render_adapter.py +++ b/apps/worker/video_processing/render_adapter.py @@ -49,7 +49,7 @@ class RenderAdapterResult: height: int = 0 clip_count: int = 0 rendered_clip_ids: list[str] = None # 成功渲染的 clip id 列表 - failed_clip_ids: list[str] = None # 失败的 clip id 列表 + failed_clip_ids: list[str] = None # 失败的 clip id 列表 error_message: str = "" def __post_init__(self): diff --git a/apps/worker/worker_app/tasks/edit_plan_generation.py b/apps/worker/worker_app/tasks/edit_plan_generation.py index c8245be31..c879a6632 100755 --- a/apps/worker/worker_app/tasks/edit_plan_generation.py +++ b/apps/worker/worker_app/tasks/edit_plan_generation.py @@ -266,9 +266,7 @@ def _render_with_unified( if not result.success: logger.error("渲染失败(unified): %s — %s", plan_id, result.error_message) - _mark_plan_failed( - plan_repo, plan_id, gen_task_repo, generation_task_id, result.error_message or "渲染失败" - ) + _mark_plan_failed(plan_repo, plan_id, gen_task_repo, generation_task_id, result.error_message or "渲染失败") return {"status": "error", "message": result.error_message or "渲染失败"} output_path = result.output_path or Path("") @@ -437,9 +435,7 @@ def render_edit_plan(self, plan_id: str) -> dict: current_task = gen_task_repo.get(generation_task_id) if current_task: task_status = ( - current_task.status.value - if hasattr(current_task.status, "value") - else str(current_task.status) + current_task.status.value if hasattr(current_task.status, "value") else str(current_task.status) ) if task_status == "cancelled": logger.info("任务已被取消,中止渲染: plan_id=%s task_id=%s", plan_id, generation_task_id) diff --git a/tests/unit/test_render_adapter.py b/tests/unit/test_render_adapter.py index e46829ef8..e8dfd8d9d 100755 --- a/tests/unit/test_render_adapter.py +++ b/tests/unit/test_render_adapter.py @@ -493,18 +493,22 @@ class TestPrepareBgm: def test_bgm_from_url(self, tmp_path): """从 URL 下载 BGM。""" - plan = FakePlan(config={ - "bgm": { - "enabled": True, - "audio_url": "https://example.com/bgm.mp3", + plan = FakePlan( + config={ + "bgm": { + "enabled": True, + "audio_url": "https://example.com/bgm.mp3", + } } - }) + ) adapter = RenderAdapter(MagicMock()) with patch("video_processing.url_security.safe_download_file") as mock_download: + def _fake_download(url, path, **kwargs): Path(path).parent.mkdir(parents=True, exist_ok=True) Path(path).write_bytes(b"fake mp3 data") + mock_download.side_effect = _fake_download result = adapter._prepare_bgm(plan, tmp_path, "plan_001") @@ -514,13 +518,15 @@ class TestPrepareBgm: def test_bgm_from_url_failure_falls_through(self, tmp_path): """URL 下载失败时不抛异常,继续尝试其他来源。""" - plan = FakePlan(config={ - "bgm": { - "enabled": True, - "audio_url": "https://example.com/bgm.mp3", - "preset_id": "preset_001", + plan = FakePlan( + config={ + "bgm": { + "enabled": True, + "audio_url": "https://example.com/bgm.mp3", + "preset_id": "preset_001", + } } - }) + ) adapter = RenderAdapter(MagicMock()) with patch("video_processing.url_security.safe_download_file") as mock_download: @@ -535,12 +541,14 @@ class TestPrepareBgm: def test_bgm_from_asset_library(self, tmp_path): """从素材库下载 BGM。""" - plan = FakePlan(config={ - "bgm": { - "enabled": True, - "asset_id": "asset_bgm_001", + plan = FakePlan( + config={ + "bgm": { + "enabled": True, + "asset_id": "asset_bgm_001", + } } - }) + ) mock_db = MagicMock() mock_asset = MagicMock() @@ -552,10 +560,12 @@ class TestPrepareBgm: adapter = RenderAdapter(mock_db) with patch("video_processing.render_adapter.download_asset") as mock_download: + def _fake_download(storage_key, local_path): Path(local_path).parent.mkdir(parents=True, exist_ok=True) Path(local_path).write_bytes(b"fake bgm") return True + mock_download.side_effect = _fake_download result = adapter._prepare_bgm(plan, tmp_path, "plan_001") @@ -565,21 +575,25 @@ class TestPrepareBgm: def test_bgm_from_preset_library(self, tmp_path): """从预设 BGM 库下载。""" - plan = FakePlan(config={ - "bgm": { - "enabled": True, - "preset_id": "preset_calm", + plan = FakePlan( + config={ + "bgm": { + "enabled": True, + "preset_id": "preset_calm", + } } - }) + ) adapter = RenderAdapter(MagicMock()) with patch("packages.domain.preset_bgm.get_preset_bgm") as mock_preset: mock_preset.return_value = MagicMock(audio_url="https://cdn.example.com/preset_calm.mp3") with patch("video_processing.url_security.safe_download_file") as mock_download: + def _fake_download(url, path, **kwargs): Path(path).parent.mkdir(parents=True, exist_ok=True) Path(path).write_bytes(b"preset bgm data") + mock_download.side_effect = _fake_download result = adapter._prepare_bgm(plan, tmp_path, "plan_001") @@ -589,19 +603,23 @@ class TestPrepareBgm: def test_bgm_url_takes_priority_over_asset(self, tmp_path): """URL 优先级高于素材库。""" - plan = FakePlan(config={ - "bgm": { - "enabled": True, - "audio_url": "https://example.com/bgm.mp3", - "asset_id": "asset_bgm_001", + plan = FakePlan( + config={ + "bgm": { + "enabled": True, + "audio_url": "https://example.com/bgm.mp3", + "asset_id": "asset_bgm_001", + } } - }) + ) adapter = RenderAdapter(MagicMock()) with patch("video_processing.url_security.safe_download_file") as mock_url_download: + def _fake_url_download(url, path, **kwargs): Path(path).parent.mkdir(parents=True, exist_ok=True) Path(path).write_bytes(b"url bgm") + mock_url_download.side_effect = _fake_url_download with patch("video_processing.render_adapter.download_asset") as mock_asset_download: