From 1347ad61d1059d5e79ccc53afb91be47314ae2d1 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Wed, 2 Oct 2013 23:07:20 +0200 Subject: [PATCH] Changed the way we create and initialise MediaManagerItems so that we can test things better. --- openlp/core/lib/mediamanageritem.py | 17 ++++++++-- openlp/plugins/bibles/bibleplugin.py | 14 ++++++--- openlp/plugins/bibles/lib/mediaitem.py | 5 +++ openlp/plugins/custom/lib/mediaitem.py | 7 ++++- openlp/plugins/images/lib/mediaitem.py | 31 ++++++++++++++----- openlp/plugins/media/lib/mediaitem.py | 7 ++++- openlp/plugins/presentations/lib/mediaitem.py | 30 ++++++++++-------- .../presentations/presentationplugin.py | 3 +- openlp/plugins/songs/lib/mediaitem.py | 5 +++ .../openlp_core_lib/test_serviceitem.py | 4 +-- .../openlp_plugins/images/test_lib.py | 9 +++--- .../presentations/test_mediaitem.py | 16 +++++----- .../openlp_plugins/songs/test_mediaitem.py | 4 +-- 13 files changed, 104 insertions(+), 48 deletions(-) diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 9e7eb8d73..3fddc18f2 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -82,10 +82,17 @@ class MediaManagerItem(QtGui.QWidget): """ Constructor to create the media manager item. """ - super(MediaManagerItem, self).__init__() + super(MediaManagerItem, self).__init__(parent) + self.plugin = plugin + self._setup() + self.setup_item() + + def _setup(self): + """ + Run some initial setup. This method is separate from __init__ in order to mock it out in tests. + """ self.hide() self.whitespace = re.compile(r'[\W_]+', re.UNICODE) - self.plugin = plugin visible_title = self.plugin.get_string(StringContent.VisibleName) self.title = str(visible_title['title']) Registry().register(self.plugin.name, self) @@ -106,6 +113,12 @@ class MediaManagerItem(QtGui.QWidget): QtCore.QObject.connect(self, QtCore.SIGNAL('%s_go_live' % self.plugin.name), self.go_live_remote) QtCore.QObject.connect(self, QtCore.SIGNAL('%s_add_to_service' % self.plugin.name), self.add_to_service_remote) + def setup_item(self): + """ + Override this for additional Plugin setup + """ + pass + def required_icons(self): """ This method is called to define the icons for the plugin. It provides a default set and the plugin is able to diff --git a/openlp/plugins/bibles/bibleplugin.py b/openlp/plugins/bibles/bibleplugin.py index 18aab2a0d..4121b474c 100644 --- a/openlp/plugins/bibles/bibleplugin.py +++ b/openlp/plugins/bibles/bibleplugin.py @@ -67,6 +67,9 @@ __default_settings__ = { class BiblePlugin(Plugin): + """ + The Bible plugin provides a plugin for managing and displaying Bibles. + """ log.info('Bible Plugin loaded') def __init__(self): @@ -74,13 +77,14 @@ class BiblePlugin(Plugin): self.weight = -9 self.icon_path = ':/plugins/plugin_bibles.png' self.icon = build_icon(self.icon_path) - self.manager = None + self.manager = BibleManager(self) def initialise(self): + """ + Initialise the Bible plugin. + """ log.info('bibles Initialising') - if self.manager is None: - self.manager = BibleManager(self) - Plugin.initialise(self) + super(BiblePlugin, self).initialise() self.import_bible_item.setVisible(True) action_list = ActionList.get_instance() action_list.add_action(self.import_bible_item, UiStrings().Import) @@ -107,7 +111,7 @@ class BiblePlugin(Plugin): """ Perform tasks on application startup """ - Plugin.app_startup(self) + super(BiblePlugin, self).app_startup() if self.manager.old_bible_databases: if QtGui.QMessageBox.information(self.main_window, translate('OpenLP', 'Information'), diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index 94f015fdb..4ccd37df1 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -64,6 +64,11 @@ class BibleMediaItem(MediaManagerItem): self.lock_icon = build_icon(':/bibles/bibles_search_lock.png') self.unlock_icon = build_icon(':/bibles/bibles_search_unlock.png') MediaManagerItem.__init__(self, parent, plugin) + + def setup_item(self): + """ + Do some additional setup. + """ # Place to store the search results for both bibles. self.settings = self.plugin.settings_tab self.quick_preview_allowed = True diff --git a/openlp/plugins/custom/lib/mediaitem.py b/openlp/plugins/custom/lib/mediaitem.py index a01ba427f..f5b518ce8 100644 --- a/openlp/plugins/custom/lib/mediaitem.py +++ b/openlp/plugins/custom/lib/mediaitem.py @@ -58,6 +58,11 @@ class CustomMediaItem(MediaManagerItem): def __init__(self, parent, plugin): self.icon_path = 'custom/custom' super(CustomMediaItem, self).__init__(parent, plugin) + + def setup_item(self): + """ + Do some additional setup. + """ self.edit_custom_form = EditCustomForm(self, self.main_window, self.plugin.manager) self.single_service_item = False self.quick_preview_allowed = True @@ -65,7 +70,7 @@ class CustomMediaItem(MediaManagerItem): # Holds information about whether the edit is remotely triggered and # which Custom is required. self.remote_custom = -1 - self.manager = plugin.manager + self.manager = self.plugin.manager def add_end_header_bar(self): self.toolbar.addSeparator() diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index 9e396c3cf..70d4630a0 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -52,10 +52,18 @@ class ImageMediaItem(MediaManagerItem): def __init__(self, parent, plugin): self.icon_path = 'images/image' + self.manager = None + self.choose_group_form = None + self.add_group_form = None super(ImageMediaItem, self).__init__(parent, plugin) + + def setup_item(self): + """ + Do some additional setup. + """ self.quick_preview_allowed = True self.has_search = True - self.manager = plugin.manager + self.manager = self.plugin.manager self.choose_group_form = ChooseGroupForm(self) self.add_group_form = AddGroupForm(self) self.fill_groups_combobox(self.choose_group_form.group_combobox) @@ -91,8 +99,8 @@ class ImageMediaItem(MediaManagerItem): self.list_view.setIconSize(QtCore.QSize(88, 50)) self.list_view.setIndentation(self.list_view.default_indentation) self.list_view.allow_internal_dnd = True - self.servicePath = os.path.join(AppLocation.get_section_data_path(self.settings_section), 'thumbnails') - check_directory_exists(self.servicePath) + self.service_path = os.path.join(AppLocation.get_section_data_path(self.settings_section), 'thumbnails') + check_directory_exists(self.service_path) # Load images from the database self.load_full_list( self.manager.get_all_objects(ImageFilenames, order_by_ref=ImageFilenames.filename), initial_load=True) @@ -193,7 +201,7 @@ class ImageMediaItem(MediaManagerItem): """ images = self.manager.get_all_objects(ImageFilenames, ImageFilenames.group_id == image_group.id) for image in images: - delete_file(os.path.join(self.servicePath, os.path.split(image.filename)[1])) + delete_file(os.path.join(self.service_path, os.path.split(image.filename)[1])) self.manager.delete_object(ImageFilenames, image.id) image_groups = self.manager.get_all_objects(ImageGroups, ImageGroups.parent_id == image_group.id) for group in image_groups: @@ -215,7 +223,7 @@ class ImageMediaItem(MediaManagerItem): if row_item: item_data = row_item.data(0, QtCore.Qt.UserRole) if isinstance(item_data, ImageFilenames): - delete_file(os.path.join(self.servicePath, row_item.text(0))) + delete_file(os.path.join(self.service_path, row_item.text(0))) if item_data.group_id == 0: self.list_view.takeTopLevelItem(self.list_view.indexOfTopLevelItem(row_item)) else: @@ -339,7 +347,7 @@ class ImageMediaItem(MediaManagerItem): for imageFile in images: log.debug('Loading image: %s', imageFile.filename) filename = os.path.split(imageFile.filename)[1] - thumb = os.path.join(self.servicePath, filename) + thumb = os.path.join(self.service_path, filename) if not os.path.exists(imageFile.filename): icon = build_icon(':/general/general_delete.png') else: @@ -672,7 +680,16 @@ class ImageMediaItem(MediaManagerItem): translate('ImagePlugin.MediaItem', 'There was a problem replacing your background, ' 'the image file "%s" no longer exists.') % filename) - def search(self, string, showError): + def search(self, string, show_error=True): + """ + Perform a search on the image file names. + + ``string`` + The glob to search for + + ``show_error`` + Unused. + """ files = self.manager.get_all_objects(ImageFilenames, filter_clause=ImageFilenames.filename.contains(string), order_by_ref=ImageFilenames.filename) results = [] diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index a5b0397c5..4f173db84 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -61,10 +61,15 @@ class MediaMediaItem(MediaManagerItem): self.background = False self.automatic = '' super(MediaMediaItem, self).__init__(parent, plugin) + + def setup_item(self): + """ + Do some additional setup. + """ self.single_service_item = False self.has_search = True self.media_object = None - self.display_controller = DisplayController(parent) + self.display_controller = DisplayController(self.parent()) self.display_controller.controller_layout = QtGui.QVBoxLayout() self.media_controller.register_controller(self.display_controller) self.media_controller.set_controls_visible(self.display_controller, False) diff --git a/openlp/plugins/presentations/lib/mediaitem.py b/openlp/plugins/presentations/lib/mediaitem.py index f1d0f1110..695baddc5 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -52,14 +52,26 @@ class PresentationMediaItem(MediaManagerItem): """ log.info('Presentations Media Item loaded') - def __init__(self, parent, plugin, icon, controllers): + def __init__(self, parent, plugin, controllers): """ Constructor. Setup defaults """ - self.controllers = controllers self.icon_path = 'presentations/presentation' - self.Automatic = '' + self.controllers = controllers super(PresentationMediaItem, self).__init__(parent, plugin) + + def retranslateUi(self): + """ + The name of the plugin media displayed in UI + """ + self.on_new_prompt = translate('PresentationPlugin.MediaItem', 'Select Presentation(s)') + self.automatic = translate('PresentationPlugin.MediaItem', 'Automatic') + self.display_type_label.setText(translate('PresentationPlugin.MediaItem', 'Present using:')) + + def setup_item(self): + """ + Do some additional setup. + """ self.message_listener = MessageListener(self) self.has_search = True self.single_service_item = False @@ -68,14 +80,6 @@ class PresentationMediaItem(MediaManagerItem): # Allow DnD from the desktop self.list_view.activateDnD() - def retranslateUi(self): - """ - The name of the plugin media displayed in UI - """ - self.on_new_prompt = translate('PresentationPlugin.MediaItem', 'Select Presentation(s)') - self.Automatic = translate('PresentationPlugin.MediaItem', 'Automatic') - self.display_type_label.setText(translate('PresentationPlugin.MediaItem', 'Present using:')) - def build_file_mask_string(self): """ Build the list of file extensions to be used in the Open file dialog. @@ -137,7 +141,7 @@ class PresentationMediaItem(MediaManagerItem): if self.controllers[item].enabled(): self.display_type_combo_box.addItem(item) if self.display_type_combo_box.count() > 1: - self.display_type_combo_box.insertItem(0, self.Automatic) + self.display_type_combo_box.insertItem(0, self.automatic) self.display_type_combo_box.setCurrentIndex(0) if Settings().value(self.settings_section + '/override app') == QtCore.Qt.Checked: self.presentation_widget.show() @@ -253,7 +257,7 @@ class PresentationMediaItem(MediaManagerItem): (path, name) = os.path.split(filename) service_item.title = name if os.path.exists(filename): - if service_item.processor == self.Automatic: + if service_item.processor == self.automatic: service_item.processor = self.findControllerByType(filename) if not service_item.processor: return False diff --git a/openlp/plugins/presentations/presentationplugin.py b/openlp/plugins/presentations/presentationplugin.py index 1efd5ac0a..be5d3f52d 100644 --- a/openlp/plugins/presentations/presentationplugin.py +++ b/openlp/plugins/presentations/presentationplugin.py @@ -109,8 +109,7 @@ class PresentationPlugin(Plugin): """ Create the Media Manager List. """ - self.media_item = PresentationMediaItem( - self.main_window.media_dock_manager.media_dock, self, self.icon, self.controllers) + self.media_item = PresentationMediaItem(self.main_window.media_dock_manager.media_dock, self, self.controllers) def register_controllers(self, controller): """ diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index 68cd706a3..957edbca0 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -72,6 +72,11 @@ class SongMediaItem(MediaManagerItem): def __init__(self, parent, plugin): self.icon_path = 'songs/song' super(SongMediaItem, self).__init__(parent, plugin) + + def setup_item(self): + """ + Do some additional setup. + """ self.single_service_item = False # Holds information about whether the edit is remotely triggered and which Song is required. self.remote_song = -1 diff --git a/tests/functional/openlp_core_lib/test_serviceitem.py b/tests/functional/openlp_core_lib/test_serviceitem.py index fda471428..f23c92b16 100644 --- a/tests/functional/openlp_core_lib/test_serviceitem.py +++ b/tests/functional/openlp_core_lib/test_serviceitem.py @@ -95,9 +95,9 @@ class TestServiceItem(TestCase): # THEN: The frames should also be valid self.assertEqual('Test Custom', service_item.get_display_title(), 'The title should be "Test Custom"') self.assertEqual(VERSE[:-1], service_item.get_frames()[0]['text'], - 'The returned text matches the input, except the last line feed') + 'The returned text matches the input, except the last line feed') self.assertEqual(VERSE.split('\n', 1)[0], service_item.get_rendered_frame(1), - 'The first line has been returned') + 'The first line has been returned') self.assertEqual('Slide 1', service_item.get_frame_title(0), '"Slide 1" has been returned as the title') self.assertEqual('Slide 2', service_item.get_frame_title(1), '"Slide 2" has been returned as the title') self.assertEqual('', service_item.get_frame_title(2), 'Blank has been returned as the title of slide 3') diff --git a/tests/functional/openlp_plugins/images/test_lib.py b/tests/functional/openlp_plugins/images/test_lib.py index 50fd258d2..f4d0dc30d 100644 --- a/tests/functional/openlp_plugins/images/test_lib.py +++ b/tests/functional/openlp_plugins/images/test_lib.py @@ -48,11 +48,10 @@ class TestImageMediaItem(TestCase): Registry().register('service_list', MagicMock()) Registry().register('main_window', self.mocked_main_window) Registry().register('live_controller', MagicMock()) - mocked_parent = MagicMock() mocked_plugin = MagicMock() - with patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.__init__') as mocked_init: - mocked_init.return_value = None - self.media_item = ImageMediaItem(mocked_parent, mocked_plugin) + with patch('openlp.plugins.images.lib.mediaitem.MediaManagerItem._setup'), \ + patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.setup_item'): + self.media_item = ImageMediaItem(None, mocked_plugin) def save_new_images_list_empty_list_test(self): """ @@ -160,7 +159,7 @@ class TestImageMediaItem(TestCase): 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.servicePath = "" + self.media_item.service_path = "" test_group = ImageGroups() test_group.id = 1 diff --git a/tests/functional/openlp_plugins/presentations/test_mediaitem.py b/tests/functional/openlp_plugins/presentations/test_mediaitem.py index 49b47252c..5b5c99e78 100644 --- a/tests/functional/openlp_plugins/presentations/test_mediaitem.py +++ b/tests/functional/openlp_plugins/presentations/test_mediaitem.py @@ -49,11 +49,9 @@ class TestMediaItem(TestCase): Registry.create() Registry().register('service_manager', MagicMock()) Registry().register('main_window', MagicMock()) - - with patch('openlp.plugins.presentations.lib.mediaitem.PresentationMediaItem.__init__') as mocked_init: - mocked_init.return_value = None - self.media_item = PresentationMediaItem(MagicMock(), MagicMock, MagicMock(), MagicMock()) - + with patch('openlp.plugins.presentations.lib.mediaitem.MediaManagerItem._setup'), \ + patch('openlp.plugins.presentations.lib.mediaitem.PresentationMediaItem.setup_item'): + self.media_item = PresentationMediaItem(None, MagicMock, MagicMock()) self.application = QtGui.QApplication.instance() def tearDown(self): @@ -89,6 +87,8 @@ class TestMediaItem(TestCase): mocked_translate.side_effect = lambda module, string_to_translate: string_to_translate self.media_item.build_file_mask_string() - # THEN: The file mask should be generated. - assert self.media_item.on_new_file_masks == 'Presentations (*.odp *.ppt )', \ - 'The file mask should contain the odp and ppt extensions' + # THEN: The file mask should be generated correctly + self.assertIn('*.odp', self.media_item.on_new_file_masks, + 'The file mask should contain the odp extension') + self.assertIn('*.ppt', self.media_item.on_new_file_masks, + 'The file mask should contain the ppt extension') diff --git a/tests/functional/openlp_plugins/songs/test_mediaitem.py b/tests/functional/openlp_plugins/songs/test_mediaitem.py index a519f7021..39f3146de 100644 --- a/tests/functional/openlp_plugins/songs/test_mediaitem.py +++ b/tests/functional/openlp_plugins/songs/test_mediaitem.py @@ -23,9 +23,9 @@ class TestMediaItem(TestCase): Registry.create() Registry().register('service_list', MagicMock()) Registry().register('main_window', MagicMock()) - with patch('openlp.core.lib.mediamanageritem.MediaManagerItem.__init__'), \ + with patch('openlp.core.lib.mediamanageritem.MediaManagerItem._setup'), \ patch('openlp.plugins.songs.forms.editsongform.EditSongForm.__init__'): - self.media_item = SongMediaItem(MagicMock(), MagicMock()) + self.media_item = SongMediaItem(None, MagicMock()) fd, self.ini_file = mkstemp('.ini') Settings().set_filename(self.ini_file)