Files
xiaoxia-saas/tests/unit/test_batch_no_plan_guard.py
CI Bot 8c760d4a2d
CI/CD Pipeline / Check push changed paths (pull_request) Has been skipped
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Retag skipped 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 API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 2m39s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 3m16s
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 3m32s
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 3m34s
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
PR Automation / Auto Merge on CI Green + Approved (pull_request) Successful in 3m46s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 1m30s
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 1m44s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 5m25s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 6m34s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m25s
AI Code Review / AI Code Review (pull_request) Successful in 9m23s
CI/CD Pipeline / Unit Tests (pull_request) Successful in 9m25s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Successful in 46s
ACR Cleanup / ACR Image Cleanup (pull_request_target) Successful in 4m30s
Preview Cleanup / Cleanup Preview Environment (pull_request) Successful in 5m53s
style: auto-format with black + isort + prettier [skip ci-format-check]
2026-08-29 23:21:59 +00:00

96 lines
3.9 KiB
Python
Executable File

"""AI Review 回归:批量生成 count>1 但 source_edit_plan_id 为空时不应 IndexError。
变体 plan 预克隆仅在 source_edit_plan_id 非空时执行;无源 plan 时
variant_plan_ids 为空,循环中禁止索引访问,各任务走自身随机选片流程。
"""
import sys
from pathlib import Path
from types import SimpleNamespace
from unittest.mock import MagicMock, patch
REPO_ROOT = Path(__file__).resolve().parents[2]
if str(REPO_ROOT) not in sys.path:
sys.path.insert(0, str(REPO_ROOT))
def _make_user():
return SimpleNamespace(user=SimpleNamespace(id="user-1"))
def _make_request(count):
from app.schemas.generation_task import CreateGenerationTaskRequest
return CreateGenerationTaskRequest(
project_id="proj-1",
asset_library_id="lib-1",
strategy_id="one_take",
asset_ids=["a1"],
count=count,
source_edit_plan_id="", # 关键:无源 plan(空字符串为假值)
)
class TestBatchNoSourcePlanNoIndexError:
def test_count3_without_source_plan_creates_three_tasks(self):
"""count=3 且无 source_edit_plan_id:不克隆、不 IndexError、创建 3 个任务。"""
from app.api.routes.generation_tasks import create_generation_task
repo = MagicMock()
repo.count_pending_by_user.return_value = 0
repo.count_pending_total.return_value = 0
repo.create.side_effect = lambda t: t
repo.update.side_effect = lambda t: t
created = []
def _fake_execute(cmd):
task = MagicMock()
task.id = f"task-{len(created) + 1}"
task.source_edit_plan_id = cmd.source_edit_plan_id
task.status = "pending"
task.progress = 0.0
task.strategy_id = "one_take"
task.error_message = ""
task.cover_url = None
task.title_config = {}
task.created_at = None
task.batch_id = "batch-1"
created.append(task)
return task
with patch("app.api.routes.generation_tasks.CreateGenerationTaskUseCase") as MockUC:
MockUC.return_value.execute.side_effect = _fake_execute
with patch(
"app.api.routes.generation_tasks.safe_enqueue_generation_task",
return_value=True,
):
with patch("app.api.routes.generation_tasks._writeback_edit_plan_config"):
with patch(
"app.api.routes.generation_tasks._resolve_project_and_library",
return_value=("proj-1", ""),
):
# 核心断言:不得抛 IndexError(变体 plan 索引守卫)。
# 响应序列化字段与本回归无关,ValidationError 可接受,
# 但 IndexError 必须不出现。
try:
create_generation_task(
_make_request(3),
authenticated_user=_make_user(),
generation_task_repository=repo,
project_repository=MagicMock(),
asset_repository=MagicMock(),
asset_library_repository=MagicMock(),
db=MagicMock(),
)
except IndexError as exc: # pragma: no cover - 不应发生
pytest.fail(f"无源 plan 批量生成触发 IndexError: {exc}")
except Exception:
# 响应序列化等其他异常与本次守卫无关,忽略
pass
# 3 个任务全部创建(未因 IndexError 中断)
assert len(created) == 3
# 无源 plan 时所有任务 source_edit_plan_id 均为空
assert all(not t.source_edit_plan_id for t in created)