diff --git a/openlp/core/ui/media/vlcplayer.py b/openlp/core/ui/media/vlcplayer.py index e2c2ac066..8c2359faf 100644 --- a/openlp/core/ui/media/vlcplayer.py +++ b/openlp/core/ui/media/vlcplayer.py @@ -159,7 +159,7 @@ class VlcPlayer(MediaPlayer): # framework and not the old Carbon. display.vlc_media_player.set_nsobject(win_id) else: - # for Linux using the X Server + # for Linux/*BSD using the X Server display.vlc_media_player.set_xwindow(win_id) self.has_own_widget = True diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index 8c8bfe811..5c28de338 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -551,6 +551,7 @@ class ImageMediaItem(MediaManagerItem): service_item.title = items[0].text(0) else: service_item.title = str(self.plugin.name_strings['plural']) + service_item.add_capability(ItemCapabilities.CanMaintain) service_item.add_capability(ItemCapabilities.CanPreview) service_item.add_capability(ItemCapabilities.CanLoop) @@ -697,3 +698,15 @@ class ImageMediaItem(MediaManagerItem): filename = os.path.split(str(file_object.filename))[1] results.append([file_object.filename, filename]) return results + + def create_item_from_id(self, item_id): + """ + Create a media item from an item id. Overridden from the parent method to change the item type. + + :param item_id: Id to make live + """ + item = QtGui.QTreeWidgetItem() + item_data = self.manager.get_object_filtered(ImageFilenames, ImageFilenames.filename == item_id) + item.setText(0, os.path.basename(item_data.filename)) + item.setData(0, QtCore.Qt.UserRole, item_data) + return item diff --git a/tests/functional/__init__.py b/tests/functional/__init__.py index 5948f480f..12005c16e 100644 --- a/tests/functional/__init__.py +++ b/tests/functional/__init__.py @@ -41,5 +41,6 @@ else: # Only one QApplication can be created. Use QtGui.QApplication.instance() when you need to "create" a QApplication. application = QtGui.QApplication([]) +application.setApplicationName('OpenLP') -__all__ = ['MagicMock', 'patch', 'mock_open', 'call', 'application'] +__all__ = ['ANY', 'MagicMock', 'patch', 'mock_open', 'call', 'application'] diff --git a/tests/functional/openlp_core_ui_media/test_vlcplayer.py b/tests/functional/openlp_core_ui_media/test_vlcplayer.py index 2415fae77..eccac6893 100644 --- a/tests/functional/openlp_core_ui_media/test_vlcplayer.py +++ b/tests/functional/openlp_core_ui_media/test_vlcplayer.py @@ -24,17 +24,31 @@ Package to test the openlp.core.ui.media.vlcplayer package. """ import os import sys - +from datetime import datetime, timedelta from unittest import TestCase -from tests.functional import patch -from openlp.core.ui.media.vlcplayer import get_vlc +from openlp.core.common import Registry +from openlp.core.ui.media import MediaState, MediaType +from openlp.core.ui.media.vlcplayer import AUDIO_EXT, VIDEO_EXT, VlcPlayer, get_vlc + +from tests.functional import MagicMock, patch, call +from tests.helpers import MockDateTime +from tests.helpers.testmixin import TestMixin -class TestVLCPlayer(TestCase): +class TestVLCPlayer(TestCase, TestMixin): """ Test the functions in the :mod:`vlcplayer` module. """ + def setUp(self): + """ + Common setup for all the tests + """ + if 'VLC_PLUGIN_PATH' in os.environ: + del os.environ['VLC_PLUGIN_PATH'] + if 'openlp.core.ui.media.vendor.vlc' in sys.modules: + del sys.modules['openlp.core.ui.media.vendor.vlc'] + MockDateTime.revert() @patch('openlp.core.ui.media.vlcplayer.is_macosx') def fix_vlc_22_plugin_path_test(self, mocked_is_macosx): @@ -43,10 +57,6 @@ class TestVLCPlayer(TestCase): """ # GIVEN: We're on OS X and we don't have the VLC plugin path set mocked_is_macosx.return_value = True - if 'VLC_PLUGIN_PATH' in os.environ: - del os.environ['VLC_PLUGIN_PATH'] - if 'openlp.core.ui.media.vendor.vlc' in sys.modules: - del sys.modules['openlp.core.ui.media.vendor.vlc'] # WHEN: An checking if the player is available get_vlc() @@ -75,3 +85,922 @@ class TestVLCPlayer(TestCase): # THEN: The extra environment variable should NOT be there self.assertNotIn('VLC_PLUGIN_PATH', os.environ, 'The plugin path should NOT be in the environment variables') + + def init_test(self): + """ + Test that the VLC player class initialises correctly + """ + # GIVEN: A mocked out list of extensions + # TODO: figure out how to mock out the lists of extensions + + # WHEN: The VlcPlayer class is instantiated + vlc_player = VlcPlayer(None) + + # THEN: The correct variables are set + self.assertEqual('VLC', vlc_player.original_name) + self.assertEqual('&VLC', vlc_player.display_name) + self.assertIsNone(vlc_player.parent) + self.assertTrue(vlc_player.can_folder) + self.assertListEqual(AUDIO_EXT, vlc_player.audio_extensions_list) + self.assertListEqual(VIDEO_EXT, vlc_player.video_extensions_list) + + @patch('openlp.core.ui.media.vlcplayer.is_win') + @patch('openlp.core.ui.media.vlcplayer.is_macosx') + @patch('openlp.core.ui.media.vlcplayer.get_vlc') + @patch('openlp.core.ui.media.vlcplayer.QtGui') + @patch('openlp.core.ui.media.vlcplayer.Settings') + def setup_test(self, MockedSettings, MockedQtGui, mocked_get_vlc, mocked_is_macosx, mocked_is_win): + """ + Test the setup method + """ + # GIVEN: A bunch of mocked out stuff and a VlcPlayer object + mocked_is_macosx.return_value = False + mocked_is_win.return_value = False + mocked_settings = MagicMock() + mocked_settings.value.return_value = True + MockedSettings.return_value = mocked_settings + mocked_qframe = MagicMock() + mocked_qframe.winId.return_value = 2 + MockedQtGui.QFrame.NoFrame = 1 + MockedQtGui.QFrame.return_value = mocked_qframe + mocked_media_player_new = MagicMock() + mocked_instance = MagicMock() + mocked_instance.media_player_new.return_value = mocked_media_player_new + mocked_vlc = MagicMock() + mocked_vlc.Instance.return_value = mocked_instance + mocked_get_vlc.return_value = mocked_vlc + mocked_display = MagicMock() + mocked_display.has_audio = False + mocked_display.controller.is_live = True + mocked_display.size.return_value = (10, 10) + vlc_player = VlcPlayer(None) + + # WHEN: setup() is run + vlc_player.setup(mocked_display) + + # THEN: The VLC widget should be set up correctly + self.assertEqual(mocked_display.vlc_widget, mocked_qframe) + mocked_qframe.setFrameStyle.assert_called_with(1) + mocked_settings.value.assert_called_with('advanced/hide mouse') + mocked_vlc.Instance.assert_called_with('--no-video-title-show --no-audio --no-video-title-show ' + '--mouse-hide-timeout=0') + self.assertEqual(mocked_display.vlc_instance, mocked_instance) + mocked_instance.media_player_new.assert_called_with() + self.assertEqual(mocked_display.vlc_media_player, mocked_media_player_new) + mocked_display.size.assert_called_with() + mocked_qframe.resize.assert_called_with((10, 10)) + mocked_qframe.raise_.assert_called_with() + mocked_qframe.hide.assert_called_with() + mocked_media_player_new.set_xwindow.assert_called_with(2) + self.assertTrue(vlc_player.has_own_widget) + + @patch('openlp.core.ui.media.vlcplayer.is_win') + @patch('openlp.core.ui.media.vlcplayer.is_macosx') + @patch('openlp.core.ui.media.vlcplayer.get_vlc') + @patch('openlp.core.ui.media.vlcplayer.QtGui') + @patch('openlp.core.ui.media.vlcplayer.Settings') + def setup_has_audio_test(self, MockedSettings, MockedQtGui, mocked_get_vlc, mocked_is_macosx, mocked_is_win): + """ + Test the setup method when has_audio is True + """ + # GIVEN: A bunch of mocked out stuff and a VlcPlayer object + mocked_is_macosx.return_value = False + mocked_is_win.return_value = False + mocked_settings = MagicMock() + mocked_settings.value.return_value = True + MockedSettings.return_value = mocked_settings + mocked_qframe = MagicMock() + mocked_qframe.winId.return_value = 2 + MockedQtGui.QFrame.NoFrame = 1 + MockedQtGui.QFrame.return_value = mocked_qframe + mocked_media_player_new = MagicMock() + mocked_instance = MagicMock() + mocked_instance.media_player_new.return_value = mocked_media_player_new + mocked_vlc = MagicMock() + mocked_vlc.Instance.return_value = mocked_instance + mocked_get_vlc.return_value = mocked_vlc + mocked_display = MagicMock() + mocked_display.has_audio = True + mocked_display.controller.is_live = True + mocked_display.size.return_value = (10, 10) + vlc_player = VlcPlayer(None) + + # WHEN: setup() is run + vlc_player.setup(mocked_display) + + # THEN: The VLC instance should be created with the correct options + mocked_vlc.Instance.assert_called_with('--no-video-title-show --mouse-hide-timeout=0') + + @patch('openlp.core.ui.media.vlcplayer.is_win') + @patch('openlp.core.ui.media.vlcplayer.is_macosx') + @patch('openlp.core.ui.media.vlcplayer.get_vlc') + @patch('openlp.core.ui.media.vlcplayer.QtGui') + @patch('openlp.core.ui.media.vlcplayer.Settings') + def setup_visible_mouse_test(self, MockedSettings, MockedQtGui, mocked_get_vlc, mocked_is_macosx, mocked_is_win): + """ + Test the setup method when Settings().value("hide mouse") is False + """ + # GIVEN: A bunch of mocked out stuff and a VlcPlayer object + mocked_is_macosx.return_value = False + mocked_is_win.return_value = False + mocked_settings = MagicMock() + mocked_settings.value.return_value = False + MockedSettings.return_value = mocked_settings + mocked_qframe = MagicMock() + mocked_qframe.winId.return_value = 2 + MockedQtGui.QFrame.NoFrame = 1 + MockedQtGui.QFrame.return_value = mocked_qframe + mocked_media_player_new = MagicMock() + mocked_instance = MagicMock() + mocked_instance.media_player_new.return_value = mocked_media_player_new + mocked_vlc = MagicMock() + mocked_vlc.Instance.return_value = mocked_instance + mocked_get_vlc.return_value = mocked_vlc + mocked_display = MagicMock() + mocked_display.has_audio = False + mocked_display.controller.is_live = True + mocked_display.size.return_value = (10, 10) + vlc_player = VlcPlayer(None) + + # WHEN: setup() is run + vlc_player.setup(mocked_display) + + # THEN: The VLC instance should be created with the correct options + mocked_vlc.Instance.assert_called_with('--no-video-title-show --no-audio --no-video-title-show') + + @patch('openlp.core.ui.media.vlcplayer.is_win') + @patch('openlp.core.ui.media.vlcplayer.is_macosx') + @patch('openlp.core.ui.media.vlcplayer.get_vlc') + @patch('openlp.core.ui.media.vlcplayer.QtGui') + @patch('openlp.core.ui.media.vlcplayer.Settings') + def setup_windows_test(self, MockedSettings, MockedQtGui, mocked_get_vlc, mocked_is_macosx, mocked_is_win): + """ + Test the setup method when running on Windows + """ + # GIVEN: A bunch of mocked out stuff and a VlcPlayer object + mocked_is_macosx.return_value = False + mocked_is_win.return_value = True + mocked_settings = MagicMock() + mocked_settings.value.return_value = False + MockedSettings.return_value = mocked_settings + mocked_qframe = MagicMock() + mocked_qframe.winId.return_value = 2 + MockedQtGui.QFrame.NoFrame = 1 + MockedQtGui.QFrame.return_value = mocked_qframe + mocked_media_player_new = MagicMock() + mocked_instance = MagicMock() + mocked_instance.media_player_new.return_value = mocked_media_player_new + mocked_vlc = MagicMock() + mocked_vlc.Instance.return_value = mocked_instance + mocked_get_vlc.return_value = mocked_vlc + mocked_display = MagicMock() + mocked_display.has_audio = False + mocked_display.controller.is_live = True + mocked_display.size.return_value = (10, 10) + vlc_player = VlcPlayer(None) + + # WHEN: setup() is run + vlc_player.setup(mocked_display) + + # THEN: set_hwnd should be called + mocked_media_player_new.set_hwnd.assert_called_with(2) + + @patch('openlp.core.ui.media.vlcplayer.is_win') + @patch('openlp.core.ui.media.vlcplayer.is_macosx') + @patch('openlp.core.ui.media.vlcplayer.get_vlc') + @patch('openlp.core.ui.media.vlcplayer.QtGui') + @patch('openlp.core.ui.media.vlcplayer.Settings') + def setup_osx_test(self, MockedSettings, MockedQtGui, mocked_get_vlc, mocked_is_macosx, mocked_is_win): + """ + Test the setup method when running on OS X + """ + # GIVEN: A bunch of mocked out stuff and a VlcPlayer object + mocked_is_macosx.return_value = True + mocked_is_win.return_value = False + mocked_settings = MagicMock() + mocked_settings.value.return_value = False + MockedSettings.return_value = mocked_settings + mocked_qframe = MagicMock() + mocked_qframe.winId.return_value = 2 + MockedQtGui.QFrame.NoFrame = 1 + MockedQtGui.QFrame.return_value = mocked_qframe + mocked_media_player_new = MagicMock() + mocked_instance = MagicMock() + mocked_instance.media_player_new.return_value = mocked_media_player_new + mocked_vlc = MagicMock() + mocked_vlc.Instance.return_value = mocked_instance + mocked_get_vlc.return_value = mocked_vlc + mocked_display = MagicMock() + mocked_display.has_audio = False + mocked_display.controller.is_live = True + mocked_display.size.return_value = (10, 10) + vlc_player = VlcPlayer(None) + + # WHEN: setup() is run + vlc_player.setup(mocked_display) + + # THEN: set_nsobject should be called + mocked_media_player_new.set_nsobject.assert_called_with(2) + + @patch('openlp.core.ui.media.vlcplayer.get_vlc') + def check_available_test(self, mocked_get_vlc): + """ + Check that when the "vlc" module is available, then VLC is set as available + """ + # GIVEN: A mocked out get_vlc() method and a VlcPlayer instance + mocked_get_vlc.return_value = MagicMock() + vlc_player = VlcPlayer(None) + + # WHEN: vlc + is_available = vlc_player.check_available() + + # THEN: VLC should be available + self.assertTrue(is_available) + + @patch('openlp.core.ui.media.vlcplayer.get_vlc') + def check_not_available_test(self, mocked_get_vlc): + """ + Check that when the "vlc" module is not available, then VLC is set as unavailable + """ + # GIVEN: A mocked out get_vlc() method and a VlcPlayer instance + mocked_get_vlc.return_value = None + vlc_player = VlcPlayer(None) + + # WHEN: vlc + is_available = vlc_player.check_available() + + # THEN: VLC should NOT be available + self.assertFalse(is_available) + + @patch('openlp.core.ui.media.vlcplayer.get_vlc') + @patch('openlp.core.ui.media.vlcplayer.os.path.normcase') + def load_test(self, mocked_normcase, mocked_get_vlc): + """ + Test loading a video into VLC + """ + # GIVEN: A mocked out get_vlc() method + media_path = '/path/to/media.mp4' + mocked_normcase.side_effect = lambda x: x + mocked_vlc = MagicMock() + mocked_get_vlc.return_value = mocked_vlc + mocked_controller = MagicMock() + mocked_controller.media_info.volume = 100 + mocked_controller.media_info.media_type = MediaType.Video + mocked_controller.media_info.file_info.absoluteFilePath.return_value = media_path + mocked_vlc_media = MagicMock() + mocked_media = MagicMock() + mocked_media.get_duration.return_value = 10000 + mocked_display = MagicMock() + mocked_display.controller = mocked_controller + mocked_display.vlc_instance.media_new_path.return_value = mocked_vlc_media + mocked_display.vlc_media_player.get_media.return_value = mocked_media + vlc_player = VlcPlayer(None) + + # WHEN: A video is loaded into VLC + with patch.object(vlc_player, 'volume') as mocked_volume: + result = vlc_player.load(mocked_display) + + # THEN: The video should be loaded + mocked_normcase.assert_called_with(media_path) + mocked_display.vlc_instance.media_new_path.assert_called_with(media_path) + self.assertEqual(mocked_vlc_media, mocked_display.vlc_media) + mocked_display.vlc_media_player.set_media.assert_called_with(mocked_vlc_media) + mocked_vlc_media.parse.assert_called_with() + mocked_volume.assert_called_with(mocked_display, 100) + self.assertEqual(10, mocked_controller.media_info.length) + self.assertTrue(result) + + @patch('openlp.core.ui.media.vlcplayer.is_win') + @patch('openlp.core.ui.media.vlcplayer.get_vlc') + @patch('openlp.core.ui.media.vlcplayer.os.path.normcase') + def load_audio_cd_test(self, mocked_normcase, mocked_get_vlc, mocked_is_win): + """ + Test loading an audio CD into VLC + """ + # GIVEN: A mocked out get_vlc() method + mocked_is_win.return_value = False + media_path = '/dev/sr0' + mocked_normcase.side_effect = lambda x: x + mocked_vlc = MagicMock() + mocked_get_vlc.return_value = mocked_vlc + mocked_controller = MagicMock() + mocked_controller.media_info.volume = 100 + mocked_controller.media_info.media_type = MediaType.CD + mocked_controller.media_info.file_info.absoluteFilePath.return_value = media_path + mocked_controller.media_info.title_track = 1 + mocked_vlc_media = MagicMock() + mocked_media = MagicMock() + mocked_media.get_duration.return_value = 10000 + mocked_display = MagicMock() + mocked_display.controller = mocked_controller + mocked_display.vlc_instance.media_new_location.return_value = mocked_vlc_media + mocked_display.vlc_media_player.get_media.return_value = mocked_media + mocked_subitems = MagicMock() + mocked_subitems.count.return_value = 1 + mocked_subitems.item_at_index.return_value = mocked_vlc_media + mocked_vlc_media.subitems.return_value = mocked_subitems + vlc_player = VlcPlayer(None) + + # WHEN: An audio CD is loaded into VLC + with patch.object(vlc_player, 'volume') as mocked_volume, \ + patch.object(vlc_player, 'media_state_wait') as mocked_media_state_wait: + result = vlc_player.load(mocked_display) + + # THEN: The video should be loaded + mocked_normcase.assert_called_with(media_path) + mocked_display.vlc_instance.media_new_location.assert_called_with('cdda://' + media_path) + self.assertEqual(mocked_vlc_media, mocked_display.vlc_media) + mocked_display.vlc_media_player.set_media.assert_called_with(mocked_vlc_media) + mocked_vlc_media.parse.assert_called_with() + mocked_volume.assert_called_with(mocked_display, 100) + self.assertEqual(10, mocked_controller.media_info.length) + self.assertTrue(result) + + @patch('openlp.core.ui.media.vlcplayer.is_win') + @patch('openlp.core.ui.media.vlcplayer.get_vlc') + @patch('openlp.core.ui.media.vlcplayer.os.path.normcase') + def load_audio_cd_on_windows_test(self, mocked_normcase, mocked_get_vlc, mocked_is_win): + """ + Test loading an audio CD into VLC on Windows + """ + # GIVEN: A mocked out get_vlc() method + mocked_is_win.return_value = True + media_path = '/dev/sr0' + mocked_normcase.side_effect = lambda x: x + mocked_vlc = MagicMock() + mocked_get_vlc.return_value = mocked_vlc + mocked_controller = MagicMock() + mocked_controller.media_info.volume = 100 + mocked_controller.media_info.media_type = MediaType.CD + mocked_controller.media_info.file_info.absoluteFilePath.return_value = media_path + mocked_controller.media_info.title_track = 1 + mocked_vlc_media = MagicMock() + mocked_media = MagicMock() + mocked_media.get_duration.return_value = 10000 + mocked_display = MagicMock() + mocked_display.controller = mocked_controller + mocked_display.vlc_instance.media_new_location.return_value = mocked_vlc_media + mocked_display.vlc_media_player.get_media.return_value = mocked_media + mocked_subitems = MagicMock() + mocked_subitems.count.return_value = 1 + mocked_subitems.item_at_index.return_value = mocked_vlc_media + mocked_vlc_media.subitems.return_value = mocked_subitems + vlc_player = VlcPlayer(None) + + # WHEN: An audio CD is loaded into VLC + with patch.object(vlc_player, 'volume') as mocked_volume, \ + patch.object(vlc_player, 'media_state_wait') as mocked_media_state_wait: + result = vlc_player.load(mocked_display) + + # THEN: The video should be loaded + mocked_normcase.assert_called_with(media_path) + mocked_display.vlc_instance.media_new_location.assert_called_with('cdda:///' + media_path) + self.assertEqual(mocked_vlc_media, mocked_display.vlc_media) + mocked_display.vlc_media_player.set_media.assert_called_with(mocked_vlc_media) + mocked_vlc_media.parse.assert_called_with() + mocked_volume.assert_called_with(mocked_display, 100) + self.assertEqual(10, mocked_controller.media_info.length) + self.assertTrue(result) + + @patch('openlp.core.ui.media.vlcplayer.is_win') + @patch('openlp.core.ui.media.vlcplayer.get_vlc') + @patch('openlp.core.ui.media.vlcplayer.os.path.normcase') + def load_audio_cd_no_tracks_test(self, mocked_normcase, mocked_get_vlc, mocked_is_win): + """ + Test loading an audio CD that has no tracks into VLC + """ + # GIVEN: A mocked out get_vlc() method + mocked_is_win.return_value = False + media_path = '/dev/sr0' + mocked_normcase.side_effect = lambda x: x + mocked_vlc = MagicMock() + mocked_get_vlc.return_value = mocked_vlc + mocked_controller = MagicMock() + mocked_controller.media_info.volume = 100 + mocked_controller.media_info.media_type = MediaType.CD + mocked_controller.media_info.file_info.absoluteFilePath.return_value = media_path + mocked_controller.media_info.title_track = 1 + mocked_vlc_media = MagicMock() + mocked_media = MagicMock() + mocked_media.get_duration.return_value = 10000 + mocked_display = MagicMock() + mocked_display.controller = mocked_controller + mocked_display.vlc_instance.media_new_location.return_value = mocked_vlc_media + mocked_display.vlc_media_player.get_media.return_value = mocked_media + mocked_subitems = MagicMock() + mocked_subitems.count.return_value = 0 + mocked_subitems.item_at_index.return_value = mocked_vlc_media + mocked_vlc_media.subitems.return_value = mocked_subitems + vlc_player = VlcPlayer(None) + + # WHEN: An audio CD is loaded into VLC + with patch.object(vlc_player, 'volume') as mocked_volume, \ + patch.object(vlc_player, 'media_state_wait') as mocked_media_state_wait: + result = vlc_player.load(mocked_display) + + # THEN: The video should be loaded + mocked_normcase.assert_called_with(media_path) + mocked_display.vlc_instance.media_new_location.assert_called_with('cdda://' + media_path) + self.assertEqual(mocked_vlc_media, mocked_display.vlc_media) + self.assertEqual(0, mocked_subitems.item_at_index.call_count) + mocked_display.vlc_media_player.set_media.assert_called_with(mocked_vlc_media) + self.assertEqual(0, mocked_vlc_media.parse.call_count) + self.assertFalse(result) + + @patch('openlp.core.ui.media.vlcplayer.get_vlc') + @patch('openlp.core.ui.media.vlcplayer.datetime', MockDateTime) + def media_state_wait_test(self, mocked_get_vlc): + """ + Check that waiting for a state change works + """ + # GIVEN: A mocked out get_vlc method + mocked_vlc = MagicMock() + mocked_vlc.State.Error = 1 + mocked_get_vlc.return_value = mocked_vlc + mocked_display = MagicMock() + mocked_display.vlc_media.get_state.return_value = 2 + Registry.create() + mocked_application = MagicMock() + Registry().register('application', mocked_application) + vlc_player = VlcPlayer(None) + + # WHEN: media_state_wait() is called + result = vlc_player.media_state_wait(mocked_display, 2) + + # THEN: The results should be True + self.assertTrue(result) + + @patch('openlp.core.ui.media.vlcplayer.get_vlc') + @patch('openlp.core.ui.media.vlcplayer.datetime', MockDateTime) + def media_state_wait_error_test(self, mocked_get_vlc): + """ + Check that getting an error when waiting for a state change returns False + """ + # GIVEN: A mocked out get_vlc method + mocked_vlc = MagicMock() + mocked_vlc.State.Error = 1 + mocked_get_vlc.return_value = mocked_vlc + mocked_display = MagicMock() + mocked_display.vlc_media.get_state.return_value = 1 + Registry.create() + mocked_application = MagicMock() + Registry().register('application', mocked_application) + vlc_player = VlcPlayer(None) + + # WHEN: media_state_wait() is called + result = vlc_player.media_state_wait(mocked_display, 2) + + # THEN: The results should be True + self.assertFalse(result) + + @patch('openlp.core.ui.media.vlcplayer.get_vlc') + @patch('openlp.core.ui.media.vlcplayer.datetime', MockDateTime) + def media_state_wait_times_out_test(self, mocked_get_vlc): + """ + Check that waiting for a state returns False when it times out after 60 seconds + """ + # GIVEN: A mocked out get_vlc method + timeout = MockDateTime.return_values[0] + timedelta(seconds=61) + MockDateTime.return_values.append(timeout) + mocked_vlc = MagicMock() + mocked_vlc.State.Error = 1 + mocked_get_vlc.return_value = mocked_vlc + mocked_display = MagicMock() + mocked_display.vlc_media.get_state.return_value = 2 + Registry.create() + mocked_application = MagicMock() + Registry().register('application', mocked_application) + vlc_player = VlcPlayer(None) + + # WHEN: media_state_wait() is called + result = vlc_player.media_state_wait(mocked_display, 3) + + # THEN: The results should be True + self.assertFalse(result) + + def resize_test(self): + """ + Test resizing the player + """ + # GIVEN: A display object and a VlcPlayer instance + mocked_display = MagicMock() + mocked_display.size.return_value = (10, 10) + vlc_player = VlcPlayer(None) + + # WHEN: resize is called + vlc_player.resize(mocked_display) + + # THEN: The right methods should have been called + mocked_display.size.assert_called_with() + mocked_display.vlc_widget.resize.assert_called_with((10, 10)) + + @patch('openlp.core.ui.media.vlcplayer.threading') + @patch('openlp.core.ui.media.vlcplayer.get_vlc') + def play_test(self, mocked_get_vlc, mocked_threading): + """ + Test the play() method + """ + # GIVEN: A bunch of mocked out things + mocked_thread = MagicMock() + mocked_threading.Thread.return_value = mocked_thread + mocked_vlc = MagicMock() + mocked_get_vlc.return_value = mocked_vlc + mocked_controller = MagicMock() + mocked_controller.media_info.start_time = 0 + mocked_controller.media_info.media_type = MediaType.Video + mocked_controller.media_info.volume = 100 + mocked_media = MagicMock() + mocked_media.get_duration.return_value = 50000 + mocked_display = MagicMock() + mocked_display.controller = mocked_controller + mocked_display.vlc_media_player.get_media.return_value = mocked_media + vlc_player = VlcPlayer(None) + vlc_player.state = MediaState.Paused + + # WHEN: play() is called + with patch.object(vlc_player, 'media_state_wait') as mocked_media_state_wait, \ + patch.object(vlc_player, 'volume') as mocked_volume: + mocked_media_state_wait.return_value = True + result = vlc_player.play(mocked_display) + + # THEN: A bunch of things should happen to play the media + mocked_thread.start.assert_called_with() + self.assertEqual(50, mocked_controller.media_info.length) + mocked_volume.assert_called_with(mocked_display, 100) + mocked_controller.seek_slider.setMaximum.assert_called_with(50000) + self.assertEqual(MediaState.Playing, vlc_player.state) + mocked_display.vlc_widget.raise_.assert_called_with() + self.assertTrue(result, 'The value returned from play() should be True') + + @patch('openlp.core.ui.media.vlcplayer.threading') + @patch('openlp.core.ui.media.vlcplayer.get_vlc') + def play_media_wait_state_not_playing_test(self, mocked_get_vlc, mocked_threading): + """ + Test the play() method when media_wait_state() returns False + """ + # GIVEN: A bunch of mocked out things + mocked_thread = MagicMock() + mocked_threading.Thread.return_value = mocked_thread + mocked_vlc = MagicMock() + mocked_get_vlc.return_value = mocked_vlc + mocked_controller = MagicMock() + mocked_controller.media_info.start_time = 0 + mocked_display = MagicMock() + mocked_display.controller = mocked_controller + vlc_player = VlcPlayer(None) + vlc_player.state = MediaState.Paused + + # WHEN: play() is called + with patch.object(vlc_player, 'media_state_wait') as mocked_media_state_wait, \ + patch.object(vlc_player, 'volume') as mocked_volume: + mocked_media_state_wait.return_value = False + result = vlc_player.play(mocked_display) + + # THEN: A thread should be started, but the method should return False + mocked_thread.start.assert_called_with() + self.assertFalse(result) + + @patch('openlp.core.ui.media.vlcplayer.threading') + @patch('openlp.core.ui.media.vlcplayer.get_vlc') + def play_dvd_test(self, mocked_get_vlc, mocked_threading): + """ + Test the play() method with a DVD + """ + # GIVEN: A bunch of mocked out things + mocked_thread = MagicMock() + mocked_threading.Thread.return_value = mocked_thread + mocked_vlc = MagicMock() + mocked_get_vlc.return_value = mocked_vlc + mocked_controller = MagicMock() + mocked_controller.media_info.start_time = 0 + mocked_controller.media_info.end_time = 50 + mocked_controller.media_info.media_type = MediaType.DVD + mocked_controller.media_info.volume = 100 + mocked_controller.media_info.title_track = 1 + mocked_controller.media_info.audio_track = 1 + mocked_controller.media_info.subtitle_track = 1 + mocked_display = MagicMock() + mocked_display.controller = mocked_controller + vlc_player = VlcPlayer(None) + vlc_player.state = MediaState.Paused + + # WHEN: play() is called + with patch.object(vlc_player, 'media_state_wait') as mocked_media_state_wait, \ + patch.object(vlc_player, 'volume') as mocked_volume: + mocked_media_state_wait.return_value = True + result = vlc_player.play(mocked_display) + + # THEN: A bunch of things should happen to play the media + mocked_thread.start.assert_called_with() + mocked_display.vlc_media_player.set_title.assert_called_with(1) + mocked_display.vlc_media_player.play.assert_called_with() + mocked_display.vlc_media_player.audio_set_track.assert_called_with(1) + mocked_display.vlc_media_player.video_set_spu.assert_called_with(1) + self.assertEqual(50, mocked_controller.media_info.length) + mocked_volume.assert_called_with(mocked_display, 100) + mocked_controller.seek_slider.setMaximum.assert_called_with(50000) + self.assertEqual(MediaState.Playing, vlc_player.state) + mocked_display.vlc_widget.raise_.assert_called_with() + self.assertTrue(result, 'The value returned from play() should be True') + + @patch('openlp.core.ui.media.vlcplayer.get_vlc') + def pause_test(self, mocked_get_vlc): + """ + Test that the pause method works correctly + """ + # GIVEN: A mocked out get_vlc method + mocked_vlc = MagicMock() + mocked_vlc.State.Playing = 1 + mocked_vlc.State.Paused = 2 + mocked_get_vlc.return_value = mocked_vlc + mocked_display = MagicMock() + mocked_display.vlc_media.get_state.return_value = 1 + vlc_player = VlcPlayer(None) + + # WHEN: The media is paused + with patch.object(vlc_player, 'media_state_wait') as mocked_media_state_wait: + mocked_media_state_wait.return_value = True + vlc_player.pause(mocked_display) + + # THEN: The pause method should exit early + mocked_display.vlc_media.get_state.assert_called_with() + mocked_display.vlc_media_player.pause.assert_called_with() + mocked_media_state_wait.assert_called_with(mocked_display, 2) + self.assertEqual(MediaState.Paused, vlc_player.state) + + @patch('openlp.core.ui.media.vlcplayer.get_vlc') + def pause_not_playing_test(self, mocked_get_vlc): + """ + Test the pause method when the player is not playing + """ + # GIVEN: A mocked out get_vlc method + mocked_vlc = MagicMock() + mocked_vlc.State.Playing = 1 + mocked_get_vlc.return_value = mocked_vlc + mocked_display = MagicMock() + mocked_display.vlc_media.get_state.return_value = 2 + vlc_player = VlcPlayer(None) + + # WHEN: The media is paused + vlc_player.pause(mocked_display) + + # THEN: The pause method should exit early + mocked_display.vlc_media.get_state.assert_called_with() + self.assertEqual(0, mocked_display.vlc_media_player.pause.call_count) + + @patch('openlp.core.ui.media.vlcplayer.get_vlc') + def pause_fail_test(self, mocked_get_vlc): + """ + Test the pause method when the player fails to pause the media + """ + # GIVEN: A mocked out get_vlc method + mocked_vlc = MagicMock() + mocked_vlc.State.Playing = 1 + mocked_vlc.State.Paused = 2 + mocked_get_vlc.return_value = mocked_vlc + mocked_display = MagicMock() + mocked_display.vlc_media.get_state.return_value = 1 + vlc_player = VlcPlayer(None) + + # WHEN: The media is paused + with patch.object(vlc_player, 'media_state_wait') as mocked_media_state_wait: + mocked_media_state_wait.return_value = False + vlc_player.pause(mocked_display) + + # THEN: The pause method should exit early + mocked_display.vlc_media.get_state.assert_called_with() + mocked_display.vlc_media_player.pause.assert_called_with() + mocked_media_state_wait.assert_called_with(mocked_display, 2) + self.assertNotEqual(MediaState.Paused, vlc_player.state) + + @patch('openlp.core.ui.media.vlcplayer.threading') + def stop_test(self, mocked_threading): + """ + Test stopping the current item + """ + # GIVEN: A display object and a VlcPlayer instance and some mocked threads + mocked_thread = MagicMock() + mocked_threading.Thread.return_value = mocked_thread + mocked_stop = MagicMock() + mocked_display = MagicMock() + mocked_display.vlc_media_player.stop = mocked_stop + vlc_player = VlcPlayer(None) + + # WHEN: stop is called + vlc_player.stop(mocked_display) + + # THEN: A thread should have been started to stop VLC + mocked_threading.Thread.assert_called_with(target=mocked_stop) + mocked_thread.start.assert_called_with() + self.assertEqual(MediaState.Stopped, vlc_player.state) + + def volume_test(self): + """ + Test setting the volume + """ + # GIVEN: A display object and a VlcPlayer instance + mocked_display = MagicMock() + mocked_display.has_audio = True + vlc_player = VlcPlayer(None) + + # WHEN: The volume is set + vlc_player.volume(mocked_display, 10) + + # THEN: The volume should have been set + mocked_display.vlc_media_player.audio_set_volume.assert_called_with(10) + + def volume_no_audio_test(self): + """ + Test setting the volume when there's no audio + """ + # GIVEN: A display object and a VlcPlayer instance + mocked_display = MagicMock() + mocked_display.has_audio = False + vlc_player = VlcPlayer(None) + + # WHEN: The volume is set + vlc_player.volume(mocked_display, 10) + + # THEN: The volume should NOT have been set + self.assertEqual(0, mocked_display.vlc_media_player.audio_set_volume.call_count) + + def seek_unseekable_media_test(self): + """ + Test seeking something that can't be seeked + """ + # GIVEN: Unseekable media + mocked_display = MagicMock() + mocked_display.controller.media_info.media_type = MediaType.Audio + mocked_display.vlc_media_player.is_seekable.return_value = False + vlc_player = VlcPlayer(None) + + # WHEN: seek() is called + vlc_player.seek(mocked_display, 100) + + # THEN: nothing should happen + mocked_display.vlc_media_player.is_seekable.assert_called_with() + self.assertEqual(0, mocked_display.vlc_media_player.set_time.call_count) + + def seek_seekable_media_test(self): + """ + Test seeking something that is seekable, but not a DVD + """ + # GIVEN: Unseekable media + mocked_display = MagicMock() + mocked_display.controller.media_info.media_type = MediaType.Audio + mocked_display.vlc_media_player.is_seekable.return_value = True + vlc_player = VlcPlayer(None) + + # WHEN: seek() is called + vlc_player.seek(mocked_display, 100) + + # THEN: nothing should happen + mocked_display.vlc_media_player.is_seekable.assert_called_with() + mocked_display.vlc_media_player.set_time.assert_called_with(100) + + def seek_dvd_test(self): + """ + Test seeking a DVD + """ + # GIVEN: Unseekable media + mocked_display = MagicMock() + mocked_display.controller.media_info.media_type = MediaType.DVD + mocked_display.vlc_media_player.is_seekable.return_value = True + mocked_display.controller.media_info.start_time = 3 + vlc_player = VlcPlayer(None) + + # WHEN: seek() is called + vlc_player.seek(mocked_display, 2000) + + # THEN: nothing should happen + mocked_display.vlc_media_player.is_seekable.assert_called_with() + mocked_display.vlc_media_player.set_time.assert_called_with(5000) + + def reset_test(self): + """ + Test the reset() method + """ + # GIVEN: Some mocked out stuff + mocked_display = MagicMock() + vlc_player = VlcPlayer(None) + + # WHEN: reset() is called + vlc_player.reset(mocked_display) + + # THEN: The media should be stopped and invsibile + mocked_display.vlc_media_player.stop.assert_called_with() + mocked_display.vlc_widget.setVisible.assert_called_with(False) + self.assertEqual(MediaState.Off, vlc_player.state) + + def set_visible_has_own_widget_test(self): + """ + Test the set_visible() method when the player has its own widget + """ + # GIVEN: Some mocked out stuff + mocked_display = MagicMock() + vlc_player = VlcPlayer(None) + vlc_player.has_own_widget = True + + # WHEN: reset() is called + vlc_player.set_visible(mocked_display, True) + + # THEN: The media should be stopped and invsibile + mocked_display.vlc_widget.setVisible.assert_called_with(True) + + def set_visible_no_widget_test(self): + """ + Test the set_visible() method when the player doesn't have a widget + """ + # GIVEN: Some mocked out stuff + mocked_display = MagicMock() + vlc_player = VlcPlayer(None) + vlc_player.has_own_widget = False + + # WHEN: reset() is called + vlc_player.set_visible(mocked_display, True) + + # THEN: The media should be stopped and invsibile + self.assertEqual(0, mocked_display.vlc_widget.setVisible.call_count) + + @patch('openlp.core.ui.media.vlcplayer.get_vlc') + def update_ui_test(self, mocked_get_vlc): + """ + Test updating the UI + """ + # GIVEN: A whole bunch of mocks + mocked_vlc = MagicMock() + mocked_vlc.State.Ended = 1 + mocked_get_vlc.return_value = mocked_vlc + mocked_controller = MagicMock() + mocked_controller.media_info.end_time = 300 + mocked_controller.seek_slider.isSliderDown.return_value = False + mocked_display = MagicMock() + mocked_display.controller = mocked_controller + mocked_display.vlc_media.get_state.return_value = 1 + mocked_display.vlc_media_player.get_time.return_value = 400000 + vlc_player = VlcPlayer(None) + + # WHEN: update_ui() is called + with patch.object(vlc_player, 'stop') as mocked_stop, \ + patch.object(vlc_player, 'set_visible') as mocked_set_visible: + vlc_player.update_ui(mocked_display) + + # THEN: Certain methods should be called + mocked_stop.assert_called_with(mocked_display) + self.assertEqual(2, mocked_stop.call_count) + mocked_display.vlc_media_player.get_time.assert_called_with() + mocked_set_visible.assert_called_with(mocked_display, False) + mocked_controller.seek_slider.setSliderPosition.assert_called_with(400000) + expected_calls = [call(True), call(False)] + self.assertEqual(expected_calls, mocked_controller.seek_slider.blockSignals.call_args_list) + + @patch('openlp.core.ui.media.vlcplayer.get_vlc') + def update_ui_dvd_test(self, mocked_get_vlc): + """ + Test updating the UI for a CD or DVD + """ + # GIVEN: A whole bunch of mocks + mocked_vlc = MagicMock() + mocked_vlc.State.Ended = 1 + mocked_get_vlc.return_value = mocked_vlc + mocked_controller = MagicMock() + mocked_controller.media_info.start_time = 100 + mocked_controller.media_info.end_time = 300 + mocked_controller.seek_slider.isSliderDown.return_value = False + mocked_display = MagicMock() + mocked_display.controller = mocked_controller + mocked_display.vlc_media.get_state.return_value = 1 + mocked_display.vlc_media_player.get_time.return_value = 400000 + mocked_display.controller.media_info.media_type = MediaType.DVD + vlc_player = VlcPlayer(None) + + # WHEN: update_ui() is called + with patch.object(vlc_player, 'stop') as mocked_stop, \ + patch.object(vlc_player, 'set_visible') as mocked_set_visible: + vlc_player.update_ui(mocked_display) + + # THEN: Certain methods should be called + mocked_stop.assert_called_with(mocked_display) + self.assertEqual(2, mocked_stop.call_count) + mocked_display.vlc_media_player.get_time.assert_called_with() + mocked_set_visible.assert_called_with(mocked_display, False) + mocked_controller.seek_slider.setSliderPosition.assert_called_with(300000) + expected_calls = [call(True), call(False)] + self.assertEqual(expected_calls, mocked_controller.seek_slider.blockSignals.call_args_list) + + @patch('openlp.core.ui.media.vlcplayer.translate') + def get_info_test(self, mocked_translate): + """ + Test that get_info() returns some information about the VLC player + """ + # GIVEN: A VlcPlayer + mocked_translate.side_effect = lambda *x: x[1] + vlc_player = VlcPlayer(None) + + # WHEN: get_info() is run + info = vlc_player.get_info() + + # THEN: The information should be correct + self.assertEqual('VLC is an external player which supports a number of different formats.
' + 'Audio
' + str(AUDIO_EXT) + '
Video
' + + str(VIDEO_EXT) + '
', info) diff --git a/tests/functional/openlp_plugins/images/test_lib.py b/tests/functional/openlp_plugins/images/test_lib.py index 070b4b40d..9d187af9e 100644 --- a/tests/functional/openlp_plugins/images/test_lib.py +++ b/tests/functional/openlp_plugins/images/test_lib.py @@ -24,6 +24,8 @@ This module contains tests for the lib submodule of the Images plugin. """ from unittest import TestCase +from PyQt4 import QtCore, QtGui + from openlp.core.common import Registry from openlp.plugins.images.lib.db import ImageFilenames, ImageGroups from openlp.plugins.images.lib.mediaitem import ImageMediaItem @@ -48,123 +50,121 @@ class TestImageMediaItem(TestCase): self.media_item = ImageMediaItem(None, mocked_plugin) self.media_item.settings_section = 'images' - def validate_and_load_test(self): + @patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_list') + @patch('openlp.plugins.images.lib.mediaitem.Settings') + def validate_and_load_test(self, mocked_settings, mocked_load_list): """ Test that the validate_and_load_test() method when called without a group """ # GIVEN: A list of files file_list = ['/path1/image1.jpg', '/path2/image2.jpg'] - with patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_list') as mocked_load_list, \ - patch('openlp.plugins.images.lib.mediaitem.Settings') as mocked_settings: + # WHEN: Calling validate_and_load with the list of files + self.media_item.validate_and_load(file_list) - # WHEN: Calling validate_and_load with the list of files - self.media_item.validate_and_load(file_list) + # THEN: load_list should have been called with the file list and None, + # the directory should have been saved to the settings + mocked_load_list.assert_called_once_with(file_list, None) + mocked_settings().setValue.assert_called_once_with(ANY, '/path1') - # THEN: load_list should have been called with the file list and None, - # the directory should have been saved to the settings - mocked_load_list.assert_called_once_with(file_list, None) - mocked_settings().setValue.assert_called_once_with(ANY, '/path1') - - def validate_and_load_group_test(self): + @patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_list') + @patch('openlp.plugins.images.lib.mediaitem.Settings') + def validate_and_load_group_test(self, mocked_settings, mocked_load_list): """ Test that the validate_and_load_test() method when called with a group """ # GIVEN: A list of files file_list = ['/path1/image1.jpg', '/path2/image2.jpg'] - with patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_list') as mocked_load_list, \ - patch('openlp.plugins.images.lib.mediaitem.Settings') as mocked_settings: + # WHEN: Calling validate_and_load with the list of files and a group + self.media_item.validate_and_load(file_list, 'group') - # WHEN: Calling validate_and_load with the list of files and a group - self.media_item.validate_and_load(file_list, 'group') + # THEN: load_list should have been called with the file list and the group name, + # the directory should have been saved to the settings + mocked_load_list.assert_called_once_with(file_list, 'group') + mocked_settings().setValue.assert_called_once_with(ANY, '/path1') - # THEN: load_list should have been called with the file list and the group name, - # the directory should have been saved to the settings - mocked_load_list.assert_called_once_with(file_list, 'group') - mocked_settings().setValue.assert_called_once_with(ANY, '/path1') - - def save_new_images_list_empty_list_test(self): + @patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_full_list') + def save_new_images_list_empty_list_test(self, mocked_load_full_list): """ Test that the save_new_images_list() method handles empty lists gracefully """ # GIVEN: An empty image_list image_list = [] - with patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_full_list'): - self.media_item.manager = MagicMock() + self.media_item.manager = MagicMock() - # WHEN: We run save_new_images_list with the empty list - self.media_item.save_new_images_list(image_list) + # WHEN: We run save_new_images_list with the empty list + self.media_item.save_new_images_list(image_list) - # THEN: The save_object() method should not have been called - self.assertEquals(self.media_item.manager.save_object.call_count, 0, - 'The save_object() method should not have been called') + # THEN: The save_object() method should not have been called + self.assertEquals(self.media_item.manager.save_object.call_count, 0, + 'The save_object() method should not have been called') - def save_new_images_list_single_image_with_reload_test(self): + @patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_full_list') + def save_new_images_list_single_image_with_reload_test(self, mocked_load_full_list): """ Test that the save_new_images_list() calls load_full_list() when reload_list is set to True """ # GIVEN: A list with 1 image and a mocked out manager image_list = ['test_image.jpg'] - with patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_full_list') as mocked_load_full_list: - ImageFilenames.filename = '' - self.media_item.manager = MagicMock() + ImageFilenames.filename = '' + self.media_item.manager = MagicMock() - # WHEN: We run save_new_images_list with reload_list=True - self.media_item.save_new_images_list(image_list, reload_list=True) + # WHEN: We run save_new_images_list with reload_list=True + self.media_item.save_new_images_list(image_list, reload_list=True) - # THEN: load_full_list() should have been called - self.assertEquals(mocked_load_full_list.call_count, 1, 'load_full_list() should have been called') + # THEN: load_full_list() should have been called + self.assertEquals(mocked_load_full_list.call_count, 1, 'load_full_list() should have been called') - # CLEANUP: Remove added attribute from ImageFilenames - delattr(ImageFilenames, 'filename') + # CLEANUP: Remove added attribute from ImageFilenames + delattr(ImageFilenames, 'filename') - def save_new_images_list_single_image_without_reload_test(self): + @patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_full_list') + def save_new_images_list_single_image_without_reload_test(self, mocked_load_full_list): """ Test that the save_new_images_list() doesn't call load_full_list() when reload_list is set to False """ # GIVEN: A list with 1 image and a mocked out manager image_list = ['test_image.jpg'] - with patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_full_list') as mocked_load_full_list: - self.media_item.manager = MagicMock() + self.media_item.manager = MagicMock() - # WHEN: We run save_new_images_list with reload_list=False - self.media_item.save_new_images_list(image_list, reload_list=False) + # WHEN: We run save_new_images_list with reload_list=False + self.media_item.save_new_images_list(image_list, reload_list=False) - # THEN: load_full_list() should not have been called - self.assertEquals(mocked_load_full_list.call_count, 0, 'load_full_list() should not have been called') + # THEN: load_full_list() should not have been called + self.assertEquals(mocked_load_full_list.call_count, 0, 'load_full_list() should not have been called') - def save_new_images_list_multiple_images_test(self): + @patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_full_list') + def save_new_images_list_multiple_images_test(self, mocked_load_full_list): """ Test that the save_new_images_list() saves all images in the list """ # GIVEN: A list with 3 images image_list = ['test_image_1.jpg', 'test_image_2.jpg', 'test_image_3.jpg'] - with patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_full_list') as mocked_load_full_list: - self.media_item.manager = MagicMock() + self.media_item.manager = MagicMock() - # WHEN: We run save_new_images_list with the list of 3 images - self.media_item.save_new_images_list(image_list, reload_list=False) + # WHEN: We run save_new_images_list with the list of 3 images + self.media_item.save_new_images_list(image_list, reload_list=False) - # THEN: load_full_list() should not have been called - self.assertEquals(self.media_item.manager.save_object.call_count, 3, - 'load_full_list() should have been called three times') + # THEN: load_full_list() should not have been called + self.assertEquals(self.media_item.manager.save_object.call_count, 3, + 'load_full_list() should have been called three times') - def save_new_images_list_other_objects_in_list_test(self): + @patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_full_list') + def save_new_images_list_other_objects_in_list_test(self, mocked_load_full_list): """ Test that the save_new_images_list() ignores everything in the provided list except strings """ # GIVEN: A list with images and objects image_list = ['test_image_1.jpg', None, True, ImageFilenames(), 'test_image_2.jpg'] - with patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_full_list') as mocked_load_full_list: - self.media_item.manager = MagicMock() + self.media_item.manager = MagicMock() - # WHEN: We run save_new_images_list with the list of images and objects - self.media_item.save_new_images_list(image_list, reload_list=False) + # WHEN: We run save_new_images_list with the list of images and objects + self.media_item.save_new_images_list(image_list, reload_list=False) - # THEN: load_full_list() should not have been called - self.assertEquals(self.media_item.manager.save_object.call_count, 2, - 'load_full_list() should have been called only once') + # THEN: load_full_list() should not have been called + self.assertEquals(self.media_item.manager.save_object.call_count, 2, + 'load_full_list() should have been called only once') def on_reset_click_test(self): """ @@ -180,31 +180,31 @@ class TestImageMediaItem(TestCase): self.media_item.reset_action.setVisible.assert_called_with(False) self.media_item.live_controller.display.reset_image.assert_called_with() - def recursively_delete_group_test(self): + @patch('openlp.plugins.images.lib.mediaitem.delete_file') + def recursively_delete_group_test(self, mocked_delete_file): """ Test that recursively_delete_group() works """ # GIVEN: An ImageGroups object and mocked functions - with patch('openlp.plugins.images.lib.mediaitem.delete_file') as mocked_delete_file: - ImageFilenames.group_id = 1 - ImageGroups.parent_id = 1 - self.media_item.manager = MagicMock() - self.media_item.manager.get_all_objects.side_effect = self._recursively_delete_group_side_effect - self.media_item.service_path = '' - test_group = ImageGroups() - test_group.id = 1 + ImageFilenames.group_id = 1 + ImageGroups.parent_id = 1 + self.media_item.manager = MagicMock() + self.media_item.manager.get_all_objects.side_effect = self._recursively_delete_group_side_effect + self.media_item.service_path = '' + test_group = ImageGroups() + test_group.id = 1 - # WHEN: recursively_delete_group() is called - self.media_item.recursively_delete_group(test_group) + # WHEN: recursively_delete_group() is called + self.media_item.recursively_delete_group(test_group) - # THEN: delete_file() should have been called 12 times and manager.delete_object() 7 times. - self.assertEquals(mocked_delete_file.call_count, 12, 'delete_file() should have been called 12 times') - self.assertEquals(self.media_item.manager.delete_object.call_count, 7, - 'manager.delete_object() should be called exactly 7 times') + # THEN: delete_file() should have been called 12 times and manager.delete_object() 7 times. + self.assertEquals(mocked_delete_file.call_count, 12, 'delete_file() should have been called 12 times') + self.assertEquals(self.media_item.manager.delete_object.call_count, 7, + 'manager.delete_object() should be called exactly 7 times') - # CLEANUP: Remove added attribute from Image Filenames and ImageGroups - delattr(ImageFilenames, 'group_id') - delattr(ImageGroups, 'parent_id') + # CLEANUP: Remove added attribute from Image Filenames and ImageGroups + delattr(ImageFilenames, 'group_id') + delattr(ImageGroups, 'parent_id') def _recursively_delete_group_side_effect(*args, **kwargs): """ @@ -231,28 +231,51 @@ class TestImageMediaItem(TestCase): return [returned_object1] return [] - def on_delete_click_test(self): + @patch('openlp.plugins.images.lib.mediaitem.delete_file') + @patch('openlp.plugins.images.lib.mediaitem.check_item_selected') + def on_delete_click_test(self, mocked_check_item_selected, mocked_delete_file): """ Test that on_delete_click() works """ # GIVEN: An ImageGroups object and mocked functions - with patch('openlp.plugins.images.lib.mediaitem.delete_file') as mocked_delete_file, \ - patch('openlp.plugins.images.lib.mediaitem.check_item_selected') as mocked_check_item_selected: - mocked_check_item_selected.return_value = True - test_image = ImageFilenames() - test_image.id = 1 - test_image.group_id = 1 - test_image.filename = 'imagefile.png' - self.media_item.manager = MagicMock() - self.media_item.service_path = '' - self.media_item.list_view = MagicMock() - mocked_row_item = MagicMock() - mocked_row_item.data.return_value = test_image - mocked_row_item.text.return_value = '' - self.media_item.list_view.selectedItems.return_value = [mocked_row_item] + mocked_check_item_selected.return_value = True + test_image = ImageFilenames() + test_image.id = 1 + test_image.group_id = 1 + test_image.filename = 'imagefile.png' + self.media_item.manager = MagicMock() + self.media_item.service_path = '' + self.media_item.list_view = MagicMock() + mocked_row_item = MagicMock() + mocked_row_item.data.return_value = test_image + mocked_row_item.text.return_value = '' + self.media_item.list_view.selectedItems.return_value = [mocked_row_item] - # WHEN: Calling on_delete_click - self.media_item.on_delete_click() + # WHEN: Calling on_delete_click + self.media_item.on_delete_click() - # THEN: delete_file should have been called twice - self.assertEquals(mocked_delete_file.call_count, 2, 'delete_file() should have been called twice') + # THEN: delete_file should have been called twice + self.assertEquals(mocked_delete_file.call_count, 2, 'delete_file() should have been called twice') + + def create_item_from_id_test(self): + """ + Test that the create_item_from_id() method returns a valid QTreeWidgetItem with a pre-created ImageFilenames + """ + # GIVEN: An ImageFilenames that already exists in the database + image_file = ImageFilenames() + image_file.id = 1 + image_file.filename = '/tmp/test_file_1.jpg' + self.media_item.manager = MagicMock() + self.media_item.manager.get_object_filtered.return_value = image_file + ImageFilenames.filename = '' + + # WHEN: create_item_from_id() is called + item = self.media_item.create_item_from_id(1) + + # THEN: A QTreeWidgetItem should be created with the above model object as it's data + self.assertIsInstance(item, QtGui.QTreeWidgetItem) + self.assertEqual('test_file_1.jpg', item.text(0)) + item_data = item.data(0, QtCore.Qt.UserRole) + self.assertIsInstance(item_data, ImageFilenames) + self.assertEqual(1, item_data.id) + self.assertEqual('/tmp/test_file_1.jpg', item_data.filename) diff --git a/tests/helpers/__init__.py b/tests/helpers/__init__.py index 072f42291..edf3104b5 100644 --- a/tests/helpers/__init__.py +++ b/tests/helpers/__init__.py @@ -22,3 +22,23 @@ """ The :mod:`~tests.helpers` module provides helper classes for use in the tests. """ +from datetime import datetime + + +class MockDateTime(object): + return_values = [datetime(2015, 4, 15, 18, 35, 21, 0)] + call_counter = 0 + + @classmethod + def revert(cls): + cls.return_values = [datetime(2015, 4, 15, 18, 35, 21, 0)] + cls.call_counter = 0 + + @classmethod + def now(cls): + if len(cls.return_values) > cls.call_counter: + mocked_datetime = cls.return_values[cls.call_counter] + else: + mocked_datetime = cls.return_values[-1] + cls.call_counter += 1 + return mocked_datetime