"""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"