- Add pytest config with 90% coverage threshold - 15 test files covering all routers, services, schemas, models - 300 tests: unit tests, integration tests, edge cases, mocked external APIs - Update CI workflow to run pytest with coverage enforcement - Mock external services (Genius, MusicBrainz, RadioBrowser) - In-memory SQLite DB per test via conftest fixtures
163 lines
5.6 KiB
Python
163 lines
5.6 KiB
Python
"""Extended mood engine and SharePlay service tests."""
|
|
from unittest.mock import MagicMock, patch
|
|
from sqlalchemy.orm import Session
|
|
|
|
|
|
class TestAnalyzeLyrics:
|
|
def test_all_zero_empty(self):
|
|
from app.services.mood_engine import analyze_lyrics, MOOD_NAMES
|
|
scores = analyze_lyrics("")
|
|
assert all(v == 0.0 for v in scores.values())
|
|
assert len(scores) == len(MOOD_NAMES)
|
|
|
|
def test_none_input(self):
|
|
from app.services.mood_engine import analyze_lyrics, MOOD_NAMES
|
|
scores = analyze_lyrics(None)
|
|
assert all(v == 0.0 for v in scores.values())
|
|
|
|
def test_case_insensitive(self):
|
|
from app.services.mood_engine import analyze_lyrics
|
|
a = analyze_lyrics("I cry alone")
|
|
b = analyze_lyrics("I CRY ALONE")
|
|
assert a == b
|
|
|
|
def test_normalized(self):
|
|
from app.services.mood_engine import analyze_lyrics
|
|
scores = analyze_lyrics("happy joy smile sunshine")
|
|
assert max(scores.values()) <= 1.0
|
|
|
|
def test_keyword_weights(self):
|
|
from app.services.mood_engine import analyze_lyrics
|
|
scores = analyze_lyrics("cry tears broken alone lonely heartbreak")
|
|
assert scores["Sad"] == 1.0
|
|
|
|
|
|
class TestMoodEngineConstants:
|
|
def test_mood_names(self):
|
|
from app.services.mood_engine import MOOD_NAMES
|
|
expected = ["Sad", "Happy", "Energetic", "Focused", "Chill",
|
|
"Romantic", "Angry", "Nostalgic", "Melancholy", "Dreamy"]
|
|
assert MOOD_NAMES == expected
|
|
|
|
def test_confidence_threshold(self):
|
|
from app.services.mood_engine import CONFIDENCE_THRESHOLD
|
|
assert 0 < CONFIDENCE_THRESHOLD < 1
|
|
|
|
def test_keyword_counts(self):
|
|
from app.services.mood_engine import MOOD_KEYWORDS
|
|
for mood, keywords in MOOD_KEYWORDS.items():
|
|
assert len(keywords) == 15
|
|
|
|
|
|
class TestGetMoodPlaylist:
|
|
def test_empty_db(self):
|
|
from app.services.mood_engine import get_mood_playlist
|
|
from app.db.database import SessionLocal
|
|
db = SessionLocal()
|
|
songs = get_mood_playlist("happy", db, limit=50)
|
|
assert songs == []
|
|
db.close()
|
|
|
|
|
|
class TestSharePlayManager:
|
|
def test_init(self):
|
|
from app.services.shareplay import SharePlayManager
|
|
m = SharePlayManager()
|
|
assert m.rooms == {}
|
|
assert m.connections == {}
|
|
|
|
def test_create_room(self):
|
|
from app.services.shareplay import SharePlayManager
|
|
from app.db.database import SessionLocal
|
|
db = SessionLocal()
|
|
m = SharePlayManager()
|
|
result = m.create_room(db, creator="alice")
|
|
assert result["creator_user"] == "alice"
|
|
assert result["active_connections"] == 1
|
|
assert result["id"] in m.rooms
|
|
db.close()
|
|
|
|
def test_join_room(self):
|
|
from app.services.shareplay import SharePlayManager
|
|
from app.db.database import SessionLocal
|
|
db = SessionLocal()
|
|
m = SharePlayManager()
|
|
room = m.create_room(db, creator="alice")
|
|
result = m.join_room(db, room["id"])
|
|
assert result["active_connections"] == 2
|
|
assert "state" in result
|
|
db.close()
|
|
|
|
def test_join_nonexistent(self):
|
|
from app.services.shareplay import SharePlayManager
|
|
from app.db.database import SessionLocal
|
|
db = SessionLocal()
|
|
m = SharePlayManager()
|
|
result = m.join_room(db, "nonexistent")
|
|
assert result is None
|
|
db.close()
|
|
|
|
def test_leave_room(self):
|
|
from app.services.shareplay import SharePlayManager
|
|
from app.db.database import SessionLocal
|
|
db = SessionLocal()
|
|
m = SharePlayManager()
|
|
room = m.create_room(db, creator="alice")
|
|
result = m.leave_room(db, room["id"])
|
|
assert result is True
|
|
db.close()
|
|
|
|
def test_leave_nonexistent(self):
|
|
from app.services.shareplay import SharePlayManager
|
|
from app.db.database import SessionLocal
|
|
db = SessionLocal()
|
|
m = SharePlayManager()
|
|
result = m.leave_room(db, "nonexistent")
|
|
assert result is False
|
|
db.close()
|
|
|
|
def test_get_state(self):
|
|
from app.services.shareplay import SharePlayManager
|
|
m = SharePlayManager()
|
|
assert m.get_state("nonexistent") is None
|
|
|
|
def test_update_state(self):
|
|
from app.services.shareplay import SharePlayManager
|
|
m = SharePlayManager()
|
|
m.rooms["test"] = {"is_playing": False, "position": 0}
|
|
result = m.update_state("test", is_playing=True)
|
|
assert result["is_playing"] is True
|
|
|
|
def test_update_state_nonexistent(self):
|
|
from app.services.shareplay import SharePlayManager
|
|
m = SharePlayManager()
|
|
result = m.update_state("nonexistent", is_playing=True)
|
|
assert result is None
|
|
|
|
def test_get_cue_empty(self):
|
|
from app.services.shareplay import SharePlayManager
|
|
from app.db.database import SessionLocal
|
|
db = SessionLocal()
|
|
m = SharePlayManager()
|
|
result = m.get_cue(db, "any_room")
|
|
assert result == []
|
|
db.close()
|
|
|
|
def test_add_to_cue_nonexistent_song(self):
|
|
from app.services.shareplay import SharePlayManager
|
|
from app.db.database import SessionLocal
|
|
db = SessionLocal()
|
|
m = SharePlayManager()
|
|
result = m.add_to_cue(db, "room1", "nonexistent_song", "alice")
|
|
assert result is False
|
|
db.close()
|
|
|
|
def test_next_cue_empty(self):
|
|
from app.services.shareplay import SharePlayManager
|
|
from app.db.database import SessionLocal
|
|
db = SessionLocal()
|
|
m = SharePlayManager()
|
|
result = m.next_cue(db, "room1")
|
|
assert result is None
|
|
db.close()
|