emmental/tests/sidebar/test_sidebar.py
Anna Schumaker 2504f4b91d sidebar: Add a timeout when selecting playlists on load
I've found that during startup, we sometimes try to select the current
playlist before the Gtk sidebar widgets are completely loaded. This
results showing the right section, but not actually selecting a
playlist. We can fix this by selecting the playlist after a short
timeout to give everything a chance to load.

Signed-off-by: Anna Schumaker <Anna@NoWheyCreamery.com>
2023-08-30 13:22:28 -04:00

230 lines
10 KiB
Python

# Copyright 2022 (c) Anna Schumaker.
"""Tests our playlist Sidebar card."""
import emmental.sidebar
import tests.util
import unittest.mock
from gi.repository import GLib
from gi.repository import Gtk
class TestSidebar(tests.util.TestCase):
"""Tests the Sidebar card."""
def setUp(self):
"""Set up common variables."""
super().setUp()
self.sidebar = emmental.sidebar.Card(sql=self.sql)
def test_init(self):
"""Test that the Sidebar has been set up correctly."""
self.assertIsInstance(self.sidebar, Gtk.Box)
self.assertEqual(self.sidebar.sql, self.sql)
self.assertEqual(self.sidebar.get_orientation(),
Gtk.Orientation.VERTICAL)
self.assertFalse(self.sidebar.get_sensitive())
self.assertTrue(self.sidebar.has_css_class("card"))
def test_header(self):
"""Test the Sidebar header."""
self.assertIsInstance(self.sidebar._header, Gtk.CenterBox)
self.assertEqual(self.sidebar.get_first_child(), self.sidebar._header)
self.assertTrue(self.sidebar._header.has_css_class("toolbar"))
def test_filter(self):
"""Test the Sidebar filter entry."""
self.assertIsInstance(self.sidebar._filter, emmental.entry.Filter)
self.assertEqual(self.sidebar._header.get_center_widget(),
self.sidebar._filter)
self.assertEqual(self.sidebar._filter.get_placeholder_text(),
"type to filter playlists")
self.assertTrue(self.sidebar._filter.get_hexpand())
with unittest.mock.patch.object(self.sql, "filter") as mock_filter:
self.sidebar._filter.set_text("test text")
self.sidebar._filter.emit("search-changed")
mock_filter.assert_called_with("*test text*")
def test_jump(self):
"""Test the jump button."""
self.assertIsInstance(self.sidebar._jump, Gtk.Button)
self.assertEqual(self.sidebar._header.get_end_widget(),
self.sidebar._jump)
self.assertEqual(self.sidebar._jump.get_icon_name(),
"go-jump-symbolic")
self.assertEqual(self.sidebar._jump.get_tooltip_text(),
"scroll to current playlist")
self.sql.playlists.load(now=True)
with unittest.mock.patch.object(self.sidebar,
"select_playlist") as mock_select:
self.sidebar._jump.emit("clicked")
mock_select.assert_called_with(self.sql.active_playlist)
def test_sensitivity_and_startup(self):
"""Test setting the sidebar sensitivity when all tables have loaded."""
tables = [t for t in self.sql.playlist_tables()]
self.sidebar.select_playlist = unittest.mock.Mock()
self.sidebar._libraries.extra_widget.emit = unittest.mock.Mock()
for table in tables:
self.assertFalse(self.sidebar.get_sensitive())
self.sidebar.select_playlist.assert_not_called()
self.sidebar._libraries.extra_widget.emit.assert_not_called()
table.load(now=True)
self.assertEqual(self.sidebar.get_sensitive(),
table == tables[-1])
playlist = self.sql.playlists.collection
self.sidebar.select_playlist.assert_called_with(playlist, 150)
self.sidebar._libraries.extra_widget.emit.assert_called_with("clicked")
self.sidebar.select_playlist.reset_mock()
self.sql.emit("table-loaded", tables[0])
self.sidebar.select_playlist.assert_not_called()
def test_show_all_artists(self):
"""Test the show-all-artists property."""
self.assertFalse(self.sidebar.show_all_artists)
self.sidebar.show_all_artists = True
self.assertTrue(self.sidebar._artists.show_all)
self.sidebar._artists.show_all = False
self.assertFalse(self.sidebar.show_all_artists)
def test_selected_playlist(self):
"""Test the selected-playlist property."""
self.assertIsNone(self.sidebar.selected_playlist)
playlist1 = self.sql.playlists.create("Playlist 1")
self.sidebar._view.selected_playlist = playlist1
self.assertEqual(self.sidebar.selected_playlist, playlist1)
def test_view(self):
"""Test that sidebar sections are in the View."""
self.assertIsInstance(self.sidebar._view,
emmental.sidebar.section.View)
self.assertEqual(self.sidebar._header.get_next_sibling(),
self.sidebar._view)
self.assertListEqual(self.sidebar._view._sections,
[self.sidebar._playlists,
self.sidebar._artists,
self.sidebar._genres,
self.sidebar._decades,
self.sidebar._libraries])
def test_sections(self):
"""Tests sidebar section models."""
self.assertIsInstance(self.sidebar._playlists,
emmental.sidebar.playlist.Section)
self.assertIsInstance(self.sidebar._artists,
emmental.sidebar.artist.Section)
self.assertIsInstance(self.sidebar._genres,
emmental.sidebar.genre.Section)
self.assertIsInstance(self.sidebar._decades,
emmental.sidebar.decade.Section)
self.assertIsInstance(self.sidebar._libraries,
emmental.sidebar.library.Section)
self.assertEqual(self.sidebar._view.get_first_child(),
self.sidebar._playlists)
self.assertEqual(self.sidebar._playlists.get_next_sibling(),
self.sidebar._artists)
self.assertEqual(self.sidebar._artists.get_next_sibling(),
self.sidebar._genres)
self.assertEqual(self.sidebar._genres.get_next_sibling(),
self.sidebar._decades)
self.assertEqual(self.sidebar._decades.get_next_sibling(),
self.sidebar._libraries)
self.assertEqual(self.sidebar._playlists.table, self.sql.playlists)
self.assertEqual(self.sidebar._artists.table, self.sql.artists)
self.assertEqual(self.sidebar._artists.album_table, self.sql.albums)
self.assertEqual(self.sidebar._genres.table, self.sql.genres)
self.assertEqual(self.sidebar._decades.table, self.sql.decades)
self.assertEqual(self.sidebar._decades.year_table, self.sql.years)
self.assertEqual(self.sidebar._libraries.table, self.sql.libraries)
def test_select_playlist(self):
"""Test setting the active playlist."""
self.assertEqual(self.sidebar._Card__select_playlist(None),
GLib.SOURCE_REMOVE)
playlist = self.sql.playlists.create("Test Playlist")
with unittest.mock.patch.object(self.sidebar._playlists,
"select_playlist") as mock_select:
self.assertEqual(self.sidebar._Card__select_playlist(playlist),
GLib.SOURCE_CONTINUE)
self.assertTrue(self.sidebar._playlists.active)
mock_select.assert_not_called()
self.assertEqual(self.sidebar._Card__select_playlist(playlist),
GLib.SOURCE_REMOVE)
mock_select.assert_called_with(playlist)
with unittest.mock.patch.object(GLib, "timeout_add") as mock_to:
self.sidebar.select_playlist(playlist)
mock_to.assert_called_with(0, self.sidebar._Card__select_playlist,
playlist)
self.sidebar.select_playlist(playlist, 42)
mock_to.assert_called_with(42, self.sidebar._Card__select_playlist,
playlist)
def test_table_section(self):
"""Test converting a Playlist database table into a Section."""
self.assertEqual(self.sidebar.table_section(self.sql.playlists),
self.sidebar._playlists)
self.assertEqual(self.sidebar.table_section(self.sql.artists),
self.sidebar._artists)
self.assertEqual(self.sidebar.table_section(self.sql.albums),
self.sidebar._artists)
self.assertEqual(self.sidebar.table_section(self.sql.media),
self.sidebar._artists)
self.assertEqual(self.sidebar.table_section(self.sql.genres),
self.sidebar._genres)
self.assertEqual(self.sidebar.table_section(self.sql.decades),
self.sidebar._decades)
self.assertEqual(self.sidebar.table_section(self.sql.years),
self.sidebar._decades)
self.assertEqual(self.sidebar.table_section(self.sql.libraries),
self.sidebar._libraries)
self.assertIsNone(self.sidebar.table_section(None))
def test_accelerators(self):
"""Check that the accelerators list is set up properly."""
entries = [("focus-search-playlist", self.sidebar._filter.grab_focus,
["<Control>question"]),
("goto-active-playlist", self.sidebar._jump.activate,
["<Control><Alt>g"]),
("goto-playlists", self.sidebar._playlists.activate,
["<Shift><Control>p"]),
("goto-artists", self.sidebar._artists.activate,
["<Shift><Control>a"]),
("goto-genres", self.sidebar._genres.activate,
["<Shift><Control>g"]),
("goto-decades", self.sidebar._decades.activate,
["<Shift><Control>d"]),
("goto-libraries", self.sidebar._libraries.activate,
["<Shift><Control>l"])]
accels = self.sidebar.accelerators
self.assertIsInstance(accels, list)
for i, (name, func, accel) in enumerate(entries):
with self.subTest(action=name):
self.assertIsInstance(accels[i], emmental.action.ActionEntry)
self.assertEqual(accels[i].name, name)
self.assertEqual(accels[i].func, func)
self.assertListEqual(accels[i].accels, accel)
enabled = self.sidebar.get_sensitive()
self.assertEqual(accels[i].enabled, enabled)
self.sidebar.set_sensitive(not enabled)
self.assertEqual(accels[i].enabled, not enabled)
self.assertEqual(len(accels), i + 1)