Start on osis importer. Some further improvements of other importers

This commit is contained in:
Philip Ridout 2016-08-28 22:03:04 +01:00
parent 9b41814511
commit e91b87da8c
9 changed files with 451 additions and 383 deletions

View File

@ -25,6 +25,7 @@ The bible import functions for OpenLP
import logging import logging
import os import os
import urllib.error import urllib.error
from lxml import etree
from PyQt5 import QtWidgets from PyQt5 import QtWidgets
try: try:
@ -33,14 +34,15 @@ try:
except: except:
PYSWORD_AVAILABLE = False PYSWORD_AVAILABLE = False
from openlp.core.common import AppLocation, Settings, UiStrings, translate, clean_filename from openlp.core.common import AppLocation, Settings, UiStrings, trace_error_handler, translate
from openlp.core.common.languagemanager import get_locale_key
from openlp.core.lib.db import delete_database from openlp.core.lib.db import delete_database
from openlp.core.lib.exceptions import ValidationError
from openlp.core.lib.ui import critical_error_message_box from openlp.core.lib.ui import critical_error_message_box
from openlp.core.ui.lib.wizard import OpenLPWizard, WizardStrings from openlp.core.ui.lib.wizard import OpenLPWizard, WizardStrings
from openlp.core.common.languagemanager import get_locale_key
from openlp.plugins.bibles.lib.manager import BibleFormat
from openlp.plugins.bibles.lib.db import clean_filename from openlp.plugins.bibles.lib.db import clean_filename
from openlp.plugins.bibles.lib.importers.http import CWExtract, BGExtract, BSExtract from openlp.plugins.bibles.lib.importers.http import CWExtract, BGExtract, BSExtract
from openlp.plugins.bibles.lib.manager import BibleFormat
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -809,16 +811,22 @@ class BibleImportForm(OpenLPWizard):
sword_path=self.field('sword_zip_path'), sword_path=self.field('sword_zip_path'),
sword_key=self.sword_zipbible_combo_box.itemData( sword_key=self.sword_zipbible_combo_box.itemData(
self.sword_zipbible_combo_box.currentIndex())) self.sword_zipbible_combo_box.currentIndex()))
if importer.do_import(license_version):
self.manager.save_meta_data(license_version, license_version, license_copyright, license_permissions) try:
self.manager.reload_bibles() if importer.do_import(license_version):
if bible_type == BibleFormat.WebDownload: self.manager.save_meta_data(license_version, license_version, license_copyright, license_permissions)
self.progress_label.setText( self.manager.reload_bibles()
translate('BiblesPlugin.ImportWizardForm', 'Registered Bible. Please note, that verses will be ' if bible_type == BibleFormat.WebDownload:
'downloaded on demand and thus an internet connection is required.')) self.progress_label.setText(
else: translate('BiblesPlugin.ImportWizardForm', 'Registered Bible. Please note, that verses will be '
self.progress_label.setText(WizardStrings.FinishedImport) 'downloaded on demand and thus an internet connection is required.'))
else: else:
self.progress_label.setText(translate('BiblesPlugin.ImportWizardForm', 'Your Bible import failed.')) self.progress_label.setText(WizardStrings.FinishedImport)
del self.manager.db_cache[importer.name] return
delete_database(self.plugin.settings_section, importer.file) except (AttributeError, ValidationError, etree.XMLSyntaxError):
log.exception('Importing bible failed')
trace_error_handler(log)
self.progress_label.setText(translate('BiblesPlugin.ImportWizardForm', 'Your Bible import failed.'))
del self.manager.db_cache[importer.name]
delete_database(self.plugin.settings_section, importer.file)

View File

@ -25,8 +25,8 @@ import logging
from lxml import etree, objectify from lxml import etree, objectify
from zipfile import is_zipfile from zipfile import is_zipfile
from openlp.core.common import OpenLPMixin, languages from openlp.core.common import OpenLPMixin, languages, trace_error_handler, translate
from openlp.core.lib import ValidationError, translate from openlp.core.lib import ValidationError
from openlp.core.lib.ui import critical_error_message_box from openlp.core.lib.ui import critical_error_message_box
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
@ -103,8 +103,7 @@ class BibleImport(OpenLPMixin, BibleDB):
'importing {file}'.format(book_ref=book_ref_id, file=self.filename)) 'importing {file}'.format(book_ref=book_ref_id, file=self.filename))
return self.create_book(name, book_ref_id, book_details['testament_id']) return self.create_book(name, book_ref_id, book_details['testament_id'])
@staticmethod def parse_xml(self, filename, use_objectify=False, elements=None, tags=None):
def parse_xml(filename, use_objectify=False, elements=None, tags=None):
""" """
Parse and clean the supplied file by removing any elements or tags we don't use. Parse and clean the supplied file by removing any elements or tags we don't use.
:param filename: The filename of the xml file to parse. Str :param filename: The filename of the xml file to parse. Str
@ -113,17 +112,28 @@ class BibleImport(OpenLPMixin, BibleDB):
:param tags: A tuple of element names (Str) to remove, preserving their content. :param tags: A tuple of element names (Str) to remove, preserving their content.
:return: The root element of the xml document :return: The root element of the xml document
""" """
with open(filename, 'rb') as import_file: try:
# NOTE: We don't need to do any of the normal encoding detection here, because lxml does it's own encoding with open(filename, 'rb') as import_file:
# detection, and the two mechanisms together interfere with each other. # NOTE: We don't need to do any of the normal encoding detection here, because lxml does it's own encoding
if not use_objectify: # detection, and the two mechanisms together interfere with each other.
tree = etree.parse(import_file, parser=etree.XMLParser(recover=True)) if not use_objectify:
else: tree = etree.parse(import_file, parser=etree.XMLParser(recover=True))
tree = objectify.parse(import_file, parser=objectify.makeparser(recover=True)) else:
if elements: tree = objectify.parse(import_file, parser=objectify.makeparser(recover=True))
# Strip tags we don't use - remove content if elements or tags:
etree.strip_elements(tree, elements, with_tail=False) self.wizard.increment_progress_bar(translate('BiblesPlugin.OsisImport',
if tags: 'Removing unused tags (this may take a few minutes)...'))
# Strip tags we don't use - keep content if elements:
etree.strip_tags(tree, tags) # Strip tags we don't use - remove content
return tree.getroot() etree.strip_elements(tree, elements, with_tail=False)
if tags:
# Strip tags we don't use - keep content
etree.strip_tags(tree, tags)
return tree.getroot()
except OSError as e:
log.exception('Opening {file_name} failed.'.format(file_name=e.filename))
trace_error_handler(log)
critical_error_message_box( title='An Error Occured When Opening A File',
message='The following error occurred when trying to open\n{file_name}:\n\n{error}'
.format(file_name=e.filename, error=e.strerror))
return None

View File

@ -128,7 +128,6 @@ class CSVBible(BibleImport):
translate('BiblesPlugin.CSVBible', 'Importing books... {book}').format(book=book.name)) translate('BiblesPlugin.CSVBible', 'Importing books... {book}').format(book=book.name))
self.find_and_create_book(book.name, number_of_books, self.language_id) self.find_and_create_book(book.name, number_of_books, self.language_id)
book_list.update({int(book.id): book.name}) book_list.update({int(book.id): book.name})
self.application.process_events()
return book_list return book_list
def process_verses(self, verses, books): def process_verses(self, verses, books):
@ -153,7 +152,6 @@ class CSVBible(BibleImport):
self.session.commit() self.session.commit()
self.create_verse(book.id, verse.chapter_number, verse.number, verse.text) self.create_verse(book.id, verse.chapter_number, verse.number, verse.text)
self.wizard.increment_progress_bar(translate('BiblesPlugin.CSVBible', 'Importing verses... done.')) self.wizard.increment_progress_bar(translate('BiblesPlugin.CSVBible', 'Importing verses... done.'))
self.application.process_events()
self.session.commit() self.session.commit()
def do_import(self, bible_name=None): def do_import(self, bible_name=None):
@ -163,24 +161,18 @@ class CSVBible(BibleImport):
:param bible_name: Optional name of the bible being imported. Str or None :param bible_name: Optional name of the bible being imported. Str or None
:return: True if the import was successful, False if it failed or was cancelled :return: True if the import was successful, False if it failed or was cancelled
""" """
try: self.language_id = self.get_language(bible_name)
self.language_id = self.get_language(bible_name) if not self.language_id:
if not self.language_id:
raise ValidationError(msg='Invalid language selected')
books = self.parse_csv_file(self.books_file, Book)
self.wizard.progress_bar.setValue(0)
self.wizard.progress_bar.setMinimum(0)
self.wizard.progress_bar.setMaximum(len(books))
book_list = self.process_books(books)
if self.stop_import_flag:
return False
verses = self.parse_csv_file(self.verses_file, Verse)
self.wizard.progress_bar.setValue(0)
self.wizard.progress_bar.setMaximum(len(books) + 1)
self.process_verses(verses, book_list)
if self.stop_import_flag:
return False
except ValidationError:
log.exception('Could not import CSV bible')
return False return False
return True books = self.parse_csv_file(self.books_file, Book)
self.wizard.progress_bar.setValue(0)
self.wizard.progress_bar.setMinimum(0)
self.wizard.progress_bar.setMaximum(len(books))
book_list = self.process_books(books)
if self.stop_import_flag:
return False
verses = self.parse_csv_file(self.verses_file, Verse)
self.wizard.progress_bar.setValue(0)
self.wizard.progress_bar.setMaximum(len(books) + 1)
self.process_verses(verses, book_list)
return not self.stop_import_flag

View File

@ -23,7 +23,7 @@
import logging import logging
from lxml import etree from lxml import etree
from openlp.core.common import translate, trace_error_handler from openlp.core.common import trace_error_handler, translate
from openlp.core.lib.exceptions import ValidationError from openlp.core.lib.exceptions import ValidationError
from openlp.core.lib.ui import critical_error_message_box from openlp.core.lib.ui import critical_error_message_box
from openlp.plugins.bibles.lib.bibleimport import BibleImport from openlp.plugins.bibles.lib.bibleimport import BibleImport
@ -146,6 +146,8 @@ class OpenSongBible(BibleImport):
if BibleImport.is_compressed(filename): if BibleImport.is_compressed(filename):
raise ValidationError(msg='Compressed file') raise ValidationError(msg='Compressed file')
bible = self.parse_xml(filename, use_objectify=True) bible = self.parse_xml(filename, use_objectify=True)
if bible is None:
raise ValidationError(msg='Error when opening file')
root_tag = bible.tag.lower() root_tag = bible.tag.lower()
if root_tag != 'bible': if root_tag != 'bible':
if root_tag == 'xmlbible': if root_tag == 'xmlbible':
@ -165,20 +167,13 @@ class OpenSongBible(BibleImport):
:return: True if import completed, False if import was unsuccessful :return: True if import completed, False if import was unsuccessful
""" """
log.debug('Starting OpenSong import from "{name}"'.format(name=self.filename)) log.debug('Starting OpenSong import from "{name}"'.format(name=self.filename))
try: self.validate_file(self.filename)
self.validate_file(self.filename) bible = self.parse_xml(self.filename, use_objectify=True)
bible = self.parse_xml(self.filename, use_objectify=True) if bible is None:
# Check that we're not trying to import a Zefania XML bible, it is sometimes refered to as 'OpenSong'
# No language info in the opensong format, so ask the user
self.language_id = self.get_language_id(bible_name=self.filename)
if not self.language_id:
return False
self.process_books(bible.b)
self.application.process_events()
except (AttributeError, ValidationError, etree.XMLSyntaxError):
log.exception('Loading Bible from OpenSong file failed')
trace_error_handler(log)
return False return False
if self.stop_import_flag: # No language info in the opensong format, so ask the user
self.language_id = self.get_language_id(bible_name=self.filename)
if not self.language_id:
return False return False
return True self.process_books(bible.b)
return not self.stop_import_flag

View File

@ -24,9 +24,9 @@ import logging
from lxml import etree from lxml import etree
from openlp.core.common import translate, trace_error_handler from openlp.core.common import translate, trace_error_handler
from openlp.core.lib.exceptions import ValidationError
from openlp.core.lib.ui import critical_error_message_box from openlp.core.lib.ui import critical_error_message_box
from openlp.plugins.bibles.lib.bibleimport import BibleImport from openlp.plugins.bibles.lib.bibleimport import BibleImport
from openlp.plugins.bibles.lib.db import BiblesResourcesDB
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -79,94 +79,119 @@ def replacement(match):
return match.group(2).upper() return match.group(2).upper()
# Precompile a few xpath-querys
verse_in_chapter = etree.XPath('count(//ns:chapter[1]/ns:verse)', namespaces=NS)
text_in_verse = etree.XPath('count(//ns:verse[1]/text())', namespaces=NS)
class OSISBible(BibleImport): class OSISBible(BibleImport):
""" """
`OSIS <http://www.bibletechnologies.net/>`_ Bible format importer class. `OSIS <http://www.bibletechnologies.net/>`_ Bible format importer class.
""" """
def process_books(self, bible_data):
"""
:param bible_data:
:return:
"""
no_of_books = int(bible_data.xpath("count(//ns:div[@type='book'])", namespaces=NS))
# Find books in the bible
bible_books = bible_data.xpath("//ns:div[@type='book']", namespaces=NS)
for book in bible_books:
if self.stop_import_flag:
break
# Remove div-tags in the book
etree.strip_tags(book, '{http://www.bibletechnologies.net/2003/OSIS/namespace}div')
db_book = self.find_and_create_book(book.get('osisID'), no_of_books, self.language_id)
self.process_chapters_and_verses(db_book, book)
self.session.commit()
def process_chapters_and_verses(self, book, chapters):
"""
:param book:
:param chapters:
:return:
"""
# Find out if chapter-tags contains the verses, or if it is used as milestone/anchor
if int(verse_in_chapter(chapters)) > 0:
# The chapter tags contains the verses
for chapter in chapters:
chapter_number = chapter.get("osisID").split('.')[1]
# Find out if verse-tags contains the text, or if it is used as milestone/anchor
if int(text_in_verse(chapter)) == 0:
# verse-tags are used as milestone
for verse in chapter:
# If this tag marks the start of a verse, the verse text is between this tag and
# the next tag, which the "tail" attribute gives us.
if verse.get('sID'):
verse_number = verse.get("osisID").split('.')[2]
verse_text = verse.tail
if verse_text:
self.create_verse(book.id, chapter_number, verse_number, verse_text.strip())
else:
# Verse-tags contains the text
for verse in chapter:
verse_number = verse.get("osisID").split('.')[2]
if verse.text:
self.create_verse(book.id, chapter_number, verse_number, verse.text.strip())
self.wizard.increment_progress_bar(
translate('BiblesPlugin.OsisImport', 'Importing %(bookname)s %(chapter)s...') %
{'bookname': book.name, 'chapter': chapter_number})
else:
# The chapter tags is used as milestones. For now we assume verses is also milestones
chapter_number = 0
for element in chapters:
if element.tag == '{http://www.bibletechnologies.net/2003/OSIS/namespace}chapter' \
and element.get('sID'):
chapter_number = element.get("osisID").split('.')[1]
self.wizard.increment_progress_bar(
translate('BiblesPlugin.OsisImport', 'Importing %(bookname)s %(chapter)s...') %
{'bookname': book.name, 'chapter': chapter_number})
elif element.tag == '{http://www.bibletechnologies.net/2003/OSIS/namespace}verse' \
and element.get('sID'):
# If this tag marks the start of a verse, the verse text is between this tag and
# the next tag, which the "tail" attribute gives us.
verse_number = element.get("osisID").split('.')[2]
verse_text = element.tail
if verse_text:
self.create_verse(book.id, chapter_number, verse_number, verse_text.strip())
def validate_file(self, filename):
"""
Validate the supplied file
:param filename: The supplied file
:return: True if valid. ValidationError is raised otherwise.
"""
if BibleImport.is_compressed(filename):
raise ValidationError(msg='Compressed file')
bible = self.parse_xml(filename, use_objectify=True)
if bible is None:
raise ValidationError(msg='Error when opening file')
root_tag = bible.tag
tag_str = '{{{name_space}}}osis'.format(name_space=NS['ns'])
if root_tag != tag_str:
critical_error_message_box(
message=translate('BiblesPlugin.OpenSongImport',
'Incorrect Bible file type supplied. This looks like a Zefania XML bible, '
'please use the Zefania import option.'))
raise ValidationError(msg='Invalid xml.')
return True
def do_import(self, bible_name=None): def do_import(self, bible_name=None):
""" """
Loads a Bible from file. Loads a Bible from file.
""" """
log.debug('Starting OSIS import from "{name}"'.format(name=self.filename)) log.debug('Starting OSIS import from "{name}"'.format(name=self.filename))
success = True self.validate_file(self.filename)
try: bible = self.parse_xml(self.filename, elements=REMOVABLE_ELEMENTS, tags=REMOVABLE_TAGS)
self.wizard.increment_progress_bar(translate('BiblesPlugin.OsisImport', if bible is None:
'Removing unused tags (this may take a few minutes)...'))
osis_bible_tree = self.parse_xml(self.filename, elements=REMOVABLE_ELEMENTS, tags=REMOVABLE_TAGS)
# Find bible language]
language = osis_bible_tree.xpath("//ns:osisText/@xml:lang", namespaces=NS)
language_id = self.get_language_id(language[0] if language else None, bible_name=self.filename)
if not language_id:
return False
no_of_books = int(osis_bible_tree.xpath("count(//ns:div[@type='book'])", namespaces=NS))
# Precompile a few xpath-querys
verse_in_chapter = etree.XPath('count(//ns:chapter[1]/ns:verse)', namespaces=NS)
text_in_verse = etree.XPath('count(//ns:verse[1]/text())', namespaces=NS)
# Find books in the bible
bible_books = osis_bible_tree.xpath("//ns:div[@type='book']", namespaces=NS)
for book in bible_books:
if self.stop_import_flag:
break
# Remove div-tags in the book
etree.strip_tags(book, '{http://www.bibletechnologies.net/2003/OSIS/namespace}div')
db_book = self.find_and_create_book(book.get('osisID'), no_of_books, language_id)
# Find out if chapter-tags contains the verses, or if it is used as milestone/anchor
if int(verse_in_chapter(book)) > 0:
# The chapter tags contains the verses
for chapter in book:
chapter_number = chapter.get("osisID").split('.')[1]
# Find out if verse-tags contains the text, or if it is used as milestone/anchor
if int(text_in_verse(chapter)) == 0:
# verse-tags are used as milestone
for verse in chapter:
# If this tag marks the start of a verse, the verse text is between this tag and
# the next tag, which the "tail" attribute gives us.
if verse.get('sID'):
verse_number = verse.get("osisID").split('.')[2]
verse_text = verse.tail
if verse_text:
self.create_verse(db_book.id, chapter_number, verse_number, verse_text.strip())
else:
# Verse-tags contains the text
for verse in chapter:
verse_number = verse.get("osisID").split('.')[2]
if verse.text:
self.create_verse(db_book.id, chapter_number, verse_number, verse.text.strip())
self.wizard.increment_progress_bar(
translate('BiblesPlugin.OsisImport', 'Importing %(bookname)s %(chapter)s...') %
{'bookname': db_book.name, 'chapter': chapter_number})
else:
# The chapter tags is used as milestones. For now we assume verses is also milestones
chapter_number = 0
for element in book:
if element.tag == '{http://www.bibletechnologies.net/2003/OSIS/namespace}chapter' \
and element.get('sID'):
chapter_number = element.get("osisID").split('.')[1]
self.wizard.increment_progress_bar(
translate('BiblesPlugin.OsisImport', 'Importing %(bookname)s %(chapter)s...') %
{'bookname': db_book.name, 'chapter': chapter_number})
elif element.tag == '{http://www.bibletechnologies.net/2003/OSIS/namespace}verse' \
and element.get('sID'):
# If this tag marks the start of a verse, the verse text is between this tag and
# the next tag, which the "tail" attribute gives us.
verse_number = element.get("osisID").split('.')[2]
verse_text = element.tail
if verse_text:
self.create_verse(db_book.id, chapter_number, verse_number, verse_text.strip())
self.session.commit()
self.application.process_events()
except (ValueError, IOError):
log.exception('Loading bible from OSIS file failed')
trace_error_handler(log)
success = False
except etree.XMLSyntaxError as e:
log.exception('Loading bible from OSIS file failed')
trace_error_handler(log)
success = False
critical_error_message_box(message=translate('BiblesPlugin.OsisImport',
'The file is not a valid OSIS-XML file:'
'\n{text}').format(text=e.msg))
if self.stop_import_flag:
return False return False
else: # Find bible language
return success language = bible.xpath("//ns:osisText/@xml:lang", namespaces=NS)
self.language_id = self.get_language_id(language[0] if language else None, bible_name=self.filename)
if not self.language_id:
return False
self.process_books(bible)
return not self.stop_import_flag

View File

@ -171,9 +171,12 @@ class TestBibleImport(TestCase):
""" """
Test BibleImport.parse_xml() when called with the use_objectify default value Test BibleImport.parse_xml() when called with the use_objectify default value
""" """
# GIVEN: A sample "file" to parse # GIVEN: A sample "file" to parse and an instance of BibleImport
instance = BibleImport(MagicMock())
instance.wizard = MagicMock()
# WHEN: Calling parse_xml # WHEN: Calling parse_xml
result = BibleImport.parse_xml('file.tst') result = instance.parse_xml('file.tst')
# THEN: The result returned should contain the correct data, and should be an instance of eetree_Element # THEN: The result returned should contain the correct data, and should be an instance of eetree_Element
self.assertEqual(etree.tostring(result), self.assertEqual(etree.tostring(result),
@ -185,9 +188,12 @@ class TestBibleImport(TestCase):
""" """
Test BibleImport.parse_xml() when called with use_objectify set to True Test BibleImport.parse_xml() when called with use_objectify set to True
""" """
# GIVEN: A sample "file" to parse # GIVEN: A sample "file" to parse and an instance of BibleImport
instance = BibleImport(MagicMock())
instance.wizard = MagicMock()
# WHEN: Calling parse_xml # WHEN: Calling parse_xml
result = BibleImport.parse_xml('file.tst', use_objectify=True) result = instance.parse_xml('file.tst', use_objectify=True)
# THEN: The result returned should contain the correct data, and should be an instance of ObjectifiedElement # THEN: The result returned should contain the correct data, and should be an instance of ObjectifiedElement
self.assertEqual(etree.tostring(result), self.assertEqual(etree.tostring(result),
@ -199,11 +205,13 @@ class TestBibleImport(TestCase):
""" """
Test BibleImport.parse_xml() when given a tuple of elements to remove Test BibleImport.parse_xml() when given a tuple of elements to remove
""" """
# GIVEN: A tuple of elements to remove # GIVEN: A tuple of elements to remove and an instance of BibleImport
elements = ('unsupported', 'x', 'y') elements = ('unsupported', 'x', 'y')
instance = BibleImport(MagicMock())
instance.wizard = MagicMock()
# WHEN: Calling parse_xml, with a test file # WHEN: Calling parse_xml, with a test file
result = BibleImport.parse_xml('file.tst', elements=elements) result = instance.parse_xml('file.tst', elements=elements)
# THEN: The result returned should contain the correct data # THEN: The result returned should contain the correct data
self.assertEqual(etree.tostring(result), self.assertEqual(etree.tostring(result),
@ -213,11 +221,14 @@ class TestBibleImport(TestCase):
""" """
Test BibleImport.parse_xml() when given a tuple of tags to remove Test BibleImport.parse_xml() when given a tuple of tags to remove
""" """
# GIVEN: A tuple of tags to remove # GIVEN: A tuple of tags to remove and an instance of BibleImport
tags = ('div', 'p', 'a') tags = ('div', 'p', 'a')
instance = BibleImport(MagicMock())
instance.wizard = MagicMock()
# WHEN: Calling parse_xml, with a test file # WHEN: Calling parse_xml, with a test file
result = BibleImport.parse_xml('file.tst', tags=tags) result = instance.parse_xml('file.tst', tags=tags)
# THEN: The result returned should contain the correct data # THEN: The result returned should contain the correct data
self.assertEqual(etree.tostring(result), b'<root>\n <data>Testdatatokeep</data>\n <data><unsupported>Test' self.assertEqual(etree.tostring(result), b'<root>\n <data>Testdatatokeep</data>\n <data><unsupported>Test'
@ -227,12 +238,14 @@ class TestBibleImport(TestCase):
""" """
Test BibleImport.parse_xml() when given a tuple of elements and of tags to remove Test BibleImport.parse_xml() when given a tuple of elements and of tags to remove
""" """
# GIVEN: A tuple of elements and of tags to remove # GIVEN: A tuple of elements and of tags to remove and an instacne of BibleImport
elements = ('unsupported', 'x', 'y') elements = ('unsupported', 'x', 'y')
tags = ('div', 'p', 'a') tags = ('div', 'p', 'a')
instance = BibleImport(MagicMock())
instance.wizard = MagicMock()
# WHEN: Calling parse_xml, with a test file # WHEN: Calling parse_xml, with a test file
result = BibleImport.parse_xml('file.tst', elements=elements, tags=tags) result = instance.parse_xml('file.tst', elements=elements, tags=tags)
# THEN: The result returned should contain the correct data # THEN: The result returned should contain the correct data
self.assertEqual(etree.tostring(result), b'<root>\n <data>Testdatatokeep</data>\n <data/>\n</root>') self.assertEqual(etree.tostring(result), b'<root>\n <data>Testdatatokeep</data>\n <data/>\n</root>')

View File

@ -207,7 +207,6 @@ class TestCSVImport(TestCase):
with patch('openlp.plugins.bibles.lib.db.BibleDB._setup'),\ with patch('openlp.plugins.bibles.lib.db.BibleDB._setup'),\
patch('openlp.plugins.bibles.lib.importers.csvbible.translate'): patch('openlp.plugins.bibles.lib.importers.csvbible.translate'):
importer = CSVBible(mocked_manager, path='.', name='.', booksfile='books.csv', versefile='verse.csv') importer = CSVBible(mocked_manager, path='.', name='.', booksfile='books.csv', versefile='verse.csv')
type(importer).application = PropertyMock()
importer.find_and_create_book = MagicMock() importer.find_and_create_book = MagicMock()
importer.language_id = 10 importer.language_id = 10
importer.stop_import_flag = False importer.stop_import_flag = False
@ -222,7 +221,6 @@ class TestCSVImport(TestCase):
# The returned data should be a dictionary with both song's id and names. # The returned data should be a dictionary with both song's id and names.
self.assertEqual(importer.find_and_create_book.mock_calls, self.assertEqual(importer.find_and_create_book.mock_calls,
[call('1. Mosebog', 2, 10), call('2. Mosebog', 2, 10)]) [call('1. Mosebog', 2, 10), call('2. Mosebog', 2, 10)])
importer.application.process_events.assert_called_once_with()
self.assertDictEqual(result, {1: '1. Mosebog', 2: '2. Mosebog'}) self.assertDictEqual(result, {1: '1. Mosebog', 2: '2. Mosebog'})
def process_verses_stopped_import_test(self): def process_verses_stopped_import_test(self):
@ -233,7 +231,6 @@ class TestCSVImport(TestCase):
mocked_manager = MagicMock() mocked_manager = MagicMock()
with patch('openlp.plugins.bibles.lib.db.BibleDB._setup'): with patch('openlp.plugins.bibles.lib.db.BibleDB._setup'):
importer = CSVBible(mocked_manager, path='.', name='.', booksfile='books.csv', versefile='verse.csv') importer = CSVBible(mocked_manager, path='.', name='.', booksfile='books.csv', versefile='verse.csv')
type(importer).application = PropertyMock()
importer.get_book_name = MagicMock() importer.get_book_name = MagicMock()
importer.session = MagicMock() importer.session = MagicMock()
importer.stop_import_flag = True importer.stop_import_flag = True
@ -245,7 +242,6 @@ class TestCSVImport(TestCase):
# THEN: get_book_name should not be called and the return value should be None # THEN: get_book_name should not be called and the return value should be None
self.assertFalse(importer.get_book_name.called) self.assertFalse(importer.get_book_name.called)
importer.wizard.increment_progress_bar.assert_called_once_with('Importing verses... done.') importer.wizard.increment_progress_bar.assert_called_once_with('Importing verses... done.')
importer.application.process_events.assert_called_once_with()
self.assertIsNone(result) self.assertIsNone(result)
def process_verses_successful_test(self): def process_verses_successful_test(self):
@ -257,7 +253,6 @@ class TestCSVImport(TestCase):
with patch('openlp.plugins.bibles.lib.db.BibleDB._setup'),\ with patch('openlp.plugins.bibles.lib.db.BibleDB._setup'),\
patch('openlp.plugins.bibles.lib.importers.csvbible.translate'): patch('openlp.plugins.bibles.lib.importers.csvbible.translate'):
importer = CSVBible(mocked_manager, path='.', name='.', booksfile='books.csv', versefile='verse.csv') importer = CSVBible(mocked_manager, path='.', name='.', booksfile='books.csv', versefile='verse.csv')
type(importer).application = PropertyMock()
importer.create_verse = MagicMock() importer.create_verse = MagicMock()
importer.get_book = MagicMock(return_value=Book('1', '1', '1. Mosebog', '1Mos')) importer.get_book = MagicMock(return_value=Book('1', '1', '1. Mosebog', '1Mos'))
importer.get_book_name = MagicMock(return_value='1. Mosebog') importer.get_book_name = MagicMock(return_value='1. Mosebog')
@ -280,7 +275,6 @@ class TestCSVImport(TestCase):
[call('1', 1, 1, 'I Begyndelsen skabte Gud Himmelen og Jorden.'), [call('1', 1, 1, 'I Begyndelsen skabte Gud Himmelen og Jorden.'),
call('1', 1, 2, 'Og Jorden var øde og tom, og der var Mørke over Verdensdybet. ' call('1', 1, 2, 'Og Jorden var øde og tom, og der var Mørke over Verdensdybet. '
'Men Guds Ånd svævede over Vandene.')]) 'Men Guds Ånd svævede over Vandene.')])
importer.application.process_events.assert_called_once_with()
def do_import_invalid_language_id_test(self): def do_import_invalid_language_id_test(self):
""" """
@ -299,7 +293,6 @@ class TestCSVImport(TestCase):
# THEN: The log.exception method should have been called to show that it reached the except clause. # THEN: The log.exception method should have been called to show that it reached the except clause.
# False should be returned. # False should be returned.
importer.get_language.assert_called_once_with('Bible Name') importer.get_language.assert_called_once_with('Bible Name')
mocked_log.exception.assert_called_once_with('Could not import CSV bible')
self.assertFalse(result) self.assertFalse(result)
def do_import_stop_import_test(self): def do_import_stop_import_test(self):

View File

@ -387,125 +387,82 @@ class TestOpenSongImport(TestCase, TestMixin):
self.assertEqual(context.exception.msg, 'Invalid xml.') self.assertEqual(context.exception.msg, 'Invalid xml.')
self.assertFalse(mocked_message_box.called) self.assertFalse(mocked_message_box.called)
@patch('openlp.plugins.bibles.lib.importers.opensong.log') def do_import_parse_xml_fails_test(self):
@patch('openlp.plugins.bibles.lib.importers.opensong.trace_error_handler')
def do_import_attribute_error_test(self, mocked_trace_error_handler, mocked_log):
""" """
Test do_import when an AttributeError exception is raised Test do_import when parse_xml fails (returns None)
""" """
# GIVEN: An instance of OpenSongBible and a mocked validate_file which raises an AttributeError # GIVEN: An instance of OpenSongBible and a mocked parse_xml which returns False
importer = OpenSongBible(MagicMock(), path='.', name='.', filename='') with patch('openlp.plugins.bibles.lib.importers.opensong.log'), \
importer.validate_file = MagicMock(**{'side_effect': AttributeError()}) patch.object(OpenSongBible, 'validate_file'), \
importer.parse_xml = MagicMock() patch.object(OpenSongBible, 'parse_xml', return_value=None), \
patch.object(OpenSongBible, 'get_language_id') as mocked_language_id:
importer = OpenSongBible(MagicMock(), path='.', name='.', filename='')
# WHEN: Calling do_import # WHEN: Calling do_import
result = importer.do_import() result = importer.do_import()
# THEN: do_import should return False after logging the exception # THEN: do_import should return False and get_language_id should have not been called
mocked_log.exception.assert_called_once_with('Loading Bible from OpenSong file failed') self.assertFalse(result)
mocked_trace_error_handler.assert_called_once_with(mocked_log) self.assertFalse(mocked_language_id.called)
self.assertFalse(result)
self.assertFalse(importer.parse_xml.called)
@patch('openlp.plugins.bibles.lib.importers.opensong.log') def do_import_no_language_test(self):
@patch('openlp.plugins.bibles.lib.importers.opensong.trace_error_handler')
def do_import_validation_error_test(self, mocked_trace_error_handler, mocked_log):
"""
Test do_import when an ValidationError exception is raised
"""
# GIVEN: An instance of OpenSongBible and a mocked validate_file which raises an ValidationError
importer = OpenSongBible(MagicMock(), path='.', name='.', filename='')
importer.validate_file = MagicMock(**{'side_effect': ValidationError()})
importer.parse_xml = MagicMock()
# WHEN: Calling do_import
result = importer.do_import()
# THEN: do_import should return False after logging the exception. parse_xml should not be called.
mocked_log.exception.assert_called_once_with('Loading Bible from OpenSong file failed')
mocked_trace_error_handler.assert_called_once_with(mocked_log)
self.assertFalse(result)
self.assertFalse(importer.parse_xml.called)
@patch('openlp.plugins.bibles.lib.importers.opensong.log')
@patch('openlp.plugins.bibles.lib.importers.opensong.trace_error_handler')
def do_import_xml_syntax_error_test(self, mocked_trace_error_handler, mocked_log):
"""
Test do_import when an etree.XMLSyntaxError exception is raised
"""
# GIVEN: An instance of OpenSongBible and a mocked validate_file which raises an etree.XMLSyntaxError
importer = OpenSongBible(MagicMock(), path='.', name='.', filename='')
importer.validate_file = MagicMock(**{'side_effect': etree.XMLSyntaxError(None, None, None, None)})
importer.parse_xml = MagicMock()
# WHEN: Calling do_import
result = importer.do_import()
# THEN: do_import should return False after logging the exception. parse_xml should not be called.
mocked_log.exception.assert_called_once_with('Loading Bible from OpenSong file failed')
mocked_trace_error_handler.assert_called_once_with(mocked_log)
self.assertFalse(result)
self.assertFalse(importer.parse_xml.called)
@patch('openlp.plugins.bibles.lib.importers.opensong.log')
def do_import_no_language_test(self, mocked_log):
""" """
Test do_import when the user cancels the language selection dialog Test do_import when the user cancels the language selection dialog
""" """
# GIVEN: An instance of OpenSongBible and a mocked get_language which returns False # GIVEN: An instance of OpenSongBible and a mocked get_language which returns False
importer = OpenSongBible(MagicMock(), path='.', name='.', filename='') with patch('openlp.plugins.bibles.lib.importers.opensong.log'), \
importer.validate_file = MagicMock() patch.object(OpenSongBible, 'validate_file'), \
importer.parse_xml = MagicMock() patch.object(OpenSongBible, 'parse_xml'), \
importer.get_language_id = MagicMock(**{'return_value': False}) patch.object(OpenSongBible, 'get_language_id', return_value=False), \
importer.process_books = MagicMock() patch.object(OpenSongBible, 'process_books') as mocked_process_books:
importer = OpenSongBible(MagicMock(), path='.', name='.', filename='')
# WHEN: Calling do_import # WHEN: Calling do_import
result = importer.do_import() result = importer.do_import()
# THEN: do_import should return False and process_books should have not been called # THEN: do_import should return False and process_books should have not been called
self.assertFalse(result) self.assertFalse(result)
self.assertFalse(importer.process_books.called) self.assertFalse(mocked_process_books.called)
@patch('openlp.plugins.bibles.lib.importers.opensong.log') def do_import_stop_import_test(self):
def do_import_stop_import_test(self, mocked_log):
""" """
Test do_import when the stop_import_flag is set to True Test do_import when the stop_import_flag is set to True
""" """
# GIVEN: An instance of OpenSongBible and stop_import_flag set to True # GIVEN: An instance of OpenSongBible and stop_import_flag set to True
importer = OpenSongBible(MagicMock(), path='.', name='.', filename='') with patch('openlp.plugins.bibles.lib.importers.opensong.log'), \
importer.validate_file = MagicMock() patch.object(OpenSongBible, 'validate_file'), \
importer.parse_xml = MagicMock() patch.object(OpenSongBible, 'parse_xml'), \
importer.get_language_id = MagicMock(**{'return_value': 10}) patch.object(OpenSongBible, 'get_language_id', return_value=10), \
importer.process_books = MagicMock() patch.object(OpenSongBible, 'process_books') as mocked_process_books:
importer.stop_import_flag = True
# WHEN: Calling do_import importer = OpenSongBible(MagicMock(), path='.', name='.', filename='')
result = importer.do_import() importer.stop_import_flag = True
# THEN: do_import should return False and process_books should have not been called # WHEN: Calling do_import
self.assertFalse(result) result = importer.do_import()
self.assertTrue(importer.application.process_events.called)
self.assertTrue(importer.application.process_events.called) # THEN: do_import should return False and process_books should have not been called
self.assertFalse(result)
self.assertTrue(mocked_process_books.called)
@patch('openlp.plugins.bibles.lib.importers.opensong.log') def do_import_completes_test(self):
def do_import_completes_test(self, mocked_log):
""" """
Test do_import when it completes successfully Test do_import when it completes successfully
""" """
# GIVEN: An instance of OpenSongBible and stop_import_flag set to True # GIVEN: An instance of OpenSongBible and stop_import_flag set to False
importer = OpenSongBible(MagicMock(), path='.', name='.', filename='') with patch('openlp.plugins.bibles.lib.importers.opensong.log'), \
importer.validate_file = MagicMock() patch.object(OpenSongBible, 'validate_file'), \
importer.parse_xml = MagicMock() patch.object(OpenSongBible, 'parse_xml'), \
importer.get_language_id = MagicMock(**{'return_value': 10}) patch.object(OpenSongBible, 'get_language_id', return_value=10), \
importer.process_books = MagicMock() patch.object(OpenSongBible, 'process_books'):
importer.stop_import_flag = False importer = OpenSongBible(MagicMock(), path='.', name='.', filename='')
importer.stop_import_flag = False
# WHEN: Calling do_import # WHEN: Calling do_import
result = importer.do_import() result = importer.do_import()
# THEN: do_import should return True # THEN: do_import should return True
self.assertTrue(result) self.assertTrue(result)
def test_file_import(self): def test_file_import(self):
""" """

View File

@ -42,143 +42,218 @@ class TestOsisImport(TestCase):
def setUp(self): def setUp(self):
self.registry_patcher = patch('openlp.plugins.bibles.lib.db.Registry') self.registry_patcher = patch('openlp.plugins.bibles.lib.db.Registry')
self.addCleanup(self.registry_patcher.stop)
self.registry_patcher.start() self.registry_patcher.start()
self.manager_patcher = patch('openlp.plugins.bibles.lib.db.Manager') self.manager_patcher = patch('openlp.plugins.bibles.lib.db.Manager')
self.addCleanup(self.manager_patcher.stop)
self.manager_patcher.start() self.manager_patcher.start()
def tearDown(self): def test_create_importer(self):
self.registry_patcher.stop() """
self.manager_patcher.stop() Test creating an instance of the OSIS file importer
"""
def test_create_importer(self): # GIVEN: A mocked out "manager"
"""
Test creating an instance of the OSIS file importer
"""
# GIVEN: A mocked out "manager"
mocked_manager = MagicMock()
# WHEN: An importer object is created
importer = OSISBible(mocked_manager, path='.', name='.', filename='')
# THEN: The importer should be an instance of BibleDB
self.assertIsInstance(importer, BibleDB)
def test_file_import_nested_tags(self):
"""
Test the actual import of OSIS Bible file, with nested chapter and verse tags
"""
# GIVEN: Test files with a mocked out "manager", "import_wizard", and mocked functions
# get_book_ref_id_by_name, create_verse, create_book, session and get_language.
result_file = open(os.path.join(TEST_PATH, 'dk1933.json'), 'rb')
test_data = json.loads(result_file.read().decode())
bible_file = 'osis-dk1933.xml'
with patch('openlp.plugins.bibles.lib.importers.osis.OSISBible.application'):
mocked_manager = MagicMock() mocked_manager = MagicMock()
mocked_import_wizard = MagicMock()
# WHEN: An importer object is created
importer = OSISBible(mocked_manager, path='.', name='.', filename='') importer = OSISBible(mocked_manager, path='.', name='.', filename='')
importer.wizard = mocked_import_wizard
importer.get_book_ref_id_by_name = MagicMock()
importer.create_verse = MagicMock()
importer.create_book = MagicMock()
importer.session = MagicMock()
importer.get_language = MagicMock()
importer.get_language.return_value = 'Danish'
# WHEN: Importing bible file # THEN: The importer should be an instance of BibleDB
importer.filename = os.path.join(TEST_PATH, bible_file) self.assertIsInstance(importer, BibleDB)
importer.do_import()
# THEN: The create_verse() method should have been called with each verse in the file. def do_import_parse_xml_fails_test(self):
self.assertTrue(importer.create_verse.called)
for verse_tag, verse_text in test_data['verses']:
importer.create_verse.assert_any_call(importer.create_book().id, '1', verse_tag, verse_text)
def test_file_import_mixed_tags(self):
""" """
Test the actual import of OSIS Bible file, with chapter tags containing milestone verse tags. Test do_import when parse_xml fails (returns None)
""" """
# GIVEN: Test files with a mocked out "manager", "import_wizard", and mocked functions # GIVEN: An instance of OpenSongBible and a mocked parse_xml which returns False
# get_book_ref_id_by_name, create_verse, create_book, session and get_language. with patch('openlp.plugins.bibles.lib.importers.opensong.log'), \
result_file = open(os.path.join(TEST_PATH, 'kjv.json'), 'rb') patch.object(OSISBible, 'validate_file'), \
test_data = json.loads(result_file.read().decode()) patch.object(OSISBible, 'parse_xml', return_value=None), \
bible_file = 'osis-kjv.xml' patch.object(OSISBible, 'get_language_id') as mocked_language_id:
with patch('openlp.plugins.bibles.lib.importers.osis.OSISBible.application'): importer = OSISBible(MagicMock(), path='.', name='.', filename='')
mocked_manager = MagicMock()
mocked_import_wizard = MagicMock()
importer = OSISBible(mocked_manager, path='.', name='.', filename='')
importer.wizard = mocked_import_wizard
importer.get_book_ref_id_by_name = MagicMock()
importer.create_verse = MagicMock()
importer.create_book = MagicMock()
importer.session = MagicMock()
importer.get_language = MagicMock()
importer.get_language.return_value = 'English'
# WHEN: Importing bible file # WHEN: Calling do_import
importer.filename = os.path.join(TEST_PATH, bible_file) result = importer.do_import()
importer.do_import()
# THEN: The create_verse() method should have been called with each verse in the file. # THEN: do_import should return False and get_language_id should have not been called
self.assertTrue(importer.create_verse.called) self.assertFalse(result)
for verse_tag, verse_text in test_data['verses']: self.assertFalse(mocked_language_id.called)
importer.create_verse.assert_any_call(importer.create_book().id, '1', verse_tag, verse_text)
def test_file_import_milestone_tags(self): def do_import_no_language_test(self):
""" """
Test the actual import of OSIS Bible file, with milestone chapter and verse tags. Test do_import when the user cancels the language selection dialog
""" """
# GIVEN: Test files with a mocked out "manager", "import_wizard", and mocked functions # GIVEN: An instance of OpenSongBible and a mocked get_language which returns False
# get_book_ref_id_by_name, create_verse, create_book, session and get_language. with patch('openlp.plugins.bibles.lib.importers.opensong.log'), \
result_file = open(os.path.join(TEST_PATH, 'web.json'), 'rb') patch.object(OSISBible, 'validate_file'), \
test_data = json.loads(result_file.read().decode()) patch.object(OSISBible, 'parse_xml'), \
bible_file = 'osis-web.xml' patch.object(OSISBible, 'get_language_id', **{'return_value': False}), \
with patch('openlp.plugins.bibles.lib.importers.osis.OSISBible.application'): patch.object(OSISBible, 'process_books') as mocked_process_books:
mocked_manager = MagicMock() importer = OSISBible(MagicMock(), path='.', name='.', filename='')
mocked_import_wizard = MagicMock()
importer = OSISBible(mocked_manager, path='.', name='.', filename='')
importer.wizard = mocked_import_wizard
importer.get_book_ref_id_by_name = MagicMock()
importer.create_verse = MagicMock()
importer.create_book = MagicMock()
importer.session = MagicMock()
importer.get_language = MagicMock()
importer.get_language.return_value = 'English'
# WHEN: Importing bible file # WHEN: Calling do_import
importer.filename = os.path.join(TEST_PATH, bible_file) result = importer.do_import()
importer.do_import()
# THEN: The create_verse() method should have been called with each verse in the file. # THEN: do_import should return False and process_books should have not been called
self.assertTrue(importer.create_verse.called) self.assertFalse(result)
for verse_tag, verse_text in test_data['verses']: self.assertFalse(mocked_process_books.called)
importer.create_verse.assert_any_call(importer.create_book().id, '1', verse_tag, verse_text)
def test_file_import_empty_verse_tags(self): def do_import_stop_import_test(self):
""" """
Test the actual import of OSIS Bible file, with an empty verse tags. Test do_import when the stop_import_flag is set to True
""" """
# GIVEN: Test files with a mocked out "manager", "import_wizard", and mocked functions # GIVEN: An instance of OpenSongBible and stop_import_flag set to True
# get_book_ref_id_by_name, create_verse, create_book, session and get_language. with patch('openlp.plugins.bibles.lib.importers.opensong.log'), \
result_file = open(os.path.join(TEST_PATH, 'dk1933.json'), 'rb') patch.object(OSISBible, 'validate_file'), \
test_data = json.loads(result_file.read().decode()) patch.object(OSISBible, 'parse_xml'), \
bible_file = 'osis-dk1933-empty-verse.xml' patch.object(OSISBible, 'get_language_id', **{'return_value': 10}), \
with patch('openlp.plugins.bibles.lib.importers.osis.OSISBible.application'): patch.object(OSISBible, 'process_books'):
mocked_manager = MagicMock() importer = OSISBible(MagicMock(), path='.', name='.', filename='')
mocked_import_wizard = MagicMock() importer.stop_import_flag = True
importer = OSISBible(mocked_manager, path='.', name='.', filename='')
importer.wizard = mocked_import_wizard
importer.get_book_ref_id_by_name = MagicMock()
importer.create_verse = MagicMock()
importer.create_book = MagicMock()
importer.session = MagicMock()
importer.get_language = MagicMock()
importer.get_language.return_value = 'Danish'
# WHEN: Importing bible file # WHEN: Calling do_import
importer.filename = os.path.join(TEST_PATH, bible_file) result = importer.do_import()
importer.do_import()
# THEN: The create_verse() method should have been called with each verse in the file. # THEN: do_import should return False and process_books should have not been called
self.assertTrue(importer.create_verse.called) self.assertFalse(result)
for verse_tag, verse_text in test_data['verses']: self.assertTrue(importer.process_books.called)
importer.create_verse.assert_any_call(importer.create_book().id, '1', verse_tag, verse_text)
@patch('openlp.plugins.bibles.lib.importers.opensong.log')
def do_import_completes_test(self, mocked_log):
"""
Test do_import when it completes successfully
"""
# GIVEN: An instance of OpenSongBible and stop_import_flag set to True
with patch('openlp.plugins.bibles.lib.importers.opensong.log'), \
patch.object(OSISBible, 'validate_file'), \
patch.object(OSISBible, 'parse_xml'), \
patch.object(OSISBible, 'get_language_id', **{'return_value': 10}), \
patch.object(OSISBible, 'process_books'):
importer = OSISBible(MagicMock(), path='.', name='.', filename='')
importer.stop_import_flag = False
# WHEN: Calling do_import
result = importer.do_import()
# THEN: do_import should return True
self.assertTrue(result)
def test_file_import_nested_tags(self):
"""
Test the actual import of OSIS Bible file, with nested chapter and verse tags
"""
# GIVEN: Test files with a mocked out "manager", "import_wizard", and mocked functions
# get_book_ref_id_by_name, create_verse, create_book, session and get_language.
result_file = open(os.path.join(TEST_PATH, 'dk1933.json'), 'rb')
test_data = json.loads(result_file.read().decode())
bible_file = 'osis-dk1933.xml'
with patch('openlp.plugins.bibles.lib.importers.osis.OSISBible.application'):
mocked_manager = MagicMock()
mocked_import_wizard = MagicMock()
importer = OSISBible(mocked_manager, path='.', name='.', filename='')
importer.wizard = mocked_import_wizard
importer.get_book_ref_id_by_name = MagicMock()
importer.create_verse = MagicMock()
importer.create_book = MagicMock()
importer.session = MagicMock()
importer.get_language = MagicMock()
importer.get_language.return_value = 'Danish'
# WHEN: Importing bible file
importer.filename = os.path.join(TEST_PATH, bible_file)
importer.do_import()
# THEN: The create_verse() method should have been called with each verse in the file.
self.assertTrue(importer.create_verse.called)
for verse_tag, verse_text in test_data['verses']:
importer.create_verse.assert_any_call(importer.create_book().id, '1', verse_tag, verse_text)
def test_file_import_mixed_tags(self):
"""
Test the actual import of OSIS Bible file, with chapter tags containing milestone verse tags.
"""
# GIVEN: Test files with a mocked out "manager", "import_wizard", and mocked functions
# get_book_ref_id_by_name, create_verse, create_book, session and get_language.
result_file = open(os.path.join(TEST_PATH, 'kjv.json'), 'rb')
test_data = json.loads(result_file.read().decode())
bible_file = 'osis-kjv.xml'
with patch('openlp.plugins.bibles.lib.importers.osis.OSISBible.application'):
mocked_manager = MagicMock()
mocked_import_wizard = MagicMock()
importer = OSISBible(mocked_manager, path='.', name='.', filename='')
importer.wizard = mocked_import_wizard
importer.get_book_ref_id_by_name = MagicMock()
importer.create_verse = MagicMock()
importer.create_book = MagicMock()
importer.session = MagicMock()
importer.get_language = MagicMock()
importer.get_language.return_value = 'English'
# WHEN: Importing bible file
importer.filename = os.path.join(TEST_PATH, bible_file)
importer.do_import()
# THEN: The create_verse() method should have been called with each verse in the file.
self.assertTrue(importer.create_verse.called)
for verse_tag, verse_text in test_data['verses']:
importer.create_verse.assert_any_call(importer.create_book().id, '1', verse_tag, verse_text)
def test_file_import_milestone_tags(self):
"""
Test the actual import of OSIS Bible file, with milestone chapter and verse tags.
"""
# GIVEN: Test files with a mocked out "manager", "import_wizard", and mocked functions
# get_book_ref_id_by_name, create_verse, create_book, session and get_language.
result_file = open(os.path.join(TEST_PATH, 'web.json'), 'rb')
test_data = json.loads(result_file.read().decode())
bible_file = 'osis-web.xml'
with patch('openlp.plugins.bibles.lib.importers.osis.OSISBible.application'):
mocked_manager = MagicMock()
mocked_import_wizard = MagicMock()
importer = OSISBible(mocked_manager, path='.', name='.', filename='')
importer.wizard = mocked_import_wizard
importer.get_book_ref_id_by_name = MagicMock()
importer.create_verse = MagicMock()
importer.create_book = MagicMock()
importer.session = MagicMock()
importer.get_language = MagicMock()
importer.get_language.return_value = 'English'
# WHEN: Importing bible file
importer.filename = os.path.join(TEST_PATH, bible_file)
importer.do_import()
# THEN: The create_verse() method should have been called with each verse in the file.
self.assertTrue(importer.create_verse.called)
for verse_tag, verse_text in test_data['verses']:
importer.create_verse.assert_any_call(importer.create_book().id, '1', verse_tag, verse_text)
def test_file_import_empty_verse_tags(self):
"""
Test the actual import of OSIS Bible file, with an empty verse tags.
"""
# GIVEN: Test files with a mocked out "manager", "import_wizard", and mocked functions
# get_book_ref_id_by_name, create_verse, create_book, session and get_language.
result_file = open(os.path.join(TEST_PATH, 'dk1933.json'), 'rb')
test_data = json.loads(result_file.read().decode())
bible_file = 'osis-dk1933-empty-verse.xml'
with patch('openlp.plugins.bibles.lib.importers.osis.OSISBible.application'):
mocked_manager = MagicMock()
mocked_import_wizard = MagicMock()
importer = OSISBible(mocked_manager, path='.', name='.', filename='')
importer.wizard = mocked_import_wizard
importer.get_book_ref_id_by_name = MagicMock()
importer.create_verse = MagicMock()
importer.create_book = MagicMock()
importer.session = MagicMock()
importer.get_language = MagicMock()
importer.get_language.return_value = 'Danish'
# WHEN: Importing bible file
importer.filename = os.path.join(TEST_PATH, bible_file)
importer.do_import()
# THEN: The create_verse() method should have been called with each verse in the file.
self.assertTrue(importer.create_verse.called)
for verse_tag, verse_text in test_data['verses']:
importer.create_verse.assert_any_call(importer.create_book().id, '1', verse_tag, verse_text)