Files
Momento/.agent/skills/suno-band-profile-manager/scripts/tests/test-validate-profile.py
Antigravity bd495be965
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 12s
feat: design system overhaul — sidebar, AI chats, settings, brainstorm, color cleanup
- Sidebar: dynamic brand-accent colors, brainstorm section restyled
- AI chat general: popup panel with expand/collapse, hides when contextual AI open
- AI chat contextual: tabs reordered (Actions first), X close button, height fix
- Settings: all tabs restyled, 6 new color presets (sage, terracotta, iron, etc.)
- Global color cleanup: emerald/orange hardcoded → brand-accent dynamic
- Brainstorm page: orange → brand-accent throughout
- PageEntry animation component added to key pages
- Floating AI button: bg-brand-accent instead of hardcoded black
- i18n: all 15 locales updated with new AI/billing keys
- Billing: freemium quota tracking, BYOK, stripe subscription scaffolding
- Admin: integrated into new design
- AGENTS.md + CLAUDE.md project rules added
2026-05-16 12:59:30 +00:00

315 lines
10 KiB
Python

#!/usr/bin/env python3
# /// script
# requires-python = ">=3.10"
# dependencies = ["pytest>=7.0", "pyyaml>=6.0"]
# ///
"""Tests for validate-profile.py"""
import json
import sys
import tempfile
from pathlib import Path
import pytest
import yaml
# Add parent directory to path for import
sys.path.insert(0, str(Path(__file__).parent.parent))
from importlib.util import spec_from_file_location, module_from_spec
# Import the module
spec = spec_from_file_location(
"validate_profile",
Path(__file__).parent.parent / "validate-profile.py"
)
validate_profile_mod = module_from_spec(spec)
spec.loader.exec_module(validate_profile_mod)
validate_profile = validate_profile_mod.validate_profile
derive_filename = validate_profile_mod.derive_filename
def write_profile(tmp_path, data):
"""Helper to write a YAML profile and return its path."""
profile_path = tmp_path / "test-band.yaml"
with open(profile_path, "w") as f:
yaml.dump(data, f)
return profile_path
VALID_PROFILE = {
"name": "Test Band",
"genre": "indie rock",
"mood": "melancholic",
"model_preference": "v4.5-all",
"tier": "free",
"style_baseline": "Indie rock with warm guitars and atmospheric pads",
"vocal": {
"gender": "male",
"tone": "warm, breathy",
"delivery": "intimate",
"energy": "restrained",
},
}
VALID_INSTRUMENTAL_PROFILE = {
"name": "Ambient Waves",
"genre": "ambient electronic",
"mood": "contemplative, spacious",
"model_preference": "v4.5-all",
"tier": "free",
"style_baseline": "Ambient electronic with lush pads and field recordings",
"instrumental": True,
}
def test_valid_profile(tmp_path):
path = write_profile(tmp_path, VALID_PROFILE)
result = validate_profile(path)
assert result["status"] == "pass"
assert result["summary"]["total"] == 0
def test_missing_file(tmp_path):
path = tmp_path / "nonexistent.yaml"
result = validate_profile(path)
assert result["status"] == "fail"
assert result["summary"]["critical"] == 1
def test_invalid_yaml(tmp_path):
path = tmp_path / "bad.yaml"
path.write_text(": invalid: yaml: {{{{")
result = validate_profile(path)
assert result["status"] == "fail"
assert result["summary"]["critical"] >= 1
def test_missing_required_fields(tmp_path):
path = write_profile(tmp_path, {"name": "Test"})
result = validate_profile(path)
assert result["status"] == "fail"
assert result["summary"]["critical"] >= 1
def test_invalid_model(tmp_path):
data = {**VALID_PROFILE, "model_preference": "v99 Ultra"}
path = write_profile(tmp_path, data)
result = validate_profile(path)
assert any(f.get("location", {}).get("field") == "model_preference"
for f in result["findings"])
def test_invalid_tier(tmp_path):
data = {**VALID_PROFILE, "tier": "ultimate"}
path = write_profile(tmp_path, data)
result = validate_profile(path)
assert any("tier" in str(f) for f in result["findings"])
def test_style_baseline_too_long(tmp_path):
data = {**VALID_PROFILE, "style_baseline": "x" * 1001}
path = write_profile(tmp_path, data)
result = validate_profile(path)
assert any("style_baseline" in str(f) for f in result["findings"])
def test_style_baseline_v4_pro_200_limit(tmp_path):
data = {**VALID_PROFILE, "model_preference": "v4 Pro", "tier": "pro",
"style_baseline": "x" * 201}
path = write_profile(tmp_path, data)
result = validate_profile(path)
assert any("style_baseline" in str(f) and "200" in str(f)
for f in result["findings"])
def test_free_tier_wrong_model(tmp_path):
data = {**VALID_PROFILE, "tier": "free", "model_preference": "v5 Pro"}
path = write_profile(tmp_path, data)
result = validate_profile(path)
assert any("free" in f.get("issue", "").lower() or "free" in f.get("fix", "").lower()
for f in result["findings"])
def test_free_tier_slider_warning(tmp_path):
data = {**VALID_PROFILE, "sliders": {"weirdness": 80, "style_influence": 30}}
path = write_profile(tmp_path, data)
result = validate_profile(path)
assert any("slider" in f.get("issue", "").lower() for f in result["findings"])
def test_slider_out_of_range(tmp_path):
data = {**VALID_PROFILE, "tier": "pro", "model_preference": "v5 Pro",
"sliders": {"weirdness": 150}}
path = write_profile(tmp_path, data)
result = validate_profile(path)
assert any("out of range" in f.get("issue", "").lower() for f in result["findings"])
def test_audio_influence_slider_validation(tmp_path):
data = {**VALID_PROFILE, "tier": "pro", "model_preference": "v5 Pro",
"sliders": {"audio_influence": 200}}
path = write_profile(tmp_path, data)
result = validate_profile(path)
assert any("audio_influence" in str(f) and "out of range" in f.get("issue", "").lower()
for f in result["findings"])
def test_invalid_vocal_gender(tmp_path):
data = {**VALID_PROFILE}
data["vocal"] = {**VALID_PROFILE["vocal"], "gender": "robot"}
path = write_profile(tmp_path, data)
result = validate_profile(path)
assert any("gender" in str(f) for f in result["findings"])
def test_missing_vocal_fields(tmp_path):
data = {**VALID_PROFILE, "vocal": {"gender": "male"}}
path = write_profile(tmp_path, data)
result = validate_profile(path)
assert result["summary"]["high"] >= 1
def test_too_many_exclusions(tmp_path):
data = {**VALID_PROFILE, "exclusion_defaults": [f"no thing {i}" for i in range(7)]}
path = write_profile(tmp_path, data)
result = validate_profile(path)
assert any("exclusion" in f.get("issue", "").lower() for f in result["findings"])
def test_pro_tier_valid_with_sliders(tmp_path):
data = {
**VALID_PROFILE,
"tier": "pro",
"model_preference": "v5 Pro",
"sliders": {"weirdness": 70, "style_influence": 40},
}
path = write_profile(tmp_path, data)
result = validate_profile(path)
assert result["status"] == "pass"
# --- Instrumental profile tests ---
def test_instrumental_profile_valid_without_vocal(tmp_path):
path = write_profile(tmp_path, VALID_INSTRUMENTAL_PROFILE)
result = validate_profile(path)
assert result["status"] == "pass"
assert result["summary"]["total"] == 0
def test_instrumental_profile_with_optional_vocal(tmp_path):
data = {**VALID_INSTRUMENTAL_PROFILE, "vocal": {"gender": "any"}}
path = write_profile(tmp_path, data)
result = validate_profile(path)
assert result["status"] == "pass"
def test_non_instrumental_requires_vocal(tmp_path):
data = {**VALID_PROFILE}
del data["vocal"]
path = write_profile(tmp_path, data)
result = validate_profile(path)
assert result["status"] == "fail"
assert result["summary"]["high"] >= 1
# --- New field tests ---
def test_valid_creativity_default(tmp_path):
for mode in ["conservative", "balanced", "experimental"]:
data = {**VALID_PROFILE, "creativity_default": mode}
path = write_profile(tmp_path, data)
result = validate_profile(path)
assert not any(f.get("location", {}).get("field") == "creativity_default"
for f in result["findings"]), f"Failed for {mode}"
def test_invalid_creativity_default(tmp_path):
data = {**VALID_PROFILE, "creativity_default": "wild"}
path = write_profile(tmp_path, data)
result = validate_profile(path)
assert any("creativity_default" in str(f) for f in result["findings"])
def test_valid_language(tmp_path):
data = {**VALID_PROFILE, "language": "Spanish"}
path = write_profile(tmp_path, data)
result = validate_profile(path)
assert not any(f.get("location", {}).get("field") == "language"
for f in result["findings"])
def test_empty_language(tmp_path):
data = {**VALID_PROFILE, "language": ""}
path = write_profile(tmp_path, data)
result = validate_profile(path)
assert any("language" in str(f) for f in result["findings"])
def test_generation_history_valid(tmp_path):
data = {**VALID_PROFILE, "generation_history": [
{"date": "2026-03-19", "style_prompt": "test", "model": "v4.5-all"}
]}
path = write_profile(tmp_path, data)
result = validate_profile(path)
assert not any(f.get("location", {}).get("field") == "generation_history"
for f in result["findings"])
def test_generation_history_too_many(tmp_path):
data = {**VALID_PROFILE, "generation_history": [
{"date": f"2026-03-{i:02d}"} for i in range(1, 15)
]}
path = write_profile(tmp_path, data)
result = validate_profile(path)
assert any("generation_history" in str(f) for f in result["findings"])
def test_generation_history_not_list(tmp_path):
data = {**VALID_PROFILE, "generation_history": "not a list"}
path = write_profile(tmp_path, data)
result = validate_profile(path)
assert any("generation_history" in str(f) for f in result["findings"])
def test_studio_preferences_non_premier_warning(tmp_path):
data = {**VALID_PROFILE, "tier": "pro", "model_preference": "v5 Pro",
"studio_preferences": {"bpm": 120, "key": "C minor"}}
path = write_profile(tmp_path, data)
result = validate_profile(path)
assert any("studio" in f.get("issue", "").lower() for f in result["findings"])
def test_studio_preferences_premier_valid(tmp_path):
data = {**VALID_PROFILE, "tier": "premier", "model_preference": "v5 Pro",
"studio_preferences": {"bpm": 120, "key": "C minor", "time_signature": "4/4"}}
path = write_profile(tmp_path, data)
result = validate_profile(path)
assert not any("studio" in f.get("issue", "").lower() for f in result["findings"])
def test_studio_preferences_invalid_bpm(tmp_path):
data = {**VALID_PROFILE, "tier": "premier", "model_preference": "v5 Pro",
"studio_preferences": {"bpm": "fast"}}
path = write_profile(tmp_path, data)
result = validate_profile(path)
assert any("bpm" in str(f).lower() for f in result["findings"])
# --- derive_filename tests ---
def test_derive_filename_basic():
assert derive_filename("Test Band") == "test-band.yaml"
def test_derive_filename_special_chars():
assert derive_filename("The Band's Name!") == "the-bands-name.yaml"
def test_derive_filename_multiple_spaces():
assert derive_filename(" My Cool Band ") == "my-cool-band.yaml"
def test_derive_filename_already_kebab():
assert derive_filename("already-kebab") == "already-kebab.yaml"