Files
xiaoxia-saas/tests/integration/test_generation_pipeline.py
xiaoxia 53fb25efcf
CI/CD Pipeline / Dedup Check - skip PR tests when covered by push pipeline (push) Successful in 2s
CI/CD Pipeline / Check push changed paths (push) Successful in 19s
CI/CD Pipeline / Build Staging API Image (push) Successful in 41s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 48s
CI/CD Pipeline / Integration Tests (push) Successful in 3m10s
CI/CD Pipeline / Validate - Python (mypy + alembic) (push) Successful in 3m17s
CI/CD Pipeline / Build Staging Web Image (push) Successful in 3m30s
CI/CD Pipeline / Validate - Style (push) Successful in 4m17s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 59s
CI/CD Pipeline / Frontend Unit Tests (push) Failing after 5m33s
CI/CD Pipeline / Validate - Security (push) Successful in 7m12s
CI/CD Pipeline / ACR Image Cleanup (push) Successful in 2m38s
CI/CD Pipeline / Staging API Integration Tests (push) Successful in 3m13s
CI/CD Pipeline / Unit Tests (push) Successful in 10m11s
CI/CD Pipeline / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / Staging E2E Tests (push) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (push) Failing after 26h14m3s
CI/CD Pipeline / PR Build Worker Image (push) Failing after 26h24m21s
CI/CD Pipeline / Retag skipped Staging API Image (push) Failing after 26h19m47s
CI/CD Pipeline / PR Build Web Image (push) Failing after 26h23m44s
CI/CD Pipeline / PR Build API Image (push) Failing after 26h23m44s
CI/CD Pipeline / Deploy Production (push) Failing after 26h13m23s
CI/CD Pipeline / Build Production Web Image (push) Failing after 26h13m26s
CI/CD Pipeline / CI Gate (push) Failing after 26h13m25s
CI/CD Pipeline / Build Production API Image (push) Failing after 26h13m26s
CI/CD Pipeline / Canary Release to Production (push) Failing after 26h13m23s
CI/CD Pipeline / Retag skipped Staging Web Image (push) Failing after 26h19m46s
CI/CD Pipeline / Frontend Lint (push) Failing after 26h23m37s
CI/CD Pipeline / Check if frontend-only change (push) Failing after 26h23m45s
CI/CD Pipeline / Retag skipped Staging Worker Image (push) Failing after 26h19m46s
fix(#1834): 批量修复 UP 系列静态分析警告(UP007/UP006/UP017/UP035) (#1928)
Co-authored-by: xiaoxia <dev@xiaoxiajianji.com>
Co-committed-by: xiaoxia <dev@xiaoxiajianji.com>
2026-09-15 12:59:17 +08:00

174 lines
5.1 KiB
Python
Executable File

from datetime import UTC, datetime, timezone
from packages.application import (
CreateGenerationTaskCommand,
CreateGenerationTaskUseCase,
GetGeneratedVideoDownloadUrlUseCase,
)
from packages.domain import GeneratedVideo, GenerationTaskStatus
class DummyGenerationTaskRepository:
def __init__(self):
self.items = {}
def create(self, task):
self.items[task.id] = task
return task
def get(self, task_id):
return self.items.get(task_id)
def list_by_project(self, project_id):
return [task for task in self.items.values() if task.project_id == project_id]
def update(self, task):
self.items[task.id] = task
return task
class DummyGeneratedVideoRepository:
def __init__(self):
self.items = {}
def create(self, video):
self.items[video.id] = video
return video
def get(self, video_id):
return self.items.get(video_id)
def list_by_project(self, project_id):
return [video for video in self.items.values() if video.project_id == project_id]
def list_by_generation_task(self, generation_task_id):
return [video for video in self.items.values() if video.generation_task_id == generation_task_id]
def simulate_generate_video(
task_id: str,
task_repo: DummyGenerationTaskRepository,
video_repo: DummyGeneratedVideoRepository,
) -> dict:
task = task_repo.get(task_id)
if task is None:
return {"status": "failed", "error": "task not found"}
task.status = GenerationTaskStatus.RUNNING
task.progress = 20.0
task.started_at = task.started_at or datetime.now(UTC)
task_repo.update(task)
file_url = f"/projects/{task.project_id}/generated/{task.id}/{task.id}.mp4"
video = GeneratedVideo.create(
project_id=task.project_id,
generation_task_id=task.id,
name=f"{task.id}.mp4",
file_url=file_url,
file_size=2048,
duration=12.5,
width=1920,
height=1080,
fps=25.0,
)
video_repo.create(video)
task.status = GenerationTaskStatus.COMPLETED
task.progress = 100.0
task.result_count = 1
task.completed_at = datetime.now(UTC)
task_repo.update(task)
return {
"status": "completed",
"task_id": task.id,
"video_id": video.id,
"file_url": file_url,
}
def test_create_generation_task_smoke():
repo = DummyGenerationTaskRepository()
use_case = CreateGenerationTaskUseCase(repo)
task = use_case.execute(
CreateGenerationTaskCommand(
project_id="proj-1",
asset_library_id="lib-1",
strategy_id="str-1",
voice_library_id="voice-1",
created_by_user_id="user-1",
)
)
assert task.project_id == "proj-1"
assert task.asset_library_id == "lib-1"
assert task.status == GenerationTaskStatus.PENDING
assert repo.get(task.id) is not None
def test_generation_pipeline_smoke():
task_repo = DummyGenerationTaskRepository()
video_repo = DummyGeneratedVideoRepository()
use_case = CreateGenerationTaskUseCase(task_repo)
task = use_case.execute(
CreateGenerationTaskCommand(
project_id="proj-1",
asset_library_id="lib-1",
strategy_id="str-1",
voice_library_id="voice-1",
created_by_user_id="user-1",
)
)
result = simulate_generate_video(task.id, task_repo, video_repo)
assert result["status"] == "completed"
assert "/projects/proj-1/generated/" in result["file_url"]
updated_task = task_repo.get(task.id)
assert updated_task is not None
assert updated_task.status == GenerationTaskStatus.COMPLETED
assert updated_task.result_count == 1
videos = video_repo.list_by_generation_task(task.id)
assert len(videos) == 1
assert videos[0].project_id == "proj-1"
assert videos[0].generation_task_id == task.id
def test_get_generated_video_download_url():
video_repo = DummyGeneratedVideoRepository()
video = GeneratedVideo.create(
project_id="proj-1",
generation_task_id="task-1",
name="task-1.mp4",
file_url="https://example.invalid/generated/task-1.mp4",
file_size=2048,
duration=12.5,
width=1920,
height=1080,
fps=25.0,
)
video_repo.create(video)
use_case = GetGeneratedVideoDownloadUrlUseCase(video_repo)
assert use_case.execute(video.id) == "https://example.invalid/generated/task-1.mp4"
assert use_case.execute("missing") is None
def test_generated_video_download_source_url_is_stable():
video_repo = DummyGeneratedVideoRepository()
video = GeneratedVideo.create(
project_id="proj-1",
generation_task_id="task-2",
name="task-2.mp4",
file_url="http://localhost:9000/xiaoxia-assets/generated/task-2.mp4",
file_size=1024,
duration=8.0,
width=1280,
height=720,
fps=25.0,
)
video_repo.create(video)
use_case = GetGeneratedVideoDownloadUrlUseCase(video_repo)
assert use_case.execute(video.id).endswith("/generated/task-2.mp4")