fix: 清单4 未完成项二轮(视频项目收口/选用角色/场景空镜/场景刷新 + 4:5 尺寸)
ZWQ#15 视频进度卡 3/4(真因补全): - current_stage 没推到 VIDEO 时 settle 守卫直接返回 → 永不收口。 submit/poll/adopt 幂等补推 current_stage→VIDEO;进详情(retrieve)检测全段已出片即自愈收口。 存量卡死项目一打开就自动变「已完成」。+2 测试 ZWQ#7 演员库选用角色未自动「已过审/已采用」: - 真实流程是 attach(选用),非详情弹窗按钮。attach 时显式置 adopt=adopted + 人物立绘自动送审(on_commit)。+1 测试 ZWQ#13 场景出真人致视频被拒(加强): - 场景空镜约束改为显式压过脚本描述里的人物词(「即使上文提到人也只画环境」)。 ZWQ#17 场景生成中刷新跳新窗口: - 正在生成的场景草稿不再落盘 → 生成中刷新页面不会与新实体卡并存成两个窗口。 附:平台套图 4:5 尺寸 1664x2080→1728x2160(≥Seedream 5.0 最小面积 3686400px,否则 ARK 退 400)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -648,6 +648,30 @@ class ProjectApiTests(TestCase):
|
||||
self.assertEqual(project.current_stage, ProjectStage.Stage.VIDEO)
|
||||
self.assertEqual(project.status, Project.Status.COMPLETED)
|
||||
|
||||
def test_retrieve_recovers_stuck_project_to_completed(self):
|
||||
"""ZWQ#15(存量项目):已经卡在 storyboard 阶段、视频段都出片采用的历史项目,
|
||||
进入详情(GET)时应自动补推阶段并收口成 completed,不必用户再做任何操作。"""
|
||||
project = Project.objects.create(
|
||||
team=self.team, created_by=self.user, product=self.product, name="P",
|
||||
current_stage=ProjectStage.Stage.STORYBOARD, status=Project.Status.STORYBOARDING,
|
||||
)
|
||||
for i in range(2):
|
||||
seg = VideoSegment.objects.create(project=project, sort_order=i, target_duration_seconds=15)
|
||||
asset = Asset.objects.create(
|
||||
team=self.team, created_by=self.user, name=f"clip{i}",
|
||||
asset_type=Asset.Type.VIDEO, source=Asset.Source.AI_GENERATED, category=Asset.Category.VIDEO_CLIP,
|
||||
)
|
||||
ver = VideoSegmentVersion.objects.create(video_segment=seg, asset=asset, is_adopted=True)
|
||||
seg.adopted_version = ver
|
||||
seg.status = VideoSegment.Status.SUCCEEDED
|
||||
seg.save(update_fields=["adopted_version", "status"])
|
||||
|
||||
res = self.client.get(f"/api/projects/{project.id}/")
|
||||
self.assertEqual(res.status_code, 200)
|
||||
project.refresh_from_db()
|
||||
self.assertEqual(project.current_stage, ProjectStage.Stage.VIDEO)
|
||||
self.assertEqual(project.status, Project.Status.COMPLETED)
|
||||
|
||||
def _make_audio_model(self):
|
||||
return ModelConfig.objects.create(
|
||||
provider=self.provider, name="doubao-voice-bigtts", display_name="豆包语音合成",
|
||||
@@ -975,3 +999,31 @@ class AttachOfficialModelTests(TestCase):
|
||||
)
|
||||
self.assertEqual(res.status_code, 404)
|
||||
self.assertEqual(self.BaseAssetGroup.objects.filter(project=self.proj).count(), before)
|
||||
|
||||
def test_attach_own_actor_auto_adopts_and_submits_review(self):
|
||||
"""ZWQ#7:在演员库选用「自己创建的角色」(本团队 person 资产)后,组应自动标 adopt=adopted(已采用),
|
||||
且自动送审(已过审),不必用户再手动点采用 / 灰盾。"""
|
||||
from unittest.mock import patch
|
||||
|
||||
from apps.assets.models import Asset, AssetFile
|
||||
|
||||
mine = Asset.objects.create(
|
||||
team=self.team, created_by=self.user, name="我的主播",
|
||||
asset_type=Asset.Type.IMAGE, source=Asset.Source.AI_GENERATED, category=Asset.Category.PERSON,
|
||||
)
|
||||
AssetFile.objects.create(asset=mine, object_key="me/host.png", bucket="b", content_type="image/png", preview_url="http://x/host.png", is_primary=True)
|
||||
group = self.BaseAssetGroup.objects.create(project=self.proj, kind=self.BaseAssetGroup.Kind.PERSON, metadata={"label": "主播"})
|
||||
|
||||
with patch("apps.assets.review.submit_asset_for_review") as sub:
|
||||
with self.captureOnCommitCallbacks(execute=True):
|
||||
res = self.client.post(
|
||||
f"/api/projects/{self.proj.id}/attach-base-asset/",
|
||||
{"group_id": str(group.id), "asset_id": str(mine.id)},
|
||||
format="json",
|
||||
)
|
||||
self.assertEqual(res.status_code, 200, res.content)
|
||||
group.refresh_from_db()
|
||||
self.assertEqual(group.adopted_asset_id, mine.id)
|
||||
self.assertEqual((group.metadata or {}).get("adopt"), "adopted") # 自动采用
|
||||
sub.assert_called_once() # 自动送审(on_commit 在 TestCase 事务提交点触发)
|
||||
self.assertEqual(sub.call_args.args[0].id, mine.id)
|
||||
|
||||
Reference in New Issue
Block a user