diff --git a/openlp/plugins/bibles/lib/opensong.py b/openlp/plugins/bibles/lib/opensong.py index a522c1c57..c7bfa01a2 100644 --- a/openlp/plugins/bibles/lib/opensong.py +++ b/openlp/plugins/bibles/lib/opensong.py @@ -73,13 +73,13 @@ class OpenSongBible(BibleDB): log.debug('Starting OpenSong import from "%s"' % self.filename) if not isinstance(self.filename, str): self.filename = str(self.filename, 'utf8') - file = None + import_file = None success = True try: # NOTE: We don't need to do any of the normal encoding detection here, because lxml does it's own encoding # detection, and the two mechanisms together interfere with each other. - file = open(self.filename, 'r') - opensong = objectify.parse(file) + import_file = open(self.filename, 'rb') + opensong = objectify.parse(import_file) bible = opensong.getroot() language_id = self.get_language(bible_name) if not language_id: @@ -93,7 +93,7 @@ class OpenSongBible(BibleDB): log.error('Importing books from "%s" failed' % self.filename) return False book_details = BiblesResourcesDB.get_book_by_id(book_ref_id) - db_book = self.create_book(str(book.attrib['n']), book_ref_id, book_details['testament_id']) + db_book = self.create_book(book.attrib['n'], book_ref_id, book_details['testament_id']) chapter_number = 0 for chapter in book.c: if self.stop_import_flag: @@ -122,8 +122,8 @@ class OpenSongBible(BibleDB): verse_number += 1 self.create_verse(db_book.id, chapter_number, verse_number, self.get_text(verse)) self.wizard.increment_progress_bar( - translate('BiblesPlugin.Opensong', 'Importing %s %s...', - 'Importing ...')) % (db_book.name, chapter_number) + translate('BiblesPlugin.Opensong', 'Importing %(bookname)s %(chapter)s...' % + {'bookname': db_book.name, 'chapter': chapter_number})) self.session.commit() self.application.process_events() except etree.XMLSyntaxError as inst: @@ -137,8 +137,8 @@ class OpenSongBible(BibleDB): log.exception('Loading Bible from OpenSong file failed') success = False finally: - if file: - file.close() + if import_file: + import_file.close() if self.stop_import_flag: return False else: diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index df51db1e0..314d1ffe7 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -192,7 +192,7 @@ class SongMediaItem(MediaManagerItem): song_number = False if not search_results: search_keywords = search_keywords.rpartition(' ') - search_string = '%' + search_keywords + '%' + search_string = '%' + search_keywords[0] + '%' search_results = self.plugin.manager.get_all_objects(Book, Book.name.like(search_string), Book.name.asc()) song_number = re.sub(r'[^0-9]', '', search_keywords[2]) diff --git a/openlp/plugins/songs/lib/openlyricsimport.py b/openlp/plugins/songs/lib/openlyricsimport.py index 675c0d98a..031c5ba72 100644 --- a/openlp/plugins/songs/lib/openlyricsimport.py +++ b/openlp/plugins/songs/lib/openlyricsimport.py @@ -53,7 +53,7 @@ class OpenLyricsImport(SongImport): Initialise the Open Lyrics importer. """ log.debug('initialise OpenLyricsImport') - SongImport.__init__(self, manager, **kwargs) + super(OpenLyricsImport, self).__init__(manager, **kwargs) self.open_lyrics = OpenLyrics(self.manager) def do_import(self): @@ -69,7 +69,7 @@ class OpenLyricsImport(SongImport): try: # Pass a file object, because lxml does not cope with some # special characters in the path (see lp:757673 and lp:744337). - parsed_file = etree.parse(open(file_path, 'r'), parser) + parsed_file = etree.parse(open(file_path, 'rb'), parser) xml = etree.tostring(parsed_file).decode() self.open_lyrics.xml_to_song(xml) except etree.XMLSyntaxError: diff --git a/tests/functional/openlp_plugins/songs/test_ewimport.py b/tests/functional/openlp_plugins/songs/test_ewimport.py index 981bc677d..182a6b04a 100644 --- a/tests/functional/openlp_plugins/songs/test_ewimport.py +++ b/tests/functional/openlp_plugins/songs/test_ewimport.py @@ -229,7 +229,7 @@ class TestEasyWorshipSongImport(TestCase): for field_index, result in field_results: return_value = importer.get_field(field_index) - # THEN: get_field should return the known results + # THEN: get_field should return the known results self.assertEqual(return_value, result, 'get_field should return "%s" when called with "%s"' % (result, TEST_FIELDS[field_index])) @@ -403,8 +403,8 @@ class TestEasyWorshipSongImport(TestCase): if song_copyright: self.assertEqual(importer.copyright, song_copyright) if ccli_number: - self.assertEqual(importer.ccli_number, ccli_number, 'ccli_number for %s should be %s' - % (title, ccli_number)) + self.assertEqual(importer.ccli_number, ccli_number, + 'ccli_number for %s should be %s' % (title, ccli_number)) for verse_text, verse_tag in add_verse_calls: mocked_add_verse.assert_any_call(verse_text, verse_tag) if verse_order_list: diff --git a/tests/functional/openlp_plugins/songs/test_openlyricsimport.py b/tests/functional/openlp_plugins/songs/test_openlyricsimport.py new file mode 100644 index 000000000..93ecafb78 --- /dev/null +++ b/tests/functional/openlp_plugins/songs/test_openlyricsimport.py @@ -0,0 +1,99 @@ +# -*- 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 # +############################################################################### +""" +This module contains tests for the OpenLyrics song importer. +""" + +import os +from unittest import TestCase + +from tests.functional import MagicMock, patch +from openlp.plugins.songs.lib.openlyricsimport import OpenLyricsImport +from openlp.plugins.songs.lib.songimport import SongImport + +TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), + '..', '..', '..', 'resources', 'openlyricssongs')) +SONG_TEST_DATA = { + 'What a friend we have in Jesus.xml': { + 'title': 'What A Friend We Have In Jesus', + 'verses': [ + ('What a friend we have in Jesus, All ours sins and griefs to bear;\n\ + What a privilege to carry, Everything to God in prayer!\n\ + O what peace we often forfeit, O what needless pain we bear;\n\ + All because we do not carry, Everything to God in prayer!', 'v1'), + ('Have we trials and temptations? Is there trouble anywhere?\n\ + We should never be discouraged, Take it to the Lord in prayer.\n\ + Can we find a friend so faithful? Who will all our sorrows share?\n\ + Jesus knows our every weakness; Take it to the Lord in prayer.', 'v2'), + ('Are we weak and heavy laden, Cumbered with a load of care?\n\ + Precious Saviour still our refuge; Take it to the Lord in prayer.\n\ + Do thy friends despise forsake thee? Take it to the Lord in prayer!\n\ + In His arms He’ll take and shield thee; Thou wilt find a solace there.', 'v3') + ] + } +} + + +class TestOpenLyricsImport(TestCase): + """ + Test the functions in the :mod:`openlyricsimport` module. + """ + def create_importer_test(self): + """ + Test creating an instance of the OpenLyrics file importer + """ + # GIVEN: A mocked out SongImport class, and a mocked out "manager" + with patch('openlp.plugins.songs.lib.songbeamerimport.SongImport'): + mocked_manager = MagicMock() + + # WHEN: An importer object is created + importer = OpenLyricsImport(mocked_manager, filenames=[]) + + # THEN: The importer should be an instance of SongImport + self.assertIsInstance(importer, SongImport) + + def file_import_test(self): + """ + Test the actual import of real song files + """ + # GIVEN: Test files with a mocked out "manager" and a mocked out "import_wizard" + for song_file in SONG_TEST_DATA: + mocked_manager = MagicMock() + mocked_import_wizard = MagicMock() + importer = OpenLyricsImport(mocked_manager, filenames=[]) + importer.import_wizard = mocked_import_wizard + importer.open_lyrics = MagicMock() + importer.open_lyrics.xml_to_song = MagicMock() + + # WHEN: Importing each file + importer.import_source = [os.path.join(TEST_PATH, song_file)] + importer.do_import() + + # THEN: The xml_to_song() method should have been called + self.assertTrue(importer.open_lyrics.xml_to_song.called) diff --git a/tests/functional/openlp_plugins/songs/test_songbeamerimport.py b/tests/functional/openlp_plugins/songs/test_songbeamerimport.py index 284f972ef..a69d4a86c 100644 --- a/tests/functional/openlp_plugins/songs/test_songbeamerimport.py +++ b/tests/functional/openlp_plugins/songs/test_songbeamerimport.py @@ -49,7 +49,8 @@ SONG_TEST_DATA = { ('4. Lobsingt seiner Treu´,\ndie immerdar neu,\nbis Er uns zur Herrlichket führet!\n\n', 'v') ], 'song_book_name': 'Glaubenslieder I', - 'song_number': "1" + 'song_number': "1", + 'authors': ['Carl Brockhaus', 'Johann Jakob Vetter'] } } @@ -140,6 +141,7 @@ class TestSongBeamerImport(TestCase): add_verse_calls = SONG_TEST_DATA[song_file]['verses'] song_book_name = SONG_TEST_DATA[song_file]['song_book_name'] song_number = SONG_TEST_DATA[song_file]['song_number'] + song_authors = SONG_TEST_DATA[song_file]['authors'] # THEN: do_import should return none, the song data should be as expected, and finish should have been # called. @@ -148,11 +150,14 @@ class TestSongBeamerImport(TestCase): for verse_text, verse_tag in add_verse_calls: mocked_add_verse.assert_any_call(verse_text, verse_tag) if song_book_name: - self.assertEqual(importer.song_book_name, song_book_name, 'song_book_name for %s should be "%s"' % - (song_file, song_book_name)) + self.assertEqual(importer.song_book_name, song_book_name, + 'song_book_name for %s should be "%s"' % (song_file, song_book_name)) if song_number: - self.assertEqual(importer.song_number, song_number, 'song_number for %s should be %s' % - (song_file, song_number)) + self.assertEqual(importer.song_number, song_number, + 'song_number for %s should be %s' % (song_file, song_number)) + if song_authors: + for author in importer.authors: + self.assertIn(author, song_authors) mocked_finish.assert_called_with() def check_verse_marks_test(self): diff --git a/tests/functional/openlp_plugins/songs/test_songshowplusimport.py b/tests/functional/openlp_plugins/songs/test_songshowplusimport.py index 63e5beb8a..7292bb2b0 100644 --- a/tests/functional/openlp_plugins/songs/test_songshowplusimport.py +++ b/tests/functional/openlp_plugins/songs/test_songshowplusimport.py @@ -116,7 +116,7 @@ class TestSongShowPlusImport(TestCase): # THEN: do_import should return none and the progress bar setMaximum should be called with the length of # import_source. self.assertIsNone(importer.do_import(), 'do_import should return None when import_source is a list ' - 'and stop_import_flag is True') + 'and stop_import_flag is True') mocked_import_wizard.progress_bar.setMaximum.assert_called_with(len(importer.import_source)) def to_openlp_verse_tag_test(self): diff --git a/tests/helpers/songfileimport.py b/tests/helpers/songfileimport.py index 16935ffca..5364c2c3b 100644 --- a/tests/helpers/songfileimport.py +++ b/tests/helpers/songfileimport.py @@ -116,24 +116,24 @@ class SongImportTestHelper(TestCase): if song_copyright: self.mocked_add_copyright.assert_called_with(song_copyright) if ccli_number: - self.assertEqual(importer.ccli_number, ccli_number, 'ccli_number for %s should be %s' % - (source_file_name, ccli_number)) + self.assertEqual(importer.ccli_number, ccli_number, + 'ccli_number for %s should be %s' % (source_file_name, ccli_number)) for verse_text, verse_tag in add_verse_calls: self.mocked_add_verse.assert_any_call(verse_text, verse_tag) if topics: self.assertEqual(importer.topics, topics, 'topics for %s should be %s' % (source_file_name, topics)) if comments: - self.assertEqual(importer.comments, comments, 'comments for %s should be "%s"' % - (source_file_name, comments)) + self.assertEqual(importer.comments, comments, + 'comments for %s should be "%s"' % (source_file_name, comments)) if song_book_name: - self.assertEqual(importer.song_book_name, song_book_name, 'song_book_name for %s should be "%s"' % - (source_file_name, song_book_name)) + self.assertEqual(importer.song_book_name, song_book_name, + 'song_book_name for %s should be "%s"' % (source_file_name, song_book_name)) if song_number: - self.assertEqual(importer.song_number, song_number, 'song_number for %s should be %s' % - (source_file_name, song_number)) + self.assertEqual(importer.song_number, song_number, + 'song_number for %s should be %s' % (source_file_name, song_number)) if verse_order_list: - self.assertEqual(importer.verse_order_list, [], 'verse_order_list for %s should be %s' % - (source_file_name, verse_order_list)) + self.assertEqual(importer.verse_order_list, [], + 'verse_order_list for %s should be %s' % (source_file_name, verse_order_list)) self.mocked_finish.assert_called_with() def _get_data(self, data, key): diff --git a/tests/interfaces/openlp_plugins/bibles/test_lib_parse_reference.py b/tests/interfaces/openlp_plugins/bibles/test_lib_parse_reference.py index 6883f9eb5..e20105ea1 100644 --- a/tests/interfaces/openlp_plugins/bibles/test_lib_parse_reference.py +++ b/tests/interfaces/openlp_plugins/bibles/test_lib_parse_reference.py @@ -103,5 +103,5 @@ class TestBibleManager(TestCase, TestMixin): # WHEN asking to parse the bible reference results = parse_reference('1 Timothy 1:1-2:1', self.manager.db_cache['tests'], MagicMock(), 54) # THEN a verse array should be returned - self.assertEqual([(54, 1, 1, -1), (54, 2, 1, 1)], results, "The bible verses should matches the expected " - "results") + self.assertEqual([(54, 1, 1, -1), (54, 2, 1, 1)], results, + "The bible verses should match the expected results") diff --git a/tests/resources/openlyricssongs/What a friend we have in Jesus.xml b/tests/resources/openlyricssongs/What a friend we have in Jesus.xml new file mode 100644 index 000000000..a111c853c --- /dev/null +++ b/tests/resources/openlyricssongs/What a friend we have in Jesus.xml @@ -0,0 +1,44 @@ + + + + + What A Friend We Have In Jesus + + + Joseph M. Scriven + Charles C. Convers + + Public Domain + 27714 + + Christ: Love/Mercy + Fruit: Peace/Comfort + + + + + + What a friend we have in Jesus, All ours sins and griefs to bear;
+ What a privilege to carry, Everything to God in prayer!
+ O what peace we often forfeit, O what needless pain we bear;
+ All because we do not carry, Everything to God in prayer! +
+
+ + + Have we trials and temptations? Is there trouble anywhere?
+ We should never be discouraged, Take it to the Lord in prayer.
+ Can we find a friend so faithful? Who will all our sorrows share?
+ Jesus knows our every weakness; Take it to the Lord in prayer. +
+
+ + + Are we weak and heavy laden, Cumbered with a load of care?
+ Precious Saviour still our refuge; Take it to the Lord in prayer.
+ Do thy friends despise forsake thee? Take it to the Lord in prayer!
+ In His arms He’ll take and shield thee; Thou wilt find a solace there. +
+
+
+
diff --git a/tests/resources/songbeamersongs/Lobsinget dem Herrn.sng b/tests/resources/songbeamersongs/Lobsinget dem Herrn.sng index fbc9aa9fc..c93a143fa 100644 --- a/tests/resources/songbeamersongs/Lobsinget dem Herrn.sng +++ b/tests/resources/songbeamersongs/Lobsinget dem Herrn.sng @@ -1,5 +1,7 @@ #LangCount=1 #Title=GL 1 - Lobsinget dem Herrn +#Author=Carl Brockhaus +#Melody=Johann Jakob Vetter #Editor=SongBeamer 4.20 #Version=3 #Format=F/K//