emmental/tests/sidebar/test_section.py

236 lines
9.7 KiB
Python

# Copyright 2022 (c) Anna Schumaker.
"""Tests our sidebar section widget."""
import emmental.db
import emmental.sidebar.section
import tests.util
import unittest.mock
from gi.repository import GObject
from gi.repository import GLib
from gi.repository import Gtk
class TestSection(tests.util.TestCase):
"""Test our sidebar section widget."""
def setUp(self):
"""Set up common variables."""
super().setUp()
self.table = tests.util.playlist.MockTable(self.sql)
self.row_type = emmental.sidebar.row.TreeRow
self.section = emmental.sidebar.section.Section(self.table,
self.row_type)
def test_init(self):
"""Test that the sidebar Section is set up properly."""
self.assertIsInstance(self.section, emmental.sidebar.header.Header)
self.assertIsInstance(self.section.reveal_widget, Gtk.ScrolledWindow)
self.assertEqual(self.section.reveal_widget.get_policy(),
(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC))
self.assertTrue(self.section.has_css_class("emmental-sidebar-section"))
def test_listview(self):
"""Test the listview widget."""
self.assertIsInstance(self.section._selection, Gtk.SingleSelection)
self.assertIsInstance(self.section._factory, emmental.factory.Factory)
self.assertIsInstance(self.section._listview, Gtk.ListView)
self.assertEqual(self.section.table, self.table)
self.assertEqual(self.section._selection.get_model(),
self.table.treemodel)
self.assertFalse(self.section._selection.get_autoselect())
self.assertEqual(self.section._factory.row_type, self.row_type)
self.assertEqual(self.section._listview.get_model(),
self.section._selection)
self.assertEqual(self.section._listview.get_factory(),
self.section._factory)
self.assertTrue(self.section._listview.has_css_class(
"navigation-sidebar"))
self.assertEqual(self.section.reveal_widget.get_child(),
self.section._listview)
def test_progress(self):
"""Test that the header progress property is wired up correctly."""
self.assertFalse(self.section.pending)
self.assertEqual(self.section.progress, 0.0)
self.table.queue.running = True
self.table.queue.progress = 0.5
self.assertTrue(self.section.pending)
self.assertEqual(self.section.progress, 0.5)
section2 = emmental.sidebar.section.Section(self.table, self.row_type)
self.assertTrue(section2.pending)
def test_do_get_subtitle(self):
"""Test updating the subtitle when the treemodel items change."""
with self.assertRaises(NotImplementedError):
self.assertEqual(self.section.do_get_subtitle(42))
self.section.do_get_subtitle = unittest.mock.Mock()
self.section.do_get_subtitle.return_value = "My Subtitle"
self.table.treemodel.items_changed(0, 0, 0)
self.assertEqual(self.section.subtitle, "My Subtitle")
self.section.do_get_subtitle.assert_called_with(0)
def test_clear_selection(self):
"""Test clearing the currently selected playlist."""
with unittest.mock.patch.object(self.section._selection,
"set_selected") as mock_set_selected:
self.section.clear_selection()
mock_set_selected.assert_called_with(Gtk.INVALID_LIST_POSITION)
def test_playlist_index(self):
"""Test finding the index of a specific playlist."""
self.section.do_get_subtitle = unittest.mock.Mock(return_value="")
playlists = [self.table.create(f"Playlist {i}") for i in range(3)]
for i, playlist in enumerate(playlists):
with self.subTest(i=i, playlist=playlist):
self.assertEqual(self.section.playlist_index(playlist), i)
table2 = tests.util.playlist.MockTable(self.sql)
table2.do_sql_update = unittest.mock.Mock(return_value=True)
children = [table2.create(f"Child {i}") for i in range(3)]
playlists[1].children = Gtk.FilterListModel.new(table2, None)
for i, child in enumerate(children):
child.parent = playlists[1]
with self.subTest(i=i, child=child):
self.assertEqual(self.section.playlist_index(child), i + 2)
def test_select_playlist(self):
"""Test selecting a specific playlist."""
self.section.do_get_subtitle = unittest.mock.Mock(return_value="")
playlist_selected = unittest.mock.Mock()
self.section.connect("playlist-selected", playlist_selected)
playlist = self.table.create("Test Playlist")
playlist_selected.assert_not_called()
with unittest.mock.patch.object(self.section._listview,
"activate_action") as mock_action:
self.section.select_playlist(playlist)
playlist_selected.assert_called_with(self.section, playlist)
mock_action.assert_called_with("list.scroll-to-item",
GLib.Variant.new_uint32(0))
def test_playlist_selected(self):
"""Test selecting a playlist in the list."""
self.section.do_get_subtitle = unittest.mock.Mock(return_value="")
playlist_selected = unittest.mock.Mock()
self.section.connect("playlist-selected", playlist_selected)
playlist = self.table.create("Test Playlist")
self.section._selection.set_selected(0)
playlist_selected.assert_called_with(self.section, playlist)
playlist_selected.reset_mock()
self.section.clear_selection()
playlist_selected.assert_not_called()
def test_playlist_activated(self):
"""Test activating a playlist."""
self.section.do_get_subtitle = unittest.mock.Mock(return_value="")
playlist_activated = unittest.mock.Mock()
self.section.connect("playlist-activated", playlist_activated)
playlist = self.table.create("Test Playlist")
self.section._listview.emit("activate", 0)
playlist_activated.assert_called_with(self.section, playlist)
class TestGroup(tests.util.TestCase):
"""Test our sidebar section group."""
def setUp(self):
"""Set up common variables."""
super().setUp()
self.group = emmental.sidebar.section.Group(self.sql)
self.row_type = emmental.sidebar.row.TreeRow
self.section1 = emmental.sidebar.section.Section(self.sql.playlists,
self.row_type)
self.section2 = emmental.sidebar.section.Section(self.sql.genres,
self.row_type)
self.section1.do_get_subtitle = unittest.mock.Mock(return_value="")
self.section2.do_get_subtitle = unittest.mock.Mock(return_value="")
def test_init(self):
"""Test that the Group is set up properly."""
self.assertIsInstance(self.group, GObject.GObject)
self.assertListEqual(self.group._sections, [])
self.assertEqual(self.group.sql, self.sql)
def test_add(self):
"""Test adding sections to the Group."""
self.group.add(self.section1)
self.assertListEqual(self.group._sections, [self.section1])
self.group.add(self.section2)
self.assertListEqual(self.group._sections,
[self.section1, self.section2])
def test_current(self):
"""Test the current section property."""
self.group.add(self.section1)
self.group.add(self.section2)
self.assertIsNone(self.group.current)
self.section1.active = True
self.assertEqual(self.group.current, self.section1)
self.section2.active = True
self.assertEqual(self.group.current, self.section2)
self.assertFalse(self.section1.active)
def test_animation(self):
"""Test setting the section animation style."""
self.group.add(self.section1)
self.group.add(self.section2)
self.section1.active = True
self.assertEqual(self.section1.animation,
Gtk.RevealerTransitionType.SLIDE_DOWN)
self.section2.active = True
self.assertEqual(self.section2.animation,
Gtk.RevealerTransitionType.SLIDE_UP)
def test_playlist_activated(self):
"""Test responding to the section playlist-activated signal."""
self.group.add(self.section1)
self.group.add(self.section2)
self.assertIsNone(self.sql.active_playlist)
playlist = self.sql.playlists.create("Test Playlist")
self.section1.emit("playlist-activated", playlist)
self.assertEqual(self.sql.active_playlist, playlist)
genre = self.sql.genres.create("Test Genre")
self.section2.emit("playlist-activated", genre)
self.assertEqual(self.sql.active_playlist, genre)
def test_selections(self):
"""Test the selected section & playlist properties."""
self.group.add(self.section1)
self.group.add(self.section2)
self.assertIsNone(self.group.selected_section)
self.assertIsNone(self.group.selected_playlist)
genre = self.sql.genres.create("Test Genre")
self.section2.emit("playlist-selected", genre)
self.assertEqual(self.group.selected_section, self.section2)
self.assertEqual(self.group.selected_playlist, genre)
self.section2.active = True
treerow = self.section2._selection.get_selected_item()
self.assertEqual(treerow.get_item(), genre)
playlist = self.sql.playlists.create("Test Playlist")
self.section1.emit("playlist-selected", playlist)
self.assertIsNone(self.section2._selection.get_selected_item())