From 7a47e5cb67e50b733cbe70c6e972d64a9b92a14c Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Sun, 15 Jun 2014 22:35:31 +0200 Subject: [PATCH 01/22] fixed bug #719514 ' Themes: and are the same file' Fixes: https://launchpad.net/bugs/719514 --- openlp/core/ui/thememanager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index fdd2ea592..6a67605d4 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -650,7 +650,7 @@ class ThemeManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ThemeManager, R finally: if out_file: out_file.close() - if image_from and image_from != image_to: + if image_from and os.path.abspath(image_from) != os.path.abspath(image_to): try: encoding = get_filesystem_encoding() shutil.copyfile(str(image_from).encode(encoding), str(image_to).encode(encoding)) From 05f4f2d72e2fad9e63926d59762b97e9cc3f152e Mon Sep 17 00:00:00 2001 From: Phill Ridout Date: Mon, 30 Jun 2014 21:54:11 +0100 Subject: [PATCH 02/22] fixed tests --- tests/functional/openlp_core_lib/test_file_dialog.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/functional/openlp_core_lib/test_file_dialog.py b/tests/functional/openlp_core_lib/test_file_dialog.py index ab7663a83..875e422da 100644 --- a/tests/functional/openlp_core_lib/test_file_dialog.py +++ b/tests/functional/openlp_core_lib/test_file_dialog.py @@ -65,11 +65,11 @@ class TestFileDialog(TestCase): # THEN: os.path.exists should have been called with known args. QmessageBox.information should have been # called. The returned result should correlate with the input. - self.mocked_os.path.exists.assert_callde_with('/Valid File') - self.mocked_os.path.exists.assert_callde_with('/url%20encoded%20file%20%231') - self.mocked_os.path.exists.assert_callde_with('/url encoded file #1') - self.mocked_os.path.exists.assert_callde_with('/non-existing') - self.mocked_os.path.exists.assert_callde_with('/non-existing') + self.mocked_os.path.exists.assert_any_call('/Valid File') + self.mocked_os.path.exists.assert_any_call('/url%20encoded%20file%20%231') + self.mocked_os.path.exists.assert_any_call('/url encoded file #1') + self.mocked_os.path.exists.assert_any_call('/non-existing') + self.mocked_os.path.exists.assert_any_call('/non-existing') self.mocked_qt_gui.QmessageBox.information.called_with(self.mocked_parent, UiStrings().FileNotFound, UiStrings().FileNotFoundMessage % '/non-existing') self.assertEqual(result, ['/Valid File', '/url encoded file #1'], 'The returned file list is incorrect') From 9b6979b840f393a3f31f30213260147a68397c60 Mon Sep 17 00:00:00 2001 From: Phill Ridout Date: Mon, 30 Jun 2014 21:59:22 +0100 Subject: [PATCH 03/22] Changed log.warn to log.warning --- openlp/core/lib/toolbar.py | 2 +- openlp/core/lib/ui.py | 6 +++--- openlp/core/ui/media/mediacontroller.py | 2 +- openlp/core/utils/actions.py | 4 ++-- .../plugins/bibles/forms/bibleupgradeform.py | 12 ++++++------ openlp/plugins/bibles/lib/http.py | 4 ++-- openlp/plugins/bibles/lib/opensong.py | 2 +- .../presentations/lib/impresscontroller.py | 18 +++++++++--------- .../presentations/lib/messagelistener.py | 4 ++-- .../presentations/presentationplugin.py | 4 ++-- openlp/plugins/songs/lib/songshowplusimport.py | 2 +- .../songs/lib/worshipcenterproimport.py | 2 +- 12 files changed, 31 insertions(+), 31 deletions(-) diff --git a/openlp/core/lib/toolbar.py b/openlp/core/lib/toolbar.py index b1cc7b249..b24be89a8 100644 --- a/openlp/core/lib/toolbar.py +++ b/openlp/core/lib/toolbar.py @@ -81,4 +81,4 @@ class OpenLPToolbar(QtGui.QToolBar): if handle in self.actions: self.actions[handle].setVisible(visible) else: - log.warn('No handle "%s" in actions list.', str(handle)) + log.warning('No handle "%s" in actions list.', str(handle)) diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py index a1e37abcf..cbc35e28d 100644 --- a/openlp/core/lib/ui.py +++ b/openlp/core/lib/ui.py @@ -172,7 +172,7 @@ def create_button(parent, name, **kwargs): kwargs.setdefault('icon', ':/services/service_down.png') kwargs.setdefault('tooltip', translate('OpenLP.Ui', 'Move selection down one position.')) else: - log.warn('The role "%s" is not defined in create_push_button().', role) + log.warning('The role "%s" is not defined in create_push_button().', role) if kwargs.pop('btn_class', '') == 'toolbutton': button = QtGui.QToolButton(parent) else: @@ -190,7 +190,7 @@ def create_button(parent, name, **kwargs): button.clicked.connect(kwargs.pop('click')) for key in list(kwargs.keys()): if key not in ['text', 'icon', 'tooltip', 'click']: - log.warn('Parameter %s was not consumed in create_button().', key) + log.warning('Parameter %s was not consumed in create_button().', key) return button @@ -275,7 +275,7 @@ def create_action(parent, name, **kwargs): action.triggered.connect(kwargs.pop('triggers')) for key in list(kwargs.keys()): if key not in ['text', 'icon', 'tooltip', 'statustip', 'checked', 'can_shortcuts', 'category', 'triggers']: - log.warn('Parameter %s was not consumed in create_action().' % key) + log.warning('Parameter %s was not consumed in create_action().' % key) return action diff --git a/openlp/core/ui/media/mediacontroller.py b/openlp/core/ui/media/mediacontroller.py index 596b618cb..f086b80b2 100644 --- a/openlp/core/ui/media/mediacontroller.py +++ b/openlp/core/ui/media/mediacontroller.py @@ -175,7 +175,7 @@ class MediaController(RegistryMixin, OpenLPMixin, RegistryProperties): # On some platforms importing vlc.py might cause # also OSError exceptions. (e.g. Mac OS X) except (ImportError, OSError): - log.warn('Failed to import %s on path %s', module_name, path) + log.warning('Failed to import %s on path %s', module_name, path) player_classes = MediaPlayer.__subclasses__() for player_class in player_classes: player = player_class(self) diff --git a/openlp/core/utils/actions.py b/openlp/core/utils/actions.py index d81e16b2e..fb794866b 100644 --- a/openlp/core/utils/actions.py +++ b/openlp/core/utils/actions.py @@ -279,7 +279,7 @@ class ActionList(object): actions.append(action) ActionList.shortcut_map[shortcuts[1]] = actions else: - log.warn('Shortcut "%s" is removed from "%s" because another action already uses this shortcut.' % + log.warning('Shortcut "%s" is removed from "%s" because another action already uses this shortcut.' % (shortcuts[1], action.objectName())) shortcuts.remove(shortcuts[1]) # Check the primary shortcut. @@ -290,7 +290,7 @@ class ActionList(object): actions.append(action) ActionList.shortcut_map[shortcuts[0]] = actions else: - log.warn('Shortcut "%s" is removed from "%s" because another action already uses this shortcut.' % + log.warning('Shortcut "%s" is removed from "%s" because another action already uses this shortcut.' % (shortcuts[0], action.objectName())) shortcuts.remove(shortcuts[0]) action.setShortcuts([QtGui.QKeySequence(shortcut) for shortcut in shortcuts]) diff --git a/openlp/plugins/bibles/forms/bibleupgradeform.py b/openlp/plugins/bibles/forms/bibleupgradeform.py index 09c0942b7..2b0b57695 100644 --- a/openlp/plugins/bibles/forms/bibleupgradeform.py +++ b/openlp/plugins/bibles/forms/bibleupgradeform.py @@ -423,7 +423,7 @@ class BibleUpgradeForm(OpenLPWizard): else: language_id = self.new_bibles[number].get_language(name) if not language_id: - log.warn('Upgrading from "%s" failed' % filename[0]) + log.warning('Upgrading from "%s" failed' % filename[0]) self.new_bibles[number].session.close() del self.new_bibles[number] self.increment_progress_bar( @@ -444,7 +444,7 @@ class BibleUpgradeForm(OpenLPWizard): book_ref_id = self.new_bibles[number].\ get_book_ref_id_by_name(book, len(books), language_id) if not book_ref_id: - log.warn('Upgrading books from %s - download name: "%s" aborted by user' % ( + log.warning('Upgrading books from %s - download name: "%s" aborted by user' % ( meta_data['download_source'], meta_data['download_name'])) self.new_bibles[number].session.close() del self.new_bibles[number] @@ -457,7 +457,7 @@ class BibleUpgradeForm(OpenLPWizard): if oldbook: verses = old_bible.get_verses(oldbook['id']) if not verses: - log.warn('No verses found to import for book "%s"', book) + log.warning('No verses found to import for book "%s"', book) continue for verse in verses: if self.stop_import_flag: @@ -472,7 +472,7 @@ class BibleUpgradeForm(OpenLPWizard): if not language_id: language_id = self.new_bibles[number].get_language(name) if not language_id: - log.warn('Upgrading books from "%s" failed' % name) + log.warning('Upgrading books from "%s" failed' % name) self.new_bibles[number].session.close() del self.new_bibles[number] self.increment_progress_bar( @@ -493,7 +493,7 @@ class BibleUpgradeForm(OpenLPWizard): (number + 1, max_bibles, name, book['name'])) book_ref_id = self.new_bibles[number].get_book_ref_id_by_name(book['name'], len(books), language_id) if not book_ref_id: - log.warn('Upgrading books from %s " failed - aborted by user' % name) + log.warning('Upgrading books from %s " failed - aborted by user' % name) self.new_bibles[number].session.close() del self.new_bibles[number] self.success[number] = False @@ -503,7 +503,7 @@ class BibleUpgradeForm(OpenLPWizard): book_details['testament_id']) verses = old_bible.get_verses(book['id']) if not verses: - log.warn('No verses found to import for book "%s"', book['name']) + log.warning('No verses found to import for book "%s"', book['name']) self.new_bibles[number].delete_book(db_book) continue for verse in verses: diff --git a/openlp/plugins/bibles/lib/http.py b/openlp/plugins/bibles/lib/http.py index 64b024639..8be0dbb5f 100644 --- a/openlp/plugins/bibles/lib/http.py +++ b/openlp/plugins/bibles/lib/http.py @@ -165,7 +165,7 @@ class BGExtract(RegistryProperties): if len(verse_parts) > 1: verse = int(verse_parts[0]) except TypeError: - log.warn('Illegal verse number: %s', str(verse)) + log.warning('Illegal verse number: %s', str(verse)) verses.append((verse, text)) verse_list = {} for verse, text in verses[::-1]: @@ -198,7 +198,7 @@ class BGExtract(RegistryProperties): if len(verse_parts) > 1: clean_verse_num = int(verse_parts[0]) except TypeError: - log.warn('Illegal verse number: %s', str(raw_verse_num)) + log.warning('Illegal verse number: %s', str(raw_verse_num)) if clean_verse_num: verse_text = raw_verse_num.next_element part = raw_verse_num.next_element.next_element diff --git a/openlp/plugins/bibles/lib/opensong.py b/openlp/plugins/bibles/lib/opensong.py index fa8323d7f..ecd1f718e 100644 --- a/openlp/plugins/bibles/lib/opensong.py +++ b/openlp/plugins/bibles/lib/opensong.py @@ -123,7 +123,7 @@ class OpenSongBible(BibleDB): if len(verse_parts) > 1: number = int(verse_parts[0]) except TypeError: - log.warn('Illegal verse number: %s', str(verse.attrib['n'])) + log.warning('Illegal verse number: %s', str(verse.attrib['n'])) verse_number = number else: verse_number += 1 diff --git a/openlp/plugins/presentations/lib/impresscontroller.py b/openlp/plugins/presentations/lib/impresscontroller.py index 584c1401f..1d5e111c9 100644 --- a/openlp/plugins/presentations/lib/impresscontroller.py +++ b/openlp/plugins/presentations/lib/impresscontroller.py @@ -129,7 +129,7 @@ class ImpressController(PresentationController): try: uno_instance = get_uno_instance(resolver) except: - log.warn('Unable to find running instance ') + log.warning('Unable to find running instance ') self.start_process() loop += 1 try: @@ -138,7 +138,7 @@ class ImpressController(PresentationController): desktop = self.manager.createInstanceWithContext("com.sun.star.frame.Desktop", uno_instance) return desktop except: - log.warn('Failed to get UNO desktop') + log.warning('Failed to get UNO desktop') return None def get_com_desktop(self): @@ -152,7 +152,7 @@ class ImpressController(PresentationController): try: desktop = self.manager.createInstance('com.sun.star.frame.Desktop') except (AttributeError, pywintypes.com_error): - log.warn('Failure to find desktop - Impress may have closed') + log.warning('Failure to find desktop - Impress may have closed') return desktop if desktop else None def get_com_servicemanager(self): @@ -163,7 +163,7 @@ class ImpressController(PresentationController): try: return Dispatch('com.sun.star.ServiceManager') except pywintypes.com_error: - log.warn('Failed to get COM service manager. Impress Controller has been disabled') + log.warning('Failed to get COM service manager. Impress Controller has been disabled') return None def kill(self): @@ -180,7 +180,7 @@ class ImpressController(PresentationController): else: desktop = self.get_com_desktop() except: - log.warn('Failed to find an OpenOffice desktop to terminate') + log.warning('Failed to find an OpenOffice desktop to terminate') if not desktop: return docs = desktop.getComponents() @@ -198,7 +198,7 @@ class ImpressController(PresentationController): desktop.terminate() log.debug('OpenOffice killed') except: - log.warn('Failed to terminate OpenOffice') + log.warning('Failed to terminate OpenOffice') class ImpressDocument(PresentationDocument): @@ -244,7 +244,7 @@ class ImpressDocument(PresentationDocument): try: self.document = desktop.loadComponentFromURL(url, '_blank', 0, properties) except: - log.warn('Failed to load presentation %s' % url) + log.warning('Failed to load presentation %s' % url) return False if os.name == 'nt': # As we can't start minimized the Impress window gets in the way. @@ -318,7 +318,7 @@ class ImpressDocument(PresentationDocument): self.presentation = None self.document.dispose() except: - log.warn("Closing presentation failed") + log.warning("Closing presentation failed") self.document = None self.controller.remove_doc(self) @@ -335,7 +335,7 @@ class ImpressDocument(PresentationDocument): log.debug("getPresentation failed to find a presentation") return False except: - log.warn("getPresentation failed to find a presentation") + log.warning("getPresentation failed to find a presentation") return False return True diff --git a/openlp/plugins/presentations/lib/messagelistener.py b/openlp/plugins/presentations/lib/messagelistener.py index 724282eb4..ac115228a 100644 --- a/openlp/plugins/presentations/lib/messagelistener.py +++ b/openlp/plugins/presentations/lib/messagelistener.py @@ -98,7 +98,7 @@ class Controller(object): return True if not self.doc.is_loaded(): if not self.doc.load_presentation(): - log.warn('Failed to activate %s' % self.doc.filepath) + log.warning('Failed to activate %s' % self.doc.filepath) return False if self.is_live: self.doc.start_presentation() @@ -109,7 +109,7 @@ class Controller(object): if self.doc.is_active(): return True else: - log.warn('Failed to activate %s' % self.doc.filepath) + log.warning('Failed to activate %s' % self.doc.filepath) return False def slide(self, slide): diff --git a/openlp/plugins/presentations/presentationplugin.py b/openlp/plugins/presentations/presentationplugin.py index 5e0d7395d..7f080df22 100644 --- a/openlp/plugins/presentations/presentationplugin.py +++ b/openlp/plugins/presentations/presentationplugin.py @@ -90,7 +90,7 @@ class PresentationPlugin(Plugin): try: self.controllers[controller].start_process() except Exception: - log.warn('Failed to start controller process') + log.warning('Failed to start controller process') self.controllers[controller].available = False self.media_item.build_file_mask_string() @@ -134,7 +134,7 @@ class PresentationPlugin(Plugin): try: __import__(module_name, globals(), locals(), []) except ImportError: - log.warn('Failed to import %s on path %s', module_name, path) + log.warning('Failed to import %s on path %s', module_name, path) controller_classes = PresentationController.__subclasses__() for controller_class in controller_classes: controller = controller_class(self) diff --git a/openlp/plugins/songs/lib/songshowplusimport.py b/openlp/plugins/songs/lib/songshowplusimport.py index aebded029..b57a9bac1 100644 --- a/openlp/plugins/songs/lib/songshowplusimport.py +++ b/openlp/plugins/songs/lib/songshowplusimport.py @@ -152,7 +152,7 @@ class SongShowPlusImport(SongImport): if match: self.ccli_number = int(match.group()) else: - log.warn("Can't parse CCLI Number from string: %s" % self.decode(data)) + log.warning("Can't parse CCLI Number from string: %s" % self.decode(data)) elif block_key == VERSE: self.add_verse(self.decode(data), "%s%s" % (VerseType.tags[VerseType.Verse], verse_no)) elif block_key == CHORUS: diff --git a/openlp/plugins/songs/lib/worshipcenterproimport.py b/openlp/plugins/songs/lib/worshipcenterproimport.py index b24d2ae83..8c32870a1 100644 --- a/openlp/plugins/songs/lib/worshipcenterproimport.py +++ b/openlp/plugins/songs/lib/worshipcenterproimport.py @@ -58,7 +58,7 @@ class WorshipCenterProImport(SongImport): try: conn = pyodbc.connect('DRIVER={Microsoft Access Driver (*.mdb)};DBQ=%s' % self.import_source) except (pyodbc.DatabaseError, pyodbc.IntegrityError, pyodbc.InternalError, pyodbc.OperationalError) as e: - log.warn('Unable to connect the WorshipCenter Pro database %s. %s', self.import_source, str(e)) + log.warning('Unable to connect the WorshipCenter Pro database %s. %s', self.import_source, str(e)) # Unfortunately no specific exception type self.log_error(self.import_source, translate('SongsPlugin.WorshipCenterProImport', 'Unable to connect the WorshipCenter Pro database.')) From 376f8f3dc7d0714a876c6ab184638ffc7f0d2db7 Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Wed, 2 Jul 2014 21:18:18 +0200 Subject: [PATCH 04/22] Added test for thememanager --- .../openlp_core_ui/test_thememanager.py | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 tests/functional/openlp_core_ui/test_thememanager.py diff --git a/tests/functional/openlp_core_ui/test_thememanager.py b/tests/functional/openlp_core_ui/test_thememanager.py new file mode 100644 index 000000000..a0bfbd01e --- /dev/null +++ b/tests/functional/openlp_core_ui/test_thememanager.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2014 Raoul Snyman # +# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan # +# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, # +# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. # +# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, # +# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # +# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, # +# Frode Woldsund, Martin Zibricky, Patrick Zimmermann # +# --------------------------------------------------------------------------- # +# This program is free software; you can redistribute it and/or modify it # +# under the terms of the GNU General Public License as published by the Free # +# Software Foundation; version 2 of the License. # +# # +# This program is distributed in the hope that it will be useful, but WITHOUT # +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +# more details. # +# # +# You should have received a copy of the GNU General Public License along # +# with this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### +""" +Package to test the openlp.core.ui.slidecontroller package. +""" +import os + +from unittest import TestCase + +from openlp.core.common import Registry +from openlp.core.ui import ThemeManager + +from tests.utils.constants import TEST_RESOURCES_PATH +from tests.interfaces import MagicMock, patch + + +class TestThemeManager(TestCase): + + def setUp(self): + """ + Create the UI + """ + Registry.create() + + def tearDown(self): + """ + Delete all the C++ objects at the end so that we don't have a segfault + """ + pass + + def initial_theme_manager_test(self): + """ + Test the initial of theme manager. + """ + # GIVEN: A new service manager instance. + ThemeManager(None) + + # WHEN: the default theme manager is built. + # THEN: The the controller should be registered in the registry. + self.assertNotEqual(Registry().get('theme_manager'), None, 'The base theme manager should be registered') + + def write_theme_test(self): + """ + Test that we don't try to overwrite a theme bacground image with itself + """ + # GIVEN: A new theme manager instance, with mocked builtins.open, shutil.copyfile, + # theme, check_directory_exists and thememanager-attributes. + with patch('builtins.open') as mocked_open, \ + patch('openlp.core.ui.thememanager.shutil.copyfile') as mocked_copyfile, \ + patch('openlp.core.ui.thememanager.check_directory_exists') as mocked_check_directory_exists: + mocked_open.return_value = MagicMock() + theme_manager = ThemeManager(None) + theme_manager.old_background_image = None + theme_manager.generate_and_save_image = MagicMock() + theme_manager.path = '' + mocked_theme = MagicMock() + mocked_theme.theme_name = 'themename' + mocked_theme.extract_formatted_xml = MagicMock() + mocked_theme.extract_formatted_xml.return_value = 'fake_theme_xml'.encode() + + # WHEN: Calling _write_theme with path to the same image, but the path written slightly different + file_name1 = os.path.join(TEST_RESOURCES_PATH, 'church.jpg') + # Do replacement from end of string to avoid problems with path start + file_name2 = file_name1[::-1].replace(os.sep, os.sep + os.sep, 2)[::-1] + theme_manager._write_theme(mocked_theme, file_name1, file_name2) + + # THEN: The mocked_copyfile should not have been called + self.assertFalse(mocked_copyfile.called, 'shutil.copyfile should not be called') From e6f5136708c99f5883d0395e676f17001475a9f7 Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Mon, 7 Jul 2014 19:22:58 +0200 Subject: [PATCH 05/22] Suggested changes to tests --- .../openlp_core_ui/test_thememanager.py | 43 ++++++++++++++----- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/tests/functional/openlp_core_ui/test_thememanager.py b/tests/functional/openlp_core_ui/test_thememanager.py index a0bfbd01e..496e78aa4 100644 --- a/tests/functional/openlp_core_ui/test_thememanager.py +++ b/tests/functional/openlp_core_ui/test_thememanager.py @@ -44,30 +44,24 @@ class TestThemeManager(TestCase): def setUp(self): """ - Create the UI + Set up the tests """ Registry.create() - def tearDown(self): - """ - Delete all the C++ objects at the end so that we don't have a segfault - """ - pass - def initial_theme_manager_test(self): """ - Test the initial of theme manager. + Test the instantiation of theme manager. """ # GIVEN: A new service manager instance. ThemeManager(None) # WHEN: the default theme manager is built. # THEN: The the controller should be registered in the registry. - self.assertNotEqual(Registry().get('theme_manager'), None, 'The base theme manager should be registered') + self.assertIsNotNone(Registry().get('theme_manager'), 'The base theme manager should be registered') - def write_theme_test(self): + def write_theme_same_image_test(self): """ - Test that we don't try to overwrite a theme bacground image with itself + Test that we don't try to overwrite a theme background image with itself """ # GIVEN: A new theme manager instance, with mocked builtins.open, shutil.copyfile, # theme, check_directory_exists and thememanager-attributes. @@ -92,3 +86,30 @@ class TestThemeManager(TestCase): # THEN: The mocked_copyfile should not have been called self.assertFalse(mocked_copyfile.called, 'shutil.copyfile should not be called') + + def write_theme_diff_images_test(self): + """ + Test that we do overwrite a theme background image when a new is submitted + """ + # GIVEN: A new theme manager instance, with mocked builtins.open, shutil.copyfile, + # theme, check_directory_exists and thememanager-attributes. + with patch('builtins.open') as mocked_open, \ + patch('openlp.core.ui.thememanager.shutil.copyfile') as mocked_copyfile, \ + patch('openlp.core.ui.thememanager.check_directory_exists') as mocked_check_directory_exists: + mocked_open.return_value = MagicMock() + theme_manager = ThemeManager(None) + theme_manager.old_background_image = None + theme_manager.generate_and_save_image = MagicMock() + theme_manager.path = '' + mocked_theme = MagicMock() + mocked_theme.theme_name = 'themename' + mocked_theme.extract_formatted_xml = MagicMock() + mocked_theme.extract_formatted_xml.return_value = 'fake_theme_xml'.encode() + + # WHEN: Calling _write_theme with path to different images + file_name1 = os.path.join(TEST_RESOURCES_PATH, 'church.jpg') + file_name2 = os.path.join(TEST_RESOURCES_PATH, 'church2.jpg') + theme_manager._write_theme(mocked_theme, file_name1, file_name2) + + # THEN: The mocked_copyfile should not have been called + self.assertTrue(mocked_copyfile.called, 'shutil.copyfile should be called') From fdded5adc22d14f2b04df73d5047679b0597e953 Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Mon, 7 Jul 2014 19:28:27 +0200 Subject: [PATCH 06/22] Fix tag tests --- tests/utils/test_bzr_tags.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/utils/test_bzr_tags.py b/tests/utils/test_bzr_tags.py index acadbd8c4..393f4ce25 100644 --- a/tests/utils/test_bzr_tags.py +++ b/tests/utils/test_bzr_tags.py @@ -50,6 +50,10 @@ TAGS = [ ['1.9.11', '2039'], ['1.9.12', '2063'], ['2.0', '2118'], + ['2.0.1', '?'], + ['2.0.2', '?'], + ['2.0.3', '?'], + ['2.0.4', '?'], ['2.1.0', '2119'] ] From 15ca94554b9309b8d57fa98be3e101bf01821805 Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Mon, 14 Jul 2014 09:21:36 +0200 Subject: [PATCH 07/22] Updated jenkins script to match tests --- scripts/jenkins_script.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/jenkins_script.py b/scripts/jenkins_script.py index eeafbfe23..cd6a0c9cf 100755 --- a/scripts/jenkins_script.py +++ b/scripts/jenkins_script.py @@ -62,11 +62,12 @@ class OpenLPJobs(object): Branch_Pull = 'Branch-01-Pull' Branch_Functional = 'Branch-02-Functional-Tests' Branch_Interface = 'Branch-03-Interface-Tests' - Branch_Windows = 'Branch-04-Windows_Tests' + Branch_Windows_Functional = 'Branch-04a-Windows_Functional_Tests' + Branch_Windows_Interface = 'Branch-04b-Windows_Interface_Tests' Branch_PEP = 'Branch-05a-Code_Analysis' Branch_Coverage = 'Branch-05b-Test_Coverage' - Jobs = [Branch_Pull, Branch_Functional, Branch_Interface, Branch_Windows, Branch_PEP, Branch_Coverage] + Jobs = [Branch_Pull, Branch_Functional, Branch_Interface, Branch_Windows_Functional, Branch_Windows_Interface, Branch_PEP, Branch_Coverage] class Colour(object): From dc4c9f389b0b1a6bb5e14cfe76e6bdb2b1936fe4 Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Mon, 14 Jul 2014 09:27:38 +0200 Subject: [PATCH 08/22] pep8 fix --- scripts/jenkins_script.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/jenkins_script.py b/scripts/jenkins_script.py index cd6a0c9cf..4ee0b3aa2 100755 --- a/scripts/jenkins_script.py +++ b/scripts/jenkins_script.py @@ -67,7 +67,8 @@ class OpenLPJobs(object): Branch_PEP = 'Branch-05a-Code_Analysis' Branch_Coverage = 'Branch-05b-Test_Coverage' - Jobs = [Branch_Pull, Branch_Functional, Branch_Interface, Branch_Windows_Functional, Branch_Windows_Interface, Branch_PEP, Branch_Coverage] + Jobs = [Branch_Pull, Branch_Functional, Branch_Interface, Branch_Windows_Functional, Branch_Windows_Interface, + Branch_PEP, Branch_Coverage] class Colour(object): From cad82e637d3a9f5743ddde113d34e50d7c49bd60 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Fri, 18 Jul 2014 22:09:25 +0100 Subject: [PATCH 09/22] Update script --- scripts/jenkins_script.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/scripts/jenkins_script.py b/scripts/jenkins_script.py index eeafbfe23..64d76bef9 100755 --- a/scripts/jenkins_script.py +++ b/scripts/jenkins_script.py @@ -87,7 +87,7 @@ class JenkinsTrigger(object): :param token: The token we need to trigger the build. If you do not have this token, ask in IRC. """ self.token = token - self.repo_name = get_repo_name() + self.base_name, self.repo_name = get_repo_name('b') self.jenkins_instance = Jenkins(JENKINS_URL) def trigger_build(self): @@ -111,7 +111,8 @@ class JenkinsTrigger(object): bzr = Popen(('bzr', 'revno'), stdout=PIPE, stderr=PIPE) raw_output, error = bzr.communicate() revno = raw_output.decode().strip() - print('%s (revision %s)' % (get_repo_name(), revno)) + print('Remote repository: %s ' % self.repo_name) + print(' Local repository: %s (revision %s)' % (self.repo_name, revno)) for job in OpenLPJobs.Jobs: self.__print_build_info(job) @@ -146,7 +147,7 @@ class JenkinsTrigger(object): print('[%s] %s' % (result_string, url)) -def get_repo_name(): +def get_repo_name(branch_type='l'): """ This returns the name of branch of the working directory. For example it returns *lp:~googol/openlp/render*. """ @@ -162,6 +163,7 @@ def get_repo_name(): output_list = list(map(str.strip, raw_output.split('\n'))) # Determine the branch's name repo_name = '' + base_name = '' for line in output_list: # Check if it is remote branch. if 'push branch' in line: @@ -174,7 +176,15 @@ def get_repo_name(): if match: repo_name = 'lp:%s' % match.group(2) break - return repo_name.strip('/') + elif 'repository branch' in line: + base_name = line.split(':')[1] + break + if branch_type == 'b': + return base_name.strip('/'), repo_name.strip('/') + elif branch_type == 'r': + return base_name.strip('/') + else: + return repo_name.strip('/') def main(): @@ -188,9 +198,12 @@ def main(): options, args = parser.parse_args(sys.argv) if len(args) == 2: - if not get_repo_name(): + if not get_repo_name('l'): print('Not a branch. Have you pushed it to launchpad? Did you cd to the branch?') return + if not get_repo_name('r'): + print('No remote branch. Have you pushed it to launchpad? Did you cd to the branch?') + return token = args[-1] if token in OLD_TOKENS: print('Your token is not valid anymore. Get the most recent one.') From 67ab5082862cda6f248f0c0f7cf3078e760bd679 Mon Sep 17 00:00:00 2001 From: Phill Ridout Date: Sun, 20 Jul 2014 21:00:06 +0100 Subject: [PATCH 10/22] Tweeked test to use a call list --- tests/functional/openlp_core_lib/test_file_dialog.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/functional/openlp_core_lib/test_file_dialog.py b/tests/functional/openlp_core_lib/test_file_dialog.py index 875e422da..1190810da 100644 --- a/tests/functional/openlp_core_lib/test_file_dialog.py +++ b/tests/functional/openlp_core_lib/test_file_dialog.py @@ -5,7 +5,7 @@ from unittest import TestCase from openlp.core.common import UiStrings from openlp.core.lib.filedialog import FileDialog -from tests.functional import MagicMock, patch +from tests.functional import MagicMock, call, patch class TestFileDialog(TestCase): @@ -65,11 +65,9 @@ class TestFileDialog(TestCase): # THEN: os.path.exists should have been called with known args. QmessageBox.information should have been # called. The returned result should correlate with the input. - self.mocked_os.path.exists.assert_any_call('/Valid File') - self.mocked_os.path.exists.assert_any_call('/url%20encoded%20file%20%231') - self.mocked_os.path.exists.assert_any_call('/url encoded file #1') - self.mocked_os.path.exists.assert_any_call('/non-existing') - self.mocked_os.path.exists.assert_any_call('/non-existing') + call_list = [call('/Valid File'), call('/url%20encoded%20file%20%231'), call('/url encoded file #1'), + call('/non-existing'), call('/non-existing')] + self.mocked_os.path.exists.assert_has_calls(call_list) self.mocked_qt_gui.QmessageBox.information.called_with(self.mocked_parent, UiStrings().FileNotFound, UiStrings().FileNotFoundMessage % '/non-existing') self.assertEqual(result, ['/Valid File', '/url encoded file #1'], 'The returned file list is incorrect') From 63f08f0c4aba91196866aaeb5a78da99e075ad54 Mon Sep 17 00:00:00 2001 From: Samuel Mehrbrodt Date: Mon, 18 Aug 2014 20:45:15 +0200 Subject: [PATCH 11/22] Fix ProPresenter import Fixes: https://launchpad.net/bugs/1358418 --- openlp/plugins/songs/lib/importer.py | 2 +- openlp/plugins/songs/lib/importers/__init__.py | 2 +- openlp/plugins/songs/lib/importers/propresenter.py | 11 ++++++++++- openlp/plugins/songs/lib/importers/songimport.py | 9 +++++++++ 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/openlp/plugins/songs/lib/importer.py b/openlp/plugins/songs/lib/importer.py index 0084a74de..9c17e1f67 100644 --- a/openlp/plugins/songs/lib/importer.py +++ b/openlp/plugins/songs/lib/importer.py @@ -292,7 +292,7 @@ class SongFormat(object): 'class': ProPresenterImport, 'name': 'ProPresenter', 'prefix': 'proPresenter', - 'filter': '%s (*.pro4)' % translate('SongsPlugin.ImportWizardForm', 'ProPresenter Song Files') + 'filter': '%s (*.pro4)' % translate('SongsPlugin.ImportWizardForm', 'ProPresenter 4 Song Files') }, SongBeamer: { 'class': SongBeamerImport, diff --git a/openlp/plugins/songs/lib/importers/__init__.py b/openlp/plugins/songs/lib/importers/__init__.py index da302572e..f86a3e95e 100644 --- a/openlp/plugins/songs/lib/importers/__init__.py +++ b/openlp/plugins/songs/lib/importers/__init__.py @@ -27,5 +27,5 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### """ -The :mod:`~openlp.plugins.songs.lib.import` module contains importers for the Songs plugin. +The :mod:`~openlp.plugins.songs.lib.importers` module contains importers for the Songs plugin. """ diff --git a/openlp/plugins/songs/lib/importers/propresenter.py b/openlp/plugins/songs/lib/importers/propresenter.py index 3bf7f9cd8..ca9a2e9c8 100644 --- a/openlp/plugins/songs/lib/importers/propresenter.py +++ b/openlp/plugins/songs/lib/importers/propresenter.py @@ -33,17 +33,20 @@ ProPresenter song files into the current installation database. import os import base64 +import logging from lxml import objectify from openlp.core.ui.wizard import WizardStrings from openlp.plugins.songs.lib import strip_rtf from .songimport import SongImport +log = logging.getLogger(__name__) + class ProPresenterImport(SongImport): """ The :class:`ProPresenterImport` class provides OpenLP with the - ability to import ProPresenter song files. + ability to import ProPresenter 4 song files. """ def do_import(self): self.import_wizard.progress_bar.setMaximum(len(self.import_source)) @@ -67,9 +70,15 @@ class ProPresenterImport(SongImport): count = 0 for slide in root.slides.RVDisplaySlide: count += 1 + if not hasattr(slide.displayElements, 'RVTextElement'): + log.debug('No text found, may be an image slide') + continue RTFData = slide.displayElements.RVTextElement.get('RTFData') rtf = base64.standard_b64decode(RTFData) words, encoding = strip_rtf(rtf.decode()) self.add_verse(words, "v%d" % count) + # Some songs don't have a title - use the first line as title + if not self.title: + self.title = self.guess_title() if not self.finish(): self.log_error(self.import_source) diff --git a/openlp/plugins/songs/lib/importers/songimport.py b/openlp/plugins/songs/lib/importers/songimport.py index 5382efbe5..14622e978 100644 --- a/openlp/plugins/songs/lib/importers/songimport.py +++ b/openlp/plugins/songs/lib/importers/songimport.py @@ -316,6 +316,15 @@ class SongImport(QtCore.QObject): self.verse_order_list_generated.append(self.verse_order_list_generated[-1]) self.verse_order_list_generated_useful = True + def guess_title(self): + """ + Guess the title from the first verse (to be used when the song has no title information) + :return: The guessed title + """ + if not self.verses: + return '' + return self.verses[0][1].split('\n')[0].strip() + def check_complete(self): """ Check the mandatory fields are entered (i.e. title and a verse) From 0bf256070a898317a88d0cfca8af6ca9aa16c3dd Mon Sep 17 00:00:00 2001 From: Samuel Mehrbrodt Date: Mon, 18 Aug 2014 21:04:46 +0200 Subject: [PATCH 12/22] Add test --- .../songs/lib/importers/propresenter.py | 9 ++--- .../plugins/songs/lib/importers/songimport.py | 9 ----- .../songs/test_propresenterimport.py | 2 ++ .../propresentersongs/Vaste Grond.json | 34 +++++++++++++++++++ .../propresentersongs/Vaste Grond.pro4 | 1 + 5 files changed, 40 insertions(+), 15 deletions(-) create mode 100644 tests/resources/propresentersongs/Vaste Grond.json create mode 100644 tests/resources/propresentersongs/Vaste Grond.pro4 diff --git a/openlp/plugins/songs/lib/importers/propresenter.py b/openlp/plugins/songs/lib/importers/propresenter.py index ca9a2e9c8..b0509393b 100644 --- a/openlp/plugins/songs/lib/importers/propresenter.py +++ b/openlp/plugins/songs/lib/importers/propresenter.py @@ -55,11 +55,11 @@ class ProPresenterImport(SongImport): return self.import_wizard.increment_progress_bar(WizardStrings.ImportingType % os.path.basename(file_path)) root = objectify.parse(open(file_path, 'rb')).getroot() - self.process_song(root) + self.process_song(root, file_path) - def process_song(self, root): + def process_song(self, root, filename): self.set_defaults() - self.title = root.get('CCLISongTitle') + self.title = os.path.basename(filename).rstrip('.pro4') self.copyright = root.get('CCLICopyrightInfo') self.comments = root.get('notes') self.ccli_number = root.get('CCLILicenseNumber') @@ -77,8 +77,5 @@ class ProPresenterImport(SongImport): rtf = base64.standard_b64decode(RTFData) words, encoding = strip_rtf(rtf.decode()) self.add_verse(words, "v%d" % count) - # Some songs don't have a title - use the first line as title - if not self.title: - self.title = self.guess_title() if not self.finish(): self.log_error(self.import_source) diff --git a/openlp/plugins/songs/lib/importers/songimport.py b/openlp/plugins/songs/lib/importers/songimport.py index 14622e978..5382efbe5 100644 --- a/openlp/plugins/songs/lib/importers/songimport.py +++ b/openlp/plugins/songs/lib/importers/songimport.py @@ -316,15 +316,6 @@ class SongImport(QtCore.QObject): self.verse_order_list_generated.append(self.verse_order_list_generated[-1]) self.verse_order_list_generated_useful = True - def guess_title(self): - """ - Guess the title from the first verse (to be used when the song has no title information) - :return: The guessed title - """ - if not self.verses: - return '' - return self.verses[0][1].split('\n')[0].strip() - def check_complete(self): """ Check the mandatory fields are entered (i.e. title and a verse) diff --git a/tests/functional/openlp_plugins/songs/test_propresenterimport.py b/tests/functional/openlp_plugins/songs/test_propresenterimport.py index 3b79961f9..f3bdcb959 100644 --- a/tests/functional/openlp_plugins/songs/test_propresenterimport.py +++ b/tests/functional/openlp_plugins/songs/test_propresenterimport.py @@ -52,3 +52,5 @@ class TestProPresenterFileImport(SongImportTestHelper): """ self.file_import([os.path.join(TEST_PATH, 'Amazing Grace.pro4')], self.load_external_result_data(os.path.join(TEST_PATH, 'Amazing Grace.json'))) + self.file_import([os.path.join(TEST_PATH, 'Vaste Grond.pro4')], + self.load_external_result_data(os.path.join(TEST_PATH, 'Vaste Grond.json'))) diff --git a/tests/resources/propresentersongs/Vaste Grond.json b/tests/resources/propresentersongs/Vaste Grond.json new file mode 100644 index 000000000..f55abd83e --- /dev/null +++ b/tests/resources/propresentersongs/Vaste Grond.json @@ -0,0 +1,34 @@ +{ + "title": "Vaste Grond", + "verse_order_list": [], + "verses": [ + [ + "God voor U is niets onmogelijk\nHoe ongelofelijk\nU heeft alles in de hand", + "v1" + ], + [ + "U bent God en trekt Uw eigen plan\nU bent voor niemand bang\nVoor niets en niemand bang", + "v2" + ], + [ + "U houd me vast en geeft me moed\nOm door te gaan als ik niet durf\nIk wil van U zijn", + "v3" + ], + [ + "U geeft me kracht, en bent de vaste grond\nwaarop ik stevig sta\nik wil van U zijn, voor altijd van U zijn\nO God.", + "v4" + ], + [ + "Grote God, U bent uitzonderlijk\nen ondoorgrondelijk\nU biedt Uw liefde aan", + "v5" + ], + [ + "Wie ben ik, dat U mij ziet staan\nen met mij om wilt gaan?\nIk kan U niet weerstaan", + "v6" + ], + [ + "Onweerstaanbaar,\nonweerstaanbare God", + "v7" + ] + ] +} \ No newline at end of file diff --git a/tests/resources/propresentersongs/Vaste Grond.pro4 b/tests/resources/propresentersongs/Vaste Grond.pro4 new file mode 100644 index 000000000..7abfb593d --- /dev/null +++ b/tests/resources/propresentersongs/Vaste Grond.pro4 @@ -0,0 +1 @@ +<_-RVRect3D-_position x="32.37209" y="29" z="0" width="1074.349" height="818.7442"><_-D-_serializedShadow containerClass="NSMutableDictionary"><_-RVRect3D-_position x="32.37209" y="29" z="0" width="1074.349" height="818.7442"><_-D-_serializedShadow containerClass="NSMutableDictionary"><_-RVRect3D-_position x="32.37209" y="29" z="0" width="1074.349" height="818.7442"><_-D-_serializedShadow containerClass="NSMutableDictionary"><_-RVRect3D-_position x="32.37209" y="29" z="0" width="1074.349" height="818.7442"><_-D-_serializedShadow containerClass="NSMutableDictionary"><_-RVRect3D-_position x="32.37209" y="29" z="0" width="1074.349" height="818.7442"><_-D-_serializedShadow containerClass="NSMutableDictionary"><_-RVRect3D-_position x="32.37209" y="29" z="0" width="1074.349" height="818.7442"><_-D-_serializedShadow containerClass="NSMutableDictionary"><_-RVRect3D-_position x="32.37209" y="29" z="0" width="1074.349" height="818.7442"><_-D-_serializedShadow containerClass="NSMutableDictionary"> \ No newline at end of file From eeeb2b558ee7080fe378bdb496d5f146970a846f Mon Sep 17 00:00:00 2001 From: Samuel Mehrbrodt Date: Mon, 18 Aug 2014 21:05:39 +0200 Subject: [PATCH 13/22] PEP8 --- scripts/jenkins_script.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/jenkins_script.py b/scripts/jenkins_script.py index 6c6fdac80..d7c8a3427 100755 --- a/scripts/jenkins_script.py +++ b/scripts/jenkins_script.py @@ -67,7 +67,8 @@ class OpenLPJobs(object): Branch_PEP = 'Branch-05a-Code_Analysis' Branch_Coverage = 'Branch-05b-Test_Coverage' - Jobs = [Branch_Pull, Branch_Functional, Branch_Interface, Branch_Windows_Functional, Branch_Windows_Interface, Branch_PEP, Branch_Coverage] + Jobs = [Branch_Pull, Branch_Functional, Branch_Interface, Branch_Windows_Functional, + Branch_Windows_Interface, Branch_PEP, Branch_Coverage] class Colour(object): From bde55c79f87d911a675f4556379a85ac51aa78b1 Mon Sep 17 00:00:00 2001 From: Samuel Mehrbrodt Date: Mon, 18 Aug 2014 21:15:23 +0200 Subject: [PATCH 14/22] No newline at end of file... --- tests/resources/propresentersongs/Vaste Grond.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/resources/propresentersongs/Vaste Grond.json b/tests/resources/propresentersongs/Vaste Grond.json index f55abd83e..75ffac7a2 100644 --- a/tests/resources/propresentersongs/Vaste Grond.json +++ b/tests/resources/propresentersongs/Vaste Grond.json @@ -31,4 +31,4 @@ "v7" ] ] -} \ No newline at end of file +} From ce26493dac45976aa2b54aa75d370dcc3e670f3c Mon Sep 17 00:00:00 2001 From: Samuel Mehrbrodt Date: Tue, 19 Aug 2014 07:57:54 +0200 Subject: [PATCH 15/22] We only support v4 files --- openlp/plugins/songs/lib/importer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/plugins/songs/lib/importer.py b/openlp/plugins/songs/lib/importer.py index 9c17e1f67..e9ee2c2f3 100644 --- a/openlp/plugins/songs/lib/importer.py +++ b/openlp/plugins/songs/lib/importer.py @@ -290,7 +290,7 @@ class SongFormat(object): }, ProPresenter: { 'class': ProPresenterImport, - 'name': 'ProPresenter', + 'name': 'ProPresenter 4', 'prefix': 'proPresenter', 'filter': '%s (*.pro4)' % translate('SongsPlugin.ImportWizardForm', 'ProPresenter 4 Song Files') }, From 49fca807f4d476fd00b0bf872f24e89932719938 Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Thu, 21 Aug 2014 14:41:46 +0200 Subject: [PATCH 16/22] deleted file leftover from merge --- .../openlp_core_ui/test_thememanager.py.moved | 115 ------------------ 1 file changed, 115 deletions(-) delete mode 100644 tests/functional/openlp_core_ui/test_thememanager.py.moved diff --git a/tests/functional/openlp_core_ui/test_thememanager.py.moved b/tests/functional/openlp_core_ui/test_thememanager.py.moved deleted file mode 100644 index 496e78aa4..000000000 --- a/tests/functional/openlp_core_ui/test_thememanager.py.moved +++ /dev/null @@ -1,115 +0,0 @@ -# -*- coding: utf-8 -*- -# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 - -############################################################################### -# OpenLP - Open Source Lyrics Projection # -# --------------------------------------------------------------------------- # -# Copyright (c) 2008-2014 Raoul Snyman # -# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan # -# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, # -# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. # -# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, # -# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # -# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, # -# Frode Woldsund, Martin Zibricky, Patrick Zimmermann # -# --------------------------------------------------------------------------- # -# This program is free software; you can redistribute it and/or modify it # -# under the terms of the GNU General Public License as published by the Free # -# Software Foundation; version 2 of the License. # -# # -# This program is distributed in the hope that it will be useful, but WITHOUT # -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # -# more details. # -# # -# You should have received a copy of the GNU General Public License along # -# with this program; if not, write to the Free Software Foundation, Inc., 59 # -# Temple Place, Suite 330, Boston, MA 02111-1307 USA # -############################################################################### -""" -Package to test the openlp.core.ui.slidecontroller package. -""" -import os - -from unittest import TestCase - -from openlp.core.common import Registry -from openlp.core.ui import ThemeManager - -from tests.utils.constants import TEST_RESOURCES_PATH -from tests.interfaces import MagicMock, patch - - -class TestThemeManager(TestCase): - - def setUp(self): - """ - Set up the tests - """ - Registry.create() - - def initial_theme_manager_test(self): - """ - Test the instantiation of theme manager. - """ - # GIVEN: A new service manager instance. - ThemeManager(None) - - # WHEN: the default theme manager is built. - # THEN: The the controller should be registered in the registry. - self.assertIsNotNone(Registry().get('theme_manager'), 'The base theme manager should be registered') - - def write_theme_same_image_test(self): - """ - Test that we don't try to overwrite a theme background image with itself - """ - # GIVEN: A new theme manager instance, with mocked builtins.open, shutil.copyfile, - # theme, check_directory_exists and thememanager-attributes. - with patch('builtins.open') as mocked_open, \ - patch('openlp.core.ui.thememanager.shutil.copyfile') as mocked_copyfile, \ - patch('openlp.core.ui.thememanager.check_directory_exists') as mocked_check_directory_exists: - mocked_open.return_value = MagicMock() - theme_manager = ThemeManager(None) - theme_manager.old_background_image = None - theme_manager.generate_and_save_image = MagicMock() - theme_manager.path = '' - mocked_theme = MagicMock() - mocked_theme.theme_name = 'themename' - mocked_theme.extract_formatted_xml = MagicMock() - mocked_theme.extract_formatted_xml.return_value = 'fake_theme_xml'.encode() - - # WHEN: Calling _write_theme with path to the same image, but the path written slightly different - file_name1 = os.path.join(TEST_RESOURCES_PATH, 'church.jpg') - # Do replacement from end of string to avoid problems with path start - file_name2 = file_name1[::-1].replace(os.sep, os.sep + os.sep, 2)[::-1] - theme_manager._write_theme(mocked_theme, file_name1, file_name2) - - # THEN: The mocked_copyfile should not have been called - self.assertFalse(mocked_copyfile.called, 'shutil.copyfile should not be called') - - def write_theme_diff_images_test(self): - """ - Test that we do overwrite a theme background image when a new is submitted - """ - # GIVEN: A new theme manager instance, with mocked builtins.open, shutil.copyfile, - # theme, check_directory_exists and thememanager-attributes. - with patch('builtins.open') as mocked_open, \ - patch('openlp.core.ui.thememanager.shutil.copyfile') as mocked_copyfile, \ - patch('openlp.core.ui.thememanager.check_directory_exists') as mocked_check_directory_exists: - mocked_open.return_value = MagicMock() - theme_manager = ThemeManager(None) - theme_manager.old_background_image = None - theme_manager.generate_and_save_image = MagicMock() - theme_manager.path = '' - mocked_theme = MagicMock() - mocked_theme.theme_name = 'themename' - mocked_theme.extract_formatted_xml = MagicMock() - mocked_theme.extract_formatted_xml.return_value = 'fake_theme_xml'.encode() - - # WHEN: Calling _write_theme with path to different images - file_name1 = os.path.join(TEST_RESOURCES_PATH, 'church.jpg') - file_name2 = os.path.join(TEST_RESOURCES_PATH, 'church2.jpg') - theme_manager._write_theme(mocked_theme, file_name1, file_name2) - - # THEN: The mocked_copyfile should not have been called - self.assertTrue(mocked_copyfile.called, 'shutil.copyfile should be called') From 3a1fda85d5ba63a0a5489c3344e3a78277e9271e Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Thu, 21 Aug 2014 14:51:34 +0200 Subject: [PATCH 17/22] Fixed windows test failure by removing special char from filenames --- .../functional/openlp_plugins/songs/test_powerpraiseimport.py | 4 ++-- ...her, mein Gott zu Dir.json => Naher, mein Gott zu Dir.json} | 0 ...äher, mein Gott zu Dir.ppl => Naher, mein Gott zu Dir.ppl} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename tests/resources/powerpraisesongs/{Näher, mein Gott zu Dir.json => Naher, mein Gott zu Dir.json} (100%) rename tests/resources/powerpraisesongs/{Näher, mein Gott zu Dir.ppl => Naher, mein Gott zu Dir.ppl} (100%) diff --git a/tests/functional/openlp_plugins/songs/test_powerpraiseimport.py b/tests/functional/openlp_plugins/songs/test_powerpraiseimport.py index dbe834e1c..e6a2a5194 100644 --- a/tests/functional/openlp_plugins/songs/test_powerpraiseimport.py +++ b/tests/functional/openlp_plugins/songs/test_powerpraiseimport.py @@ -50,7 +50,7 @@ class TestPowerPraiseFileImport(SongImportTestHelper): """ Test that loading a PowerPraise file works correctly """ - self.file_import([os.path.join(TEST_PATH, 'Näher, mein Gott zu Dir.ppl')], - self.load_external_result_data(os.path.join(TEST_PATH, 'Näher, mein Gott zu Dir.json'))) + self.file_import([os.path.join(TEST_PATH, 'Naher, mein Gott zu Dir.ppl')], + self.load_external_result_data(os.path.join(TEST_PATH, 'Naher, mein Gott zu Dir.json'))) self.file_import([os.path.join(TEST_PATH, 'You are so faithful.ppl')], self.load_external_result_data(os.path.join(TEST_PATH, 'You are so faithful.json'))) diff --git a/tests/resources/powerpraisesongs/Näher, mein Gott zu Dir.json b/tests/resources/powerpraisesongs/Naher, mein Gott zu Dir.json similarity index 100% rename from tests/resources/powerpraisesongs/Näher, mein Gott zu Dir.json rename to tests/resources/powerpraisesongs/Naher, mein Gott zu Dir.json diff --git a/tests/resources/powerpraisesongs/Näher, mein Gott zu Dir.ppl b/tests/resources/powerpraisesongs/Naher, mein Gott zu Dir.ppl similarity index 100% rename from tests/resources/powerpraisesongs/Näher, mein Gott zu Dir.ppl rename to tests/resources/powerpraisesongs/Naher, mein Gott zu Dir.ppl From fd4dc4caf7eeec3206f7ab58ac00d19c9592f100 Mon Sep 17 00:00:00 2001 From: Tomas Groth Date: Thu, 21 Aug 2014 15:07:02 +0200 Subject: [PATCH 18/22] Fixed another windows test by properly constructing paths. --- tests/functional/openlp_core_ui/test_thememanager.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/functional/openlp_core_ui/test_thememanager.py b/tests/functional/openlp_core_ui/test_thememanager.py index 3fd15baac..0f3fa8ac4 100644 --- a/tests/functional/openlp_core_ui/test_thememanager.py +++ b/tests/functional/openlp_core_ui/test_thememanager.py @@ -62,12 +62,12 @@ class TestThemeManager(TestCase): zipfile.ZipFile.write = MagicMock() # WHEN: The theme is exported - theme_manager._export_theme('/some/path', 'Default') + theme_manager._export_theme(os.path.join('some', 'path'), 'Default') # THEN: The zipfile should be created at the given path - zipfile.ZipFile.__init__.assert_called_with('/some/path/Default.otz', 'w') + zipfile.ZipFile.__init__.assert_called_with(os.path.join('some', 'path', 'Default.otz'), 'w') zipfile.ZipFile.write.assert_called_with(os.path.join(TEST_RESOURCES_PATH, 'themes', 'Default', 'Default.xml'), - 'Default/Default.xml') + os.path.join('Default', 'Default.xml')) def initial_theme_manager_test(self): """ From 516fd30bc7fe6e7205a22d737d932d8d66e59593 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 23 Aug 2014 21:42:10 +0100 Subject: [PATCH 19/22] fix conversion bug --- openlp/core/ui/servicemanager.py | 2 +- .../openlp_core_ui/test_servicemanager.py | 243 +++++++++++++++++- 2 files changed, 243 insertions(+), 2 deletions(-) diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 592b01524..369137694 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -993,7 +993,7 @@ class ServiceManager(OpenLPMixin, RegistryMixin, QtGui.QWidget, Ui_ServiceManage service_item.auto_play_slides_once = False self.set_modified() - def on_auto_start(self): + def on_auto_start(self, field=None): """ Toggles to Auto Start Setting. """ diff --git a/tests/functional/openlp_core_ui/test_servicemanager.py b/tests/functional/openlp_core_ui/test_servicemanager.py index 2c76ed965..bb9dff91e 100644 --- a/tests/functional/openlp_core_ui/test_servicemanager.py +++ b/tests/functional/openlp_core_ui/test_servicemanager.py @@ -31,7 +31,8 @@ Package to test the openlp.core.ui.slidecontroller package. """ from unittest import TestCase -from openlp.core.common import Registry +from openlp.core.common import Registry, ThemeLevel +from openlp.core.lib import ServiceItem, ServiceItemType, ItemCapabilities from openlp.core.ui import ServiceManager from tests.interfaces import MagicMock, patch @@ -89,3 +90,243 @@ class TestServiceManager(TestCase): self.assertEqual('txt' in service_manager.suffixes, True, 'The suffix txt should be in the list') self.assertEqual('ppt' in service_manager.suffixes, True, 'The suffix ppt should be in the list') self.assertEqual('pptx' in service_manager.suffixes, True, 'The suffix pptx should be in the list') + + def build_context_menu_test(self): + """ + Test the creation of a context menu from a null service item. + """ + # GIVEN: A new service manager instance and a default service item. + service_manager = ServiceManager(None) + item = MagicMock() + item.parent.return_value = False + item.data.return_value = 0 + service_manager.service_manager_list = MagicMock() + service_manager.service_manager_list.itemAt.return_value = item + service_item = ServiceItem(None) + service_manager.service_items.insert(1, {'service_item': service_item}) + service_manager.edit_action = MagicMock() + service_manager.rename_action = MagicMock() + service_manager.create_custom_action = MagicMock() + service_manager.maintain_action = MagicMock() + service_manager.notes_action = MagicMock() + service_manager.time_action = MagicMock() + service_manager.auto_start_action = MagicMock() + service_manager.auto_play_slides_menu = MagicMock() + service_manager.auto_play_slides_once = MagicMock() + service_manager.auto_play_slides_loop = MagicMock() + service_manager.timed_slide_interval = MagicMock() + service_manager.theme_menu = MagicMock() + service_manager.menu = MagicMock() + # WHEN I define a context menu + service_manager.context_menu(1) + # THEN the following calls should have occurred. + self.assertEquals(service_manager.edit_action.setVisible.call_count, 1, 'Should have been called once') + self.assertEquals(service_manager.rename_action.setVisible.call_count, 1, 'Should have been called once') + self.assertEquals(service_manager.create_custom_action.setVisible.call_count, 1, 'Should have been called once') + self.assertEquals(service_manager.maintain_action.setVisible.call_count, 1, 'Should have been called once') + self.assertEquals(service_manager.notes_action.setVisible.call_count, 1, 'Should have been called once') + self.assertEquals(service_manager.time_action.setVisible.call_count, 1, 'Should have been called once') + self.assertEquals(service_manager.auto_start_action.setVisible.call_count, 1, 'Should have been called once') + self.assertEquals(service_manager.auto_play_slides_menu.menuAction().setVisible.call_count, 1, + 'Should have been called once') + self.assertEquals(service_manager.auto_play_slides_once.setChecked.call_count, 0, 'Should not be called') + self.assertEquals(service_manager.auto_play_slides_loop.setChecked.call_count, 0, 'Should not be called') + self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 0, 'Should not be called') + self.assertEquals(service_manager.theme_menu.menuAction().setVisible.call_count, 1, + 'Should have been called once') + + def build_song_context_menu_test(self): + """ + Test the creation of a context menu from service item of type text from Songs. + """ + # GIVEN: A new service manager instance and a default service item. + mocked_renderer = MagicMock() + mocked_renderer.theme_level = ThemeLevel.Song + Registry().register('plugin_manager', MagicMock()) + Registry().register('renderer', mocked_renderer) + service_manager = ServiceManager(None) + item = MagicMock() + item.parent.return_value = False + item.data.return_value = 0 + service_manager.service_manager_list = MagicMock() + service_manager.service_manager_list.itemAt.return_value = item + service_item = ServiceItem(None) + service_item.add_capability(ItemCapabilities.CanEdit) + service_item.add_capability(ItemCapabilities.CanPreview) + service_item.add_capability(ItemCapabilities.CanLoop) + service_item.add_capability(ItemCapabilities.OnLoadUpdate) + service_item.add_capability(ItemCapabilities.AddIfNewItem) + service_item.add_capability(ItemCapabilities.CanSoftBreak) + service_item.service_item_type = ServiceItemType.Text + service_item.edit_id = 1 + service_item._display_frames.append(MagicMock()) + service_manager.service_items.insert(1, {'service_item': service_item}) + service_manager.edit_action = MagicMock() + service_manager.rename_action = MagicMock() + service_manager.create_custom_action = MagicMock() + service_manager.maintain_action = MagicMock() + service_manager.notes_action = MagicMock() + service_manager.time_action = MagicMock() + service_manager.auto_start_action = MagicMock() + service_manager.auto_play_slides_menu = MagicMock() + service_manager.auto_play_slides_once = MagicMock() + service_manager.auto_play_slides_loop = MagicMock() + service_manager.timed_slide_interval = MagicMock() + service_manager.theme_menu = MagicMock() + service_manager.menu = MagicMock() + # WHEN I define a context menu + service_manager.context_menu(1) + # THEN the following calls should have occurred. + self.assertEquals(service_manager.edit_action.setVisible.call_count, 2, 'Should have be called twice') + self.assertEquals(service_manager.rename_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.create_custom_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.maintain_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.notes_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.time_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.auto_start_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.auto_play_slides_menu.menuAction().setVisible.call_count, 1, + 'Should have be called once') + self.assertEquals(service_manager.auto_play_slides_once.setChecked.call_count, 0, 'Should not be called') + self.assertEquals(service_manager.auto_play_slides_loop.setChecked.call_count, 0, 'Should not be called') + self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 0, 'Should not be called') + self.assertEquals(service_manager.theme_menu.menuAction().setVisible.call_count, 2, + 'Should have be called twice') + # THEN we add a 2nd display frame + service_item._display_frames.append(MagicMock()) + service_manager.context_menu(1) + # THEN the following additional calls should have occurred. + self.assertEquals(service_manager.auto_play_slides_menu.menuAction().setVisible.call_count, 2, + 'Should have be called twice') + self.assertEquals(service_manager.auto_play_slides_once.setChecked.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.auto_play_slides_loop.setChecked.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 1, 'Should have be called once') + + def build_bible_context_menu_test(self): + """ + Test the creation of a context menu from service item of type text from Bibles. + """ + # GIVEN: A new service manager instance and a default service item. + mocked_renderer = MagicMock() + mocked_renderer.theme_level = ThemeLevel.Song + Registry().register('plugin_manager', MagicMock()) + Registry().register('renderer', mocked_renderer) + service_manager = ServiceManager(None) + item = MagicMock() + item.parent.return_value = False + item.data.return_value = 0 + service_manager.service_manager_list = MagicMock() + service_manager.service_manager_list.itemAt.return_value = item + service_item = ServiceItem(None) + service_item.add_capability(ItemCapabilities.NoLineBreaks) + service_item.add_capability(ItemCapabilities.CanPreview) + service_item.add_capability(ItemCapabilities.CanLoop) + service_item.add_capability(ItemCapabilities.CanWordSplit) + service_item.add_capability(ItemCapabilities.CanEditTitle) + service_item.service_item_type = ServiceItemType.Text + service_item.edit_id = 1 + service_item._display_frames.append(MagicMock()) + service_manager.service_items.insert(1, {'service_item': service_item}) + service_manager.edit_action = MagicMock() + service_manager.rename_action = MagicMock() + service_manager.create_custom_action = MagicMock() + service_manager.maintain_action = MagicMock() + service_manager.notes_action = MagicMock() + service_manager.time_action = MagicMock() + service_manager.auto_start_action = MagicMock() + service_manager.auto_play_slides_menu = MagicMock() + service_manager.auto_play_slides_once = MagicMock() + service_manager.auto_play_slides_loop = MagicMock() + service_manager.timed_slide_interval = MagicMock() + service_manager.theme_menu = MagicMock() + service_manager.menu = MagicMock() + # WHEN I define a context menu + service_manager.context_menu(1) + # THEN the following calls should have occurred. + self.assertEquals(service_manager.edit_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.rename_action.setVisible.call_count, 2, 'Should have be called twice') + self.assertEquals(service_manager.create_custom_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.maintain_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.notes_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.time_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.auto_start_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.auto_play_slides_menu.menuAction().setVisible.call_count, 1, + 'Should have be called once') + self.assertEquals(service_manager.auto_play_slides_once.setChecked.call_count, 0, 'Should not be called') + self.assertEquals(service_manager.auto_play_slides_loop.setChecked.call_count, 0, 'Should not be called') + self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 0, 'Should not be called') + self.assertEquals(service_manager.theme_menu.menuAction().setVisible.call_count, 2, + 'Should have be called twice') + # THEN we add a 2nd display frame + service_item._display_frames.append(MagicMock()) + service_manager.context_menu(1) + # THEN the following additional calls should have occurred. + self.assertEquals(service_manager.auto_play_slides_menu.menuAction().setVisible.call_count, 2, + 'Should have be called twice') + self.assertEquals(service_manager.auto_play_slides_once.setChecked.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.auto_play_slides_loop.setChecked.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 1, 'Should have be called once') + + def build_custom_context_menu_test(self): + """ + Test the creation of a context menu from service item of type text from Custom. + """ + # GIVEN: A new service manager instance and a default service item. + mocked_renderer = MagicMock() + mocked_renderer.theme_level = ThemeLevel.Song + Registry().register('plugin_manager', MagicMock()) + Registry().register('renderer', mocked_renderer) + service_manager = ServiceManager(None) + item = MagicMock() + item.parent.return_value = False + item.data.return_value = 0 + service_manager.service_manager_list = MagicMock() + service_manager.service_manager_list.itemAt.return_value = item + service_item = ServiceItem(None) + service_item.add_capability(ItemCapabilities.CanEdit) + service_item.add_capability(ItemCapabilities.CanPreview) + service_item.add_capability(ItemCapabilities.CanLoop) + service_item.add_capability(ItemCapabilities.CanSoftBreak) + service_item.add_capability(ItemCapabilities.OnLoadUpdate) + service_item.service_item_type = ServiceItemType.Text + service_item.edit_id = 1 + service_item._display_frames.append(MagicMock()) + service_manager.service_items.insert(1, {'service_item': service_item}) + service_manager.edit_action = MagicMock() + service_manager.rename_action = MagicMock() + service_manager.create_custom_action = MagicMock() + service_manager.maintain_action = MagicMock() + service_manager.notes_action = MagicMock() + service_manager.time_action = MagicMock() + service_manager.auto_start_action = MagicMock() + service_manager.auto_play_slides_menu = MagicMock() + service_manager.auto_play_slides_once = MagicMock() + service_manager.auto_play_slides_loop = MagicMock() + service_manager.timed_slide_interval = MagicMock() + service_manager.theme_menu = MagicMock() + service_manager.menu = MagicMock() + # WHEN I define a context menu + service_manager.context_menu(1) + # THEN the following calls should have occurred. + self.assertEquals(service_manager.edit_action.setVisible.call_count, 2, 'Should have be called twice') + self.assertEquals(service_manager.rename_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.create_custom_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.maintain_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.notes_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.time_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.auto_start_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.auto_play_slides_menu.menuAction().setVisible.call_count, 1, + 'Should have be called once') + self.assertEquals(service_manager.auto_play_slides_once.setChecked.call_count, 0, 'Should not be called') + self.assertEquals(service_manager.auto_play_slides_loop.setChecked.call_count, 0, 'Should not be called') + self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 0, 'Should not be called') + self.assertEquals(service_manager.theme_menu.menuAction().setVisible.call_count, 2, + 'Should have be called twice') + # THEN we add a 2nd display frame + service_item._display_frames.append(MagicMock()) + service_manager.context_menu(1) + # THEN the following additional calls should have occurred. + self.assertEquals(service_manager.auto_play_slides_menu.menuAction().setVisible.call_count, 2, + 'Should have be called twice') + self.assertEquals(service_manager.auto_play_slides_once.setChecked.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.auto_play_slides_loop.setChecked.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 1, 'Should have be called once') \ No newline at end of file From 09bb622af89af633b7d9b368c8e596d79db9d4c6 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 24 Aug 2014 10:32:26 +0100 Subject: [PATCH 20/22] Final tests --- .../openlp_core_ui/test_servicemanager.py | 225 +++++++++++++++++- 1 file changed, 224 insertions(+), 1 deletion(-) diff --git a/tests/functional/openlp_core_ui/test_servicemanager.py b/tests/functional/openlp_core_ui/test_servicemanager.py index bb9dff91e..d8d2be50e 100644 --- a/tests/functional/openlp_core_ui/test_servicemanager.py +++ b/tests/functional/openlp_core_ui/test_servicemanager.py @@ -329,4 +329,227 @@ class TestServiceManager(TestCase): 'Should have be called twice') self.assertEquals(service_manager.auto_play_slides_once.setChecked.call_count, 1, 'Should have be called once') self.assertEquals(service_manager.auto_play_slides_loop.setChecked.call_count, 1, 'Should have be called once') - self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 1, 'Should have be called once') \ No newline at end of file + self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 1, 'Should have be called once') + + def build_image_context_menu_test(self): + """ + Test the creation of a context menu from service item of type Image from Image. + """ + # GIVEN: A new service manager instance and a default service item. + Registry().register('plugin_manager', MagicMock()) + Registry().register('renderer', MagicMock()) + service_manager = ServiceManager(None) + item = MagicMock() + item.parent.return_value = False + item.data.return_value = 0 + service_manager.service_manager_list = MagicMock() + service_manager.service_manager_list.itemAt.return_value = item + service_item = ServiceItem(None) + service_item.add_capability(ItemCapabilities.CanMaintain) + service_item.add_capability(ItemCapabilities.CanPreview) + service_item.add_capability(ItemCapabilities.CanLoop) + service_item.add_capability(ItemCapabilities.CanAppend) + service_item.add_capability(ItemCapabilities.CanEditTitle) + service_item.service_item_type = ServiceItemType.Image + service_item.edit_id = 1 + service_item._raw_frames.append(MagicMock()) + service_manager.service_items.insert(1, {'service_item': service_item}) + service_manager.edit_action = MagicMock() + service_manager.rename_action = MagicMock() + service_manager.create_custom_action = MagicMock() + service_manager.maintain_action = MagicMock() + service_manager.notes_action = MagicMock() + service_manager.time_action = MagicMock() + service_manager.auto_start_action = MagicMock() + service_manager.auto_play_slides_menu = MagicMock() + service_manager.auto_play_slides_once = MagicMock() + service_manager.auto_play_slides_loop = MagicMock() + service_manager.timed_slide_interval = MagicMock() + service_manager.theme_menu = MagicMock() + service_manager.menu = MagicMock() + # WHEN I define a context menu + service_manager.context_menu(1) + # THEN the following calls should have occurred. + self.assertEquals(service_manager.edit_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.rename_action.setVisible.call_count, 2, 'Should have be called twice') + self.assertEquals(service_manager.create_custom_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.maintain_action.setVisible.call_count, 2, 'Should have be called twice') + self.assertEquals(service_manager.notes_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.time_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.auto_start_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.auto_play_slides_menu.menuAction().setVisible.call_count, 1, + 'Should have be called once') + self.assertEquals(service_manager.auto_play_slides_once.setChecked.call_count, 0, 'Should not be called') + self.assertEquals(service_manager.auto_play_slides_loop.setChecked.call_count, 0, 'Should not be called') + self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 0, 'Should not be called') + self.assertEquals(service_manager.theme_menu.menuAction().setVisible.call_count, 1, + 'Should have be called once') + # THEN we add a 2nd display frame and regenerate the menu. + service_item._raw_frames.append(MagicMock()) + service_manager.context_menu(1) + # THEN the following additional calls should have occurred. + self.assertEquals(service_manager.auto_play_slides_menu.menuAction().setVisible.call_count, 2, + 'Should have be called twice') + self.assertEquals(service_manager.auto_play_slides_once.setChecked.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.auto_play_slides_loop.setChecked.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 1, 'Should have be called once') + + def build_media_context_menu_test(self): + """ + Test the creation of a context menu from service item of type Command from Media. + """ + # GIVEN: A new service manager instance and a default service item. + Registry().register('plugin_manager', MagicMock()) + Registry().register('renderer', MagicMock()) + service_manager = ServiceManager(None) + item = MagicMock() + item.parent.return_value = False + item.data.return_value = 0 + service_manager.service_manager_list = MagicMock() + service_manager.service_manager_list.itemAt.return_value = item + service_item = ServiceItem(None) + service_item.add_capability(ItemCapabilities.CanAutoStartForLive) + service_item.add_capability(ItemCapabilities.CanEditTitle) + service_item.add_capability(ItemCapabilities.RequiresMedia) + service_item.service_item_type = ServiceItemType.Command + service_item.edit_id = 1 + service_item._raw_frames.append(MagicMock()) + service_manager.service_items.insert(1, {'service_item': service_item}) + service_manager.edit_action = MagicMock() + service_manager.rename_action = MagicMock() + service_manager.create_custom_action = MagicMock() + service_manager.maintain_action = MagicMock() + service_manager.notes_action = MagicMock() + service_manager.time_action = MagicMock() + service_manager.auto_start_action = MagicMock() + service_manager.auto_play_slides_menu = MagicMock() + service_manager.auto_play_slides_once = MagicMock() + service_manager.auto_play_slides_loop = MagicMock() + service_manager.timed_slide_interval = MagicMock() + service_manager.theme_menu = MagicMock() + service_manager.menu = MagicMock() + # WHEN I define a context menu + service_manager.context_menu(1) + # THEN the following calls should have occurred. + self.assertEquals(service_manager.edit_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.rename_action.setVisible.call_count, 2, 'Should have be called twice') + self.assertEquals(service_manager.create_custom_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.maintain_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.notes_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.time_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.auto_start_action.setVisible.call_count, 2, 'Should have be called twice') + self.assertEquals(service_manager.auto_play_slides_menu.menuAction().setVisible.call_count, 1, + 'Should have be called once') + self.assertEquals(service_manager.auto_play_slides_once.setChecked.call_count, 0, 'Should not be called') + self.assertEquals(service_manager.auto_play_slides_loop.setChecked.call_count, 0, 'Should not be called') + self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 0, 'Should not be called') + self.assertEquals(service_manager.theme_menu.menuAction().setVisible.call_count, 1, + 'Should have be called once') + # THEN I change the length of the media and regenerate the menu. + service_item.set_media_length(5) + service_manager.context_menu(1) + # THEN the following additional calls should have occurred. + self.assertEquals(service_manager.time_action.setVisible.call_count, 3, 'Should have be called three times') + + def build_presentation_pdf_context_menu_test(self): + """ + Test the creation of a context menu from service item of type Command with PDF from Presentation. + """ + # GIVEN: A new service manager instance and a default service item. + Registry().register('plugin_manager', MagicMock()) + Registry().register('renderer', MagicMock()) + service_manager = ServiceManager(None) + item = MagicMock() + item.parent.return_value = False + item.data.return_value = 0 + service_manager.service_manager_list = MagicMock() + service_manager.service_manager_list.itemAt.return_value = item + service_item = ServiceItem(None) + service_item.add_capability(ItemCapabilities.CanMaintain) + service_item.add_capability(ItemCapabilities.CanPreview) + service_item.add_capability(ItemCapabilities.CanLoop) + service_item.add_capability(ItemCapabilities.CanAppend) + service_item.service_item_type = ServiceItemType.Command + service_item.edit_id = 1 + service_item._raw_frames.append(MagicMock()) + service_manager.service_items.insert(1, {'service_item': service_item}) + service_manager.edit_action = MagicMock() + service_manager.rename_action = MagicMock() + service_manager.create_custom_action = MagicMock() + service_manager.maintain_action = MagicMock() + service_manager.notes_action = MagicMock() + service_manager.time_action = MagicMock() + service_manager.auto_start_action = MagicMock() + service_manager.auto_play_slides_menu = MagicMock() + service_manager.auto_play_slides_once = MagicMock() + service_manager.auto_play_slides_loop = MagicMock() + service_manager.timed_slide_interval = MagicMock() + service_manager.theme_menu = MagicMock() + service_manager.menu = MagicMock() + # WHEN I define a context menu + service_manager.context_menu(1) + # THEN the following calls should have occurred. + self.assertEquals(service_manager.edit_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.rename_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.create_custom_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.maintain_action.setVisible.call_count, 2, 'Should have be called twice') + self.assertEquals(service_manager.notes_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.time_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.auto_start_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.auto_play_slides_menu.menuAction().setVisible.call_count, 1, + 'Should have be called once') + self.assertEquals(service_manager.auto_play_slides_once.setChecked.call_count, 0, 'Should not be called') + self.assertEquals(service_manager.auto_play_slides_loop.setChecked.call_count, 0, 'Should not be called') + self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 0, 'Should not be called') + self.assertEquals(service_manager.theme_menu.menuAction().setVisible.call_count, 1, + 'Should have be called once') + + def build_presentation_non_pdf_context_menu_test(self): + """ + Test the creation of a context menu from service item of type Command with Impress from Presentation. + """ + # GIVEN: A new service manager instance and a default service item. + Registry().register('plugin_manager', MagicMock()) + Registry().register('renderer', MagicMock()) + service_manager = ServiceManager(None) + item = MagicMock() + item.parent.return_value = False + item.data.return_value = 0 + service_manager.service_manager_list = MagicMock() + service_manager.service_manager_list.itemAt.return_value = item + service_item = ServiceItem(None) + service_item.add_capability(ItemCapabilities.ProvidesOwnDisplay) + service_item.service_item_type = ServiceItemType.Command + service_item.edit_id = 1 + service_item._raw_frames.append(MagicMock()) + service_manager.service_items.insert(1, {'service_item': service_item}) + service_manager.edit_action = MagicMock() + service_manager.rename_action = MagicMock() + service_manager.create_custom_action = MagicMock() + service_manager.maintain_action = MagicMock() + service_manager.notes_action = MagicMock() + service_manager.time_action = MagicMock() + service_manager.auto_start_action = MagicMock() + service_manager.auto_play_slides_menu = MagicMock() + service_manager.auto_play_slides_once = MagicMock() + service_manager.auto_play_slides_loop = MagicMock() + service_manager.timed_slide_interval = MagicMock() + service_manager.theme_menu = MagicMock() + service_manager.menu = MagicMock() + # WHEN I define a context menu + service_manager.context_menu(1) + # THEN the following calls should have occurred. + self.assertEquals(service_manager.edit_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.rename_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.create_custom_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.maintain_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.notes_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.time_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.auto_start_action.setVisible.call_count, 1, 'Should have be called once') + self.assertEquals(service_manager.auto_play_slides_menu.menuAction().setVisible.call_count, 1, + 'Should have be called once') + self.assertEquals(service_manager.auto_play_slides_once.setChecked.call_count, 0, 'Should not be called') + self.assertEquals(service_manager.auto_play_slides_loop.setChecked.call_count, 0, 'Should not be called') + self.assertEquals(service_manager.timed_slide_interval.setChecked.call_count, 0, 'Should not be called') + self.assertEquals(service_manager.theme_menu.menuAction().setVisible.call_count, 1, + 'Should have be called once') From 3026e7bd47fd40271c1171f96ae2f5b8c7908609 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 24 Aug 2014 11:24:23 +0100 Subject: [PATCH 21/22] remove script change --- scripts/jenkins_script.py | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/scripts/jenkins_script.py b/scripts/jenkins_script.py index 430e842ce..7abdbccd0 100755 --- a/scripts/jenkins_script.py +++ b/scripts/jenkins_script.py @@ -89,7 +89,7 @@ class JenkinsTrigger(object): :param token: The token we need to trigger the build. If you do not have this token, ask in IRC. """ self.token = token - self.base_name, self.repo_name = get_repo_name('b') + self.repo_name = get_repo_name() self.jenkins_instance = Jenkins(JENKINS_URL) def trigger_build(self): @@ -113,8 +113,7 @@ class JenkinsTrigger(object): bzr = Popen(('bzr', 'revno'), stdout=PIPE, stderr=PIPE) raw_output, error = bzr.communicate() revno = raw_output.decode().strip() - print('Remote repository: %s ' % self.repo_name) - print(' Local repository: %s (revision %s)' % (self.repo_name, revno)) + print('%s (revision %s)' % (get_repo_name(), revno)) for job in OpenLPJobs.Jobs: if not self.__print_build_info(job): @@ -154,7 +153,7 @@ class JenkinsTrigger(object): return is_success -def get_repo_name(branch_type='l'): +def get_repo_name(): """ This returns the name of branch of the working directory. For example it returns *lp:~googol/openlp/render*. """ @@ -170,7 +169,6 @@ def get_repo_name(branch_type='l'): output_list = list(map(str.strip, raw_output.split('\n'))) # Determine the branch's name repo_name = '' - base_name = '' for line in output_list: # Check if it is remote branch. if 'push branch' in line: @@ -183,15 +181,7 @@ def get_repo_name(branch_type='l'): if match: repo_name = 'lp:%s' % match.group(2) break - elif 'repository branch' in line: - base_name = line.split(':')[1] - break - if branch_type == 'b': - return base_name.strip('/'), repo_name.strip('/') - elif branch_type == 'r': - return base_name.strip('/') - else: - return repo_name.strip('/') + return repo_name.strip('/') def main(): @@ -205,12 +195,9 @@ def main(): options, args = parser.parse_args(sys.argv) if len(args) == 2: - if not get_repo_name('l'): + if not get_repo_name(): print('Not a branch. Have you pushed it to launchpad? Did you cd to the branch?') return - if not get_repo_name('r'): - print('No remote branch. Have you pushed it to launchpad? Did you cd to the branch?') - return token = args[-1] if token in OLD_TOKENS: print('Your token is not valid anymore. Get the most recent one.') From 0b93faf7b9c877fef5714b8c9b228065278b906f Mon Sep 17 00:00:00 2001 From: Phill Ridout Date: Tue, 26 Aug 2014 18:38:07 +0100 Subject: [PATCH 22/22] PEP fixes --- openlp/core/utils/actions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openlp/core/utils/actions.py b/openlp/core/utils/actions.py index fb794866b..9b5117233 100644 --- a/openlp/core/utils/actions.py +++ b/openlp/core/utils/actions.py @@ -280,7 +280,7 @@ class ActionList(object): ActionList.shortcut_map[shortcuts[1]] = actions else: log.warning('Shortcut "%s" is removed from "%s" because another action already uses this shortcut.' % - (shortcuts[1], action.objectName())) + (shortcuts[1], action.objectName())) shortcuts.remove(shortcuts[1]) # Check the primary shortcut. existing_actions = ActionList.shortcut_map.get(shortcuts[0], []) @@ -291,7 +291,7 @@ class ActionList(object): ActionList.shortcut_map[shortcuts[0]] = actions else: log.warning('Shortcut "%s" is removed from "%s" because another action already uses this shortcut.' % - (shortcuts[0], action.objectName())) + (shortcuts[0], action.objectName())) shortcuts.remove(shortcuts[0]) action.setShortcuts([QtGui.QKeySequence(shortcut) for shortcut in shortcuts])