feat(music-lab): metadata tracks 옵션 + YouTube 챕터 자동 형식
This commit is contained in:
@@ -80,3 +80,75 @@ async def test_metadata_falls_back_on_api_error(monkeypatch):
|
||||
)
|
||||
assert result["used_fallback"] is True
|
||||
assert "Drive" in result["title"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@respx.mock
|
||||
async def test_metadata_with_tracks_includes_chapter_format(monkeypatch):
|
||||
monkeypatch.setenv("ANTHROPIC_API_KEY", "k")
|
||||
captured = {}
|
||||
|
||||
def hook(req):
|
||||
import json as _json
|
||||
captured["body"] = _json.loads(req.content)
|
||||
return Response(200, json={"content": [{"type": "text", "text":
|
||||
'{"title":"Lo-Fi Mix 3 Tracks","description":"Track 1: [00:00] T1\\nTrack 2: [03:00] T2",'
|
||||
'"tags":["lofi","mix"],"category_id":10}'}]})
|
||||
|
||||
respx.post("https://api.anthropic.com/v1/messages").mock(side_effect=hook)
|
||||
result = await metadata.generate(
|
||||
track={"title": "Mix", "genre": "mix", "duration_sec": 600,
|
||||
"moods": []},
|
||||
template={"title": "{title}", "description": "{title}",
|
||||
"tags": [], "category_id": 10},
|
||||
trend_keywords=[],
|
||||
tracks=[
|
||||
{"id": 1, "title": "T1", "start_offset_sec": 0, "duration_sec": 180},
|
||||
{"id": 2, "title": "T2", "start_offset_sec": 180, "duration_sec": 200},
|
||||
{"id": 3, "title": "T3", "start_offset_sec": 380, "duration_sec": 220},
|
||||
],
|
||||
)
|
||||
body_str = str(captured["body"])
|
||||
assert "T1" in body_str and "T2" in body_str and "T3" in body_str
|
||||
assert "00:00" in body_str
|
||||
assert result["used_fallback"] is False
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_metadata_fallback_with_tracks(monkeypatch):
|
||||
"""API 키 없을 때 폴백에서도 트랙 챕터 포함."""
|
||||
monkeypatch.delenv("ANTHROPIC_API_KEY", raising=False)
|
||||
result = await metadata.generate(
|
||||
track={"title": "Mix", "genre": "mix", "duration_sec": 600, "moods": []},
|
||||
template={"title": "{title}", "description": "{title}",
|
||||
"tags": [], "category_id": 10},
|
||||
trend_keywords=[],
|
||||
tracks=[
|
||||
{"id": 1, "title": "T1", "start_offset_sec": 0, "duration_sec": 180},
|
||||
{"id": 2, "title": "T2", "start_offset_sec": 180, "duration_sec": 200},
|
||||
],
|
||||
)
|
||||
assert result["used_fallback"] is True
|
||||
assert "00:00" in result["description"]
|
||||
assert "T1" in result["description"]
|
||||
assert "T2" in result["description"]
|
||||
|
||||
|
||||
def test_format_chapters_under_hour():
|
||||
from app.pipeline.metadata import _format_chapters
|
||||
out = _format_chapters([
|
||||
{"start_offset_sec": 0, "title": "T1"},
|
||||
{"start_offset_sec": 180, "title": "T2"},
|
||||
])
|
||||
assert "00:00 T1" in out
|
||||
assert "03:00 T2" in out
|
||||
|
||||
|
||||
def test_format_chapters_over_hour():
|
||||
from app.pipeline.metadata import _format_chapters
|
||||
out = _format_chapters([
|
||||
{"start_offset_sec": 0, "title": "T1"},
|
||||
{"start_offset_sec": 3700, "title": "T2"},
|
||||
])
|
||||
assert "00:00 T1" in out
|
||||
assert "01:01:40 T2" in out
|
||||
|
||||
Reference in New Issue
Block a user