emmental/tests/db/test_playlists.py

689 lines
29 KiB
Python

# Copyright 2022 (c) Anna Schumaker
"""Tests our playlist Gio.ListModel."""
import datetime
import pathlib
import unittest.mock
import emmental.db
import tests.util
class TestPlaylistObject(tests.util.TestCase):
"""Tests our playlist object."""
def setUp(self):
"""Set up common variables."""
super().setUp()
self.table = self.sql.playlists
self.playlist = emmental.db.playlists.Playlist(table=self.table,
playlistid=12345,
propertyid=67890,
name="Test Playlist")
def test_init(self):
"""Test that the Playlist is set up properly."""
self.assertIsInstance(self.playlist, emmental.db.playlist.Playlist)
self.assertEqual(self.playlist.table, self.table)
self.assertEqual(self.playlist.propertyid, 67890)
self.assertEqual(self.playlist.playlistid, 12345)
self.assertEqual(self.playlist.primary_key, 12345)
self.assertEqual(self.playlist.name, "Test Playlist")
self.assertIsNone(self.playlist.image)
self.assertIsNone(self.playlist.parent)
def test_image_path(self):
"""Test the image-path property."""
path = pathlib.Path("/a/b/c.jpg")
playlist = emmental.db.playlists.Playlist(table=self.table,
playlistid=1, propertyid=1,
image=path, name="Test")
self.assertEqual(playlist.image, path)
def test_rename(self):
"""Test the rename() function."""
with unittest.mock.patch.object(self.table, "rename",
return_value=True) as mock_rename:
self.assertTrue(self.playlist.rename("New Name"))
mock_rename.assert_called_with(self.playlist, "New Name")
class TestPlaylistTable(tests.util.TestCase):
"""Tests our playlist table."""
def setUp(self):
"""Set up common variables."""
super().setUp()
self.sql("DELETE FROM playlists")
self.table = self.sql.playlists
self.library = self.sql.libraries.create(pathlib.Path("/a/b"))
self.album = self.sql.albums.create("Test Album", "Artist", "2023-04")
self.medium = self.sql.media.create(self.album, "", number=1)
self.year = self.sql.years.create(2023)
self.track = self.sql.tracks.create(self.library,
pathlib.Path("/a/b/c.ogg"),
self.medium, self.year, number=1)
def test_init(self):
"""Test that the playlist model is configured correctly."""
self.assertIsInstance(self.table, emmental.db.playlist.Table)
self.assertFalse(self.table.autodelete)
self.assertFalse(self.table.system_tracks)
self.assertFalse(self.table.have_collection_tracks)
self.assertEqual(len(self.table), 0)
self.assertIsNone(self.table.collection)
self.assertIsNone(self.table.favorites)
self.assertIsNone(self.table.most_played)
self.assertIsNone(self.table.new_tracks)
self.assertIsNone(self.table.previous)
self.assertIsNone(self.table.queued)
self.assertIsNone(self.table.unplayed)
def test_add_track(self):
"""Test adding tracks to user Playlists."""
playlist = self.table.create("Test Playlist")
playlist.add_track(self.track)
self.assertTrue(playlist.has_track(self.track))
rows = self.sql("SELECT trackid FROM user_tracks WHERE propertyid=?",
playlist.propertyid).fetchall()
self.assertEqual(len(rows), 1)
self.assertEqual(rows[0]["trackid"], self.track.trackid)
self.assertFalse(playlist.add_track(self.track))
def test_construct(self):
"""Test constructing a playlist."""
playlist = self.table.construct(playlistid=1, propertyid=1,
name="Test Playlist")
self.assertIsInstance(playlist, emmental.db.playlists.Playlist)
self.assertEqual(playlist.table, self.table)
self.assertEqual(playlist.propertyid, 1)
self.assertEqual(playlist.playlistid, 1)
self.assertEqual(playlist.name, "Test Playlist")
self.assertIsNone(playlist.image)
self.assertTrue(playlist.user_tracks)
self.assertTrue(playlist.tracks_movable)
def test_create(self):
"""Test creating a playlist."""
playlist = self.table.create(" Test Playlist ")
self.assertIsInstance(playlist, emmental.db.playlists.Playlist)
self.assertEqual(playlist.name, "Test Playlist")
self.assertEqual(playlist.loop, "None")
self.assertEqual(playlist.sort_order,
"albumartist, album, mediumno, number")
self.assertIsNone(playlist.image)
self.assertTrue(playlist.tracks_movable)
cur = self.sql("SELECT COUNT(name) FROM playlists")
self.assertEqual(cur.fetchone()["COUNT(name)"], 1)
self.assertEqual(len(self.table), 1)
self.assertEqual(self.table.get_item(0), playlist)
cur = self.sql("SELECT COUNT(*) FROM playlist_properties")
self.assertEqual(cur.fetchone()["COUNT(*)"], playlist.propertyid)
for name in ["", " ", "Test Playlist", "test playlist"]:
self.assertIsNone(self.table.create(name))
self.assertEqual(len(self.table), 1)
cur = self.sql("SELECT COUNT(rowid) FROM playlists")
self.assertEqual(cur.fetchone()["COUNT(rowid)"], 1)
def test_delete(self):
"""Test deleting a playlist."""
playlist = self.table.create("Test Playlist")
self.assertTrue(playlist.delete())
self.assertIsNone(self.table.index(playlist))
cur = self.sql("SELECT COUNT(name) FROM playlists")
self.assertEqual(cur.fetchone()["COUNT(name)"], 0)
self.assertEqual(len(self.table), 0)
self.assertIsNone(self.table.get_item(0))
cur = self.sql("SELECT COUNT(*) FROM playlist_properties")
self.assertEqual(cur.fetchone()["COUNT(*)"], playlist.propertyid - 1)
self.assertFalse(playlist.delete())
def test_filter(self):
"""Test filtering the playlist model."""
self.table.create("Playlist 1")
self.table.create("Playlist 2")
self.table.filter("*1", now=True)
self.assertSetEqual(self.table.get_filter().keys, {1})
self.table.filter("playlist*", now=True)
self.assertSetEqual(self.table.get_filter().keys, {1, 2})
def test_get_trackids(self):
"""Test loading playlist tracks from the database."""
playlist = self.table.create("Test Playlist")
self.assertSetEqual(self.table.get_trackids(playlist), set())
playlist.add_track(self.track)
self.assertSetEqual(self.table.get_trackids(playlist),
{self.track.trackid})
def test_get_track_order(self):
"""Test getting the user track order for a playlist."""
track2 = self.sql.tracks.create(self.library,
pathlib.Path("/a/b/d.ogg"),
self.medium, self.year)
playlist = self.table.create("Test Playlist")
playlist.add_track(self.track)
playlist.add_track(track2)
playlist.sort_order = "user"
self.assertDictEqual(self.table.get_track_order(playlist),
{self.track.trackid: 0, track2.trackid: 1})
self.sql("UPDATE user_tracks SET position=? WHERE trackid=?",
3, track2.trackid)
self.assertDictEqual(self.table.get_track_order(playlist),
{self.track.trackid: 1, track2.trackid: 0})
def test_load(self):
"""Test loading playlists from the database."""
self.table.create("Playlist 1").image = tests.util.COVER_JPG
self.table.create("Playlist 2")
playlists2 = emmental.db.playlists.Table(self.sql)
playlists2.load(now=True)
self.assertEqual(len(playlists2), 2)
self.assertEqual(playlists2[0].name, "Playlist 1")
self.assertEqual(playlists2[0].image, tests.util.COVER_JPG)
self.assertEqual(playlists2[1].name, "Playlist 2")
self.assertIsNone(playlists2[1].image)
def test_lookup(self):
"""Test looking up a playlist."""
playlist = self.table.create("Test Playlist")
self.assertEqual(self.table.lookup("Test Playlist"), playlist)
self.assertEqual(self.table.lookup("test playlist"), playlist)
self.assertIsNone(self.table.lookup("No Playlist"))
def test_move_track_down(self):
"""Test moving a track down in the sort order."""
track2 = self.sql.tracks.create(self.library,
pathlib.Path("/a/b/d.ogg"),
self.medium, self.year, number=2)
track3 = self.sql.tracks.create(self.library,
pathlib.Path("/a/b/e.ogg"),
self.medium, self.year, number=3)
playlist = self.table.create("Test Playlist")
for track in [self.track, track2, track3]:
playlist.add_track(track)
playlist.sort_order = "number"
self.assertFalse(self.table.move_track_down(playlist, track3))
self.assertEqual(playlist.sort_order, "number")
self.assertTrue(self.table.move_track_down(playlist, self.track))
self.assertEqual(playlist.sort_order, "user")
self.assertDictEqual(self.table.get_track_order(playlist),
{track2.trackid: 0,
self.track.trackid: 1,
track3.trackid: 2})
def test_move_track_up(self):
"""Test moving a track up in the sort order."""
track2 = self.sql.tracks.create(self.library,
pathlib.Path("/a/b/d.ogg"),
self.medium, self.year, number=2)
track3 = self.sql.tracks.create(self.library,
pathlib.Path("/a/b/e.ogg"),
self.medium, self.year, number=3)
playlist = self.table.create("Test Playlist")
for track in [self.track, track2, track3]:
playlist.add_track(track)
playlist.sort_order = "number"
self.assertFalse(self.table.move_track_up(playlist, self.track))
self.assertEqual(playlist.sort_order, "number")
self.assertTrue(self.table.move_track_up(playlist, track3))
self.assertEqual(playlist.sort_order, "user")
self.assertDictEqual(self.table.get_track_order(playlist),
{self.track.trackid: 0,
track3.trackid: 1,
track2.trackid: 2})
def test_remove_track(self):
"""Test removing tracks from user Playlists."""
playlist = self.table.create("Test Playlist")
playlist.add_track(self.track)
playlist.remove_track(self.track)
self.assertFalse(playlist.has_track(self.track))
rows = self.sql("SELECT trackid FROM user_tracks WHERE propertyid=?",
playlist.propertyid).fetchall()
self.assertEqual(len(rows), 0)
def test_rename(self):
"""Test renaming a playlist."""
playlist = self.table.create("Test Playlist")
self.table.store.append = unittest.mock.Mock()
self.table.store.remove = unittest.mock.Mock()
self.assertTrue(playlist.rename(" New Name "))
self.assertEqual(playlist.name, "New Name")
self.table.store.remove.assert_called_with(playlist)
self.table.store.append.assert_called_with(playlist)
rows = self.sql("SELECT name FROM playlists").fetchall()
self.assertEqual(len(rows), 1)
self.assertEqual(rows[0]["name"], "New Name")
self.table.create("Other Name")
self.assertFalse(playlist.rename("New Name"))
self.assertFalse(playlist.rename("Other Name"))
def test_update(self):
"""Test updating playlist properties."""
playlist = self.table.create("Test Playlist")
playlist.image = tests.util.COVER_JPG
playlist.active = True
playlist.loop = "Track"
playlist.sort_order = "trackid"
playlist.shuffle = True
playlist.current_trackid = self.track.trackid
cur = self.sql("""SELECT image, active, loop, shuffle,
sort_order, current_trackid
FROM playlists_view
WHERE playlistid=?""", playlist.playlistid)
row = cur.fetchone()
self.assertEqual(row["image"], tests.util.COVER_JPG)
self.assertEqual(row["loop"], "Track")
self.assertEqual(row["shuffle"], True)
self.assertEqual(row["sort_order"], "trackid")
self.assertEqual(row["current_trackid"], self.track.trackid)
self.assertTrue(row["active"])
class TestSystemPlaylists(tests.util.TestCase):
"""Tests our system playlists."""
def setUp(self):
"""Set up common variables."""
super().setUp()
self.table = self.sql.playlists
self.table.load(now=True)
self.library = self.sql.libraries.create(pathlib.Path("/a/b"))
self.album = self.sql.albums.create("Test Album", "Artist", "2023-04")
self.medium = self.sql.media.create(self.album, "", number=1)
self.year = self.sql.years.create(2023)
self.track = self.sql.tracks.create(self.library,
pathlib.Path("/a/b/1.ogg"),
self.medium, self.year)
def test_midnight_alarm(self):
"""Test playlist maintenance run every night at midnight."""
with unittest.mock.patch.object(self.table.new_tracks,
"reload_tracks") as mock_reload:
self.table._Table__at_midnight()
mock_reload.assert_called()
with unittest.mock.patch("emmental.alarm.set_alarm") as mock_set:
table2 = emmental.db.playlists.Table(self.sql)
mock_set.assert_called_with(datetime.time(second=5),
table2._Table__at_midnight)
def test_collection(self):
"""Test the Collection playlist."""
self.assertIsInstance(self.table.collection,
emmental.db.playlists.Playlist)
self.assertEqual(self.table.collection.name, "Collection")
self.assertEqual(self.table.collection.loop, "Playlist")
self.assertEqual(self.table.collection.sort_order,
"albumartist, album, mediumno, number")
self.assertTrue(self.table.collection.active)
self.assertFalse(self.table.collection.shuffle)
self.assertFalse(self.table.collection.user_tracks)
self.assertFalse(self.table.collection.tracks_movable)
self.assertEqual(self.table.lookup("Collection"),
self.table.collection)
def test_collection_loop(self):
"""Test that the Collection::loop property cannot be disabled."""
self.assertIsNone(self.sql("""UPDATE playlist_properties
SET loop='None' WHERE propertyid=?""",
self.table.collection.propertyid))
self.assertEqual(self.table.collection.loop, "Playlist")
self.table.collection.loop = "Track"
self.assertEqual(self.table.collection.loop, "Track")
self.table.collection.loop = "None"
self.assertEqual(self.table.collection.loop, "Playlist")
def test_collection_tracks(self):
"""Test the Collection playlist track functions."""
for (enabled, deleting) in [(False, False), (False, True),
(True, True), (True, False)]:
with self.subTest(enabled=enabled, deleting=deleting):
self.library.enabled = enabled
self.library.deleting = deleting
self.table.collection.add_track(self.track)
self.assertEqual(self.table.collection.has_track(self.track),
enabled and not deleting)
self.assertEqual(self.table.have_collection_tracks,
enabled and not deleting)
self.table.collection.remove_track(self.track)
self.assertFalse(self.table.collection.has_track(self.track))
self.table.collection.reload_tracks()
self.assertTrue(self.table.collection.has_track(self.track))
self.library.enabled = False
self.table.queue.complete()
self.assertFalse(self.table.collection.has_track(self.track))
self.library.enabled = True
self.table.queue.complete()
self.assertTrue(self.table.collection.has_track(self.track))
self.library.deleting = True
self.table.collection.reload_tracks()
self.assertFalse(self.table.collection.has_track(self.track))
def test_favorites(self):
"""Test the favorite tracks playlist."""
self.assertIsInstance(self.table.favorites,
emmental.db.playlists.Playlist)
self.assertEqual(self.table.favorites.name, "Favorite Tracks")
self.assertEqual(self.table.favorites.loop, "None")
self.assertEqual(self.table.favorites.sort_order,
"albumartist, album, mediumno, number")
self.assertTrue(self.table.favorites.user_tracks)
self.assertFalse(self.table.favorites.shuffle)
self.assertFalse(self.table.favorites.active)
self.assertFalse(self.table.favorites.tracks_movable)
self.assertEqual(self.table.lookup("Favorite Tracks"),
self.table.favorites)
def test_favorite_tracks(self):
"""Test the Favorite Tracks track functions."""
self.table.favorites.add_track(self.track)
self.assertTrue(self.table.favorites.has_track(self.track))
self.assertTrue(self.track.favorite)
self.library.deleting = True
self.table.favorites.reload_tracks()
self.assertFalse(self.table.favorites.has_track(self.track))
self.library.deleting = False
self.table.favorites.reload_tracks()
self.assertTrue(self.table.favorites.has_track(self.track))
self.table.favorites.remove_track(self.track)
self.assertFalse(self.table.favorites.has_track(self.track))
self.assertFalse(self.track.favorite)
def test_most_played(self):
"""Test the most-played tracks playlist."""
self.assertIsInstance(self.table.most_played,
emmental.db.playlists.Playlist)
sort_order = "playcount DESC, albumartist, album, mediumno, number"
self.assertEqual(self.table.most_played.name, "Most Played Tracks")
self.assertEqual(self.table.most_played.loop, "None")
self.assertEqual(self.table.most_played.sort_order, sort_order)
self.assertFalse(self.table.most_played.active)
self.assertFalse(self.table.most_played.shuffle)
self.assertFalse(self.table.most_played.user_tracks)
self.assertFalse(self.table.most_played.tracks_movable)
self.assertEqual(self.table.lookup("Most Played Tracks"),
self.table.most_played)
def test_most_played_tracks(self):
"""Test the Most Played Tracks track functions."""
track2 = self.sql.tracks.create(self.library,
pathlib.Path("/a/b/2.ogg"),
self.medium, self.year)
self.sql("UPDATE tracks SET playcount=2 WHERE trackid=?",
self.track.trackid)
self.sql("UPDATE tracks SET playcount=1 WHERE trackid=?",
track2.trackid)
self.table.most_played.add_track(self.track)
self.assertFalse(self.table.most_played.has_track(self.track))
self.table.most_played.tracks.add_track(self.track)
self.table.most_played.remove_track(self.track)
self.assertFalse(self.table.most_played.has_track(self.track))
self.table.most_played.reload_tracks()
self.assertFalse(self.table.most_played.has_track(self.track))
self.sql("UPDATE tracks SET playcount=5 WHERE trackid=?",
self.track.trackid)
self.table.most_played.reload_tracks()
self.assertTrue(self.table.most_played.has_track(self.track))
self.library.deleting = True
self.table.most_played.reload_tracks()
self.assertFalse(self.table.most_played.has_track(self.track))
def test_new_tracks(self):
"""Test the new tracks playlist."""
self.assertIsInstance(self.table.new_tracks,
emmental.db.playlists.Playlist)
self.assertEqual(self.table.new_tracks.name, "New Tracks")
self.assertEqual(self.table.new_tracks.loop, "None")
self.assertEqual(self.table.new_tracks.sort_order,
"albumartist, album, mediumno, number")
self.assertFalse(self.table.new_tracks.active)
self.assertFalse(self.table.new_tracks.shuffle)
self.assertFalse(self.table.new_tracks.user_tracks)
self.assertFalse(self.table.new_tracks.tracks_movable)
self.assertEqual(self.table.lookup("New Tracks"),
self.table.new_tracks)
def test_new_tracks_tracks(self):
"""Test the New Tracks track functions."""
self.table.new_tracks.add_track(self.track)
self.assertTrue(self.table.new_tracks.has_track(self.track))
self.library.deleting = True
self.table.new_tracks.reload_tracks()
self.assertFalse(self.table.new_tracks.has_track(self.track))
self.library.deleting = False
self.table.new_tracks.reload_tracks()
self.assertTrue(self.table.new_tracks.has_track(self.track))
self.table.new_tracks.remove_track(self.track)
self.assertFalse(self.table.new_tracks.has_track(self.track))
def test_previous(self):
"""Test the previous tracks playlist."""
self.assertIsInstance(self.table.previous,
emmental.db.playlists.Playlist)
self.assertEqual(self.table.previous.name, "Previous Tracks")
self.assertEqual(self.table.previous.loop, "None")
self.assertEqual(self.table.previous.sort_order, "laststarted DESC")
self.assertFalse(self.table.previous.active)
self.assertFalse(self.table.previous.shuffle)
self.assertFalse(self.table.previous.user_tracks)
self.assertFalse(self.table.previous.tracks_movable)
self.assertEqual(self.table.lookup("Previous Tracks"),
self.table.previous)
def test_previous_loop(self):
"""Test that the Previous::loop property cannot be disabled."""
for loop in ["Track", "Playlist"]:
with self.subTest(loop=loop):
cur = self.sql("""UPDATE playlist_properties
SET loop=? WHERE propertyid=?""",
loop, self.table.previous.propertyid)
self.assertIsNone(cur)
self.table.previous.loop = loop
self.assertEqual(self.table.previous.loop, "None")
def test_previous_shuffle(self):
"""Test that the Previous::shuffle property cannot be enabled."""
self.assertIsNone(self.sql("""UPDATE playlist_properties
SET shuffle=TRUE WHERE propertyid=?""",
self.table.previous.propertyid))
self.assertFalse(self.table.previous.shuffle)
self.table.previous.shuffle = True
self.assertFalse(self.table.previous.shuffle)
def test_previous_sort_order(self):
"""Test that the Previous::sort-order property cannot be changed."""
self.assertIsNone(self.sql("""UPDATE playlist_properties
SET sort_order='trackid'
WHERE propertyid=?""",
self.table.previous.propertyid))
self.assertEqual(self.table.previous.sort_order, "laststarted DESC")
self.table.previous.sort_order = "trackid"
self.assertEqual(self.table.previous.sort_order, "laststarted DESC")
def test_previous_tracks(self):
"""Test the Previous Tracks track functions."""
self.table.previous.add_track(self.track)
self.assertTrue(self.table.previous.has_track(self.track))
rows = self.sql("SELECT trackid FROM system_tracks WHERE propertyid=?",
self.table.previous.propertyid).fetchall()
self.assertEqual(len(rows), 1)
self.assertEqual(rows[0]["trackid"], self.track.trackid)
self.library.deleting = True
self.table.previous.reload_tracks()
self.assertFalse(self.table.previous.has_track(self.track))
self.library.deleting = False
self.table.previous.reload_tracks()
self.assertTrue(self.table.previous.has_track(self.track))
self.table.previous.remove_track(self.track)
self.assertFalse(self.table.previous.has_track(self.track))
rows = self.sql("SELECT trackid FROM system_tracks WHERE propertyid=?",
self.table.previous.propertyid).fetchall()
self.assertEqual(len(rows), 0)
def test_previous_tracks_reset(self):
"""Test that the Previous Tracks are reset during startup."""
self.table.previous.add_track(self.track)
self.table.load(now=True)
rows = self.sql("SELECT trackid FROM system_tracks WHERE propertyid=?",
self.table.previous.propertyid).fetchall()
self.assertEqual(len(rows), 0)
def test_queued(self):
"""Test the queued tracks playlist."""
self.assertIsInstance(self.table.queued,
emmental.db.playlists.Playlist)
self.assertEqual(self.table.queued.name, "Queued Tracks")
self.assertEqual(self.table.queued.loop, "None")
self.assertEqual(self.table.queued.sort_order,
"albumartist, album, mediumno, number")
self.assertTrue(self.table.queued.user_tracks)
self.assertTrue(self.table.queued.tracks_movable)
self.assertFalse(self.table.queued.active)
self.assertFalse(self.table.queued.shuffle)
self.assertEqual(self.table.lookup("Queued Tracks"),
self.table.queued)
def test_queued_tracks(self):
"""Test the Queued Tracks track functions."""
self.table.queued.add_track(self.track)
self.assertTrue(self.table.queued.has_track(self.track))
rows = self.sql("SELECT trackid FROM user_tracks WHERE propertyid=?",
self.table.queued.propertyid).fetchall()
self.assertEqual(len(rows), 1)
self.assertEqual(rows[0]["trackid"], self.track.trackid)
self.assertEqual(self.sql.active_playlist, self.table.queued)
self.sql.set_active_playlist(self.table.collection)
self.table.queued.add_track(self.track)
self.assertEqual(self.sql.active_playlist, self.table.queued)
self.library.deleting = True
self.table.queued.reload_tracks()
self.assertFalse(self.table.queued.has_track(self.track))
self.library.deleting = False
self.table.queued.reload_tracks()
self.assertTrue(self.table.queued.has_track(self.track))
self.table.queued.remove_track(self.track)
self.assertFalse(self.table.queued.has_track(self.track))
rows = self.sql("SELECT trackid FROM user_tracks WHERE propertyid=?",
self.table.queued.propertyid).fetchall()
self.assertEqual(len(rows), 0)
def test_unplayed(self):
"""Test the unplayed tracks playlist."""
self.assertIsInstance(self.table.unplayed,
emmental.db.playlists.Playlist)
self.assertEqual(self.table.unplayed.name, "Unplayed Tracks")
self.assertEqual(self.table.unplayed.loop, "None")
self.assertEqual(self.table.unplayed.sort_order,
"albumartist, album, mediumno, number")
self.assertFalse(self.table.unplayed.active)
self.assertFalse(self.table.unplayed.shuffle)
self.assertFalse(self.table.unplayed.user_tracks)
self.assertFalse(self.table.unplayed.tracks_movable)
self.assertEqual(self.table.lookup("Unplayed Tracks"),
self.table.unplayed)
def test_unplayed_tracks(self):
"""Test the Unplayed Tracks track functions."""
self.table.unplayed.add_track(self.track)
self.assertTrue(self.table.unplayed.has_track(self.track))
self.library.deleting = True
self.table.unplayed.reload_tracks()
self.assertFalse(self.table.unplayed.has_track(self.track))
self.library.deleting = False
self.table.unplayed.reload_tracks()
self.assertTrue(self.table.unplayed.has_track(self.track))
self.table.unplayed.remove_track(self.track)
self.assertFalse(self.table.unplayed.has_track(self.track))
self.sql("UPDATE tracks SET playcount=1 WHERE trackid=?",
self.track.trackid)
self.table.unplayed.reload_tracks()
self.assertFalse(self.table.unplayed.has_track(self.track))