music-app/backend/tests/test_routers_playlists.py
Jarian Cottingham 24c03426f8 test: add comprehensive test suite with 94% coverage
- 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
2026-07-06 06:07:31 +00:00

164 lines
5.3 KiB
Python

"""Router tests - Playlist endpoints."""
from app.models.song import Song
from app.models.playlist import Playlist, PlaylistSong
class TestListPlaylists:
def test_empty_list(self, client):
r = client.get("/api/playlists")
assert r.status_code == 200
assert r.json() == []
def test_with_playlists(self, client, db_module):
db = db_module.SessionLocal()
p = Playlist(id="p1", name="Test Playlist")
db.add(p)
db.commit()
db.close()
r = client.get("/api/playlists")
assert r.status_code == 200
data = r.json()
assert len(data) == 1
assert data[0]["name"] == "Test Playlist"
assert "song_count" in data[0]
class TestCreatePlaylist:
def test_create_basic(self, client):
r = client.post("/api/playlists", json={"name": "New Playlist", "description": "Test"})
assert r.status_code == 200
data = r.json()
assert data["name"] == "New Playlist"
assert "id" in data
assert len(data["id"]) > 0
def test_create_with_songs(self, client, db_module):
db = db_module.SessionLocal()
song = Song(id="s1", title="Test", artist="A", file_path="/tmp/t.mp3")
db.add(song)
db.commit()
db.close()
r = client.post("/api/playlists", json={"name": "With Songs", "song_ids": ["s1"]})
assert r.status_code == 200
class TestGetPlaylist:
def test_found(self, client, db_module):
db = db_module.SessionLocal()
p = Playlist(id="p1", name="Test")
db.add(p)
db.commit()
db.close()
r = client.get("/api/playlists/p1")
assert r.status_code == 200
assert r.json()["name"] == "Test"
assert "songs" in r.json()
def test_not_found(self, client):
r = client.get("/api/playlists/nonexistent")
assert r.status_code == 404
class TestUpdatePlaylist:
def test_update(self, client, db_module):
db = db_module.SessionLocal()
p = Playlist(id="p1", name="Old")
db.add(p)
db.commit()
db.close()
r = client.put("/api/playlists/p1", json={"name": "New", "description": "Updated"})
assert r.status_code == 200
assert r.json()["name"] == "New"
def test_update_not_found(self, client):
r = client.put("/api/playlists/nonexistent", json={"name": "X"})
assert r.status_code == 404
class TestDeletePlaylist:
def test_delete(self, client, db_module):
db = db_module.SessionLocal()
p = Playlist(id="p1", name="Test")
db.add(p)
db.commit()
db.close()
r = client.delete("/api/playlists/p1")
assert r.status_code == 200
assert r.json()["message"] == "Playlist deleted"
def test_delete_not_found(self, client):
r = client.delete("/api/playlists/nonexistent")
assert r.status_code == 404
class TestAddRemoveSong:
def test_add_song(self, client, db_module):
db = db_module.SessionLocal()
p = Playlist(id="p1", name="Test")
s = Song(id="s1", title="T", artist="A", file_path="/tmp/t.mp3")
db.add(p)
db.add(s)
db.commit()
db.close()
r = client.post("/api/playlists/p1/songs", params={"song_id": "s1"})
assert r.status_code == 200
def test_add_duplicate(self, client, db_module):
db = db_module.SessionLocal()
p = Playlist(id="p1", name="Test")
s = Song(id="s1", title="T", artist="A", file_path="/tmp/t.mp3")
ps = PlaylistSong(playlist_id="p1", song_id="s1", position=0)
db.add(p)
db.add(s)
db.add(ps)
db.commit()
db.close()
r = client.post("/api/playlists/p1/songs", params={"song_id": "s1"})
assert r.status_code == 400
def test_remove_song(self, client, db_module):
db = db_module.SessionLocal()
p = Playlist(id="p1", name="Test")
s = Song(id="s1", title="T", artist="A", file_path="/tmp/t.mp3")
ps = PlaylistSong(playlist_id="p1", song_id="s1", position=0)
db.add(p)
db.add(s)
db.add(ps)
db.commit()
db.close()
r = client.delete("/api/playlists/p1/songs/s1")
assert r.status_code == 200
def test_remove_not_in_playlist(self, client):
r = client.delete("/api/playlists/p1/songs/s1")
assert r.status_code == 404
class TestSharePlaylist:
def test_share(self, client, db_module):
db = db_module.SessionLocal()
p = Playlist(id="p1", name="Test")
db.add(p)
db.commit()
db.close()
r = client.post("/api/playlists/p1/share")
assert r.status_code == 200
assert "token" in r.json()
def test_share_not_found(self, client):
r = client.post("/api/playlists/nonexistent/share")
assert r.status_code == 404
def test_get_shared(self, client, db_module):
db = db_module.SessionLocal()
p = Playlist(id="p1", name="Test", share_token="abc123", is_shared=True)
db.add(p)
db.commit()
db.close()
r = client.get("/api/playlists/shared/abc123")
assert r.status_code == 200
def test_get_shared_not_found(self, client):
r = client.get("/api/playlists/shared/nonexistent")
assert r.status_code == 404