test(music-lab): compile_job 기반 happy path 통합 테스트
This commit is contained in:
@@ -111,3 +111,65 @@ def test_pipeline_reject_and_regenerate(client):
|
||||
assert p["feedback_count_per_step"]["cover"] == 1
|
||||
history = db.get_feedback_history(pid)
|
||||
assert history[0]["feedback_text"] == "더 어둡게"
|
||||
|
||||
|
||||
@patch("app.pipeline.youtube.upload_video", return_value={"video_id": "MIX_VID"})
|
||||
@patch("app.pipeline.review.run_4_axis", new=AsyncMock(return_value={
|
||||
"metadata_quality": {"score": 90, "notes": ""},
|
||||
"policy_compliance": {"score": 95, "issues": []},
|
||||
"viewer_experience": {"score": 85, "notes": ""},
|
||||
"trend_alignment": {"score": 70, "matched_keywords": []},
|
||||
"weighted_total": 87.0, "verdict": "pass", "summary": "ok",
|
||||
"used_fallback": False,
|
||||
}))
|
||||
@patch("app.pipeline.metadata.generate", new=AsyncMock(return_value={
|
||||
"title": "Mix", "description": "Track desc",
|
||||
"tags": ["lofi"], "category_id": 10,
|
||||
"used_fallback": False, "error": None,
|
||||
}))
|
||||
@patch("app.pipeline.thumb.generate", return_value={
|
||||
"url": "/media/videos/X/thumbnail.jpg", "used_fallback": False,
|
||||
})
|
||||
@patch("app.pipeline.video.generate", return_value={
|
||||
"url": "/media/videos/X/video.mp4", "used_fallback": False, "duration_sec": 600,
|
||||
})
|
||||
@patch("app.pipeline.cover.generate", new=AsyncMock(return_value={
|
||||
"url": "/media/videos/X/cover.jpg", "used_fallback": False, "error": None,
|
||||
}))
|
||||
def test_full_pipeline_compile_job_happy_path(mock_video, mock_thumb, mock_yt, client):
|
||||
# compile_job 1개 추가 (succeeded)
|
||||
conn = sqlite3.connect(db.DB_PATH)
|
||||
cur = conn.cursor()
|
||||
try:
|
||||
cur.execute("""
|
||||
INSERT INTO compile_jobs (title, track_ids, crossfade_sec, output_path,
|
||||
status, created_at)
|
||||
VALUES ('Test Mix', '[1]', 3, '/app/data/compiles/1.mp3', 'succeeded', datetime())
|
||||
""")
|
||||
except sqlite3.OperationalError:
|
||||
pytest.skip("compile_jobs schema mismatch — skip integration test")
|
||||
conn.commit()
|
||||
cid = cur.lastrowid
|
||||
conn.close()
|
||||
|
||||
pid = client.post("/api/music/pipeline", json={"compile_job_id": cid}).json()["id"]
|
||||
assert db.get_pipeline(pid)["state"] == "created"
|
||||
assert db.get_pipeline(pid)["compile_job_id"] == cid
|
||||
assert db.get_pipeline(pid)["track_id"] is None
|
||||
|
||||
client.post(f"/api/music/pipeline/{pid}/start")
|
||||
p = db.get_pipeline(pid)
|
||||
assert p["state"] == "cover_pending"
|
||||
|
||||
for step in ["cover", "video", "thumb", "meta"]:
|
||||
r = client.post(f"/api/music/pipeline/{pid}/feedback",
|
||||
json={"step": step, "intent": "approve"})
|
||||
assert r.status_code == 202
|
||||
|
||||
p = db.get_pipeline(pid)
|
||||
assert p["state"] == "publish_pending"
|
||||
|
||||
client.post(f"/api/music/pipeline/{pid}/publish")
|
||||
p = db.get_pipeline(pid)
|
||||
assert p["state"] == "published"
|
||||
assert p["youtube_video_id"] == "MIX_VID"
|
||||
|
||||
Reference in New Issue
Block a user