Files
xiaoxia-saas/tests/unit/test_batch_clips_endpoint.py
T
CI Bot 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
refactor(worker): generate_video直接读取edit_plan_clips渲染,删除内存重建逻辑
核心改造:
- 有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
2026-08-23 15:14:01 +08:00

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