fixing tests
This commit is contained in:
parent
27e8ee48eb
commit
70f55105de
|
@ -23,7 +23,7 @@ class ConfigurationError(Exception):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
class PlaylistImportError(Exception):
|
class PlaylistValidationError(Exception):
|
||||||
"""
|
"""
|
||||||
An error was discovered in a playlist template.
|
An error was discovered in the playlist definition.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -5,7 +5,7 @@ from typing import Union, List
|
||||||
|
|
||||||
from groove import db
|
from groove import db
|
||||||
from groove.editor import PlaylistEditor, EDITOR_TEMPLATE
|
from groove.editor import PlaylistEditor, EDITOR_TEMPLATE
|
||||||
from groove.exceptions import PlaylistImportError
|
from groove.exceptions import PlaylistValidationError
|
||||||
|
|
||||||
from slugify import slugify
|
from slugify import slugify
|
||||||
from sqlalchemy import func, delete
|
from sqlalchemy import func, delete
|
||||||
|
@ -20,8 +20,8 @@ class Playlist:
|
||||||
"""
|
"""
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
slug: str,
|
slug: str,
|
||||||
|
name: str,
|
||||||
session: Session,
|
session: Session,
|
||||||
name: str = '',
|
|
||||||
description: str = '',
|
description: str = '',
|
||||||
create_ok=True):
|
create_ok=True):
|
||||||
self._session = session
|
self._session = session
|
||||||
|
@ -114,9 +114,13 @@ class Playlist:
|
||||||
"""
|
"""
|
||||||
Return a dictionary of the playlist and its entries.
|
Return a dictionary of the playlist and its entries.
|
||||||
"""
|
"""
|
||||||
if not self.exists:
|
playlist = {
|
||||||
return {}
|
'name': self.name,
|
||||||
playlist = dict(self.record)
|
'slug': self.slug,
|
||||||
|
'description': self.description
|
||||||
|
}
|
||||||
|
if self.record:
|
||||||
|
playlist.update(dict(self.record))
|
||||||
playlist['entries'] = [dict(entry) for entry in self.entries]
|
playlist['entries'] = [dict(entry) for entry in self.entries]
|
||||||
return playlist
|
return playlist
|
||||||
|
|
||||||
|
@ -225,7 +229,7 @@ class Playlist:
|
||||||
stmt = db.playlist.insert(values)
|
stmt = db.playlist.insert(values)
|
||||||
results = self.session.execute(stmt)
|
results = self.session.execute(stmt)
|
||||||
self.session.commit()
|
self.session.commit()
|
||||||
logging.debug(f"Saved playlist with slug {self.slug}")
|
logging.debug(f"Inserted playlist with slug {self.slug}")
|
||||||
return self.session.query(db.playlist).filter(
|
return self.session.query(db.playlist).filter(
|
||||||
db.playlist.c.id == results.inserted_primary_key[0]
|
db.playlist.c.id == results.inserted_primary_key[0]
|
||||||
).one()
|
).one()
|
||||||
|
@ -246,7 +250,10 @@ class Playlist:
|
||||||
'name': self.name,
|
'name': self.name,
|
||||||
'description': self.description
|
'description': self.description
|
||||||
}
|
}
|
||||||
logging.debug(f"Saving values: {values}")
|
if not self.name:
|
||||||
|
raise PlaylistValidationError("This playlist has no name.")
|
||||||
|
if not self.slug:
|
||||||
|
raise PlaylistValidationError("This playlist has no slug.")
|
||||||
self._record = self._update(values) if self._record else self._insert(values)
|
self._record = self._update(values) if self._record else self._insert(values)
|
||||||
logging.debug(f"Saved playlist {self._record.id} with slug {self._record.slug}")
|
logging.debug(f"Saved playlist {self._record.id} with slug {self._record.slug}")
|
||||||
self.save_entries()
|
self.save_entries()
|
||||||
|
@ -254,7 +261,7 @@ class Playlist:
|
||||||
def save_entries(self):
|
def save_entries(self):
|
||||||
plid = self.record.id
|
plid = self.record.id
|
||||||
stmt = delete(db.entry).where(db.entry.c.playlist_id == plid)
|
stmt = delete(db.entry).where(db.entry.c.playlist_id == plid)
|
||||||
logging.debug(f"Deleting entries associated with playlist {plid}: {stmt}")
|
logging.debug(f"Deleting stale entries associated with playlist {plid}: {stmt}")
|
||||||
self.session.execute(stmt)
|
self.session.execute(stmt)
|
||||||
return self.create_entries(self.entries)
|
return self.create_entries(self.entries)
|
||||||
|
|
||||||
|
@ -273,6 +280,10 @@ class Playlist:
|
||||||
Returns:
|
Returns:
|
||||||
int: The number of tracks added.
|
int: The number of tracks added.
|
||||||
"""
|
"""
|
||||||
|
if not tracks:
|
||||||
|
tracks = self.entries
|
||||||
|
if not tracks:
|
||||||
|
return 0
|
||||||
maxtrack = self.session.query(func.max(db.entry.c.track)).filter_by(
|
maxtrack = self.session.query(func.max(db.entry.c.track)).filter_by(
|
||||||
playlist_id=self.record.id
|
playlist_id=self.record.id
|
||||||
).one()[0] or 0
|
).one()[0] or 0
|
||||||
|
@ -288,9 +299,25 @@ class Playlist:
|
||||||
self._entries = None
|
self._entries = None
|
||||||
return len(tracks)
|
return len(tracks)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def by_slug(cls, slug, session):
|
||||||
|
try:
|
||||||
|
row = session.query(db.playlist).filter(
|
||||||
|
db.playlist.c.slug == slug
|
||||||
|
).one()
|
||||||
|
except NoResultFound as ex:
|
||||||
|
logging.error(f"Could not locate an existing playlist with slug {slug}.")
|
||||||
|
raise ex
|
||||||
|
return cls.from_row(row, session)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_row(cls, row, session):
|
def from_row(cls, row, session):
|
||||||
pl = Playlist(slug=row.slug, session=session)
|
pl = Playlist(
|
||||||
|
slug=row.slug,
|
||||||
|
name=row.name,
|
||||||
|
description=row.description,
|
||||||
|
session=session
|
||||||
|
)
|
||||||
pl._record = row
|
pl._record = row
|
||||||
return pl
|
return pl
|
||||||
|
|
||||||
|
@ -306,7 +333,7 @@ class Playlist:
|
||||||
session=session,
|
session=session,
|
||||||
)
|
)
|
||||||
except (IndexError, KeyError):
|
except (IndexError, KeyError):
|
||||||
PlaylistImportError("The specified source was not a valid playlist.")
|
PlaylistValidationError("The specified source was not a valid playlist.")
|
||||||
|
|
||||||
pl._entries = pl._get_tracks_by_artist_and_title(entries=[
|
pl._entries = pl._get_tracks_by_artist_and_title(entries=[
|
||||||
list(entry.items())[0] for entry in source[name]['entries']
|
list(entry.items())[0] for entry in source[name]['entries']
|
||||||
|
|
|
@ -24,5 +24,5 @@ class load(BasePrompt):
|
||||||
session=self.manager.session,
|
session=self.manager.session,
|
||||||
create_ok=True
|
create_ok=True
|
||||||
)
|
)
|
||||||
print(self.parent.playlist.summary)
|
print(self.parent.playlist.info)
|
||||||
return self.parent.commands['_playlist'].start()
|
return self.parent.commands['_playlist'].start()
|
||||||
|
|
|
@ -89,8 +89,9 @@ def serve_playlist(slug, db):
|
||||||
Retrieve a playlist and its entries by a slug.
|
Retrieve a playlist and its entries by a slug.
|
||||||
"""
|
"""
|
||||||
logging.debug(f"Looking up playlist: {slug}...")
|
logging.debug(f"Looking up playlist: {slug}...")
|
||||||
playlist = Playlist(slug=slug, session=db, create_ok=False).load()
|
try:
|
||||||
if not playlist.record:
|
playlist = Playlist.by_slug(slug, session=db)
|
||||||
|
except NoResultFound:
|
||||||
logging.debug(f"Playist {slug} doesn't exist.")
|
logging.debug(f"Playist {slug} doesn't exist.")
|
||||||
return HTTPResponse(status=404, body="Not found")
|
return HTTPResponse(status=404, body="Not found")
|
||||||
logging.debug(f"Loaded {playlist.record}")
|
logging.debug(f"Loaded {playlist.record}")
|
||||||
|
@ -113,9 +114,10 @@ def build():
|
||||||
@bottle.auth_basic(is_authenticated)
|
@bottle.auth_basic(is_authenticated)
|
||||||
@server.route('/build/search/playlist/<slug>')
|
@server.route('/build/search/playlist/<slug>')
|
||||||
def search_playlist(slug, db):
|
def search_playlist(slug, db):
|
||||||
playlist = Playlist(slug=slug, session=db, create_ok=False).load()
|
try:
|
||||||
if not playlist.record:
|
playlist = Playlist.by_slug(slug, session=db)
|
||||||
logging.debug(f"Playist {slug} doesn't exist.")
|
except NoResultFound:
|
||||||
|
logging.debug(f"Playlist {slug} doesn't exist.")
|
||||||
body = {}
|
body = {}
|
||||||
else:
|
else:
|
||||||
body = json.dumps(playlist.as_dict)
|
body = json.dumps(playlist.as_dict)
|
||||||
|
|
|
@ -5,6 +5,7 @@ from pathlib import Path
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
import groove.db
|
import groove.db
|
||||||
|
from groove.playlist import Playlist
|
||||||
|
|
||||||
from sqlalchemy import create_engine, insert
|
from sqlalchemy import create_engine, insert
|
||||||
from sqlalchemy.orm import sessionmaker
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
@ -77,3 +78,13 @@ def db(in_memory_db):
|
||||||
{'playlist_id': '3', 'track': '2', 'track_id': '3'},
|
{'playlist_id': '3', 'track': '2', 'track_id': '3'},
|
||||||
])
|
])
|
||||||
yield in_memory_db
|
yield in_memory_db
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope='function')
|
||||||
|
def empty_playlist(db):
|
||||||
|
return Playlist(
|
||||||
|
name='an empty playlist fixture',
|
||||||
|
slug='an-empty-playlist',
|
||||||
|
description='a fixture',
|
||||||
|
session=db
|
||||||
|
)
|
||||||
|
|
|
@ -1,73 +1,73 @@
|
||||||
# 70, 73-81, 84, 88-97, 100-104
|
|
||||||
import pytest
|
import pytest
|
||||||
from groove import playlist
|
from groove import playlist
|
||||||
|
from groove.exceptions import PlaylistValidationError
|
||||||
|
|
||||||
|
|
||||||
def test_create(db):
|
def test_create(empty_playlist):
|
||||||
pl = playlist.Playlist(slug='test-create-playlist', session=db, create_ok=True)
|
assert empty_playlist.record.id
|
||||||
assert pl.record.id
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('vals, expected', [
|
||||||
|
(dict(name='missing-the-slug', ), TypeError),
|
||||||
|
(dict(name='missing-the-slug', slug=''), PlaylistValidationError),
|
||||||
|
(dict(slug='missing-the-name', name=''), PlaylistValidationError),
|
||||||
|
])
|
||||||
|
def test_create_missing_fields(vals, expected, db):
|
||||||
|
with pytest.raises(expected):
|
||||||
|
assert playlist.Playlist(**vals, session=db, create_ok=True).record.id
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('tracks', [
|
@pytest.mark.parametrize('tracks', [
|
||||||
('01 Guns Blazing', ),
|
('01 Guns Blazing', ),
|
||||||
('01 Guns Blazing', '02 UNKLE'),
|
('01 Guns Blazing', '02 UNKLE'),
|
||||||
])
|
])
|
||||||
def test_add(db, tracks):
|
def test_add(tracks, empty_playlist):
|
||||||
pl = playlist.Playlist(slug='test-create-playlist', session=db)
|
assert empty_playlist.add(tracks) == len(tracks)
|
||||||
count = pl.add(tracks)
|
|
||||||
assert count == len(tracks)
|
|
||||||
|
|
||||||
|
|
||||||
def test_add_no_matches(db):
|
def test_add_no_matches(empty_playlist):
|
||||||
pl = playlist.Playlist(slug='playlist-one', session=db)
|
assert empty_playlist.add(('no match', )) == 0
|
||||||
assert pl.add(('no match', )) == 0
|
|
||||||
|
|
||||||
|
|
||||||
def test_add_multiple_matches(db):
|
def test_add_multiple_matches(empty_playlist):
|
||||||
pl = playlist.Playlist(slug='playlist-one', session=db)
|
assert empty_playlist.add('UNKLE',) == 0
|
||||||
assert pl.add('UNKLE',) == 0
|
|
||||||
|
|
||||||
|
|
||||||
def test_delete(db):
|
def test_delete(empty_playlist):
|
||||||
pl = playlist.Playlist(slug='playlist-one', session=db)
|
expected = empty_playlist.record.id
|
||||||
expected = pl.record.id
|
assert empty_playlist.delete() == expected
|
||||||
assert pl.delete() == expected
|
assert not empty_playlist.exists
|
||||||
assert not pl.exists
|
assert empty_playlist.deleted
|
||||||
assert pl.deleted
|
|
||||||
|
|
||||||
|
|
||||||
def test_delete_playlist_not_exist(db):
|
def test_delete_playlist_not_exist(db):
|
||||||
pl = playlist.Playlist(slug='playlist-doesnt-exist', session=db, create_ok=False)
|
pl = playlist.Playlist(name='foo', slug='foo', session=db, create_ok=False)
|
||||||
assert not pl.delete()
|
assert not pl.delete()
|
||||||
assert not pl.exists
|
assert not pl.exists
|
||||||
assert not pl.deleted
|
assert not pl.deleted
|
||||||
|
|
||||||
|
|
||||||
def test_cannot_create_after_delete(db):
|
def test_cannot_create_after_delete(db, empty_playlist):
|
||||||
pl = playlist.Playlist(slug='playlist-one', session=db)
|
empty_playlist.delete()
|
||||||
pl.delete()
|
|
||||||
with pytest.raises(RuntimeError):
|
with pytest.raises(RuntimeError):
|
||||||
assert pl.record
|
assert empty_playlist.record
|
||||||
assert not pl.exists
|
assert not empty_playlist.exists
|
||||||
|
|
||||||
|
|
||||||
def test_entries(db):
|
def test_entries(db):
|
||||||
pl = playlist.Playlist(slug='playlist-one', session=db)
|
|
||||||
# assert twice for branch coverage of cached values
|
# assert twice for branch coverage of cached values
|
||||||
|
pl = playlist.Playlist.by_slug('playlist-one', db)
|
||||||
assert pl.entries
|
assert pl.entries
|
||||||
assert pl.entries
|
assert pl.entries
|
||||||
|
|
||||||
|
|
||||||
def test_playlist_not_exist_formatted(db):
|
def test_playlist_not_exist_formatted(db):
|
||||||
pl = playlist.Playlist(slug='fnord', session=db, create_ok=False)
|
pl = playlist.Playlist(name='foo', slug='foo', session=db, create_ok=False)
|
||||||
assert not repr(pl)
|
|
||||||
assert not pl.as_dict
|
|
||||||
|
|
||||||
|
|
||||||
def test_playlist_formatted(db):
|
|
||||||
pl = playlist.Playlist(slug='playlist-one', session=db)
|
|
||||||
assert repr(pl)
|
assert repr(pl)
|
||||||
assert pl.as_string
|
|
||||||
assert pl.as_dict
|
assert pl.as_dict
|
||||||
|
|
||||||
|
|
||||||
|
def test_playlist_formatted(db, empty_playlist):
|
||||||
|
assert repr(empty_playlist)
|
||||||
|
assert empty_playlist.as_string
|
||||||
|
assert empty_playlist.as_dict
|
||||||
|
|
Loading…
Reference in New Issue
Block a user