0cb67afd61
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 40s
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 1m34s
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 1m46s
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 1m54s
AI Code Review / AI Code Review (pull_request) Failing after 2m10s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m16s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 31s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 1m46s
CI/CD Pipeline / Validate - Code Quality (pull_request) Has been cancelled
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
PR Automation / Auto Approve on CI Green (pull_request) Has been cancelled
核心改造:
- 有source_edit_plan_id时,Worker直接调用RenderAdapter.render_plan(plan_id)
从数据库加载edit_plan+clips渲染,不再_download_all_assets+_build_plan_and_clips
- 新增_sync_task_config_to_plan:将title_config/bgm_config/分辨率同步到plan.config,
配音下载后通过voiceover_audio_path传给RenderAdapter
- 无source_edit_plan_id时保留旧路径(标记DEPRECATED)
- RenderAdapter.render_plan新增voiceover_audio_path参数透传给_do_render
新增API:
- PUT /templates/{id}/editor/clips 批量替换clips(delete_all+create+mark_ready)
- EditorClipBatchItem/EditorClipBatchUpdateRequest/EditorClipBatchUpdateResponse schema
删除死代码:
- worker_app/tasks/edit_plan_generation.py(worker.render_edit_plan,452行)
- worker_app/tasks/compose_video.py(worker.compose_video,198行)
- celery_app.py imports清理、tasks/__init__.py清理
- test_edit_plan_worker_failure.py、test_cover_url_finalize.py(测试已删除模块)
- templates_editor/generation.py的send_task改为worker.generate_video
新增3个单测,全量13790 passed
101 lines
3.3 KiB
Python
Executable File
101 lines
3.3 KiB
Python
Executable File
"""Tests for PUT /templates/{id}/editor/clips batch update endpoint."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
os.environ.setdefault("JWT_SECRET_KEY", "unit-test-secret-key-for-testing")
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_services():
|
|
plan_svc = MagicMock()
|
|
tpl_svc = MagicMock()
|
|
plan_svc.get_plan_or_raise.return_value = MagicMock(id="plan-1", template_id="tpl-1")
|
|
plan_svc.delete_all_clips.return_value = 3
|
|
plan_svc.mark_clips_ready.return_value = 2
|
|
return tpl_svc, plan_svc
|
|
|
|
|
|
class TestBatchUpdateClips:
|
|
def test_batch_update_creates_clips_in_order(self, mock_services):
|
|
from app.api.routes.templates_editor.draft import batch_update_clips
|
|
from app.api.routes.templates_editor.schemas import (
|
|
EditorClipBatchItem,
|
|
EditorClipBatchUpdateRequest,
|
|
)
|
|
|
|
_, plan_svc = mock_services
|
|
req = EditorClipBatchUpdateRequest(
|
|
clips=[
|
|
EditorClipBatchItem(asset_id="a1", start_time=0.0, duration=3.0, order=0),
|
|
EditorClipBatchItem(asset_id="a2", start_time=3.0, duration=5.0, order=1),
|
|
]
|
|
)
|
|
|
|
result = batch_update_clips(
|
|
template_id="tpl-1",
|
|
req=req,
|
|
plan_id="plan-1",
|
|
services=mock_services,
|
|
_=MagicMock(),
|
|
)
|
|
|
|
assert result.plan_id == "plan-1"
|
|
assert result.clip_count == 2
|
|
plan_svc.delete_all_clips.assert_called_once_with("plan-1")
|
|
assert plan_svc.create_clip.call_count == 2
|
|
plan_svc.mark_clips_ready.assert_called_once_with("plan-1")
|
|
|
|
def test_batch_update_empty_clips(self, mock_services):
|
|
from app.api.routes.templates_editor.draft import batch_update_clips
|
|
from app.api.routes.templates_editor.schemas import EditorClipBatchUpdateRequest
|
|
|
|
_, plan_svc = mock_services
|
|
req = EditorClipBatchUpdateRequest(clips=[])
|
|
|
|
result = batch_update_clips(
|
|
template_id="tpl-1",
|
|
req=req,
|
|
plan_id="plan-1",
|
|
services=mock_services,
|
|
_=MagicMock(),
|
|
)
|
|
|
|
assert result.clip_count == 0
|
|
plan_svc.delete_all_clips.assert_called_once()
|
|
plan_svc.create_clip.assert_not_called()
|
|
plan_svc.mark_clips_ready.assert_called_once()
|
|
|
|
def test_batch_update_clip_uses_order_field(self, mock_services):
|
|
from app.api.routes.templates_editor.draft import batch_update_clips
|
|
from app.api.routes.templates_editor.schemas import (
|
|
EditorClipBatchItem,
|
|
EditorClipBatchUpdateRequest,
|
|
)
|
|
|
|
_, plan_svc = mock_services
|
|
req = EditorClipBatchUpdateRequest(
|
|
clips=[
|
|
EditorClipBatchItem(asset_id="a1", start_time=0.0, duration=3.0, order=5),
|
|
]
|
|
)
|
|
|
|
batch_update_clips(
|
|
template_id="tpl-1",
|
|
req=req,
|
|
plan_id="plan-1",
|
|
services=mock_services,
|
|
_=MagicMock(),
|
|
)
|
|
|
|
call_kwargs = plan_svc.create_clip.call_args.kwargs
|
|
assert call_kwargs["order"] == 5
|
|
assert call_kwargs["asset_id"] == "a1"
|
|
assert call_kwargs["clip_type"] == "main"
|
|
assert call_kwargs["start_time"] == 0.0
|
|
assert call_kwargs["duration"] == 3.0
|