# Copyright 2022 (c) Anna Schumaker. """Tests our application header.""" import emmental import tests.util import pathlib import unittest.mock from gi.repository import Gtk from gi.repository import Adw class TestHeader(tests.util.TestCase): """Test case for our custom Gtk.HeaderBar.""" def setUp(self): """Set up common variables.""" super().setUp() self.header = emmental.header.Header(sql=self.sql, title="Test Title") def test_constants(self): """Check that constants are set correctly.""" self.assertEqual(emmental.header.SUBTITLE, "The Cheesy Music Player") def test_title(self): """Check that the title is set correctly.""" self.assertIsInstance(self.header, Gtk.HeaderBar) self.assertIsInstance(self.header._title, Adw.WindowTitle) self.assertEqual(self.header.get_title_widget(), self.header._title) self.assertEqual(self.header.title, "Test Title") self.assertEqual(self.header._title.get_title(), "Test Title") self.assertEqual(self.header.subtitle, emmental.header.SUBTITLE) self.assertEqual(self.header._title.get_subtitle(), emmental.header.SUBTITLE) self.assertEqual(self.header._title.get_tooltip_text(), emmental.gsetup.env_string()) def test_show_sidebar(self): """Check that the show sidebar button works as expected.""" self.assertIsInstance(self.header._show_sidebar, Gtk.ToggleButton) self.assertEqual(self.header._show_sidebar.props.icon_name, "sidebar-show-symbolic") self.assertFalse(self.header._show_sidebar.props.has_frame) self.assertFalse(self.header._show_sidebar.props.active) self.assertFalse(self.header.show_sidebar) self.header.show_sidebar = True self.assertTrue(self.header._show_sidebar.props.active) self.header._show_sidebar.props.active = False self.assertFalse(self.header.show_sidebar) def test_open(self): """Check that the Open button works as expected.""" self.assertIsInstance(self.header._open, emmental.header.open.Button) signal = unittest.mock.Mock() self.header.connect("track-requested", signal) self.header._open.emit("track-requested", pathlib.Path("/a/b/c/1.ogg")) signal.assert_called_with(self.header, pathlib.Path("/a/b/c/1.ogg")) def test_settings(self): """Check that the Settings window is set up correctly.""" self.assertIsInstance(self.header._settings, Gtk.Button) self.assertIsInstance(self.header._window, emmental.header.settings.Window) self.assertEqual(self.header.sql, self.sql) self.assertEqual(self.header._settings.get_icon_name(), "settings-symbolic") self.assertEqual(self.header._settings.get_tooltip_text(), "open settings editor") with unittest.mock.patch.object(self.header._window, "present") as mock_present: self.header._settings.emit("clicked") mock_present.assert_called() def test_volume_icons(self): """Check that the volume icons box is set up properly.""" self.assertIsInstance(self.header._icons, Gtk.Box) self.assertIsInstance(self.header._volume_icon, Gtk.Image) self.assertIsInstance(self.header._background_icon, Gtk.Image) self.assertEqual(self.header._icons.get_spacing(), 6) self.assertEqual(self.header._icons.get_first_child(), self.header._volume_icon) self.assertEqual(self.header._volume_icon.get_next_sibling(), self.header._background_icon) def test_volume(self): """Check that volume widgets work as expected.""" self.assertIsInstance(self.header._volume, emmental.header.volume.VolumeRow) self.assertEqual(self.header.volume, 1.0) for i, vol in [(x, x/10) for x in range(11)]: with self.subTest(volume=vol): widget = self.header if i % 2 else self.header._volume match i: case 0: icon = "muted" case 1 | 2 | 3: icon = "low" case 4 | 5 | 6: icon = "medium" case _: icon = "high" widget.volume = vol self.assertEqual(self.header.volume, vol) self.assertEqual(self.header._volume.volume, vol) self.assertEqual(self.header._volume_icon.get_icon_name(), f"audio-volume-{icon}-symbolic") self.assertEqual(self.header._button.get_tooltip_text(), f"volume: {i*10}%\n" "background listening: off\nnormalizing: off") def test_background_listening(self): """Test the background listening mode.""" self.assertIsInstance(self.header._background, emmental.header.volume.BackgroundRow) self.assertEqual(self.header._background_icon.get_icon_name(), "sound-wave") self.assertFalse(self.header.bg_enabled) self.assertEqual(self.header.bg_volume, 0.5) self.header.bg_enabled = True self.assertTrue(self.header._background.enabled) self.assertEqual(self.header._background_icon.get_icon_name(), "sound-wave-alt") self.assertEqual(self.header._button.get_tooltip_text(), "volume: 100%\nbackground listening: 50%\n" "normalizing: off") self.header.bg_volume = 0.75 self.assertEqual(self.header._background.volume, 0.75) self.assertEqual(self.header._button.get_tooltip_text(), "volume: 100%\nbackground listening: 75%\n" "normalizing: off") self.header._background.volume = 0.25 self.assertEqual(self.header.bg_volume, 0.25) self.assertEqual(self.header._button.get_tooltip_text(), "volume: 100%\nbackground listening: 25%\n" "normalizing: off") self.header._background.enabled = False self.assertFalse(self.header.bg_enabled) self.assertEqual(self.header._background_icon.get_icon_name(), "sound-wave") def test_replaygain(self): """Test that we can configure ReplayGain as expected.""" self.assertIsInstance(self.header._replaygain, emmental.header.replaygain.ReplayGainRow) self.assertFalse(self.header.rg_enabled) self.assertEqual(self.header.rg_mode, "auto") self.header.rg_enabled = True self.header.rg_mode = "track" self.assertTrue(self.header._replaygain.enabled) self.assertEqual(self.header._replaygain.mode, "track") self.assertEqual(self.header._button.get_tooltip_text(), "volume: 100%\nbackground listening: off\n" "normalizing: track mode") self.header._replaygain.enabled = False self.header._replaygain.mode = "album" self.assertFalse(self.header.rg_enabled) self.assertEqual(self.header.rg_mode, "album") self.assertEqual(self.header._button.get_tooltip_text(), "volume: 100%\nbackground listening: off\n" "normalizing: off") def test_popover_button(self): """Check that the menu popover button was set up correctly.""" self.assertIsInstance(self.header._button, emmental.buttons.PopoverButton) self.assertEqual(self.header._button.popover_child, self.header._box) self.assertEqual(self.header._button.get_child(), self.header._icons) self.assertEqual(self.header._button.get_margin_end(), 6) self.assertFalse(self.header._button.get_has_frame()) def test_popover_child(self): """Check that the menu popover button child was set up correctly.""" self.assertIsInstance(self.header._box, Gtk.ListBox) self.assertEqual(self.header._box.get_selection_mode(), Gtk.SelectionMode.NONE) self.assertTrue(self.header._box.has_css_class("boxed-list")) self.assertEqual(self.header._box.get_row_at_index(0), self.header._volume) self.assertEqual(self.header._box.get_row_at_index(1), self.header._background) self.assertEqual(self.header._box.get_row_at_index(2), self.header._replaygain) def test_accelerators(self): """Check that the accelerators list is set up properly.""" entries = [("open-file", self.header._open.activate, "o"), ("decrease-volume", self.header._volume.decrement, "Down"), ("increase-volume", self.header._volume.increment, "Up"), ("toggle-bg-mode", self.header._background.activate, "b"), ("toggle-sidebar", self.header._show_sidebar.activate, "bracketright"), ("edit-settings", self.header._settings.activate, "s")] accels = self.header.accelerators self.assertIsInstance(accels, list) for i, (name, func, accel) in enumerate(entries): with self.subTest(name=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]) self.assertEqual(len(accels), i + 1)