fix(music-lab): cache-buster query 제거 + DALL·E prompt에 background_keyword 활용

1. video.py _container_to_nas, orchestrator.py _local_path에서 path 변환 전 ?쿼리 strip
   — 이전 commit 20c5268의 cache-buster ?v=...가 Windows path로 그대로 전달되어 input_validation 실패하던 문제 픽스
2. cover.py _generate_with_dalle가 background_keyword를 prompt에 포함
   — 사용자가 PipelineStartModal에서 '배경 키워드' 입력 시 처음부터 원하는 분위기 cover 생성
This commit is contained in:
2026-05-10 16:12:21 +09:00
parent 20c5268def
commit 755dea63f4
6 changed files with 52 additions and 2 deletions

View File

@@ -147,3 +147,30 @@ async def test_pexels_zero_results_falls_back(tmp_storage, monkeypatch):
image_source="pexels",
)
assert out["used_fallback"] is True
@pytest.mark.asyncio
@respx.mock
async def test_dalle_uses_background_keyword(tmp_storage, monkeypatch):
monkeypatch.setenv("OPENAI_API_KEY", "test-key")
captured = {}
def hook(req):
import json as _json
captured["body"] = _json.loads(req.content)
return Response(200, json={"data": [{"url": "https://x"}]})
respx.post("https://api.openai.com/v1/images/generations").mock(side_effect=hook)
png_bytes = bytes.fromhex(
"89504e470d0a1a0a0000000d49484452000000010000000108020000009077"
"53de0000000c4944415478da6300010000050001"
"0d0a2db40000000049454e44ae426082"
)
respx.get("https://x").mock(return_value=Response(200, content=png_bytes))
await cover.generate(
pipeline_id=80, genre="lo-fi",
prompt_template="moody anime",
mood="chill", track_title="X",
image_source="ai",
background_keyword="skateboard park bright atmosphere",
)
assert "skateboard" in captured["body"]["prompt"]
assert "bright" in captured["body"]["prompt"]

View File

@@ -75,3 +75,9 @@ def test_resolve_input_compile_job_done_status():
result = _resolve_input(pipeline)
assert result["audio_path"] == "/app/data/compiles/7.mp3"
assert result["title"] == "Done Mix"
def test_local_path_strips_cache_buster():
from app.pipeline.orchestrator import _local_path
# /media/videos/3/cover.jpg?v=... → /app/data/videos/3/cover.jpg
assert _local_path("/media/videos/3/cover.jpg?v=20260510065642") == "/app/data/videos/3/cover.jpg"

View File

@@ -132,6 +132,13 @@ def test_container_to_nas_music_path(monkeypatch):
assert video._container_to_nas("/app/data/abc.mp3") == "/volume1/docker/webpage/data/music/abc.mp3"
def test_container_to_nas_strips_cache_buster(monkeypatch):
monkeypatch.setattr(video, "NAS_VIDEOS_ROOT", "/volume1/docker/webpage/data/videos")
monkeypatch.setattr(video, "NAS_MUSIC_ROOT", "/volume1/docker/webpage/data/music")
# cache-busted path → strip ?v=... before NAS conversion
assert video._container_to_nas("/app/data/videos/3/cover.jpg?v=20260510065642") == "/volume1/docker/webpage/data/videos/3/cover.jpg"
@respx.mock
def test_generate_video_passes_essential_params(encoder_env, tmp_path, monkeypatch):
monkeypatch.setattr(storage, "VIDEO_DATA_DIR", str(tmp_path))