Add test suite for Lyria Studio backend
- conftest.py: isolated async test fixtures with temp DB and directories - test_waveform.py: waveform generation, downsampling, caching, SVG output - test_api.py: full API endpoint tests (health, models, clips CRUD, waveform endpoint, admin cache clearing) - test_analysis.py: BPM detection, key detection, clip analysis - test_models.py: request validation, model registry, prompt building - Fixed off-by-one in waveform.py downsampling (linspace upper bound) - All 40 tests passing
This commit is contained in:
1 parent
3500c73167
commit
6c1e1b4509
7 files changed
+742
-1
No files matched your search
@@ -0,0 +1,90 @@
|
||||
"""Tests for Pydantic models."""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "src"))
|
||||
|
||||
from models import GenerateRequest, GenerateResponse, ClipList, LYRIA_MODELS, DEFAULT_MODEL
|
||||
|
||||
|
||||
class TestGenerateRequest:
|
||||
"""Request validation and prompt building."""
|
||||
|
||||
def test_default_model_and_duration(self):
|
||||
req = GenerateRequest(prompt="gabber kick")
|
||||
assert req.model == DEFAULT_MODEL
|
||||
dur = req.get_effective_duration()
|
||||
assert dur == 30 # clip preview default
|
||||
|
||||
def test_pro_model_with_custom_duration(self):
|
||||
req = GenerateRequest(prompt="180 BPM hardcore", model="lyria-3-pro-preview", duration=120)
|
||||
assert req.model == "lyria-3-pro-preview"
|
||||
dur = req.get_effective_duration()
|
||||
assert dur == 120
|
||||
|
||||
def test_pro_model_duration_clamped_to_max(self):
|
||||
req = GenerateRequest(prompt="long track", model="lyria-3-pro-preview", duration=999)
|
||||
dur = req.get_effective_duration()
|
||||
assert dur == 184 # max for pro model
|
||||
|
||||
def test_clip_model_duration_clamped_to_max(self):
|
||||
req = GenerateRequest(prompt="short clip", model="lyria-3-clip-preview", duration=60)
|
||||
dur = req.get_effective_duration()
|
||||
assert dur == 30 # max for clip preview
|
||||
|
||||
def test_invalid_model_raises(self):
|
||||
with pytest.raises(ValueError, match="Unknown model"):
|
||||
GenerateRequest(prompt="test", model="nonexistent-model")
|
||||
|
||||
def test_simple_prompt(self):
|
||||
req = GenerateRequest(prompt="gabber at 200 BPM")
|
||||
assert req.build_prompt() == "gabber at 200 BPM"
|
||||
|
||||
def test_structured_prompt(self):
|
||||
req = GenerateRequest(
|
||||
prompt="ignored",
|
||||
prompt_structure={
|
||||
"style": "gabber",
|
||||
"tempo": "180 BPM",
|
||||
"mood": "aggressive",
|
||||
}
|
||||
)
|
||||
built = req.build_prompt()
|
||||
assert "**Style:** gabber" in built
|
||||
assert "**Tempo:** 180 BPM" in built
|
||||
assert "**Mood:** aggressive" in built
|
||||
|
||||
def test_model_whitespace_trimmed(self):
|
||||
req = GenerateRequest(prompt="test", model=" lyria-3-clip-preview ")
|
||||
assert req.model == "lyria-3-clip-preview"
|
||||
|
||||
|
||||
class TestModelConstants:
|
||||
"""Validate the model registry."""
|
||||
|
||||
def test_models_have_required_keys(self):
|
||||
for model_id, info in LYRIA_MODELS.items():
|
||||
assert "name" in info, f"{model_id} missing 'name'"
|
||||
assert "max_duration" in info, f"{model_id} missing 'max_duration'"
|
||||
assert "default_duration" in info, f"{model_id} missing 'default_duration'"
|
||||
assert "description" in info, f"{model_id} missing 'description'"
|
||||
|
||||
def test_default_model_exists_in_registry(self):
|
||||
assert DEFAULT_MODEL in LYRIA_MODELS
|
||||
|
||||
def test_max_duration_greater_than_default(self):
|
||||
for model_id, info in LYRIA_MODELS.items():
|
||||
assert info["max_duration"] >= info["default_duration"], \
|
||||
f"{model_id}: max_duration < default_duration"
|
||||
|
||||
|
||||
class TestGenerateResponse:
|
||||
"""Response model."""
|
||||
|
||||
def test_create_response(self):
|
||||
resp = GenerateResponse(id="test-123", status="generating", message="Clip generation started.")
|
||||
assert resp.id == "test-123"
|
||||
assert resp.status == "generating"
|
||||
Reference in new issue
Block a user