emmental/tests/db/test_libraries.py
Anna Schumaker 24c1a31367 db: Add a Library Table
This table allows us to work with Library playlists that are represented
by a filesystem path. The user can manually enable or disable library
paths to prevent their tracks from showing up in the Collection
playlist. Additionally, library paths have an online property to
determine if the library still exists in the filesystem to prevent us
from removing tracks due to a broken NFS mount or symlink.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2023-04-12 10:44:34 -04:00

187 lines
7.3 KiB
Python

# Copyright 2022 (c) Anna Schumaker
"""Tests our library Gio.ListModel."""
import pathlib
import emmental.db
import tests.util
import unittest.mock
class TestLibraryObject(tests.util.TestCase):
"""Tests our library object."""
def setUp(self):
"""Set up common variables."""
super().setUp()
self.table = self.sql.libraries
self.path = pathlib.Path("/a/b/c")
self.library = emmental.db.libraries.Library(table=self.table,
libraryid=123,
propertyid=456,
path=self.path,
name=str(self.path))
def test_init(self):
"""Test that the Library is set up properly."""
self.assertIsInstance(self.library, emmental.db.playlist.Playlist)
self.assertIsInstance(self.library.queue, emmental.db.idle.Queue)
self.assertEqual(self.library.table, self.table)
self.assertEqual(self.library.propertyid, 456)
self.assertEqual(self.library.libraryid, 123)
self.assertEqual(self.library.primary_key, 123)
self.assertEqual(self.library.path, self.path)
self.assertTrue(self.library.enabled)
self.assertFalse(self.library.deleting)
self.assertFalse(self.library.online)
self.assertIsNone(self.library.parent)
def test_delete(self):
"""Test deleting a Library path."""
with unittest.mock.patch.object(self.table, "delete") as mock_delete:
with unittest.mock.patch.object(self.table, "update"):
self.assertTrue(self.library.delete())
self.assertTrue(self.library.deleting)
mock_delete.assert_not_called()
self.assertEqual(self.library.queue[0],
(self.library._Library__queue_delete,))
self.assertFalse(self.library.delete())
self.assertEqual(self.library.queue.total, 1)
self.library.queue.complete()
mock_delete.assert_called_with(self.library)
def test_online(self):
"""Test that changing the online property notifies the table."""
with unittest.mock.patch.object(self.table,
"notify_online") as mock_notify:
self.library.online = True
mock_notify.assert_called_with(self.library)
class TestLibraryTable(tests.util.TestCase):
"""Tests our library table."""
def setUp(self):
"""Set up common variables."""
tests.util.TestCase.setUp(self)
self.table = self.sql.libraries
def test_init(self):
"""Test that the library model is configured correctly."""
self.assertIsInstance(self.table, emmental.db.playlist.Table)
self.assertEqual(len(self.table), 0)
def test_construct(self):
"""Test constructing a new library."""
library = self.table.construct(propertyid=1, libraryid=1,
path=pathlib.Path("/a/b/c"),
name="/a/b/c")
self.assertIsInstance(library, emmental.db.libraries.Library)
self.assertEqual(library.table, self.table)
self.assertEqual(library.propertyid, 1)
self.assertEqual(library.libraryid, 1)
self.assertEqual(library.path, pathlib.Path("/a/b/c"))
self.assertEqual(library.name, "/a/b/c")
self.assertFalse(library.active)
def test_create(self):
"""Test creating a library."""
library = self.table.create(pathlib.Path("/a/b/c"))
self.assertIsInstance(library, emmental.db.libraries.Library)
self.assertEqual(library.path, pathlib.Path("/a/b/c"))
cur = self.sql("SELECT COUNT(path) FROM libraries")
self.assertEqual(cur.fetchone()["COUNT(path)"], 1)
self.assertEqual(len(self.table.store), 1)
self.assertEqual(self.table.store.get_item(0), library)
cur = self.sql("""SELECT COUNT(*) FROM playlist_properties
WHERE propertyid=?""", library.propertyid)
self.assertEqual(cur.fetchone()["COUNT(*)"], 1)
self.assertIsNone(self.table.create("/a/b/c"))
def test_delete(self):
"""Test deleting a library."""
library = self.table.create(pathlib.Path("/a/b/c"))
self.assertTrue(self.table.delete(library))
self.assertIsNone(self.table.index(library))
cur = self.sql("SELECT COUNT(path) FROM libraries")
self.assertEqual(cur.fetchone()["COUNT(path)"], 0)
self.assertEqual(len(self.table), 0)
self.assertIsNone(self.table.get_item(0))
cur = self.sql("""SELECT COUNT(*) FROM playlist_properties
WHERE propertyid=?""", library.propertyid)
self.assertEqual(cur.fetchone()["COUNT(*)"], 0)
self.assertFalse(self.table.delete(library))
def test_filter(self):
"""Test filtering the library model."""
self.table.create(pathlib.Path("/a/b/c"))
self.table.create(pathlib.Path("/a/b/d"))
self.table.filter("*c", now=True)
self.assertSetEqual(self.table.get_filter().keys, {1})
self.table.filter("*a/b*", now=True)
self.assertSetEqual(self.table.get_filter().keys, {1, 2})
def test_load(self):
"""Test loading libraries from the database."""
self.table.create("/a/b/c")
self.table.create("/a/b/d").enabled = False
libraries2 = emmental.db.libraries.Table(self.sql)
self.assertEqual(len(libraries2), 0)
libraries2.load(now=True)
self.assertEqual(len(libraries2), 2)
self.assertEqual(libraries2.get_item(0).libraryid, 1)
self.assertEqual(libraries2.get_item(0).path, pathlib.Path("/a/b/c"))
self.assertTrue(libraries2.get_item(0).enabled)
self.assertEqual(libraries2.get_item(1).libraryid, 2)
self.assertEqual(libraries2.get_item(1).path, pathlib.Path("/a/b/d"))
self.assertFalse(libraries2.get_item(1).enabled)
def test_lookup(self):
"""Test looking up a library."""
library = self.table.create(pathlib.Path("/a/b/c"))
self.assertEqual(self.table.lookup(pathlib.Path("/a/b/c/")), library)
self.assertIsNone(self.table.lookup(pathlib.Path("/no/library/path")))
def test_update(self):
"""Test updating genre attributes."""
library = self.table.create("/a/b/c")
library.active = True
library.enabled = False
row = self.sql("""SELECT active, enabled FROM libraries_view
WHERE libraryid=?""", library.libraryid).fetchone()
self.assertTrue(row["active"])
self.assertFalse(row["enabled"])
def test_library_online(self):
"""Test the library-online signal."""
library = self.table.create(pathlib.Path("/a/b/c"))
callback = unittest.mock.Mock()
self.table.connect("library-online", callback)
library.online = True
callback.assert_not_called()
library.online = False
callback.assert_called_with(self.table, library)
callback.reset_mock()
self.table.loaded = True
library.online = True
callback.assert_called_with(self.table, library)
callback.reset_mock()
library.online = False
callback.assert_called_with(self.table, library)