import os, json, time import pytest from fastapi.testclient import TestClient from app.main import app from app.config import settings from app.core.auth import create_token client = TestClient(app) TEST_DATA_FILE = os.path.join(settings.PROCESSED_DIR, "ai_presets.json") if os.path.exists(TEST_DATA_FILE): os.remove(TEST_DATA_FILE) def _auth_header(): token = create_token("test_user_presets", "testuser", "standard", False) return {"Authorization": f"Bearer {token}"} def test_list_presets_defaults(): res = client.get("/api/v1/ai/presets") assert res.status_code == 200 data = res.json() assert data["success"] is True assert len(data["presets"]) == 7 names = [p["name"] for p in data["presets"]] assert "Epic Orchestra Intro (8 Bars)" in names assert "Pop Piano Chords (4 Bars)" in names assert "Cyberpunk Synthwave (8 Bars)" in names assert "Jazz Swing Variation" in names assert "80s Synthwave Arpeggiator" in names def test_create_user_preset(): preset = { "id": "preset_test_my_beat", "name": "My Beat (4 Bars)", "keywords": ["my beat", "custom beat", "beat của tôi"], "category": "Hip Hop / Beat", "default_bars": 4, "default_bpm": 100, "default_scale": "A Minor", "system_instruction_template": "Generate a 4-bar hip hop beat with kick, snare, hi-hat.", "is_user_defined": True, "is_favorite": False, "created_at": "2026-07-28T00:00:00Z" } res = client.post("/api/v1/ai/presets", json=preset, headers=_auth_header()) assert res.status_code == 200, res.text data = res.json() assert data["success"] is True assert data["preset"]["id"] == "preset_test_my_beat" # Verify it appears in listing res2 = client.get("/api/v1/ai/presets", headers=_auth_header()) assert res2.status_code == 200 names = [p["name"] for p in res2.json()["presets"]] assert "My Beat (4 Bars)" in names assert len(res2.json()["presets"]) == 8 # 7 defaults + 1 user def test_update_user_preset(): preset = { "id": "preset_test_my_beat", "name": "My Beat Updated (8 Bars)", "keywords": ["my beat", "custom beat"], "category": "Hip Hop / Beat", "default_bars": 8, "default_bpm": 110, "default_scale": "C Minor", "system_instruction_template": "Generate an 8-bar hip hop beat.", "is_user_defined": True, "is_favorite": True, "created_at": "2026-07-28T00:00:00Z" } res = client.post("/api/v1/ai/presets", json=preset, headers=_auth_header()) assert res.status_code == 200 data = res.json() assert data["preset"]["name"] == "My Beat Updated (8 Bars)" assert data["preset"]["is_favorite"] is True assert data["preset"]["default_bars"] == 8 def test_delete_user_preset(): res = client.delete("/api/v1/ai/presets/preset_test_my_beat", headers=_auth_header()) assert res.status_code == 200 data = res.json() assert data["success"] is True res2 = client.get("/api/v1/ai/presets", headers=_auth_header()) assert res2.status_code == 200 names = [p["name"] for p in res2.json()["presets"]] assert "My Beat Updated (8 Bars)" not in names def test_delete_nonexistent_preset(): res = client.delete("/api/v1/ai/presets/nonexistent_id", headers=_auth_header()) assert res.status_code == 404 def test_presets_anonymous_cannot_save(): preset = { "id": "preset_anon", "name": "Anon Preset", "keywords": ["anon"], "category": "General", "default_bars": 4, "default_bpm": 120, "default_scale": "C Major", "system_instruction_template": "Test", "is_user_defined": True, "is_favorite": False } res = client.post("/api/v1/ai/presets", json=preset) assert res.status_code == 401 res2 = client.delete("/api/v1/ai/presets/preset_anon") assert res2.status_code == 401 def test_presets_isolation_between_users(): token_a = create_token("user_a", "usera", "standard", False) token_b = create_token("user_b", "userb", "standard", False) preset_a = { "id": "preset_user_a_only", "name": "User A Preset", "keywords": ["user a"], "category": "General", "default_bars": 4, "default_bpm": 120, "default_scale": "C Major", "system_instruction_template": "User A specific", "is_user_defined": True, "is_favorite": False } res = client.post("/api/v1/ai/presets", json=preset_a, headers={"Authorization": f"Bearer {token_a}"}) assert res.status_code == 200 # User B shouldn't see User A's presets res_b = client.get("/api/v1/ai/presets", headers={"Authorization": f"Bearer {token_b}"}) assert res_b.status_code == 200 names_b = [p["name"] for p in res_b.json()["presets"]] assert "User A Preset" not in names_b assert "Epic Orchestra Intro (8 Bars)" in names_b