test(music-lab): compile_job 기반 happy path 통합 테스트

This commit is contained in:
2026-05-09 13:27:47 +09:00
parent 5fc914cd8f
commit 262366bc1e

View File

@@ -111,3 +111,65 @@ def test_pipeline_reject_and_regenerate(client):
assert p["feedback_count_per_step"]["cover"] == 1 assert p["feedback_count_per_step"]["cover"] == 1
history = db.get_feedback_history(pid) history = db.get_feedback_history(pid)
assert history[0]["feedback_text"] == "더 어둡게" 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"