More fixes for broken tests

Skip one which never worked but relied on data leakage!
This commit is contained in:
Tim Bentley 2020-03-04 06:06:47 +00:00 committed by Raoul Snyman
parent d4e6bf7a42
commit 8fa698d510
35 changed files with 3860 additions and 3964 deletions

View File

@ -680,9 +680,8 @@ class Settings(QtCore.QSettings):
else:
default_value = Settings.__default_settings__[key]
try:
setting = super(Settings, self).value(key, default_value)
setting = super().value(key, default_value)
except TypeError:
log.error(f'Setting {key} is invalid , default {default_value} used as replacement')
setting = default_value
return self._convert_value(setting, default_value)

View File

@ -55,10 +55,11 @@ def mocked_qapp():
del app
@pytest.fixture
@pytest.yield_fixture
def registry():
"""An instance of the Registry"""
Registry.create()
yield Registry.create()
Registry._instances = {}
@pytest.yield_fixture
@ -80,16 +81,18 @@ def settings(qapp, registry):
@pytest.yield_fixture
def mock_settings(registry):
def mock_settings(qapp, registry):
"""A Mock Settings() instance"""
# Create and register a mock settings object to work with
mk_settings = MagicMock()
Registry().register('settings', mk_settings)
Registry().register('application', qapp)
yield mk_settings
Registry().remove('settings')
del mk_settings
@pytest.fixture(scope='function')
@pytest.yield_fixture
def state():
State().load_settings()
yield State().load_settings()
State._instances = {}

View File

@ -126,7 +126,7 @@ def test_toggle_display_valid_action_updates_controller(flask_client, settings):
assert controller.slidecontroller_toggle_display.set == 'show'
def test_cors_headers_are_present(flask_client):
def test_cors_headers_are_present(flask_client, settings):
res = flask_client.get('/api/v2/core/system')
assert 'Access-Control-Allow-Origin' in res.headers
assert res.headers['Access-Control-Allow-Origin'] == '*'

View File

@ -29,7 +29,6 @@ from unittest.mock import MagicMock, patch
from openlp.core.common.httputils import ProxyMode, download_file, get_proxy_settings, get_url_file_size, \
get_user_agent, get_web_page
from openlp.core.common.settings import Settings
@pytest.yield_fixture
@ -168,7 +167,7 @@ def test_get_web_page_with_header(mocked_get_user_agent, mocked_requests, settin
@patch('openlp.core.common.httputils.requests')
@patch('openlp.core.common.httputils.get_user_agent')
def test_get_web_page_with_user_agent_in_headers(mocked_get_user_agent, mocked_requests):
def test_get_web_page_with_user_agent_in_headers(mocked_get_user_agent, mocked_requests, settings):
"""
Test that adding a user agent in the header when calling get_web_page() adds that user agent to the request
"""
@ -216,7 +215,7 @@ def test_get_web_page_update_openlp(MockRegistry, mocked_get_user_agent, mocked_
@patch('openlp.core.common.httputils.requests')
def test_get_url_file_size(mocked_requests):
def test_get_url_file_size(mocked_requests, settings):
"""
Test that calling "get_url_file_size" works correctly
"""
@ -276,16 +275,16 @@ def test_system_proxy_mode(settings):
assert result is None
def test_manual_proxy_mode_no_auth():
def test_manual_proxy_mode_no_auth(settings):
"""
Test that the correct proxy addresses are returned when basic authentication is not used
"""
# GIVEN: A `proxy mode` setting of MANUAL_PROXY with proxy servers, but no auth credentials are supplied
Settings().setValue('advanced/proxy mode', ProxyMode.MANUAL_PROXY)
Settings().setValue('advanced/proxy http', 'testhttp.server:port')
Settings().setValue('advanced/proxy https', 'testhttps.server:port')
Settings().setValue('advanced/proxy username', '')
Settings().setValue('advanced/proxy password', '')
settings.setValue('advanced/proxy mode', ProxyMode.MANUAL_PROXY)
settings.setValue('advanced/proxy http', 'testhttp.server:port')
settings.setValue('advanced/proxy https', 'testhttps.server:port')
settings.setValue('advanced/proxy username', '')
settings.setValue('advanced/proxy password', '')
# WHEN: Calling `get_proxy_settings`
result = get_proxy_settings()
@ -294,16 +293,16 @@ def test_manual_proxy_mode_no_auth():
assert result == {'http': 'http://testhttp.server:port', 'https': 'https://testhttps.server:port'}
def test_manual_proxy_mode_auth():
def test_manual_proxy_mode_auth(settings):
"""
Test that the correct proxy addresses are returned when basic authentication is used
"""
# GIVEN: A `proxy mode` setting of MANUAL_PROXY with proxy servers and auth credentials supplied
Settings().setValue('advanced/proxy mode', ProxyMode.MANUAL_PROXY)
Settings().setValue('advanced/proxy http', 'testhttp.server:port')
Settings().setValue('advanced/proxy https', 'testhttps.server:port')
Settings().setValue('advanced/proxy username', 'user')
Settings().setValue('advanced/proxy password', 'pass')
settings.setValue('advanced/proxy mode', ProxyMode.MANUAL_PROXY)
settings.setValue('advanced/proxy http', 'testhttp.server:port')
settings.setValue('advanced/proxy https', 'testhttps.server:port')
settings.setValue('advanced/proxy username', 'user')
settings.setValue('advanced/proxy password', 'pass')
# WHEN: Calling `get_proxy_settings`
result = get_proxy_settings()
@ -313,17 +312,17 @@ def test_manual_proxy_mode_auth():
'https': 'https://user:pass@testhttps.server:port'}
def test_manual_proxy_mode_no_servers():
def test_manual_proxy_mode_no_servers(settings):
"""
Test that the system proxies are overidden when the MANUAL_PROXY mode is specified, but no server addresses are
supplied
"""
# GIVEN: A `proxy mode` setting of MANUAL_PROXY with no servers specified
Settings().setValue('advanced/proxy mode', ProxyMode.MANUAL_PROXY)
Settings().setValue('advanced/proxy http', '')
Settings().setValue('advanced/proxy https', '')
Settings().setValue('advanced/proxy username', 'user')
Settings().setValue('advanced/proxy password', 'pass')
settings.setValue('advanced/proxy mode', ProxyMode.MANUAL_PROXY)
settings.setValue('advanced/proxy http', '')
settings.setValue('advanced/proxy https', '')
settings.setValue('advanced/proxy username', 'user')
settings.setValue('advanced/proxy password', 'pass')
# WHEN: Calling `get_proxy_settings`
result = get_proxy_settings()

View File

@ -25,7 +25,6 @@ from unittest.mock import MagicMock, patch
from openlp.core.common.i18n import LANGUAGES, Language, UiStrings, get_language, get_locale_key, get_natural_key, \
translate, LanguageManager
from openlp.core.common.settings import Settings
def test_languages_type():
@ -159,8 +158,8 @@ def test_get_language_from_settings(settings):
assert LanguageManager.get_language() == 'en'
def test_get_language_from_settings_returns_unchanged_if_unknown_format():
Settings().setValue('core/language', '(foobar)')
def test_get_language_from_settings_returns_unchanged_if_unknown_format(settings):
settings.setValue('core/language', '(foobar)')
assert LanguageManager.get_language() == '(foobar)'

View File

@ -197,7 +197,7 @@ def test_render_chords_for_printing(settings):
assert text_with_rendered_chords == expected_html, 'The rendered chords should look as expected!'
def test_find_formatting_tags():
def test_find_formatting_tags(settings):
"""
Test that find_formatting_tags works as expected
"""

View File

@ -129,7 +129,7 @@ def test_firsttimeform_exec(mocked_qwizard_exec):
mocked_qwizard_exec.assert_called_once()
def test_set_defaults(mock_settings, ftf_app):
def test_set_defaults(mock_settings):
"""
Test that the default values are set when set_defaults() is run
"""

View File

@ -43,7 +43,7 @@ def test_initial_slide_controller(registry):
assert slide_controller.is_live is False, 'The base slide controller should not be a live controller'
def test_text_service_item_blank():
def test_text_service_item_blank(settings):
"""
Test that loading a text-based service item into the slide controller sets the correct blank menu
"""
@ -63,7 +63,7 @@ def test_text_service_item_blank():
toolbar.set_widget_visible.assert_called_with(WIDE_MENU, True)
def test_non_text_service_item_blank():
def test_non_text_service_item_blank(settings):
"""
Test that loading a non-text service item into the slide controller sets the correct blank menu
"""
@ -102,7 +102,7 @@ def test_receive_spin_delay(mock_settings):
mocked_delay_spin_box.setValue.assert_called_with(1)
def test_toggle_display_blank():
def test_toggle_display_blank(settings):
"""
Check that the toggle_display('blank') method calls the on_blank_display() method
"""
@ -124,7 +124,7 @@ def test_toggle_display_blank():
assert 0 == mocked_on_hide_display.call_count, 'on_hide_display should not have been called'
def test_toggle_display_hide():
def test_toggle_display_hide(settings):
"""
Check that the toggle_display('hide') method calls the on_blank_display() method
"""
@ -146,7 +146,7 @@ def test_toggle_display_hide():
assert 0 == mocked_on_hide_display.call_count, 'on_hide_display should not have been called'
def test_toggle_display_theme():
def test_toggle_display_theme(settings):
"""
Check that the toggle_display('theme') method calls the on_theme_display() method
"""
@ -168,7 +168,7 @@ def test_toggle_display_theme():
assert 0 == mocked_on_hide_display.call_count, 'on_hide_display should not have been called'
def test_toggle_display_desktop():
def test_toggle_display_desktop(settings):
"""
Check that the toggle_display('desktop') method calls the on_hide_display() method
"""
@ -190,7 +190,7 @@ def test_toggle_display_desktop():
assert 0 == mocked_on_theme_display.call_count, 'on_theme_display should not have been called'
def test_toggle_display_show():
def test_toggle_display_show(settings):
"""
Check that the toggle_display('show') method calls all the on_X_display() methods
"""
@ -298,7 +298,7 @@ def test_on_go_live_service_manager(registry):
mocked_live_controller.preview_widget.setFocus.assert_called_once_with()
def test_service_previous():
def test_service_previous(settings):
"""
Check that calling the service_previous() method adds the previous key to the queue and processes the queue
"""
@ -317,7 +317,7 @@ def test_service_previous():
mocked_process_queue.assert_called_once_with()
def test_service_next():
def test_service_next(settings):
"""
Check that calling the service_next() method adds the next key to the queue and processes the queue
"""
@ -355,7 +355,7 @@ def test_update_slide_limits(mock_settings):
assert 10 == slide_controller.slide_limits, 'Slide limits should have been updated to 10'
def test_enable_tool_bar_live():
def test_enable_tool_bar_live(settings):
"""
Check that when enable_tool_bar on a live slide controller is called, enable_live_tool_bar is called
"""
@ -376,7 +376,7 @@ def test_enable_tool_bar_live():
assert 0 == mocked_enable_preview_tool_bar.call_count, 'The preview method should not have been called'
def test_enable_tool_bar_preview():
def test_enable_tool_bar_preview(settings):
"""
Check that when enable_tool_bar on a preview slide controller is called, enable_preview_tool_bar is called
"""
@ -397,7 +397,7 @@ def test_enable_tool_bar_preview():
assert 0 == mocked_enable_live_tool_bar.call_count, 'The live method should not have been called'
def test_refresh_service_item_text():
def test_refresh_service_item_text(settings):
"""
Test that the refresh_service_item() method refreshes a text service item
"""
@ -421,7 +421,7 @@ def test_refresh_service_item_text():
mocked_process_item.assert_called_once_with(mocked_service_item, 5)
def test_refresh_service_item_image():
def test_refresh_service_item_image(settings):
"""
Test that the refresh_service_item() method refreshes a image service item
"""
@ -445,7 +445,7 @@ def test_refresh_service_item_image():
mocked_process_item.assert_called_once_with(mocked_service_item, 5)
def test_refresh_service_item_not_image_or_text():
def test_refresh_service_item_not_image_or_text(settings):
"""
Test that the refresh_service_item() method does not refresh a service item if it's neither text or an image
"""
@ -469,7 +469,7 @@ def test_refresh_service_item_not_image_or_text():
assert 0 == mocked_process_item.call_count, 'The mocked_process_item() method should not have been called'
def test_add_service_item_with_song_edit():
def test_add_service_item_with_song_edit(settings):
"""
Test the add_service_item() method when song_edit is True
"""
@ -489,7 +489,7 @@ def test_add_service_item_with_song_edit():
mocked_process_item.assert_called_once_with(mocked_item, 2)
def test_add_service_item_without_song_edit():
def test_add_service_item_without_song_edit(settings):
"""
Test the add_service_item() method when song_edit is False
"""
@ -509,7 +509,7 @@ def test_add_service_item_without_song_edit():
mocked_process_item.assert_called_once_with(mocked_item, 0)
def test_replace_service_manager_item_different_items():
def test_replace_service_manager_item_different_items(settings):
"""
Test that when the service items are not the same, nothing happens
"""
@ -531,7 +531,7 @@ def test_replace_service_manager_item_different_items():
'The preview_widget current_slide_number.() method should not have been called'
def test_replace_service_manager_item_same_item():
def test_replace_service_manager_item_same_item(settings):
"""
Test that when the service item is the same, the service item is reprocessed
"""
@ -553,7 +553,7 @@ def test_replace_service_manager_item_same_item():
mocked_process_item.assert_called_once_with(mocked_item, 7)
def test_on_slide_blank():
def test_on_slide_blank(settings):
"""
Test on_slide_blank
"""
@ -568,7 +568,7 @@ def test_on_slide_blank():
slide_controller.on_blank_display.assert_called_once_with(True)
def test_on_slide_unblank():
def test_on_slide_unblank(settings):
"""
Test on_slide_unblank
"""
@ -583,7 +583,7 @@ def test_on_slide_unblank():
slide_controller.on_blank_display.assert_called_once_with(False)
def test_on_slide_selected_index_no_service_item():
def test_on_slide_selected_index_no_service_item(settings):
"""
Test that when there is no service item, the on_slide_selected_index() method returns immediately
"""
@ -705,7 +705,7 @@ def test_process_item(mocked_execute, registry):
'The presentation should have been stopped.'
def test_live_stolen_focus_shortcuts():
def test_live_stolen_focus_shortcuts(settings):
"""
Test that all the needed shortcuts are available in scenarios where Live has stolen focus.
These are found under def __add_actions_to_widget(self, widget): in slidecontroller.py

View File

@ -21,60 +21,52 @@
"""
This module contains tests for the CSV Bible importer.
"""
from unittest import TestCase
from unittest.mock import MagicMock
from openlp.core.common.registry import Registry
from openlp.plugins.alerts.lib.alertsmanager import AlertsManager
class TestAlertManager(TestCase):
def test_remove_message_text(registry):
"""
Test that Alerts are not triggered with empty strings
"""
# GIVEN: A valid Alert Manager
alert_manager = AlertsManager(None)
alert_manager.display_alert = MagicMock()
def setUp(self):
"""
Create the UI
"""
Registry.create()
# WHEN: Called with an empty string
alert_manager.alert_text('')
def test_remove_message_text(self):
"""
Test that Alerts are not triggered with empty strings
"""
# GIVEN: A valid Alert Manager
alert_manager = AlertsManager(None)
alert_manager.display_alert = MagicMock()
# THEN: the display should not have been triggered
assert alert_manager.display_alert.called is False, 'The Alert should not have been called'
# WHEN: Called with an empty string
alert_manager.alert_text('')
# THEN: the display should not have been triggered
assert alert_manager.display_alert.called is False, 'The Alert should not have been called'
def test_trigger_message_text(registry):
"""
Test that Alerts are triggered with a text string
"""
# GIVEN: A valid Alert Manager
alert_manager = AlertsManager(None)
alert_manager.display_alert = MagicMock()
def test_trigger_message_text(self):
"""
Test that Alerts are triggered with a text string
"""
# GIVEN: A valid Alert Manager
alert_manager = AlertsManager(None)
alert_manager.display_alert = MagicMock()
# WHEN: Called with an empty string
alert_manager.alert_text(['This is a string'])
# WHEN: Called with an empty string
alert_manager.alert_text(['This is a string'])
# THEN: the display should have been triggered
assert alert_manager.display_alert.called is True, 'The Alert should have been called'
# THEN: the display should have been triggered
assert alert_manager.display_alert.called is True, 'The Alert should have been called'
def test_line_break_message_text(self):
"""
Test that Alerts are triggered with a text string but line breaks are removed
"""
# GIVEN: A valid Alert Manager
alert_manager = AlertsManager(None)
alert_manager.display_alert = MagicMock()
def test_line_break_message_text(registry):
"""
Test that Alerts are triggered with a text string but line breaks are removed
"""
# GIVEN: A valid Alert Manager
alert_manager = AlertsManager(None)
alert_manager.display_alert = MagicMock()
# WHEN: Called with an empty string
alert_manager.alert_text(['This is \n a string'])
# WHEN: Called with an empty string
alert_manager.alert_text(['This is \n a string'])
# THEN: the display should have been triggered
assert alert_manager.display_alert.called is True, 'The Alert should have been called'
alert_manager.display_alert.assert_called_once_with('This is a string')
# THEN: the display should have been triggered
assert alert_manager.display_alert.called is True, 'The Alert should have been called'
alert_manager.display_alert.assert_called_once_with('This is a string')

File diff suppressed because it is too large Load Diff

View File

@ -22,9 +22,9 @@
This module contains tests for the CSV Bible importer.
"""
import csv
import pytest
from collections import namedtuple
from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, PropertyMock, call, patch
from openlp.core.lib.exceptions import ValidationError
@ -37,327 +37,328 @@ from tests.utils.constants import RESOURCE_PATH
TEST_PATH = RESOURCE_PATH / 'bibles'
class TestCSVImport(TestCase):
def test_create_importer(settings):
"""
Test the functions in the :mod:`csvimport` module.
Test creating an instance of the CSV file importer
"""
# GIVEN: A mocked out "manager"
mocked_manager = MagicMock()
def setUp(self):
self.manager_patcher = patch('openlp.plugins.bibles.lib.db.Manager')
self.addCleanup(self.manager_patcher.stop)
self.manager_patcher.start()
self.registry_patcher = patch('openlp.plugins.bibles.lib.bibleimport.Registry')
self.addCleanup(self.registry_patcher.stop)
self.registry_patcher.start()
# WHEN: An importer object is created
importer = \
CSVBible(mocked_manager, path='.', name='.', books_path=Path('books.csv'), verse_path=Path('verse.csv'))
def test_create_importer(self):
"""
Test creating an instance of the CSV file importer
"""
# GIVEN: A mocked out "manager"
mocked_manager = MagicMock()
# THEN: The importer should be an instance of BibleImport
assert isinstance(importer, BibleImport)
assert importer.books_path == Path('books.csv')
assert importer.verses_path == Path('verse.csv')
# WHEN: An importer object is created
importer = \
CSVBible(mocked_manager, path='.', name='.', books_path=Path('books.csv'), verse_path=Path('verse.csv'))
# THEN: The importer should be an instance of BibleImport
assert isinstance(importer, BibleImport)
assert importer.books_path == Path('books.csv')
assert importer.verses_path == Path('verse.csv')
def test_book_namedtuple():
"""
Test that the Book namedtuple is created as expected
"""
# GIVEN: The Book namedtuple
# WHEN: Creating an instance of Book
result = Book('id', 'testament_id', 'name', 'abbreviation')
def test_book_namedtuple(self):
"""
Test that the Book namedtuple is created as expected
"""
# GIVEN: The Book namedtuple
# WHEN: Creating an instance of Book
result = Book('id', 'testament_id', 'name', 'abbreviation')
# THEN: The attributes should match up with the data we used
assert result.id == 'id'
assert result.testament_id == 'testament_id'
assert result.name == 'name'
assert result.abbreviation == 'abbreviation'
# THEN: The attributes should match up with the data we used
assert result.id == 'id'
assert result.testament_id == 'testament_id'
assert result.name == 'name'
assert result.abbreviation == 'abbreviation'
def test_verse_namedtuple(self):
"""
Test that the Verse namedtuple is created as expected
"""
# GIVEN: The Verse namedtuple
# WHEN: Creating an instance of Verse
result = Verse('book_id_name', 'chapter_number', 'number', 'text')
def test_verse_namedtuple():
"""
Test that the Verse namedtuple is created as expected
"""
# GIVEN: The Verse namedtuple
# WHEN: Creating an instance of Verse
result = Verse('book_id_name', 'chapter_number', 'number', 'text')
# THEN: The attributes should match up with the data we used
assert result.book_id_name == 'book_id_name'
assert result.chapter_number == 'chapter_number'
assert result.number == 'number'
assert result.text == 'text'
# THEN: The attributes should match up with the data we used
assert result.book_id_name == 'book_id_name'
assert result.chapter_number == 'chapter_number'
assert result.number == 'number'
assert result.text == 'text'
def test_get_book_name_id(self):
"""
Test that get_book_name() returns the correct book when called with an id
"""
# GIVEN: A dictionary of books with their id as the keys
books = {1: 'Book 1', 2: 'Book 2', 3: 'Book 3'}
# WHEN: Calling get_book_name() and the name is an integer represented as a string
test_data = [['1', 'Book 1'], ['2', 'Book 2'], ['3', 'Book 3']]
for name, expected_result in test_data:
actual_result = CSVBible.get_book_name(name, books)
def test_get_book_name_id():
"""
Test that get_book_name() returns the correct book when called with an id
"""
# GIVEN: A dictionary of books with their id as the keys
books = {1: 'Book 1', 2: 'Book 2', 3: 'Book 3'}
# THEN: get_book_name() should return the book name associated with that id from the books dictionary
assert actual_result == expected_result
# WHEN: Calling get_book_name() and the name is an integer represented as a string
test_data = [['1', 'Book 1'], ['2', 'Book 2'], ['3', 'Book 3']]
for name, expected_result in test_data:
actual_result = CSVBible.get_book_name(name, books)
def test_get_book_name(self):
"""
Test that get_book_name() returns the name when called with a non integer value
"""
# GIVEN: A dictionary of books with their id as the keys
books = {1: 'Book 1', 2: 'Book 2', 3: 'Book 3'}
# THEN: get_book_name() should return the book name associated with that id from the books dictionary
assert actual_result == expected_result
# WHEN: Calling get_book_name() and the name is not an integer represented as a string
test_data = [['Book 4', 'Book 4'], ['Book 5', 'Book 5'], ['Book 6', 'Book 6']]
for name, expected_result in test_data:
actual_result = CSVBible.get_book_name(name, books)
# THEN: get_book_name() should return the input
assert actual_result == expected_result
def test_get_book_name():
"""
Test that get_book_name() returns the name when called with a non integer value
"""
# GIVEN: A dictionary of books with their id as the keys
books = {1: 'Book 1', 2: 'Book 2', 3: 'Book 3'}
def test_parse_csv_file(self):
"""
Test the parse_csv_file() with sample data
"""
# GIVEN: A mocked csv.reader which returns an iterator with test data
test_data = [['1', 'Line 1', 'Data 1'], ['2', 'Line 2', 'Data 2'], ['3', 'Line 3', 'Data 3']]
TestTuple = namedtuple('TestTuple', 'line_no line_description line_data')
mocked_csv_file = MagicMock()
mocked_enter_file = MagicMock()
mocked_csv_file.open.return_value.__enter__.return_value = mocked_enter_file
# WHEN: Calling get_book_name() and the name is not an integer represented as a string
test_data = [['Book 4', 'Book 4'], ['Book 5', 'Book 5'], ['Book 6', 'Book 6']]
for name, expected_result in test_data:
actual_result = CSVBible.get_book_name(name, books)
with patch('openlp.plugins.bibles.lib.importers.csvbible.get_file_encoding', return_value='utf-8'), \
patch('openlp.plugins.bibles.lib.importers.csvbible.csv.reader',
return_value=iter(test_data)) as mocked_reader:
# THEN: get_book_name() should return the input
assert actual_result == expected_result
# WHEN: Calling the CSVBible parse_csv_file method with a file name and TestTuple
result = CSVBible.parse_csv_file(mocked_csv_file, TestTuple)
# THEN: A list of TestTuple instances with the parsed data should be returned
assert result == [TestTuple('1', 'Line 1', 'Data 1'), TestTuple('2', 'Line 2', 'Data 2'),
TestTuple('3', 'Line 3', 'Data 3')]
mocked_csv_file.open.assert_called_once_with('r', encoding='utf-8', newline='')
mocked_reader.assert_called_once_with(mocked_enter_file, delimiter=',', quotechar='"')
def test_parse_csv_file():
"""
Test the parse_csv_file() with sample data
"""
# GIVEN: A mocked csv.reader which returns an iterator with test data
test_data = [['1', 'Line 1', 'Data 1'], ['2', 'Line 2', 'Data 2'], ['3', 'Line 3', 'Data 3']]
TestTuple = namedtuple('TestTuple', 'line_no line_description line_data')
mocked_csv_file = MagicMock()
mocked_enter_file = MagicMock()
mocked_csv_file.open.return_value.__enter__.return_value = mocked_enter_file
def test_parse_csv_file_oserror(self):
"""
Test the parse_csv_file() handles an OSError correctly
"""
# GIVEN: Mocked a mocked open object which raises an OSError
mocked_csv_file = MagicMock()
mocked_csv_file.__str__.return_value = 'file.csv'
mocked_csv_file.open.side_effect = OSError()
with patch('openlp.plugins.bibles.lib.importers.csvbible.get_file_encoding', return_value='utf-8'), \
patch('openlp.plugins.bibles.lib.importers.csvbible.csv.reader',
return_value=iter(test_data)) as mocked_reader:
with patch('openlp.plugins.bibles.lib.importers.csvbible.get_file_encoding',
return_value={'encoding': 'utf-8', 'confidence': 0.99}):
# WHEN: Calling the CSVBible parse_csv_file method with a file name and TestTuple
result = CSVBible.parse_csv_file(mocked_csv_file, TestTuple)
# WHEN: Calling CSVBible.parse_csv_file
# THEN: A ValidationError should be raised
with self.assertRaises(ValidationError) as context:
CSVBible.parse_csv_file(mocked_csv_file, None)
assert context.exception.msg == 'Parsing "file.csv" failed'
# THEN: A list of TestTuple instances with the parsed data should be returned
assert result == [TestTuple('1', 'Line 1', 'Data 1'), TestTuple('2', 'Line 2', 'Data 2'),
TestTuple('3', 'Line 3', 'Data 3')]
mocked_csv_file.open.assert_called_once_with('r', encoding='utf-8', newline='')
mocked_reader.assert_called_once_with(mocked_enter_file, delimiter=',', quotechar='"')
def test_parse_csv_file_csverror(self):
"""
Test the parse_csv_file() handles an csv.Error correctly
"""
# GIVEN: Mocked a csv.reader which raises an csv.Error
mocked_csv_file = MagicMock()
mocked_csv_file.__str__.return_value = 'file.csv'
with patch('openlp.plugins.bibles.lib.importers.csvbible.get_file_encoding',
return_value={'encoding': 'utf-8', 'confidence': 0.99}),\
patch('openlp.plugins.bibles.lib.importers.csvbible.csv.reader', side_effect=csv.Error):
def test_parse_csv_file_oserror():
"""
Test the parse_csv_file() handles an OSError correctly
"""
# GIVEN: Mocked a mocked open object which raises an OSError
mocked_csv_file = MagicMock()
mocked_csv_file.__str__.return_value = 'file.csv'
mocked_csv_file.open.side_effect = OSError()
# WHEN: Calling CSVBible.parse_csv_file
# THEN: A ValidationError should be raised
with self.assertRaises(ValidationError) as context:
CSVBible.parse_csv_file(mocked_csv_file, None)
assert context.exception.msg == 'Parsing "file.csv" failed'
with patch('openlp.plugins.bibles.lib.importers.csvbible.get_file_encoding',
return_value={'encoding': 'utf-8', 'confidence': 0.99}):
def test_process_books_stopped_import(self):
"""
Test process books when the import is stopped
"""
# GIVEN: An instance of CSVBible with the stop_import_flag set to True
mocked_manager = MagicMock()
with patch('openlp.plugins.bibles.lib.db.BibleDB._setup'):
importer = CSVBible(mocked_manager, path='.', name='.', books_path=Path('books.csv'),
verse_path=Path('verse.csv'))
type(importer).application = PropertyMock()
importer.stop_import_flag = True
importer.wizard = MagicMock()
# WHEN: Calling CSVBible.parse_csv_file
# THEN: A ValidationError should be raised
with pytest.raises(ValidationError) as context:
CSVBible.parse_csv_file(mocked_csv_file, None)
assert context.value != ValidationError('Parsing "file.csv" failed')
# WHEN: Calling process_books
result = importer.process_books(['Book 1'])
# THEN: increment_progress_bar should not be called and the return value should be an empty dictionary
assert importer.wizard.increment_progress_bar.called is False
assert result == {}
def test_parse_csv_file_csverror():
"""
Test the parse_csv_file() handles an csv.Error correctly
"""
# GIVEN: Mocked a csv.reader which raises an csv.Error
mocked_csv_file = MagicMock()
mocked_csv_file.__str__.return_value = 'file.csv'
def test_process_books(self):
"""
Test process books when it completes successfully
"""
# GIVEN: An instance of CSVBible with the stop_import_flag set to False, and some sample data
mocked_manager = MagicMock()
with patch('openlp.plugins.bibles.lib.db.BibleDB._setup'),\
patch('openlp.plugins.bibles.lib.importers.csvbible.translate'):
importer = CSVBible(mocked_manager, path='.', name='.', books_path=Path('books.csv'),
verse_path=Path('verse.csv'))
importer.find_and_create_book = MagicMock()
importer.language_id = 10
importer.stop_import_flag = False
importer.wizard = MagicMock()
with patch('openlp.plugins.bibles.lib.importers.csvbible.get_file_encoding',
return_value={'encoding': 'utf-8', 'confidence': 0.99}),\
patch('openlp.plugins.bibles.lib.importers.csvbible.csv.reader', side_effect=csv.Error):
books = [Book('1', '1', '1. Mosebog', '1Mos'), Book('2', '1', '2. Mosebog', '2Mos')]
# WHEN: Calling CSVBible.parse_csv_file
# THEN: A ValidationError should be raised
with pytest.raises(ValidationError) as context:
CSVBible.parse_csv_file(mocked_csv_file, None)
assert context.value != ValidationError('Parsing "file.csv" failed')
# WHEN: Calling process_books
result = importer.process_books(books)
# THEN: translate and find_and_create_book should have been called with both book names.
# The returned data should be a dictionary with both song's id and names.
assert importer.find_and_create_book.mock_calls == \
[call('1. Mosebog', 2, 10), call('2. Mosebog', 2, 10)]
assert result == {1: '1. Mosebog', 2: '2. Mosebog'}
def test_process_books_stopped_import(registry):
"""
Test process books when the import is stopped
"""
# GIVEN: An instance of CSVBible with the stop_import_flag set to True
mocked_manager = MagicMock()
with patch('openlp.plugins.bibles.lib.db.BibleDB._setup'):
importer = CSVBible(mocked_manager, path='.', name='.', books_path=Path('books.csv'),
verse_path=Path('verse.csv'))
type(importer).application = PropertyMock()
importer.stop_import_flag = True
importer.wizard = MagicMock()
def test_process_verses_stopped_import(self):
"""
Test process_verses when the import is stopped
"""
# GIVEN: An instance of CSVBible with the stop_import_flag set to True
mocked_manager = MagicMock()
with patch('openlp.plugins.bibles.lib.db.BibleDB._setup'):
importer = CSVBible(mocked_manager, path='.', name='.', books_path=Path('books.csv'),
verse_path=Path('verse.csv'))
importer.get_book_name = MagicMock()
importer.session = MagicMock()
importer.stop_import_flag = True
importer.wizard = MagicMock()
# WHEN: Calling process_books
result = importer.process_books(['Book 1'])
# WHEN: Calling process_verses
result = importer.process_verses(['Dummy Verse'], [])
# THEN: increment_progress_bar should not be called and the return value should be an empty dictionary
assert importer.wizard.increment_progress_bar.called is False
assert result == {}
# THEN: get_book_name should not be called and the return value should be None
assert importer.get_book_name.called is False
assert result is None
def test_process_verses_successful(self):
"""
Test process_verses when the import is successful
"""
# GIVEN: An instance of CSVBible with the application and wizard attributes mocked out, and some test data.
mocked_manager = MagicMock()
with patch('openlp.plugins.bibles.lib.db.BibleDB._setup'),\
patch('openlp.plugins.bibles.lib.importers.csvbible.translate'):
importer = CSVBible(mocked_manager, path='.', name='.', books_path=Path('books.csv'),
verse_path=Path('verse.csv'))
importer.create_verse = MagicMock()
importer.get_book = MagicMock(return_value=Book('1', '1', '1. Mosebog', '1Mos'))
importer.get_book_name = MagicMock(return_value='1. Mosebog')
importer.session = MagicMock()
importer.stop_import_flag = False
importer.wizard = MagicMock()
verses = [Verse(1, 1, 1, 'I Begyndelsen skabte Gud Himmelen og Jorden.'),
Verse(1, 1, 2, 'Og Jorden var øde og tom, og der var Mørke over Verdensdybet. '
'Men Guds Ånd svævede over Vandene.')]
books = {1: '1. Mosebog'}
def test_process_books(registry):
"""
Test process books when it completes successfully
"""
# GIVEN: An instance of CSVBible with the stop_import_flag set to False, and some sample data
mocked_manager = MagicMock()
with patch('openlp.plugins.bibles.lib.db.BibleDB._setup'),\
patch('openlp.plugins.bibles.lib.importers.csvbible.translate'):
importer = CSVBible(mocked_manager, path='.', name='.', books_path=Path('books.csv'),
verse_path=Path('verse.csv'))
importer.find_and_create_book = MagicMock()
importer.language_id = 10
importer.stop_import_flag = False
importer.wizard = MagicMock()
# WHEN: Calling process_verses
importer.process_verses(verses, books)
books = [Book('1', '1', '1. Mosebog', '1Mos'), Book('2', '1', '2. Mosebog', '2Mos')]
# THEN: create_verse is called with the test data
assert importer.get_book_name.mock_calls == [call(1, books), call(1, books)]
importer.get_book.assert_called_once_with('1. Mosebog')
assert importer.session.commit.call_count == 2
assert importer.create_verse.mock_calls == \
[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. '
# WHEN: Calling process_books
result = importer.process_books(books)
# THEN: translate and find_and_create_book should have been called with both book names.
# The returned data should be a dictionary with both song's id and names.
assert importer.find_and_create_book.mock_calls == \
[call('1. Mosebog', 2, 10), call('2. Mosebog', 2, 10)]
assert result == {1: '1. Mosebog', 2: '2. Mosebog'}
def test_process_verses_stopped_import(registry):
"""
Test process_verses when the import is stopped
"""
# GIVEN: An instance of CSVBible with the stop_import_flag set to True
mocked_manager = MagicMock()
with patch('openlp.plugins.bibles.lib.db.BibleDB._setup'):
importer = CSVBible(mocked_manager, path='.', name='.', books_path=Path('books.csv'),
verse_path=Path('verse.csv'))
importer.get_book_name = MagicMock()
importer.session = MagicMock()
importer.stop_import_flag = True
importer.wizard = MagicMock()
# WHEN: Calling process_verses
result = importer.process_verses(['Dummy Verse'], [])
# THEN: get_book_name should not be called and the return value should be None
assert importer.get_book_name.called is False
assert result is None
def test_process_verses_successful(registry):
"""
Test process_verses when the import is successful
"""
# GIVEN: An instance of CSVBible with the application and wizard attributes mocked out, and some test data.
mocked_manager = MagicMock()
with patch('openlp.plugins.bibles.lib.db.BibleDB._setup'),\
patch('openlp.plugins.bibles.lib.importers.csvbible.translate'):
importer = CSVBible(mocked_manager, path='.', name='.', books_path=Path('books.csv'),
verse_path=Path('verse.csv'))
importer.create_verse = MagicMock()
importer.get_book = MagicMock(return_value=Book('1', '1', '1. Mosebog', '1Mos'))
importer.get_book_name = MagicMock(return_value='1. Mosebog')
importer.session = MagicMock()
importer.stop_import_flag = False
importer.wizard = MagicMock()
verses = [Verse(1, 1, 1, 'I Begyndelsen skabte Gud Himmelen og Jorden.'),
Verse(1, 1, 2, 'Og Jorden var øde og tom, og der var Mørke over Verdensdybet. '
'Men Guds Ånd svævede over Vandene.')]
books = {1: '1. Mosebog'}
def test_do_import_invalid_language_id(self):
"""
Test do_import when the user cancels the language selection dialog box
"""
# GIVEN: An instance of CSVBible and a mocked get_language which simulates the user cancelling the language box
# WHEN: Calling process_verses
importer.process_verses(verses, books)
# THEN: create_verse is called with the test data
assert importer.get_book_name.mock_calls == [call(1, books), call(1, books)]
importer.get_book.assert_called_once_with('1. Mosebog')
assert importer.session.commit.call_count == 2
assert importer.create_verse.mock_calls == \
[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. '
'Men Guds Ånd svævede over Vandene.')]
def test_do_import_invalid_language_id(registry):
"""
Test do_import when the user cancels the language selection dialog box
"""
# GIVEN: An instance of CSVBible and a mocked get_language which simulates the user cancelling the language box
mocked_manager = MagicMock()
with patch('openlp.plugins.bibles.lib.db.BibleDB._setup'):
importer = CSVBible(mocked_manager, path='.', name='.', books_path=Path('books.csv'),
verse_path=Path('verse.csv'))
importer.get_language = MagicMock(return_value=None)
# WHEN: Calling do_import
result = importer.do_import('Bible Name')
# THEN: The False should be returned.
importer.get_language.assert_called_once_with('Bible Name')
assert result is False
def test_do_import_success(registry):
"""
Test do_import when the import succeeds
"""
# GIVEN: An instance of CSVBible
mocked_manager = MagicMock()
with patch('openlp.plugins.bibles.lib.db.BibleDB._setup'):
importer = CSVBible(mocked_manager, path='.', name='.', books_path=Path('books.csv'),
verse_path=Path('verses.csv'))
importer.get_language = MagicMock(return_value=10)
importer.parse_csv_file = MagicMock(side_effect=[['Book 1'], ['Verse 1']])
importer.process_books = MagicMock(return_value=['Book 1'])
importer.process_verses = MagicMock(return_value=['Verse 1'])
importer.session = MagicMock()
importer.stop_import_flag = False
importer.wizard = MagicMock()
# WHEN: Calling do_import
result = importer.do_import('Bible Name')
# THEN: parse_csv_file should be called twice,
# and True should be returned.
assert importer.parse_csv_file.mock_calls == \
[call(Path('books.csv'), Book), call(Path('verses.csv'), Verse)]
importer.process_books.assert_called_once_with(['Book 1'])
importer.process_verses.assert_called_once_with(['Verse 1'], ['Book 1'])
assert result is True
def test_file_import(settings):
"""
Test the actual import of CSV Bible file
"""
# 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.
test_data = load_external_result_data(TEST_PATH / 'dk1933.json')
books_file = TEST_PATH / 'dk1933-books.csv'
verses_file = TEST_PATH / 'dk1933-verses.csv'
with patch('openlp.plugins.bibles.lib.importers.csvbible.CSVBible.application'):
mocked_manager = MagicMock()
with patch('openlp.plugins.bibles.lib.db.BibleDB._setup'):
importer = CSVBible(mocked_manager, path='.', name='.', books_path=Path('books.csv'),
verse_path=Path('verse.csv'))
importer.get_language = MagicMock(return_value=None)
mocked_import_wizard = MagicMock()
importer = CSVBible(mocked_manager, path='.', name='.', books_path=books_file, verse_path=verses_file)
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'
importer.get_book = MagicMock()
# WHEN: Calling do_import
result = importer.do_import('Bible Name')
# WHEN: Importing bible file
importer.do_import()
# THEN: The False should be returned.
importer.get_language.assert_called_once_with('Bible Name')
assert result is False
def test_do_import_success(self):
"""
Test do_import when the import succeeds
"""
# GIVEN: An instance of CSVBible
mocked_manager = MagicMock()
with patch('openlp.plugins.bibles.lib.db.BibleDB._setup'):
importer = CSVBible(mocked_manager, path='.', name='.', books_path=Path('books.csv'),
verse_path=Path('verses.csv'))
importer.get_language = MagicMock(return_value=10)
importer.parse_csv_file = MagicMock(side_effect=[['Book 1'], ['Verse 1']])
importer.process_books = MagicMock(return_value=['Book 1'])
importer.process_verses = MagicMock(return_value=['Verse 1'])
importer.session = MagicMock()
importer.stop_import_flag = False
importer.wizard = MagicMock()
# WHEN: Calling do_import
result = importer.do_import('Bible Name')
# THEN: parse_csv_file should be called twice,
# and True should be returned.
assert importer.parse_csv_file.mock_calls == \
[call(Path('books.csv'), Book), call(Path('verses.csv'), Verse)]
importer.process_books.assert_called_once_with(['Book 1'])
importer.process_verses.assert_called_once_with(['Verse 1'], ['Book 1'])
assert result is True
def test_file_import(self):
"""
Test the actual import of CSV Bible file
"""
# 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.
test_data = load_external_result_data(TEST_PATH / 'dk1933.json')
books_file = TEST_PATH / 'dk1933-books.csv'
verses_file = TEST_PATH / 'dk1933-verses.csv'
with patch('openlp.plugins.bibles.lib.importers.csvbible.CSVBible.application'):
mocked_manager = MagicMock()
mocked_import_wizard = MagicMock()
importer = CSVBible(mocked_manager, path='.', name='.', books_path=books_file, verse_path=verses_file)
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'
importer.get_book = MagicMock()
# WHEN: Importing bible file
importer.do_import()
# THEN: The create_verse() method should have been called with each verse in the file.
assert importer.create_verse.called is True
for verse_tag, verse_text in test_data['verses']:
importer.create_verse.assert_any_call(importer.get_book().id, 1, verse_tag, verse_text)
importer.create_book.assert_any_call('1. Mosebog', importer.get_book_ref_id_by_name(), 1)
importer.create_book.assert_any_call('1. Krønikebog', importer.get_book_ref_id_by_name(), 1)
# THEN: The create_verse() method should have been called with each verse in the file.
assert importer.create_verse.called is True
for verse_tag, verse_text in test_data['verses']:
importer.create_verse.assert_any_call(importer.get_book().id, 1, verse_tag, verse_text)
importer.create_book.assert_any_call('1. Mosebog', importer.get_book_ref_id_by_name(), 1)
importer.create_book.assert_any_call('1. Krønikebog', importer.get_book_ref_id_by_name(), 1)

View File

@ -21,12 +21,3 @@
"""
This module contains tests for the db submodule of the Bibles plugin.
"""
from unittest import TestCase
class TestBibleDB(TestCase):
"""
Test the functions in the BibleDB class.
"""
pass

View File

@ -22,45 +22,31 @@
This module contains tests for the manager submodule of the Bibles plugin.
"""
from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, patch
from openlp.plugins.bibles.lib.manager import BibleManager
class TestManager(TestCase):
def test_delete_bible(settings):
"""
Test the functions in the :mod:`manager` module.
Test the BibleManager delete_bible method
"""
# GIVEN: An instance of BibleManager and a mocked bible
with patch.object(BibleManager, 'reload_bibles'), \
patch('openlp.plugins.bibles.lib.manager.delete_file', return_value=True) as mocked_delete_file:
instance = BibleManager(MagicMock())
# We need to keep a reference to the mock for close_all as it gets set to None later on!
mocked_close_all = MagicMock()
mocked_bible = MagicMock(file_path='KJV.sqlite', path=Path('bibles'),
**{'session.close_all': mocked_close_all})
instance.db_cache = {'KJV': mocked_bible}
def setUp(self):
app_location_patcher = patch('openlp.plugins.bibles.lib.manager.AppLocation')
self.addCleanup(app_location_patcher.stop)
app_location_patcher.start()
log_patcher = patch('openlp.plugins.bibles.lib.manager.log')
self.addCleanup(log_patcher.stop)
self.mocked_log = log_patcher.start()
# WHEN: Calling delete_bible with 'KJV'
result = instance.delete_bible('KJV')
def test_delete_bible(self):
"""
Test the BibleManager delete_bible method
"""
# GIVEN: An instance of BibleManager and a mocked bible
with patch.object(BibleManager, 'reload_bibles'), \
patch('openlp.plugins.bibles.lib.manager.delete_file', return_value=True) as mocked_delete_file:
instance = BibleManager(MagicMock())
# We need to keep a reference to the mock for close_all as it gets set to None later on!
mocked_close_all = MagicMock()
mocked_bible = MagicMock(file_path='KJV.sqlite', path=Path('bibles'),
**{'session.close_all': mocked_close_all})
instance.db_cache = {'KJV': mocked_bible}
# WHEN: Calling delete_bible with 'KJV'
result = instance.delete_bible('KJV')
# THEN: The session should have been closed and set to None, the bible should be deleted, and the result of
# the deletion returned.
assert result is True
mocked_close_all.assert_called_once_with()
assert mocked_bible.session is None
mocked_delete_file.assert_called_once_with(Path('bibles') / 'KJV.sqlite')
# THEN: The session should have been closed and set to None, the bible should be deleted, and the result of
# the deletion returned.
assert result is True
mocked_close_all.assert_called_once_with()
assert mocked_bible.session is None
mocked_delete_file.assert_called_once_with(Path('bibles') / 'KJV.sqlite')

File diff suppressed because it is too large Load Diff

View File

@ -21,15 +21,13 @@
"""
This module contains tests for the OpenSong Bible importer.
"""
from unittest import TestCase
import pytest
from unittest.mock import MagicMock, call, patch
from lxml import objectify
from openlp.core.common.registry import Registry
from openlp.plugins.bibles.lib.bibleimport import BibleImport
from openlp.plugins.bibles.lib.importers.opensong import OpenSongBible, get_text, parse_chapter_number
from tests.helpers.testmixin import TestMixin
from tests.utils import load_external_result_data
from tests.utils.constants import RESOURCE_PATH
@ -37,383 +35,389 @@ from tests.utils.constants import RESOURCE_PATH
TEST_PATH = RESOURCE_PATH / 'bibles'
class TestOpenSongImport(TestCase, TestMixin):
@pytest.yield_fixture
def manager():
db_man = patch('openlp.plugins.bibles.lib.db.Manager')
yield db_man.start()
db_man.stop()
@pytest.yield_fixture()
def mocked_find_and_create_book():
facb = patch.object(BibleImport, 'find_and_create_book')
yield facb.start()
facb.stop()
def test_create_importer(manager, mock_settings):
"""
Test the functions in the :mod:`opensongimport` module.
Test creating an instance of the OpenSong file importer
"""
# GIVEN: A mocked out "manager"
mocked_manager = MagicMock()
def setUp(self):
self.find_and_create_book_patch = patch.object(BibleImport, 'find_and_create_book')
self.addCleanup(self.find_and_create_book_patch.stop)
self.mocked_find_and_create_book = self.find_and_create_book_patch.start()
self.manager_patcher = patch('openlp.plugins.bibles.lib.db.Manager')
self.addCleanup(self.manager_patcher.stop)
self.manager_patcher.start()
self.setup_application()
self.app.process_events = MagicMock()
Registry.create()
Registry().register('application', self.app)
# WHEN: An importer object is created
importer = OpenSongBible(mocked_manager, path='.', name='.', file_path=None)
def test_create_importer(self):
"""
Test creating an instance of the OpenSong file importer
"""
# GIVEN: A mocked out "manager"
mocked_manager = MagicMock()
# THEN: The importer should be an instance of BibleDB
assert isinstance(importer, BibleImport)
# WHEN: An importer object is created
importer = OpenSongBible(mocked_manager, path='.', name='.', file_path=None)
# THEN: The importer should be an instance of BibleDB
assert isinstance(importer, BibleImport)
def test_get_text_no_text(manager, mock_settings):
"""
Test that get_text handles elements containing text in a combination of text and tail attributes
"""
# GIVEN: Some test data which contains an empty element and an instance of OpenSongBible
test_data = objectify.fromstring('<element></element>')
def test_get_text_no_text(self):
"""
Test that get_text handles elements containing text in a combination of text and tail attributes
"""
# GIVEN: Some test data which contains an empty element and an instance of OpenSongBible
test_data = objectify.fromstring('<element></element>')
# WHEN: Calling get_text
result = get_text(test_data)
# WHEN: Calling get_text
result = get_text(test_data)
# THEN: A blank string should be returned
assert result == ''
# THEN: A blank string should be returned
assert result == ''
def test_get_text_text(self):
"""
Test that get_text handles elements containing text in a combination of text and tail attributes
"""
# GIVEN: Some test data which contains all possible permutation of text and tail text possible and an instance
# of OpenSongBible
test_data = objectify.fromstring('<element>Element text '
'<sub_text_tail>sub_text_tail text </sub_text_tail>sub_text_tail tail '
'<sub_text>sub_text text </sub_text>'
'<sub_tail></sub_tail>sub_tail tail</element>')
def test_get_text_text(manager, mock_settings):
"""
Test that get_text handles elements containing text in a combination of text and tail attributes
"""
# GIVEN: Some test data which contains all possible permutation of text and tail text possible and an instance
# of OpenSongBible
test_data = objectify.fromstring('<element>Element text '
'<sub_text_tail>sub_text_tail text </sub_text_tail>sub_text_tail tail '
'<sub_text>sub_text text </sub_text>'
'<sub_tail></sub_tail>sub_tail tail</element>')
# WHEN: Calling get_text
result = get_text(test_data)
# WHEN: Calling get_text
result = get_text(test_data)
# THEN: The text returned should be as expected
assert result == 'Element text sub_text_tail text sub_text_tail tail sub_text text sub_tail tail'
# THEN: The text returned should be as expected
assert result == 'Element text sub_text_tail text sub_text_tail tail sub_text text sub_tail tail'
def test_parse_chapter_number(self):
"""
Test parse_chapter_number when supplied with chapter number and an instance of OpenSongBible
"""
# GIVEN: The number 10 represented as a string
# WHEN: Calling parse_chapter_nnumber
result = parse_chapter_number('10', 0)
# THEN: The 10 should be returned as an Int
assert result == 10
def test_parse_chapter_number(manager, mock_settings):
"""
Test parse_chapter_number when supplied with chapter number and an instance of OpenSongBible
"""
# GIVEN: The number 10 represented as a string
# WHEN: Calling parse_chapter_nnumber
result = parse_chapter_number('10', 0)
def test_parse_chapter_number_empty_attribute(self):
"""
Testparse_chapter_number when the chapter number is an empty string. (Bug #1074727)
"""
# GIVEN: An empty string, and the previous chapter number set as 12 and an instance of OpenSongBible
# WHEN: Calling parse_chapter_number
result = parse_chapter_number('', 12)
# THEN: The 10 should be returned as an Int
assert result == 10
# THEN: parse_chapter_number should increment the previous verse number
def test_parse_chapter_number_empty_attribute(manager, mock_settings):
"""
Testparse_chapter_number when the chapter number is an empty string. (Bug #1074727)
"""
# GIVEN: An empty string, and the previous chapter number set as 12 and an instance of OpenSongBible
# WHEN: Calling parse_chapter_number
result = parse_chapter_number('', 12)
# THEN: parse_chapter_number should increment the previous verse number
assert result == 13
def test_parse_verse_number_valid_verse_no(manager, mock_settings):
"""
Test parse_verse_number when supplied with a valid verse number
"""
# GIVEN: An instance of OpenSongBible, the number 15 represented as a string and an instance of OpenSongBible
importer = OpenSongBible(MagicMock(), path='.', name='.', file_path=None)
# WHEN: Calling parse_verse_number
result = importer.parse_verse_number('15', 0)
# THEN: parse_verse_number should return the verse number
assert result == 15
def test_parse_verse_number_verse_range(manager, mock_settings):
"""
Test parse_verse_number when supplied with a verse range
"""
# GIVEN: An instance of OpenSongBible, and the range 24-26 represented as a string
importer = OpenSongBible(MagicMock(), path='.', name='.', file_path=None)
# WHEN: Calling parse_verse_number
result = importer.parse_verse_number('24-26', 0)
# THEN: parse_verse_number should return the first verse number in the range
assert result == 24
def test_parse_verse_number_invalid_verse_no(manager, mock_settings):
"""
Test parse_verse_number when supplied with a invalid verse number
"""
# GIVEN: An instance of OpenSongBible, a non numeric string represented as a string
importer = OpenSongBible(MagicMock(), path='.', name='.', file_path=None)
# WHEN: Calling parse_verse_number
result = importer.parse_verse_number('invalid', 41)
# THEN: parse_verse_number should increment the previous verse number
assert result == 42
def test_parse_verse_number_empty_attribute(manager, mock_settings):
"""
Test parse_verse_number when the verse number is an empty string. (Bug #1074727)
"""
# GIVEN: An instance of OpenSongBible, an empty string, and the previous verse number set as 14
importer = OpenSongBible(MagicMock(), path='.', name='.', file_path=None)
# WHEN: Calling parse_verse_number
result = importer.parse_verse_number('', 14)
# THEN: parse_verse_number should increment the previous verse number
assert result == 15
def test_parse_verse_number_invalid_type(manager, mock_settings):
"""
Test parse_verse_number when the verse number is an invalid type)
"""
with patch.object(OpenSongBible, 'log_warning')as mocked_log_warning:
# GIVEN: An instance of OpenSongBible, a Tuple, and the previous verse number set as 12
importer = OpenSongBible(MagicMock(), path='.', name='.', file_path=None)
# WHEN: Calling parse_verse_number
result = importer.parse_verse_number((1, 2, 3), 12)
# THEN: parse_verse_number should log the verse number it was called with increment the previous verse
# number
mocked_log_warning.assert_called_once_with('Illegal verse number: (1, 2, 3)')
assert result == 13
def test_parse_verse_number_valid_verse_no(self):
"""
Test parse_verse_number when supplied with a valid verse number
"""
# GIVEN: An instance of OpenSongBible, the number 15 represented as a string and an instance of OpenSongBible
def test_process_books_stop_import(manager, mocked_find_and_create_book, mock_settings):
"""
Test process_books when stop_import is set to True
"""
# GIVEN: An instance of OpenSongBible
importer = OpenSongBible(MagicMock(), path='.', name='.', file_path=None)
# WHEN: stop_import_flag is set to True
importer.stop_import_flag = True
importer.process_books(['Book'])
# THEN: find_and_create_book should not have been called
assert mocked_find_and_create_book.called is False
def test_process_books_completes(manager, mocked_find_and_create_book, mock_settings):
"""
Test process_books when it processes all books
"""
# GIVEN: An instance of OpenSongBible Importer and two mocked books
mocked_find_and_create_book.side_effect = ['db_book1', 'db_book2']
with patch.object(OpenSongBible, 'process_chapters') as mocked_process_chapters:
importer = OpenSongBible(MagicMock(), path='.', name='.', file_path=None)
# WHEN: Calling parse_verse_number
result = importer.parse_verse_number('15', 0)
book1 = MagicMock()
book1.attrib = {'n': 'Name1'}
book1.c = 'Chapter1'
book2 = MagicMock()
book2.attrib = {'n': 'Name2'}
book2.c = 'Chapter2'
importer.language_id = 10
importer.session = MagicMock()
importer.stop_import_flag = False
# THEN: parse_verse_number should return the verse number
assert result == 15
# WHEN: Calling process_books with the two books
importer.process_books([book1, book2])
def test_parse_verse_number_verse_range(self):
"""
Test parse_verse_number when supplied with a verse range
"""
# GIVEN: An instance of OpenSongBible, and the range 24-26 represented as a string
importer = OpenSongBible(MagicMock(), path='.', name='.', file_path=None)
# THEN: find_and_create_book and process_books should be called with the details from the mocked books
assert mocked_find_and_create_book.call_args_list == [call('Name1', 2, 10), call('Name2', 2, 10)]
assert mocked_process_chapters.call_args_list == \
[call('db_book1', 'Chapter1'), call('db_book2', 'Chapter2')]
assert importer.session.commit.call_count == 2
# WHEN: Calling parse_verse_number
result = importer.parse_verse_number('24-26', 0)
# THEN: parse_verse_number should return the first verse number in the range
assert result == 24
def test_process_chapters_stop_import(manager, mock_settings):
"""
Test process_chapters when stop_import is set to True
"""
# GIVEN: An isntance of OpenSongBible
importer = OpenSongBible(MagicMock(), path='.', name='.', file_path=None)
importer.parse_chapter_number = MagicMock()
def test_parse_verse_number_invalid_verse_no(self):
"""
Test parse_verse_number when supplied with a invalid verse number
"""
# GIVEN: An instance of OpenSongBible, a non numeric string represented as a string
importer = OpenSongBible(MagicMock(), path='.', name='.', file_path=None)
# WHEN: stop_import_flag is set to True
importer.stop_import_flag = True
importer.process_chapters('Book', ['Chapter1'])
# WHEN: Calling parse_verse_number
result = importer.parse_verse_number('invalid', 41)
# THEN: importer.parse_chapter_number not have been called
assert importer.parse_chapter_number.called is False
# THEN: parse_verse_number should increment the previous verse number
assert result == 42
def test_parse_verse_number_empty_attribute(self):
"""
Test parse_verse_number when the verse number is an empty string. (Bug #1074727)
"""
# GIVEN: An instance of OpenSongBible, an empty string, and the previous verse number set as 14
importer = OpenSongBible(MagicMock(), path='.', name='.', file_path=None)
# WHEN: Calling parse_verse_number
result = importer.parse_verse_number('', 14)
@patch('openlp.plugins.bibles.lib.importers.opensong.parse_chapter_number', **{'side_effect': [1, 2]})
def test_process_chapters_completes(mocked_parse_chapter_number, manager, mock_settings):
"""
Test process_chapters when it completes
"""
# GIVEN: An instance of OpenSongBible
importer = OpenSongBible(MagicMock(), path='.', name='.', file_path=None)
importer.wizard = MagicMock()
# THEN: parse_verse_number should increment the previous verse number
assert result == 15
# WHEN: called with some valid data
book = MagicMock()
book.name = "Book"
chapter1 = MagicMock()
chapter1.attrib = {'n': '1'}
chapter1.c = 'Chapter1'
chapter1.v = ['Chapter1 Verses']
chapter2 = MagicMock()
chapter2.attrib = {'n': '2'}
chapter2.c = 'Chapter2'
chapter2.v = ['Chapter2 Verses']
def test_parse_verse_number_invalid_type(self):
"""
Test parse_verse_number when the verse number is an invalid type)
"""
with patch.object(OpenSongBible, 'log_warning')as mocked_log_warning:
# GIVEN: An instanceofOpenSongBible, a Tuple, and the previous verse number set as 12
importer = OpenSongBible(MagicMock(), path='.', name='.', file_path=None)
importer.process_verses = MagicMock()
importer.stop_import_flag = False
importer.process_chapters(book, [chapter1, chapter2])
# WHEN: Calling parse_verse_number
result = importer.parse_verse_number((1, 2, 3), 12)
# THEN: parse_chapter_number, process_verses and increment_process_bar should have been called
assert mocked_parse_chapter_number.call_args_list == [call('1', 0), call('2', 1)]
assert importer.process_verses.call_args_list == \
[call(book, 1, ['Chapter1 Verses']), call(book, 2, ['Chapter2 Verses'])]
assert importer.wizard.increment_progress_bar.call_args_list == [call('Importing Book 1...'),
call('Importing Book 2...')]
# THEN: parse_verse_number should log the verse number it was called with increment the previous verse
# number
mocked_log_warning.assert_called_once_with('Illegal verse number: (1, 2, 3)')
assert result == 13
def test_process_books_stop_import(self):
"""
Test process_books when stop_import is set to True
"""
# GIVEN: An instance of OpenSongBible
importer = OpenSongBible(MagicMock(), path='.', name='.', file_path=None)
def test_process_verses_stop_import(manager, mock_settings):
"""
Test process_verses when stop_import is set to True
"""
# GIVEN: An isntance of OpenSongBible
importer = OpenSongBible(MagicMock(), path='.', name='.', file_path=None)
importer.parse_verse_number = MagicMock()
# WHEN: stop_import_flag is set to True
importer.stop_import_flag = True
importer.process_books(['Book'])
# WHEN: stop_import_flag is set to True
importer.stop_import_flag = True
importer.process_verses('Book', 1, 'Verses')
# THEN: find_and_create_book should not have been called
assert self.mocked_find_and_create_book.called is False
# THEN: importer.parse_verse_number not have been called
assert importer.parse_verse_number.called is False
def test_process_books_completes(self):
"""
Test process_books when it processes all books
"""
# GIVEN: An instance of OpenSongBible Importer and two mocked books
self.mocked_find_and_create_book.side_effect = ['db_book1', 'db_book2']
with patch.object(OpenSongBible, 'process_chapters') as mocked_process_chapters:
importer = OpenSongBible(MagicMock(), path='.', name='.', file_path=None)
book1 = MagicMock()
book1.attrib = {'n': 'Name1'}
book1.c = 'Chapter1'
book2 = MagicMock()
book2.attrib = {'n': 'Name2'}
book2.c = 'Chapter2'
importer.language_id = 10
importer.session = MagicMock()
importer.stop_import_flag = False
# WHEN: Calling process_books with the two books
importer.process_books([book1, book2])
# THEN: find_and_create_book and process_books should be called with the details from the mocked books
assert self.mocked_find_and_create_book.call_args_list == [call('Name1', 2, 10), call('Name2', 2, 10)]
assert mocked_process_chapters.call_args_list == \
[call('db_book1', 'Chapter1'), call('db_book2', 'Chapter2')]
assert importer.session.commit.call_count == 2
def test_process_chapters_stop_import(self):
"""
Test process_chapters when stop_import is set to True
"""
# GIVEN: An isntance of OpenSongBible
importer = OpenSongBible(MagicMock(), path='.', name='.', file_path=None)
importer.parse_chapter_number = MagicMock()
# WHEN: stop_import_flag is set to True
importer.stop_import_flag = True
importer.process_chapters('Book', ['Chapter1'])
# THEN: importer.parse_chapter_number not have been called
assert importer.parse_chapter_number.called is False
@patch('openlp.plugins.bibles.lib.importers.opensong.parse_chapter_number', **{'side_effect': [1, 2]})
def test_process_chapters_completes(self, mocked_parse_chapter_number):
"""
Test process_chapters when it completes
"""
def test_process_verses_completes(manager, mock_settings):
"""
Test process_verses when it completes
"""
with patch('openlp.plugins.bibles.lib.importers.opensong.get_text',
**{'side_effect': ['Verse1 Text', 'Verse2 Text']}) as mocked_get_text, \
patch.object(OpenSongBible, 'parse_verse_number',
**{'side_effect': [1, 2]}) as mocked_parse_verse_number:
# GIVEN: An instance of OpenSongBible
importer = OpenSongBible(MagicMock(), path='.', name='.', file_path=None)
importer.wizard = MagicMock()
# WHEN: called with some valid data
book = MagicMock()
book.name = "Book"
chapter1 = MagicMock()
chapter1.attrib = {'n': '1'}
chapter1.c = 'Chapter1'
chapter1.v = ['Chapter1 Verses']
chapter2 = MagicMock()
chapter2.attrib = {'n': '2'}
chapter2.c = 'Chapter2'
chapter2.v = ['Chapter2 Verses']
book.id = 1
verse1 = MagicMock()
verse1.attrib = {'n': '1'}
verse1.c = 'Chapter1'
verse1.v = ['Chapter1 Verses']
verse2 = MagicMock()
verse2.attrib = {'n': '2'}
verse2.c = 'Chapter2'
verse2.v = ['Chapter2 Verses']
importer.process_verses = MagicMock()
importer.create_verse = MagicMock()
importer.stop_import_flag = False
importer.process_chapters(book, [chapter1, chapter2])
importer.process_verses(book, 1, [verse1, verse2])
# THEN: parse_chapter_number, process_verses and increment_process_bar should have been called
assert mocked_parse_chapter_number.call_args_list == [call('1', 0), call('2', 1)]
assert importer.process_verses.call_args_list == \
[call(book, 1, ['Chapter1 Verses']), call(book, 2, ['Chapter2 Verses'])]
assert importer.wizard.increment_progress_bar.call_args_list == [call('Importing Book 1...'),
call('Importing Book 2...')]
assert mocked_parse_verse_number.call_args_list == [call('1', 0), call('2', 1)]
assert mocked_get_text.call_args_list == [call(verse1), call(verse2)]
assert importer.create_verse.call_args_list == \
[call(1, 1, 1, 'Verse1 Text'), call(1, 1, 2, 'Verse2 Text')]
def test_process_verses_stop_import(self):
"""
Test process_verses when stop_import is set to True
"""
# GIVEN: An isntance of OpenSongBible
def test_do_import_parse_xml_fails(manager, mock_settings):
"""
Test do_import when parse_xml fails (returns None)
"""
# GIVEN: An instance of OpenSongBible and a mocked parse_xml which returns False
with patch.object(OpenSongBible, 'log_debug'), \
patch.object(OpenSongBible, 'validate_xml_file'), \
patch.object(OpenSongBible, 'parse_xml', return_value=None), \
patch.object(OpenSongBible, 'get_language_id') as mocked_language_id:
importer = OpenSongBible(MagicMock(), path='.', name='.', file_path=None)
importer.parse_verse_number = MagicMock()
# WHEN: stop_import_flag is set to True
importer.stop_import_flag = True
importer.process_verses('Book', 1, 'Verses')
# WHEN: Calling do_import
result = importer.do_import()
# THEN: importer.parse_verse_number not have been called
assert importer.parse_verse_number.called is False
def test_process_verses_completes(self):
"""
Test process_verses when it completes
"""
with patch('openlp.plugins.bibles.lib.importers.opensong.get_text',
**{'side_effect': ['Verse1 Text', 'Verse2 Text']}) as mocked_get_text, \
patch.object(OpenSongBible, 'parse_verse_number',
**{'side_effect': [1, 2]}) as mocked_parse_verse_number:
# GIVEN: An instance of OpenSongBible
importer = OpenSongBible(MagicMock(), path='.', name='.', file_path=None)
importer.wizard = MagicMock()
# WHEN: called with some valid data
book = MagicMock()
book.id = 1
verse1 = MagicMock()
verse1.attrib = {'n': '1'}
verse1.c = 'Chapter1'
verse1.v = ['Chapter1 Verses']
verse2 = MagicMock()
verse2.attrib = {'n': '2'}
verse2.c = 'Chapter2'
verse2.v = ['Chapter2 Verses']
importer.create_verse = MagicMock()
importer.stop_import_flag = False
importer.process_verses(book, 1, [verse1, verse2])
# THEN: parse_chapter_number, process_verses and increment_process_bar should have been called
assert mocked_parse_verse_number.call_args_list == [call('1', 0), call('2', 1)]
assert mocked_get_text.call_args_list == [call(verse1), call(verse2)]
assert importer.create_verse.call_args_list == \
[call(1, 1, 1, 'Verse1 Text'), call(1, 1, 2, 'Verse2 Text')]
def test_do_import_parse_xml_fails(self):
"""
Test do_import when parse_xml fails (returns None)
"""
# GIVEN: An instance of OpenSongBible and a mocked parse_xml which returns False
with patch.object(OpenSongBible, 'log_debug'), \
patch.object(OpenSongBible, 'validate_xml_file'), \
patch.object(OpenSongBible, 'parse_xml', return_value=None), \
patch.object(OpenSongBible, 'get_language_id') as mocked_language_id:
importer = OpenSongBible(MagicMock(), path='.', name='.', file_path=None)
# WHEN: Calling do_import
result = importer.do_import()
# THEN: do_import should return False and get_language_id should have not been called
assert result is False
assert mocked_language_id.called is False
def test_do_import_no_language(self):
"""
Test do_import when the user cancels the language selection dialog
"""
# GIVEN: An instance of OpenSongBible and a mocked get_language which returns False
with patch.object(OpenSongBible, 'log_debug'), \
patch.object(OpenSongBible, 'validate_xml_file'), \
patch.object(OpenSongBible, 'parse_xml'), \
patch.object(OpenSongBible, 'get_language_id', return_value=False), \
patch.object(OpenSongBible, 'process_books') as mocked_process_books:
importer = OpenSongBible(MagicMock(), path='.', name='.', file_path=None)
# WHEN: Calling do_import
result = importer.do_import()
# THEN: do_import should return False and process_books should have not been called
assert result is False
assert mocked_process_books.called is False
def test_do_import_completes(self):
"""
Test do_import when it completes successfully
"""
# GIVEN: An instance of OpenSongBible
with patch.object(OpenSongBible, 'log_debug'), \
patch.object(OpenSongBible, 'validate_xml_file'), \
patch.object(OpenSongBible, 'parse_xml'), \
patch.object(OpenSongBible, 'get_language_id', return_value=10), \
patch.object(OpenSongBible, 'process_books'):
importer = OpenSongBible(MagicMock(), path='.', name='.', file_path=None)
# WHEN: Calling do_import
result = importer.do_import()
# THEN: do_import should return True
assert result is True
# THEN: do_import should return False and get_language_id should have not been called
assert result is False
assert mocked_language_id.called is False
class TestOpenSongImportFileImports(TestCase, TestMixin):
def test_do_import_no_language(manager, mock_settings):
"""
Test the functions in the :mod:`opensongimport` module.
Test do_import when the user cancels the language selection dialog
"""
def setUp(self):
self.manager_patcher = patch('openlp.plugins.bibles.lib.db.Manager')
self.addCleanup(self.manager_patcher.stop)
self.manager_patcher.start()
# GIVEN: An instance of OpenSongBible and a mocked get_language which returns False
with patch.object(OpenSongBible, 'log_debug'), \
patch.object(OpenSongBible, 'validate_xml_file'), \
patch.object(OpenSongBible, 'parse_xml'), \
patch.object(OpenSongBible, 'get_language_id', return_value=False), \
patch.object(OpenSongBible, 'process_books') as mocked_process_books:
importer = OpenSongBible(MagicMock(), path='.', name='.', file_path=None)
def test_file_import(self):
"""
Test the actual import of OpenSong Bible file
"""
# 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.
test_data = load_external_result_data(TEST_PATH / 'dk1933.json')
bible_file = 'opensong-dk1933.xml'
with patch('openlp.plugins.bibles.lib.importers.opensong.OpenSongBible.application'):
mocked_manager = MagicMock()
mocked_import_wizard = MagicMock()
importer = OpenSongBible(mocked_manager, path='.', name='.', file_path=None)
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: Calling do_import
result = importer.do_import()
# WHEN: Importing bible file
importer.file_path = TEST_PATH / bible_file
importer.do_import()
# THEN: do_import should return False and process_books should have not been called
assert result is False
assert mocked_process_books.called is False
# THEN: The create_verse() method should have been called with each verse in the file.
assert importer.create_verse.called is True
for verse_tag, verse_text in test_data['verses']:
importer.create_verse.assert_any_call(importer.create_book().id, 1, int(verse_tag), verse_text)
def test_do_import_completes(manager, mock_settings):
"""
Test do_import when it completes successfully
"""
# GIVEN: An instance of OpenSongBible
with patch.object(OpenSongBible, 'log_debug'), \
patch.object(OpenSongBible, 'validate_xml_file'), \
patch.object(OpenSongBible, 'parse_xml'), \
patch.object(OpenSongBible, 'get_language_id', return_value=10), \
patch.object(OpenSongBible, 'process_books'):
importer = OpenSongBible(MagicMock(), path='.', name='.', file_path=None)
# WHEN: Calling do_import
result = importer.do_import()
# THEN: do_import should return True
assert result is True
def test_file_import(manager, mock_settings):
"""
Test the actual import of OpenSong Bible file
"""
# 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.
test_data = load_external_result_data(TEST_PATH / 'dk1933.json')
bible_file = 'opensong-dk1933.xml'
with patch('openlp.plugins.bibles.lib.importers.opensong.OpenSongBible.application'):
mocked_manager = MagicMock()
mocked_import_wizard = MagicMock()
importer = OpenSongBible(mocked_manager, path='.', name='.', file_path=None)
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.file_path = TEST_PATH / bible_file
importer.do_import()
# THEN: The create_verse() method should have been called with each verse in the file.
assert importer.create_verse.called is True
for verse_tag, verse_text in test_data['verses']:
importer.create_verse.assert_any_call(importer.create_book().id, 1, int(verse_tag), verse_text)

View File

@ -21,7 +21,7 @@
"""
This module contains tests for the SWORD Bible importer.
"""
from unittest import TestCase, skipUnless
from unittest import skipUnless
from unittest.mock import MagicMock, patch
from openlp.plugins.bibles.lib.db import BibleDB
@ -40,70 +40,56 @@ TEST_PATH = RESOURCE_PATH / 'bibles'
@skipUnless(HAS_PYSWORD, 'pysword not installed')
class TestSwordImport(TestCase):
def test_create_importer(settings):
"""
Test the functions in the :mod:`swordimport` module.
Test creating an instance of the Sword file importer
"""
# GIVEN: A mocked out "manager"
mocked_manager = MagicMock()
def setUp(self):
self.registry_patcher = patch('openlp.plugins.bibles.lib.bibleimport.Registry')
self.registry_patcher.start()
self.manager_patcher = patch('openlp.plugins.bibles.lib.db.Manager')
self.manager_patcher.start()
# WHEN: An importer object is created
importer = SwordBible(mocked_manager, path='.', name='.', file_path=None, sword_key='', sword_path='')
def tearDown(self):
self.registry_patcher.stop()
self.manager_patcher.stop()
# THEN: The importer should be an instance of BibleDB
assert isinstance(importer, BibleDB)
def test_create_importer(self):
"""
Test creating an instance of the Sword file importer
"""
# GIVEN: A mocked out "manager"
mocked_manager = MagicMock()
# WHEN: An importer object is created
importer = SwordBible(mocked_manager, path='.', name='.', file_path=None, sword_key='', sword_path='')
@skipUnless(HAS_PYSWORD, 'pysword not installed')
@patch('openlp.plugins.bibles.lib.importers.sword.modules')
def test_simple_import(mocked_pysword_modules, settings):
"""
Test that a simple SWORD import works
"""
# 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.
# Also mocked pysword structures
mocked_manager = MagicMock()
mocked_import_wizard = MagicMock()
importer = SwordBible(mocked_manager, path='.', name='.', file_path=None, sword_key='', sword_path='')
test_data = load_external_result_data(TEST_PATH / 'dk1933.json')
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(return_value='Danish')
mocked_bible = MagicMock()
mocked_genesis = MagicMock()
mocked_genesis.name = 'Genesis'
mocked_genesis.num_chapters = 1
books = {'ot': [mocked_genesis]}
mocked_structure = MagicMock()
mocked_structure.get_books.return_value = books
mocked_bible.get_structure.return_value = mocked_structure
mocked_bible.get_iter.return_value = [verse[1] for verse in test_data['verses']]
mocked_module = MagicMock()
mocked_module.get_bible_from_module.return_value = mocked_bible
mocked_pysword_modules.SwordModules.return_value = mocked_module
# THEN: The importer should be an instance of BibleDB
assert isinstance(importer, BibleDB)
# WHEN: Importing bible file
importer.do_import()
@patch('openlp.plugins.bibles.lib.importers.sword.SwordBible.application')
@patch('openlp.plugins.bibles.lib.importers.sword.modules')
def test_simple_import(self, mocked_pysword_modules, mocked_application):
"""
Test that a simple SWORD import works
"""
# 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.
# Also mocked pysword structures
mocked_manager = MagicMock()
mocked_import_wizard = MagicMock()
importer = SwordBible(mocked_manager, path='.', name='.', file_path=None, sword_key='', sword_path='')
test_data = load_external_result_data(TEST_PATH / 'dk1933.json')
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(return_value='Danish')
mocked_bible = MagicMock()
mocked_genesis = MagicMock()
mocked_genesis.name = 'Genesis'
mocked_genesis.num_chapters = 1
books = {'ot': [mocked_genesis]}
mocked_structure = MagicMock()
mocked_structure.get_books.return_value = books
mocked_bible.get_structure.return_value = mocked_structure
mocked_bible.get_iter.return_value = [verse[1] for verse in test_data['verses']]
mocked_module = MagicMock()
mocked_module.get_bible_from_module.return_value = mocked_bible
mocked_pysword_modules.SwordModules.return_value = mocked_module
# WHEN: Importing bible file
importer.do_import()
# THEN: The create_verse() method should have been called with each verse in the file.
assert importer.create_verse.called is True
for verse_tag, verse_text in test_data['verses']:
importer.create_verse.assert_any_call(importer.create_book().id, 1, int(verse_tag), verse_text)
# THEN: The create_verse() method should have been called with each verse in the file.
assert importer.create_verse.called is True
for verse_tag, verse_text in test_data['verses']:
importer.create_verse.assert_any_call(importer.create_book().id, 1, int(verse_tag), verse_text)

View File

@ -21,198 +21,160 @@
"""
This module contains tests for the upgrade submodule of the Bibles plugin.
"""
import pytest
import shutil
from pathlib import Path
from tempfile import mkdtemp
from unittest import TestCase
from unittest.mock import MagicMock, call, patch
from sqlalchemy import create_engine
from openlp.core.common.registry import Registry
from openlp.core.common.settings import ProxyMode
from openlp.core.lib.db import upgrade_db
from openlp.plugins.bibles.lib import upgrade
from tests.helpers.testmixin import TestMixin
from tests.utils.constants import RESOURCE_PATH
class TestUpgrade(TestCase, TestMixin):
@pytest.yield_fixture()
def mock_message_box():
patched_message_box = patch('openlp.plugins.bibles.lib.upgrade.QtWidgets.QMessageBox')
mocked_message_box = patched_message_box.start()
mocked_no_button = MagicMock()
mocked_http_button = MagicMock()
mocked_both_button = MagicMock()
mocked_https_button = MagicMock()
mocked_message_box_inst = MagicMock(
**{'addButton.side_effect': [mocked_no_button, mocked_http_button,
mocked_both_button, mocked_https_button]})
mocked_message_box.return_value = mocked_message_box_inst
yield mocked_message_box_inst, mocked_both_button, mocked_https_button, mocked_http_button, mocked_no_button
patched_message_box.stop()
@pytest.yield_fixture()
def db_url():
tmp_path = Path(mkdtemp())
db_path = RESOURCE_PATH / 'bibles' / 'web-bible-2.4.6-proxy-meta-v1.sqlite'
db_tmp_path = tmp_path / 'web-bible-2.4.6-proxy-meta-v1.sqlite'
shutil.copyfile(db_path, db_tmp_path)
yield 'sqlite:///' + str(db_tmp_path)
shutil.rmtree(tmp_path, ignore_errors=True)
def test_upgrade_2_basic(mock_message_box, db_url, mock_settings):
"""
Test the `upgrade_2` function in the :mod:`upgrade` module when the db does not contains proxy metadata
Test that upgrade 2 completes properly when the user chooses not to use a proxy ('No')
"""
# GIVEN: An version 1 web bible with proxy settings
mocked_message_box = mock_message_box[0]
# WHEN: Calling upgrade_db and the user has 'clicked' the 'No' button
upgrade_db(db_url, upgrade)
# THEN: The proxy meta data should have been removed, and the version should have been changed to version 2
mocked_message_box.assert_not_called()
engine = create_engine(db_url)
conn = engine.connect()
assert conn.execute('SELECT * FROM metadata WHERE key = "version"').first().value == '2'
def test_upgrade_2_none_selected(mock_message_box, db_url, mock_settings):
"""
Test that upgrade 2 completes properly when the user chooses not to use a proxy ('No')
"""
# GIVEN: An version 1 web bible with proxy settings
# WHEN: Calling upgrade_db and the user has 'clicked' the 'No' button
mocked_message_box_instance = mock_message_box[0]
mocked_no_button = mock_message_box[4]
mocked_message_box_instance.clickedButton.return_value = mocked_no_button
upgrade_db(db_url, upgrade)
# THEN: The proxy meta data should have been removed, and the version should have been changed to version 2
engine = create_engine(db_url)
conn = engine.connect()
assert len(conn.execute('SELECT * FROM metadata WHERE key = "proxy_server"').fetchall()) == 0
assert len(conn.execute('SELECT * FROM metadata WHERE key = "proxy_username"').fetchall()) == 0
assert len(conn.execute('SELECT * FROM metadata WHERE key = "proxy_password"').fetchall()) == 0
assert conn.execute('SELECT * FROM metadata WHERE key = "version"').first().value == '2'
mock_settings.setValue.assert_not_called()
def test_upgrade_2_http_selected(mock_message_box, db_url, mock_settings):
"""
Test that upgrade 2 completes properly when the user chooses to use a HTTP proxy
"""
# GIVEN: An version 1 web bible with proxy settings
# WHEN: Calling upgrade_db and the user has 'clicked' the 'HTTP' button
mocked_message_box_instance = mock_message_box[0]
mocked_http_button = mock_message_box[3]
mocked_message_box_instance.clickedButton.return_value = mocked_http_button
upgrade_db(db_url, upgrade)
# THEN: The proxy meta data should have been removed, the version should have been changed to version 2, and the
# proxy server saved to the settings
engine = create_engine(db_url)
conn = engine.connect()
assert len(conn.execute('SELECT * FROM metadata WHERE key = "proxy_server"').fetchall()) == 0
assert len(conn.execute('SELECT * FROM metadata WHERE key = "proxy_username"').fetchall()) == 0
assert len(conn.execute('SELECT * FROM metadata WHERE key = "proxy_password"').fetchall()) == 0
assert conn.execute('SELECT * FROM metadata WHERE key = "version"').first().value == '2'
assert mock_settings.setValue.call_args_list == [
call('advanced/proxy http', 'proxy_server'), call('advanced/proxy username', 'proxy_username'),
call('advanced/proxy password', 'proxy_password'), call('advanced/proxy mode', ProxyMode.MANUAL_PROXY)]
def test_upgrade_2_https_selected(mock_message_box, db_url, mock_settings):
"""
Tcest that upgrade 2 completes properly when the user chooses to use a HTTPS proxy
"""
# GIVEN: An version 1 web bible with proxy settings
# WHEN: Calling upgrade_db and the user has 'clicked' the 'HTTPS' button
mocked_message_box_instance = mock_message_box[0]
mocked_https_button = mock_message_box[2]
mocked_message_box_instance.clickedButton.return_value = mocked_https_button
upgrade_db(db_url, upgrade)
# THEN: The proxy settings should have been removed, the version should have been changed to version 2, and the
# proxy server saved to the settings
engine = create_engine(db_url)
conn = engine.connect()
assert len(conn.execute('SELECT * FROM metadata WHERE key = "proxy_server"').fetchall()) == 0
assert len(conn.execute('SELECT * FROM metadata WHERE key = "proxy_username"').fetchall()) == 0
assert len(conn.execute('SELECT * FROM metadata WHERE key = "proxy_password"').fetchall()) == 0
assert conn.execute('SELECT * FROM metadata WHERE key = "version"').first().value == '2'
assert mock_settings.setValue.call_args_list == [
call('advanced/proxy https', 'proxy_server'), call('advanced/proxy username', 'proxy_username'),
call('advanced/proxy password', 'proxy_password'), call('advanced/proxy mode', ProxyMode.MANUAL_PROXY)]
def test_upgrade_2_both_selected(mock_message_box, db_url, mock_settings):
"""
Tcest that upgrade 2 completes properly when the user chooses to use a both HTTP and HTTPS proxies
"""
def setUp(self):
"""
Setup for tests
"""
self.tmp_path = Path(mkdtemp())
db_path = RESOURCE_PATH / 'bibles' / 'web-bible-2.4.6-v1.sqlite'
db_tmp_path = self.tmp_path / 'web-bible-2.4.6-v1.sqlite'
shutil.copyfile(db_path, db_tmp_path)
self.db_url = 'sqlite:///' + str(db_tmp_path)
# GIVEN: An version 1 web bible with proxy settings
self.build_settings()
Registry().create()
Registry().register('service_list', MagicMock())
# WHEN: Calling upgrade_db
mocked_message_box_instance = mock_message_box[0]
mocked_both_button = mock_message_box[1]
mocked_message_box_instance.clickedButton.return_value = mocked_both_button
upgrade_db(db_url, upgrade)
patched_message_box = patch('openlp.plugins.bibles.lib.upgrade.QtWidgets.QMessageBox')
self.mocked_message_box = patched_message_box.start()
self.addCleanup(patched_message_box.stop)
# THEN: The proxy settings should have been removed, the version should have been changed to version 2, and the
# proxy server saved to the settings
engine = create_engine(db_url)
conn = engine.connect()
assert len(conn.execute('SELECT * FROM metadata WHERE key = "proxy_server"').fetchall()) == 0
assert len(conn.execute('SELECT * FROM metadata WHERE key = "proxy_username"').fetchall()) == 0
assert len(conn.execute('SELECT * FROM metadata WHERE key = "proxy_password"').fetchall()) == 0
assert conn.execute('SELECT * FROM metadata WHERE key = "version"').first().value == '2'
def tearDown(self):
"""
Clean up after tests
"""
# Ignore errors since windows can have problems with locked files
shutil.rmtree(self.tmp_path, ignore_errors=True)
self.destroy_settings()
def test_upgrade_2_none_selected(self):
"""
Test that upgrade 2 completes properly when the user chooses not to use a proxy ('No')
"""
# GIVEN: An version 1 web bible with proxy settings
# WHEN: Calling upgrade_db and the user has 'clicked' the 'No' button
upgrade_db(self.db_url, upgrade)
# THEN: The proxy meta data should have been removed, and the version should have been changed to version 2
self.mocked_message_box.assert_not_called()
engine = create_engine(self.db_url)
conn = engine.connect()
assert conn.execute('SELECT * FROM metadata WHERE key = "version"').first().value == '2'
class TestProxyMetaUpgrade(TestCase, TestMixin):
"""
Test the `upgrade_2` function in the :mod:`upgrade` module when the db contains proxy metadata
"""
def setUp(self):
"""
Setup for tests
"""
self.tmp_path = Path(mkdtemp())
db_path = RESOURCE_PATH / 'bibles' / 'web-bible-2.4.6-proxy-meta-v1.sqlite'
db_tmp_path = self.tmp_path / 'web-bible-2.4.6-proxy-meta-v1.sqlite'
shutil.copyfile(db_path, db_tmp_path)
self.db_url = 'sqlite:///' + str(db_tmp_path)
self.mocked_settings_instance = MagicMock()
self.mocked_settings = MagicMock()
self.mocked_settings.return_value = self.mocked_settings_instance
self.build_settings()
Registry().create()
Registry().register('service_list', MagicMock())
Registry().register('settings', self.mocked_settings)
patched_message_box = patch('openlp.plugins.bibles.lib.upgrade.QtWidgets.QMessageBox')
mocked_message_box = patched_message_box.start()
self.addCleanup(patched_message_box.stop)
self.mocked_no_button = MagicMock()
self.mocked_http_button = MagicMock()
self.mocked_both_button = MagicMock()
self.mocked_https_button = MagicMock()
self.mocked_message_box_instance = MagicMock(
**{'addButton.side_effect': [self.mocked_no_button, self.mocked_http_button,
self.mocked_both_button, self.mocked_https_button]})
mocked_message_box.return_value = self.mocked_message_box_instance
def tearDown(self):
"""
Clean up after tests
"""
# Ignore errors since windows can have problems with locked files
shutil.rmtree(self.tmp_path, ignore_errors=True)
def test_upgrade_2_none_selected(self):
"""
Test that upgrade 2 completes properly when the user chooses not to use a proxy ('No')
"""
# GIVEN: An version 1 web bible with proxy settings
# WHEN: Calling upgrade_db and the user has 'clicked' the 'No' button
self.mocked_message_box_instance.clickedButton.return_value = self.mocked_no_button
upgrade_db(self.db_url, upgrade)
# THEN: The proxy meta data should have been removed, and the version should have been changed to version 2
engine = create_engine(self.db_url)
conn = engine.connect()
assert len(conn.execute('SELECT * FROM metadata WHERE key = "proxy_server"').fetchall()) == 0
assert len(conn.execute('SELECT * FROM metadata WHERE key = "proxy_username"').fetchall()) == 0
assert len(conn.execute('SELECT * FROM metadata WHERE key = "proxy_password"').fetchall()) == 0
assert conn.execute('SELECT * FROM metadata WHERE key = "version"').first().value == '2'
self.mocked_settings_instance.setValue.assert_not_called()
def test_upgrade_2_http_selected(self):
"""
Test that upgrade 2 completes properly when the user chooses to use a HTTP proxy
"""
# GIVEN: An version 1 web bible with proxy settings
# WHEN: Calling upgrade_db and the user has 'clicked' the 'HTTP' button
self.mocked_message_box_instance.clickedButton.return_value = self.mocked_http_button
upgrade_db(self.db_url, upgrade)
# THEN: The proxy meta data should have been removed, the version should have been changed to version 2, and the
# proxy server saved to the settings
engine = create_engine(self.db_url)
conn = engine.connect()
assert len(conn.execute('SELECT * FROM metadata WHERE key = "proxy_server"').fetchall()) == 0
assert len(conn.execute('SELECT * FROM metadata WHERE key = "proxy_username"').fetchall()) == 0
assert len(conn.execute('SELECT * FROM metadata WHERE key = "proxy_password"').fetchall()) == 0
assert conn.execute('SELECT * FROM metadata WHERE key = "version"').first().value == '2'
assert self.mocked_settings.setValue.call_args_list == [
call('advanced/proxy http', 'proxy_server'), call('advanced/proxy username', 'proxy_username'),
call('advanced/proxy password', 'proxy_password'), call('advanced/proxy mode', ProxyMode.MANUAL_PROXY)]
def test_upgrade_2_https_selected(self):
"""
Tcest that upgrade 2 completes properly when the user chooses to use a HTTPS proxy
"""
# GIVEN: An version 1 web bible with proxy settings
# WHEN: Calling upgrade_db and the user has 'clicked' the 'HTTPS' button
self.mocked_message_box_instance.clickedButton.return_value = self.mocked_https_button
upgrade_db(self.db_url, upgrade)
# THEN: The proxy settings should have been removed, the version should have been changed to version 2, and the
# proxy server saved to the settings
engine = create_engine(self.db_url)
conn = engine.connect()
assert len(conn.execute('SELECT * FROM metadata WHERE key = "proxy_server"').fetchall()) == 0
assert len(conn.execute('SELECT * FROM metadata WHERE key = "proxy_username"').fetchall()) == 0
assert len(conn.execute('SELECT * FROM metadata WHERE key = "proxy_password"').fetchall()) == 0
assert conn.execute('SELECT * FROM metadata WHERE key = "version"').first().value == '2'
assert self.mocked_settings.setValue.call_args_list == [
call('advanced/proxy https', 'proxy_server'), call('advanced/proxy username', 'proxy_username'),
call('advanced/proxy password', 'proxy_password'), call('advanced/proxy mode', ProxyMode.MANUAL_PROXY)]
def test_upgrade_2_both_selected(self):
"""
Tcest that upgrade 2 completes properly when the user chooses to use a both HTTP and HTTPS proxies
"""
# GIVEN: An version 1 web bible with proxy settings
# WHEN: Calling upgrade_db
self.mocked_message_box_instance.clickedButton.return_value = self.mocked_both_button
upgrade_db(self.db_url, upgrade)
# THEN: The proxy settings should have been removed, the version should have been changed to version 2, and the
# proxy server saved to the settings
engine = create_engine(self.db_url)
conn = engine.connect()
assert len(conn.execute('SELECT * FROM metadata WHERE key = "proxy_server"').fetchall()) == 0
assert len(conn.execute('SELECT * FROM metadata WHERE key = "proxy_username"').fetchall()) == 0
assert len(conn.execute('SELECT * FROM metadata WHERE key = "proxy_password"').fetchall()) == 0
assert conn.execute('SELECT * FROM metadata WHERE key = "version"').first().value == '2'
assert self.mocked_settings.setValue.call_args_list == [
call('advanced/proxy http', 'proxy_server'), call('advanced/proxy https', 'proxy_server'),
call('advanced/proxy username', 'proxy_username'), call('advanced/proxy password', 'proxy_password'),
call('advanced/proxy mode', ProxyMode.MANUAL_PROXY)]
assert mock_settings.setValue.call_args_list == [
call('advanced/proxy http', 'proxy_server'), call('advanced/proxy https', 'proxy_server'),
call('advanced/proxy username', 'proxy_username'), call('advanced/proxy password', 'proxy_password'),
call('advanced/proxy mode', ProxyMode.MANUAL_PROXY)]

View File

@ -21,116 +21,115 @@
"""
This module contains tests for the versereferencelist submodule of the Bibles plugin.
"""
from unittest import TestCase
from openlp.plugins.bibles.lib.versereferencelist import VerseReferenceList
class TestVerseReferenceList(TestCase):
def test_add_first_verse():
"""
Test the VerseReferenceList class
Test the addition of a verse to the empty list
"""
def test_add_first_verse(self):
"""
Test the addition of a verse to the empty list
"""
# GIVEN: an empty list
reference_list = VerseReferenceList()
book = 'testBook'
chapter = 1
verse = 1
version = 'testVersion'
copyright_ = 'testCopyright'
permission = 'testPermission'
# GIVEN: an empty list
reference_list = VerseReferenceList()
book = 'testBook'
chapter = 1
verse = 1
version = 'testVersion'
copyright_ = 'testCopyright'
permission = 'testPermission'
# WHEN: We add it to the verse list
reference_list.add(book, chapter, verse, version, copyright_, permission)
# WHEN: We add it to the verse list
reference_list.add(book, chapter, verse, version, copyright_, permission)
# THEN: The entries should be in the first entry of the list
assert reference_list.current_index == 0, 'The current index should be 0'
assert reference_list.verse_list[0]['book'] == book, 'The book in first entry should be %s' % book
assert reference_list.verse_list[0]['chapter'] == chapter, 'The chapter in first entry should be %u' % chapter
assert reference_list.verse_list[0]['start'] == verse, 'The start in first entry should be %u' % verse
assert reference_list.verse_list[0]['version'] == version, 'The version in first entry should be %s' % version
assert reference_list.verse_list[0]['end'] == verse, 'The end in first entry should be %u' % verse
# THEN: The entries should be in the first entry of the list
assert reference_list.current_index == 0, 'The current index should be 0'
assert reference_list.verse_list[0]['book'] == book, 'The book in first entry should be %s' % book
assert reference_list.verse_list[0]['chapter'] == chapter, 'The chapter in first entry should be %u' % chapter
assert reference_list.verse_list[0]['start'] == verse, 'The start in first entry should be %u' % verse
assert reference_list.verse_list[0]['version'] == version, 'The version in first entry should be %s' % version
assert reference_list.verse_list[0]['end'] == verse, 'The end in first entry should be %u' % verse
def test_add_next_verse(self):
"""
Test the addition of the following verse
"""
# GIVEN: 1 line in the list of verses
book = 'testBook'
chapter = 1
verse = 1
next_verse = 2
version = 'testVersion'
copyright_ = 'testCopyright'
permission = 'testPermission'
reference_list = VerseReferenceList()
reference_list.add(book, chapter, verse, version, copyright_, permission)
# WHEN: We add the following verse to the verse list
reference_list.add(book, chapter, next_verse, version, copyright_, permission)
def test_add_next_verse():
"""
Test the addition of the following verse
"""
# GIVEN: 1 line in the list of verses
book = 'testBook'
chapter = 1
verse = 1
next_verse = 2
version = 'testVersion'
copyright_ = 'testCopyright'
permission = 'testPermission'
reference_list = VerseReferenceList()
reference_list.add(book, chapter, verse, version, copyright_, permission)
# THEN: The current index should be 0 and the end pointer of the entry should be '2'
assert reference_list.current_index == 0, 'The current index should be 0'
assert reference_list.verse_list[0]['end'] == next_verse, 'The end in first entry should be %u' % next_verse
# WHEN: We add the following verse to the verse list
reference_list.add(book, chapter, next_verse, version, copyright_, permission)
def test_add_another_verse(self):
"""
Test the addition of a verse in another book
"""
# GIVEN: 1 line in the list of verses
book = 'testBook'
chapter = 1
verse = 1
another_book = 'testBook2'
another_chapter = 2
another_verse = 5
version = 'testVersion'
copyright_ = 'testCopyright'
permission = 'testPermission'
reference_list = VerseReferenceList()
reference_list.add(book, chapter, verse, version, copyright_, permission)
# THEN: The current index should be 0 and the end pointer of the entry should be '2'
assert reference_list.current_index == 0, 'The current index should be 0'
assert reference_list.verse_list[0]['end'] == next_verse, 'The end in first entry should be %u' % next_verse
# WHEN: We add a verse of another book to the verse list
reference_list.add(another_book, another_chapter, another_verse, version, copyright_, permission)
# THEN: the current index should be 1
assert reference_list.current_index == 1, 'The current index should be 1'
def test_add_another_verse():
"""
Test the addition of a verse in another book
"""
# GIVEN: 1 line in the list of verses
book = 'testBook'
chapter = 1
verse = 1
another_book = 'testBook2'
another_chapter = 2
another_verse = 5
version = 'testVersion'
copyright_ = 'testCopyright'
permission = 'testPermission'
reference_list = VerseReferenceList()
reference_list.add(book, chapter, verse, version, copyright_, permission)
def test_add_version(self):
"""
Test the addition of a version to the list
"""
# GIVEN: version, copyright and permission
reference_list = VerseReferenceList()
version = 'testVersion'
copyright_ = 'testCopyright'
permission = 'testPermission'
# WHEN: We add a verse of another book to the verse list
reference_list.add(another_book, another_chapter, another_verse, version, copyright_, permission)
# WHEN: a not existing version will be added
reference_list.add_version(version, copyright_, permission)
# THEN: the current index should be 1
assert reference_list.current_index == 1, 'The current index should be 1'
# THEN: the data will be appended to the list
assert len(reference_list.version_list) == 1, 'The version data should be appended'
assert reference_list.version_list[0] == \
{'version': version, 'copyright': copyright_, 'permission': permission}, \
'The version data should be appended'
def test_add_existing_version(self):
"""
Test the addition of an existing version to the list
"""
# GIVEN: version, copyright and permission, added to the version list
reference_list = VerseReferenceList()
version = 'testVersion'
copyright_ = 'testCopyright'
permission = 'testPermission'
reference_list.add_version(version, copyright_, permission)
def test_add_version():
"""
Test the addition of a version to the list
"""
# GIVEN: version, copyright and permission
reference_list = VerseReferenceList()
version = 'testVersion'
copyright_ = 'testCopyright'
permission = 'testPermission'
# WHEN: an existing version will be added
reference_list.add_version(version, copyright_, permission)
# WHEN: a not existing version will be added
reference_list.add_version(version, copyright_, permission)
# THEN: the data will not be appended to the list
assert len(reference_list.version_list) == 1, 'The version data should not be appended'
# THEN: the data will be appended to the list
assert len(reference_list.version_list) == 1, 'The version data should be appended'
assert reference_list.version_list[0] == \
{'version': version, 'copyright': copyright_, 'permission': permission}, \
'The version data should be appended'
def test_add_existing_version():
"""
Test the addition of an existing version to the list
"""
# GIVEN: version, copyright and permission, added to the version list
reference_list = VerseReferenceList()
version = 'testVersion'
copyright_ = 'testCopyright'
permission = 'testPermission'
reference_list.add_version(version, copyright_, permission)
# WHEN: an existing version will be added
reference_list.add_version(version, copyright_, permission)
# THEN: the data will not be appended to the list
assert len(reference_list.version_list) == 1, 'The version data should not be appended'

View File

@ -22,7 +22,6 @@
This module contains tests for the WordProject Bible importer.
"""
from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, call, patch
from openlp.plugins.bibles.lib.importers.wordproject import WordProjectBible
@ -34,179 +33,172 @@ INDEX_PAGE = (TEST_PATH / 'wordproject_index.htm').read_bytes().decode()
CHAPTER_PAGE = (TEST_PATH / 'wordproject_chapter.htm').read_bytes().decode()
class TestWordProjectImport(TestCase):
@patch.object(Path, 'read_text')
@patch.object(Path, 'exists')
def test_process_books(mocked_exists, mocked_read_text, settings):
"""
Test the functions in the :mod:`wordprojectimport` module.
Test the process_books() method
"""
# GIVEN: A WordProject importer and a bunch of mocked things
importer = WordProjectBible(MagicMock(), path='.', name='.', file_path=Path('kj.zip'))
importer.base_path = Path()
importer.stop_import_flag = False
importer.language_id = 'en'
mocked_read_text.return_value = INDEX_PAGE
mocked_exists.return_value = True
def setUp(self):
self.registry_patcher = patch('openlp.plugins.bibles.lib.bibleimport.Registry')
self.addCleanup(self.registry_patcher.stop)
self.registry_patcher.start()
self.manager_patcher = patch('openlp.plugins.bibles.lib.db.Manager')
self.addCleanup(self.manager_patcher.stop)
self.manager_patcher.start()
# WHEN: process_books() is called
with patch.object(importer, '_unzip_file') as mocked_unzip_file, \
patch.object(importer, 'find_and_create_book') as mocked_find_and_create_book, \
patch.object(importer, 'process_chapters') as mocked_process_chapters, \
patch.object(importer, 'session') as mocked_session:
mocked_unzip_file.return_value = True
importer.process_books()
@patch.object(Path, 'read_text')
@patch.object(Path, 'exists')
def test_process_books(self, mocked_exists, mocked_read_text):
"""
Test the process_books() method
"""
# GIVEN: A WordProject importer and a bunch of mocked things
importer = WordProjectBible(MagicMock(), path='.', name='.', file_path=Path('kj.zip'))
importer.base_path = Path()
importer.stop_import_flag = False
importer.language_id = 'en'
mocked_read_text.return_value = INDEX_PAGE
mocked_exists.return_value = True
# THEN: The right methods should have been called
mocked_read_text.assert_called_once_with(encoding='utf-8', errors='ignore')
assert mocked_find_and_create_book.call_count == 66, 'There should be 66 books'
assert mocked_process_chapters.call_count == 66, 'There should be 66 books'
assert mocked_session.commit.call_count == 66, 'There should be 66 books'
# WHEN: process_books() is called
with patch.object(importer, '_unzip_file') as mocked_unzip_file, \
patch.object(importer, 'find_and_create_book') as mocked_find_and_create_book, \
patch.object(importer, 'process_chapters') as mocked_process_chapters, \
patch.object(importer, 'session') as mocked_session:
mocked_unzip_file.return_value = True
importer.process_books()
# THEN: The right methods should have been called
mocked_read_text.assert_called_once_with(encoding='utf-8', errors='ignore')
assert mocked_find_and_create_book.call_count == 66, 'There should be 66 books'
assert mocked_process_chapters.call_count == 66, 'There should be 66 books'
assert mocked_session.commit.call_count == 66, 'There should be 66 books'
@patch.object(Path, 'read_text')
def test_process_chapters(mocked_read_text, settings):
"""
Test the process_chapters() method
"""
# GIVEN: A WordProject importer and a bunch of mocked things
importer = WordProjectBible(MagicMock(), path='.', name='.', file_path=Path('kj.zip'))
importer.base_path = Path()
importer.stop_import_flag = False
importer.language_id = 'en'
mocked_read_text.return_value = CHAPTER_PAGE
mocked_db_book = MagicMock()
mocked_db_book.name = 'Genesis'
book_id = 1
book_link = '01/1.htm'
@patch.object(Path, 'read_text')
def test_process_chapters(self, mocked_read_text):
"""
Test the process_chapters() method
"""
# GIVEN: A WordProject importer and a bunch of mocked things
importer = WordProjectBible(MagicMock(), path='.', name='.', file_path=Path('kj.zip'))
importer.base_path = Path()
importer.stop_import_flag = False
importer.language_id = 'en'
mocked_read_text.return_value = CHAPTER_PAGE
mocked_db_book = MagicMock()
mocked_db_book.name = 'Genesis'
book_id = 1
book_link = '01/1.htm'
# WHEN: process_chapters() is called
with patch.object(importer, 'set_current_chapter') as mocked_set_current_chapter, \
patch.object(importer, 'process_verses') as mocked_process_verses:
importer.process_chapters(mocked_db_book, book_id, book_link)
# WHEN: process_chapters() is called
with patch.object(importer, 'set_current_chapter') as mocked_set_current_chapter, \
patch.object(importer, 'process_verses') as mocked_process_verses:
importer.process_chapters(mocked_db_book, book_id, book_link)
# THEN: The right methods should have been called
expected_set_current_chapter_calls = [call('Genesis', ch) for ch in range(1, 51)]
expected_process_verses_calls = [call(mocked_db_book, 1, ch) for ch in range(1, 51)]
mocked_read_text.assert_called_once_with(encoding='utf-8', errors='ignore')
assert mocked_set_current_chapter.call_args_list == expected_set_current_chapter_calls
assert mocked_process_verses.call_args_list == expected_process_verses_calls
# THEN: The right methods should have been called
expected_set_current_chapter_calls = [call('Genesis', ch) for ch in range(1, 51)]
expected_process_verses_calls = [call(mocked_db_book, 1, ch) for ch in range(1, 51)]
mocked_read_text.assert_called_once_with(encoding='utf-8', errors='ignore')
assert mocked_set_current_chapter.call_args_list == expected_set_current_chapter_calls
assert mocked_process_verses.call_args_list == expected_process_verses_calls
@patch.object(Path, 'read_text')
def test_process_verses(self, mocked_read_text):
"""
Test the process_verses() method
"""
# GIVEN: A WordProject importer and a bunch of mocked things
importer = WordProjectBible(MagicMock(), path='.', name='.', file_path=Path('kj.zip'))
importer.base_path = Path()
importer.stop_import_flag = False
importer.language_id = 'en'
mocked_read_text.return_value = CHAPTER_PAGE
mocked_db_book = MagicMock()
mocked_db_book.name = 'Genesis'
book_number = 1
chapter_number = 1
@patch.object(Path, 'read_text')
def test_process_verses(mocked_read_text, settings):
"""
Test the process_verses() method
"""
# GIVEN: A WordProject importer and a bunch of mocked things
importer = WordProjectBible(MagicMock(), path='.', name='.', file_path=Path('kj.zip'))
importer.base_path = Path()
importer.stop_import_flag = False
importer.language_id = 'en'
mocked_read_text.return_value = CHAPTER_PAGE
mocked_db_book = MagicMock()
mocked_db_book.name = 'Genesis'
book_number = 1
chapter_number = 1
# WHEN: process_verses() is called
with patch.object(importer, 'process_verse') as mocked_process_verse:
importer.process_verses(mocked_db_book, book_number, chapter_number)
# WHEN: process_verses() is called
with patch.object(importer, 'process_verse') as mocked_process_verse:
importer.process_verses(mocked_db_book, book_number, chapter_number)
# THEN: All the right methods should have been called
mocked_read_text.assert_called_once_with(encoding='utf-8', errors='ignore')
assert mocked_process_verse.call_count == 31
# THEN: All the right methods should have been called
mocked_read_text.assert_called_once_with(encoding='utf-8', errors='ignore')
assert mocked_process_verse.call_count == 31
def test_process_verse(self):
"""
Test the process_verse() method
"""
# GIVEN: An importer and a mocked method
importer = WordProjectBible(MagicMock(), path='.', name='.', file_path=Path('kj.zip'))
mocked_db_book = MagicMock()
mocked_db_book.id = 1
chapter_number = 1
verse_number = 1
verse_text = ' In the beginning, God created the heavens and the earth '
# WHEN: process_verse() is called
with patch.object(importer, 'create_verse') as mocked_create_verse:
importer.process_verse(mocked_db_book, chapter_number, verse_number, verse_text)
def test_process_verse(settings):
"""
Test the process_verse() method
"""
# GIVEN: An importer and a mocked method
importer = WordProjectBible(MagicMock(), path='.', name='.', file_path=Path('kj.zip'))
mocked_db_book = MagicMock()
mocked_db_book.id = 1
chapter_number = 1
verse_number = 1
verse_text = ' In the beginning, God created the heavens and the earth '
# THEN: The create_verse() method should have been called
mocked_create_verse.assert_called_once_with(1, 1, 1, 'In the beginning, God created the heavens and the earth')
# WHEN: process_verse() is called
with patch.object(importer, 'create_verse') as mocked_create_verse:
importer.process_verse(mocked_db_book, chapter_number, verse_number, verse_text)
def test_process_verse_no_text(self):
"""
Test the process_verse() method when there's no text
"""
# GIVEN: An importer and a mocked method
importer = WordProjectBible(MagicMock(), path='.', name='.', file_path=Path('kj.zip'))
mocked_db_book = MagicMock()
mocked_db_book.id = 1
chapter_number = 1
verse_number = 1
verse_text = ''
# THEN: The create_verse() method should have been called
mocked_create_verse.assert_called_once_with(1, 1, 1, 'In the beginning, God created the heavens and the earth')
# WHEN: process_verse() is called
with patch.object(importer, 'create_verse') as mocked_create_verse:
importer.process_verse(mocked_db_book, chapter_number, verse_number, verse_text)
# THEN: The create_verse() method should NOT have been called
assert mocked_create_verse.call_count == 0
def test_process_verse_no_text(settings):
"""
Test the process_verse() method when there's no text
"""
# GIVEN: An importer and a mocked method
importer = WordProjectBible(MagicMock(), path='.', name='.', file_path=Path('kj.zip'))
mocked_db_book = MagicMock()
mocked_db_book.id = 1
chapter_number = 1
verse_number = 1
verse_text = ''
def test_do_import(self):
"""
Test the do_import() method
"""
# GIVEN: An importer and mocked methods
importer = WordProjectBible(MagicMock(), path='.', name='.', file_path='kj.zip')
# WHEN: process_verse() is called
with patch.object(importer, 'create_verse') as mocked_create_verse:
importer.process_verse(mocked_db_book, chapter_number, verse_number, verse_text)
# WHEN: do_import() is called
with patch.object(importer, '_unzip_file') as mocked_unzip_file, \
patch.object(importer, 'get_language_id') as mocked_get_language_id, \
patch.object(importer, 'process_books') as mocked_process_books, \
patch.object(importer, '_cleanup') as mocked_cleanup:
mocked_unzip_file.return_value = True
mocked_process_books.return_value = True
mocked_get_language_id.return_value = 1
result = importer.do_import()
# THEN: The create_verse() method should NOT have been called
assert mocked_create_verse.call_count == 0
# THEN: The correct methods should have been called
mocked_unzip_file.assert_called_once_with()
mocked_get_language_id.assert_called_once_with(None, bible_name='kj.zip')
mocked_process_books.assert_called_once_with()
mocked_cleanup.assert_called_once_with()
assert result is True
def test_do_import_no_language(self):
"""
Test the do_import() method when the language is not available
"""
# GIVEN: An importer and mocked methods
importer = WordProjectBible(MagicMock(), path='.', name='.', file_path='kj.zip')
def test_do_import(settings):
"""
Test the do_import() method
"""
# GIVEN: An importer and mocked methods
importer = WordProjectBible(MagicMock(), path='.', name='.', file_path='kj.zip')
# WHEN: do_import() is called
with patch.object(importer, '_unzip_file') as mocked_unzip_file, \
patch.object(importer, 'get_language_id') as mocked_get_language_id, \
patch.object(importer, 'process_books') as mocked_process_books, \
patch.object(importer, '_cleanup') as mocked_cleanup:
mocked_get_language_id.return_value = None
result = importer.do_import()
# WHEN: do_import() is called
with patch.object(importer, '_unzip_file') as mocked_unzip_file, \
patch.object(importer, 'get_language_id') as mocked_get_language_id, \
patch.object(importer, 'process_books') as mocked_process_books, \
patch.object(importer, '_cleanup') as mocked_cleanup:
mocked_unzip_file.return_value = True
mocked_process_books.return_value = True
mocked_get_language_id.return_value = 1
result = importer.do_import()
# THEN: The correct methods should have been called
mocked_unzip_file.assert_called_once_with()
mocked_get_language_id.assert_called_once_with(None, bible_name='kj.zip')
assert mocked_process_books.call_count == 0
mocked_cleanup.assert_called_once_with()
assert result is False
# THEN: The correct methods should have been called
mocked_unzip_file.assert_called_once_with()
mocked_get_language_id.assert_called_once_with(None, bible_name='kj.zip')
mocked_process_books.assert_called_once_with()
mocked_cleanup.assert_called_once_with()
assert result is True
def test_do_import_no_language(settings):
"""
Test the do_import() method when the language is not available
"""
# GIVEN: An importer and mocked methods
importer = WordProjectBible(MagicMock(), path='.', name='.', file_path='kj.zip')
# WHEN: do_import() is called
with patch.object(importer, '_unzip_file') as mocked_unzip_file, \
patch.object(importer, 'get_language_id') as mocked_get_language_id, \
patch.object(importer, 'process_books') as mocked_process_books, \
patch.object(importer, '_cleanup') as mocked_cleanup:
mocked_get_language_id.return_value = None
result = importer.do_import()
# THEN: The correct methods should have been called
mocked_unzip_file.assert_called_once_with()
mocked_get_language_id.assert_called_once_with(None, bible_name='kj.zip')
assert mocked_process_books.call_count == 0
mocked_cleanup.assert_called_once_with()
assert result is False

View File

@ -21,7 +21,6 @@
"""
This module contains tests for the Zefania Bible importer.
"""
from unittest import TestCase
from unittest.mock import MagicMock, patch
from openlp.plugins.bibles.lib.db import BibleDB
@ -33,86 +32,75 @@ from tests.utils.constants import RESOURCE_PATH
TEST_PATH = RESOURCE_PATH / 'bibles'
class TestZefaniaImport(TestCase):
def test_create_importer(settings):
"""
Test the functions in the :mod:`zefaniaimport` module.
Test creating an instance of the Zefania file importer
"""
# GIVEN: A mocked out "manager"
mocked_manager = MagicMock()
def setUp(self):
self.registry_patcher = patch('openlp.plugins.bibles.lib.bibleimport.Registry')
self.addCleanup(self.registry_patcher.stop)
self.registry_patcher.start()
self.manager_patcher = patch('openlp.plugins.bibles.lib.db.Manager')
self.addCleanup(self.manager_patcher.stop)
self.manager_patcher.start()
# WHEN: An importer object is created
importer = ZefaniaBible(mocked_manager, path='.', name='.', file_path=None)
def test_create_importer(self):
"""
Test creating an instance of the Zefania file importer
"""
# GIVEN: A mocked out "manager"
# THEN: The importer should be an instance of BibleDB
assert isinstance(importer, BibleDB)
def test_file_import(settings):
"""
Test the actual import of Zefania Bible file
"""
# 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.
test_data = load_external_result_data(TEST_PATH / 'dk1933.json')
bible_file = 'zefania-dk1933.xml'
with patch('openlp.plugins.bibles.lib.importers.zefania.ZefaniaBible.application'):
mocked_manager = MagicMock()
# WHEN: An importer object is created
mocked_import_wizard = MagicMock()
importer = ZefaniaBible(mocked_manager, path='.', name='.', file_path=None)
importer.wizard = mocked_import_wizard
importer.create_verse = MagicMock()
importer.create_book = MagicMock()
importer.session = MagicMock()
importer.get_language = MagicMock()
importer.get_language.return_value = 'Danish'
# THEN: The importer should be an instance of BibleDB
assert isinstance(importer, BibleDB)
# WHEN: Importing bible file
importer.file_path = TEST_PATH / bible_file
importer.do_import()
def test_file_import(self):
"""
Test the actual import of Zefania Bible file
"""
# 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.
test_data = load_external_result_data(TEST_PATH / 'dk1933.json')
bible_file = 'zefania-dk1933.xml'
with patch('openlp.plugins.bibles.lib.importers.zefania.ZefaniaBible.application'):
mocked_manager = MagicMock()
mocked_import_wizard = MagicMock()
importer = ZefaniaBible(mocked_manager, path='.', name='.', file_path=None)
importer.wizard = mocked_import_wizard
importer.create_verse = MagicMock()
importer.create_book = MagicMock()
importer.session = MagicMock()
importer.get_language = MagicMock()
importer.get_language.return_value = 'Danish'
# THEN: The create_verse() method should have been called with each verse in the file.
assert importer.create_verse.called is True
for verse_tag, verse_text in test_data['verses']:
importer.create_verse.assert_any_call(importer.create_book().id, 1, verse_tag, verse_text)
importer.create_book.assert_any_call('Genesis', 1, 1)
# WHEN: Importing bible file
importer.file_path = TEST_PATH / bible_file
importer.do_import()
# THEN: The create_verse() method should have been called with each verse in the file.
assert importer.create_verse.called is True
for verse_tag, verse_text in test_data['verses']:
importer.create_verse.assert_any_call(importer.create_book().id, 1, verse_tag, verse_text)
importer.create_book.assert_any_call('Genesis', 1, 1)
def test_file_import_no_book_name(settings):
"""
Test the import of Zefania Bible file without book names
"""
# 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.
test_data = load_external_result_data(TEST_PATH / 'rst.json')
bible_file = 'zefania-rst.xml'
with patch('openlp.plugins.bibles.lib.importers.zefania.ZefaniaBible.application'):
mocked_manager = MagicMock()
mocked_import_wizard = MagicMock()
importer = ZefaniaBible(mocked_manager, path='.', name='.', file_path=None)
importer.wizard = mocked_import_wizard
importer.create_verse = MagicMock()
importer.create_book = MagicMock()
importer.session = MagicMock()
importer.get_language = MagicMock()
importer.get_language.return_value = 'Russian'
def test_file_import_no_book_name(self):
"""
Test the import of Zefania Bible file without book names
"""
# 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.
test_data = load_external_result_data(TEST_PATH / 'rst.json')
bible_file = 'zefania-rst.xml'
with patch('openlp.plugins.bibles.lib.importers.zefania.ZefaniaBible.application'):
mocked_manager = MagicMock()
mocked_import_wizard = MagicMock()
importer = ZefaniaBible(mocked_manager, path='.', name='.', file_path=None)
importer.wizard = mocked_import_wizard
importer.create_verse = MagicMock()
importer.create_book = MagicMock()
importer.session = MagicMock()
importer.get_language = MagicMock()
importer.get_language.return_value = 'Russian'
# WHEN: Importing bible file
importer.file_path = TEST_PATH / bible_file
importer.do_import()
# WHEN: Importing bible file
importer.file_path = TEST_PATH / bible_file
importer.do_import()
# THEN: The create_verse() method should have been called with each verse in the file.
assert importer.create_verse.called is True
for verse_tag, verse_text in test_data['verses']:
importer.create_verse.assert_any_call(importer.create_book().id, 1, verse_tag, verse_text)
importer.create_book.assert_any_call('Exodus', 2, 1)
# THEN: The create_verse() method should have been called with each verse in the file.
assert importer.create_verse.called is True
for verse_tag, verse_text in test_data['verses']:
importer.create_verse.assert_any_call(importer.create_book().id, 1, verse_tag, verse_text)
importer.create_book.assert_any_call('Exodus', 2, 1)

View File

@ -19,104 +19,92 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
##########################################################################
"""
This module contains tests for the lib submodule of the Songs plugin.
This module contains tests for the lib submodule of the Custom plugin.
"""
from unittest import TestCase
import pytest
from unittest.mock import MagicMock, patch
from PyQt5 import QtCore
from openlp.core.common.registry import Registry
from openlp.core.lib.plugin import PluginStatus
from openlp.core.lib.serviceitem import ServiceItem
from openlp.plugins.custom.lib.mediaitem import CustomMediaItem
from tests.helpers.testmixin import TestMixin
FOOTER = ['Arky Arky (Unknown)', 'Public Domain', 'CCLI 123456']
class TestMediaItem(TestCase, TestMixin):
@pytest.fixture()
def media_item(mock_settings):
Registry().register('main_window', MagicMock())
with patch('openlp.core.lib.mediamanageritem.MediaManagerItem._setup'), \
patch('openlp.core.lib.mediamanageritem.MediaManagerItem.setup_item'), \
patch('openlp.plugins.custom.forms.editcustomform.EditCustomForm.__init__'), \
patch('openlp.plugins.custom.lib.mediaitem.CustomMediaItem.setup_item'):
m_item = CustomMediaItem(None, MagicMock())
media_item.plugin = MagicMock()
m_item.settings_section = 'bibles'
m_item.results_view_tab = MagicMock()
return m_item
def test_service_load_inactive(media_item):
"""
Test the functions in the :mod:`lib` module.
Test the service load in custom with a default service item
"""
def setUp(self):
"""
Set up the components need for all tests.
"""
Registry.create()
Registry().register('service_list', MagicMock())
Registry().register('main_window', MagicMock())
with patch('openlp.core.lib.mediamanageritem.MediaManagerItem._setup'), \
patch('openlp.core.lib.mediamanageritem.MediaManagerItem.setup_item'), \
patch('openlp.plugins.custom.forms.editcustomform.EditCustomForm.__init__'), \
patch('openlp.plugins.custom.lib.mediaitem.CustomMediaItem.setup_item'):
self.media_item = CustomMediaItem(None, MagicMock())
self.setup_application()
self.build_settings()
QtCore.QLocale.setDefault(QtCore.QLocale('en_GB'))
# GIVEN: An empty Service Item
service_item = ServiceItem(None)
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault
"""
self.destroy_settings()
# WHEN: I search for the custom in the database
item = media_item.service_load(service_item)
def test_service_load_inactive(self):
"""
Test the service load in custom with a default service item
"""
# GIVEN: An empty Service Item
service_item = ServiceItem(None)
# THEN: the processing should be ignored
assert item is None, 'The Service item is inactive so processing should be bypassed'
def test_service_load_basic_custom_false(media_item):
"""
Test the service load in custom with a default service item and no requirement to add to the database
"""
# GIVEN: An empty Service Item and an active plugin
service_item = ServiceItem(None)
service_item.raw_footer = FOOTER
media_item.plugin = MagicMock()
media_item.plugin.status = PluginStatus.Active
media_item.plugin.db_manager = MagicMock()
media_item.plugin.db_manager.get_object_filtered = MagicMock()
media_item.plugin.db_manager.get_object_filtered.return_value = None
with patch('openlp.plugins.custom.lib.mediaitem.CustomSlide'):
# WHEN: I search for the custom in the database
item = self.media_item.service_load(service_item)
media_item.add_custom_from_service = False
media_item.create_from_service_item = MagicMock()
media_item.service_load(service_item)
# THEN: the processing should be ignored
assert item is None, 'The Service item is inactive so processing should be bypassed'
# THEN: the item should not be added to the database.
assert media_item.create_from_service_item.call_count == 0, \
'The item should not have been added to the database'
def test_service_load_basic_custom_false(self):
"""
Test the service load in custom with a default service item and no requirement to add to the database
"""
# GIVEN: An empty Service Item and an active plugin
service_item = ServiceItem(None)
service_item.raw_footer = FOOTER
self.media_item.plugin = MagicMock()
self.media_item.plugin.status = PluginStatus.Active
self.media_item.plugin.db_manager = MagicMock()
self.media_item.plugin.db_manager.get_object_filtered = MagicMock()
self.media_item.plugin.db_manager.get_object_filtered.return_value = None
with patch('openlp.plugins.custom.lib.mediaitem.CustomSlide'):
# WHEN: I search for the custom in the database
self.media_item.add_custom_from_service = False
self.media_item.create_from_service_item = MagicMock()
self.media_item.service_load(service_item)
def test_service_load_basic_custom_true(media_item):
"""
Test the service load in custom with a default service item and a requirement to add to the database
"""
# GIVEN: An empty Service Item and an active plugin
service_item = ServiceItem(None)
service_item.raw_footer = FOOTER
media_item.plugin = MagicMock()
media_item.plugin.status = PluginStatus.Active
media_item.plugin.db_manager = MagicMock()
media_item.plugin.db_manager.get_object_filtered = MagicMock()
media_item.plugin.db_manager.get_object_filtered.return_value = None
# THEN: the item should not be added to the database.
assert self.media_item.create_from_service_item.call_count == 0, \
'The item should not have been added to the database'
with patch('openlp.plugins.custom.lib.mediaitem.CustomSlide'):
# WHEN: I search for the custom in the database
media_item.add_custom_from_service = True
media_item.create_from_service_item = MagicMock()
media_item.service_load(service_item)
def test_service_load_basic_custom_true(self):
"""
Test the service load in custom with a default service item and a requirement to add to the database
"""
# GIVEN: An empty Service Item and an active plugin
service_item = ServiceItem(None)
service_item.raw_footer = FOOTER
self.media_item.plugin = MagicMock()
self.media_item.plugin.status = PluginStatus.Active
self.media_item.plugin.db_manager = MagicMock()
self.media_item.plugin.db_manager.get_object_filtered = MagicMock()
self.media_item.plugin.db_manager.get_object_filtered.return_value = None
with patch('openlp.plugins.custom.lib.mediaitem.CustomSlide'):
# WHEN: I search for the custom in the database
self.media_item.add_custom_from_service = True
self.media_item.create_from_service_item = MagicMock()
self.media_item.service_load(service_item)
# THEN: the item should not be added to the database.
assert self.media_item.create_from_service_item.call_count == 1, \
'The item should have been added to the database'
# THEN: the item should not be added to the database.
assert media_item.create_from_service_item.call_count == 1, \
'The item should have been added to the database'

View File

@ -21,72 +21,43 @@
"""
This module contains tests for the lib submodule of the Images plugin.
"""
from unittest import TestCase
import pytest
from unittest.mock import MagicMock
from PyQt5 import QtWidgets
from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings
from openlp.plugins.images.lib.imagetab import ImageTab
from tests.helpers.testmixin import TestMixin
__default_settings__ = {
'images/db type': 'sqlite',
'images/background color': '#000000',
}
@pytest.fixture()
def form(settings):
Registry().register('settings_form', MagicMock())
frm = ImageTab(None, 'Images', None, None)
frm.settings_form.register_post_process = MagicMock()
return frm
class TestImageMediaItem(TestCase, TestMixin):
def test_save_tab_nochange(form):
"""
This is a test case to test various methods in the ImageTab.
Test no changes does not trigger post processing
"""
# GIVEN: No changes on the form.
# WHEN: the save is invoked
form.save()
# THEN: the post process should not be requested
assert 0 == form.settings_form.register_post_process.call_count, \
'Image Post processing should not have been requested'
def setUp(self):
"""
Create the UI
"""
Registry.create()
Registry().register('settings_form', MagicMock())
self.setup_application()
self.build_settings()
Registry().register('settings', Settings())
Settings().extend_default_settings(__default_settings__)
self.parent = QtWidgets.QMainWindow()
self.form = ImageTab(self.parent, 'Images', None, None)
self.form.settings_form.register_post_process = MagicMock()
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault
"""
del self.parent
del self.form
self.destroy_settings()
def test_save_tab_nochange(self):
"""
Test no changes does not trigger post processing
"""
# GIVEN: No changes on the form.
self.initial_color = '#999999'
# WHEN: the save is invoked
self.form.save()
# THEN: the post process should not be requested
assert 0 == self.form.settings_form.register_post_process.call_count, \
'Image Post processing should not have been requested'
def test_save_tab_change(self):
"""
Test a color change is applied and triggers post processing.
"""
# GIVEN: Apply a change to the form.
self.form.on_background_color_changed('#999999')
# WHEN: the save is invoked
self.form.save()
# THEN: the post process should be requested
assert 1 == self.form.settings_form.register_post_process.call_count, \
'Image Post processing should have been requested'
# THEN: The color should be set
assert self.form.background_color == '#999999', 'The updated color should have been saved'
def test_save_tab_change(form):
"""
Test a color change is applied and triggers post processing.
"""
# GIVEN: Apply a change to the form.
form.on_background_color_changed('#999999')
# WHEN: the save is invoked
form.save()
# THEN: the post process should be requested
assert 1 == form.settings_form.register_post_process.call_count, \
'Image Post processing should have been requested'
# THEN: The color should be set
assert form.background_color == '#999999', 'The updated color should have been saved'

View File

@ -1,299 +0,0 @@
# -*- coding: utf-8 -*-
##########################################################################
# OpenLP - Open Source Lyrics Projection #
# ---------------------------------------------------------------------- #
# Copyright (c) 2008-2020 OpenLP Developers #
# ---------------------------------------------------------------------- #
# 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, either version 3 of the License, or #
# (at your option) any later version. #
# #
# 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, see <https://www.gnu.org/licenses/>. #
##########################################################################
"""
This module contains tests for the lib submodule of the Images plugin.
"""
import pytest
from pathlib import Path
from unittest import TestCase
from unittest.mock import ANY, MagicMock, patch
from PyQt5 import QtCore, QtWidgets
from openlp.core.common.registry import Registry
from openlp.plugins.images.lib.db import ImageFilenames, ImageGroups
from openlp.plugins.images.lib.mediaitem import ImageMediaItem
@pytest.yield_fixture
def mocked_media_item(mock_settings):
"""Local test setup"""
mocked_main_window = MagicMock()
Registry().register('application', MagicMock())
Registry().register('service_list', MagicMock())
Registry().register('main_window', mocked_main_window)
Registry().register('live_controller', MagicMock())
mocked_plugin = MagicMock()
with patch('openlp.plugins.images.lib.mediaitem.MediaManagerItem._setup'), \
patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.setup_item'):
media_item = ImageMediaItem(None, mocked_plugin)
media_item.settings_section = 'images'
yield media_item
class TestImageMediaItem(TestCase):
"""
This is a test case to test various methods in the ImageMediaItem class.
"""
def setUp(self):
self.mocked_main_window = MagicMock()
Registry.create()
Registry().register('application', MagicMock())
Registry().register('service_list', MagicMock())
Registry().register('main_window', self.mocked_main_window)
Registry().register('live_controller', MagicMock())
mocked_plugin = MagicMock()
with patch('openlp.plugins.images.lib.mediaitem.MediaManagerItem._setup'), \
patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.setup_item'):
self.media_item = ImageMediaItem(None, mocked_plugin)
self.media_item.settings_section = 'images'
@patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_full_list')
def test_save_new_images_list_empty_list(self, mocked_load_full_list):
"""
Test that the save_new_images_list() method handles empty lists gracefully
"""
# GIVEN: An empty image_list
image_list = []
self.media_item.manager = MagicMock()
# WHEN: We run save_new_images_list with the empty list
self.media_item.save_new_images_list(image_list)
# THEN: The save_object() method should not have been called
assert self.media_item.manager.save_object.call_count == 0, \
'The save_object() method should not have been called'
@patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_full_list')
def test_save_new_images_list_single_image_with_reload(self, mocked_load_full_list):
"""
Test that the save_new_images_list() calls load_full_list() when reload_list is set to True
"""
# GIVEN: A list with 1 image and a mocked out manager
image_list = [Path('test_image.jpg')]
ImageFilenames.file_path = None
self.media_item.manager = MagicMock()
# WHEN: We run save_new_images_list with reload_list=True
self.media_item.save_new_images_list(image_list, reload_list=True)
# THEN: load_full_list() should have been called
assert mocked_load_full_list.call_count == 1, 'load_full_list() should have been called'
# CLEANUP: Remove added attribute from ImageFilenames
delattr(ImageFilenames, 'file_path')
@patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_full_list')
def test_save_new_images_list_single_image_without_reload(self, mocked_load_full_list):
"""
Test that the save_new_images_list() doesn't call load_full_list() when reload_list is set to False
"""
# GIVEN: A list with 1 image and a mocked out manager
image_list = [Path('test_image.jpg')]
self.media_item.manager = MagicMock()
# WHEN: We run save_new_images_list with reload_list=False
self.media_item.save_new_images_list(image_list, reload_list=False)
# THEN: load_full_list() should not have been called
assert mocked_load_full_list.call_count == 0, 'load_full_list() should not have been called'
@patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_full_list')
def test_save_new_images_list_multiple_images(self, mocked_load_full_list):
"""
Test that the save_new_images_list() saves all images in the list
"""
# GIVEN: A list with 3 images
image_list = [Path('test_image_1.jpg'), Path('test_image_2.jpg'), Path('test_image_3.jpg')]
self.media_item.manager = MagicMock()
# WHEN: We run save_new_images_list with the list of 3 images
self.media_item.save_new_images_list(image_list, reload_list=False)
# THEN: load_full_list() should not have been called
assert self.media_item.manager.save_object.call_count == 3, \
'load_full_list() should have been called three times'
@patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_full_list')
def test_save_new_images_list_other_objects_in_list(self, mocked_load_full_list):
"""
Test that the save_new_images_list() ignores everything in the provided list except strings
"""
# GIVEN: A list with images and objects
image_list = [Path('test_image_1.jpg'), None, True, ImageFilenames(), Path('test_image_2.jpg')]
self.media_item.manager = MagicMock()
# WHEN: We run save_new_images_list with the list of images and objects
self.media_item.save_new_images_list(image_list, reload_list=False)
# THEN: load_full_list() should not have been called
assert self.media_item.manager.save_object.call_count == 2, 'load_full_list() should have been called only once'
def test_on_reset_click(self):
"""
Test that on_reset_click() actually resets the background
"""
# GIVEN: A mocked version of reset_action
self.media_item.reset_action = MagicMock()
self.media_item.reset_action_context = MagicMock()
# WHEN: on_reset_click is called
self.media_item.on_reset_click()
# THEN: the reset_action should be set visible, and the image should be reset
self.media_item.reset_action.setVisible.assert_called_with(False)
self.media_item.reset_action_context.setVisible.assert_called_with(False)
self.media_item.live_controller.display.reset_image.assert_called_with()
@patch('openlp.plugins.images.lib.mediaitem.delete_file')
def test_recursively_delete_group(self, mocked_delete_file):
"""
Test that recursively_delete_group() works
"""
# GIVEN: An ImageGroups object and mocked functions
ImageFilenames.group_id = 1
ImageGroups.parent_id = 1
self.media_item.manager = MagicMock()
self.media_item.manager.get_all_objects.side_effect = self._recursively_delete_group_side_effect
self.media_item.service_path = Path()
test_group = ImageGroups()
test_group.id = 1
# WHEN: recursively_delete_group() is called
self.media_item.recursively_delete_group(test_group)
# THEN: delete_file() should have been called 12 times and manager.delete_object() 7 times.
assert mocked_delete_file.call_count == 12, 'delete_file() should have been called 12 times'
assert self.media_item.manager.delete_object.call_count == 7, \
'manager.delete_object() should be called exactly 7 times'
# CLEANUP: Remove added attribute from Image Filenames and ImageGroups
delattr(ImageFilenames, 'group_id')
delattr(ImageGroups, 'parent_id')
def _recursively_delete_group_side_effect(*args, **kwargs):
"""
Side effect method that creates custom return values for the recursively_delete_group method
"""
if args[1] == ImageFilenames and args[2]:
# Create some fake objects that should be removed
returned_object1 = ImageFilenames()
returned_object1.id = 1
returned_object1.file_path = Path('/', 'tmp', 'test_file_1.jpg')
returned_object2 = ImageFilenames()
returned_object2.id = 2
returned_object2.file_path = Path('/', 'tmp', 'test_file_2.jpg')
returned_object3 = ImageFilenames()
returned_object3.id = 3
returned_object3.file_path = Path('/', 'tmp', 'test_file_3.jpg')
return [returned_object1, returned_object2, returned_object3]
if args[1] == ImageGroups and args[2]:
# Change the parent_id that is matched so we don't get into an endless loop
ImageGroups.parent_id = 0
# Create a fake group that will be used in the next run
returned_object1 = ImageGroups()
returned_object1.id = 1
return [returned_object1]
return []
@patch('openlp.plugins.images.lib.mediaitem.delete_file')
@patch('openlp.plugins.images.lib.mediaitem.check_item_selected')
def test_on_delete_click(self, mocked_check_item_selected, mocked_delete_file):
"""
Test that on_delete_click() works
"""
# GIVEN: An ImageGroups object and mocked functions
mocked_check_item_selected.return_value = True
test_image = ImageFilenames()
test_image.id = 1
test_image.group_id = 1
test_image.file_path = Path('imagefile.png')
self.media_item.manager = MagicMock()
self.media_item.service_path = Path()
self.media_item.list_view = MagicMock()
mocked_row_item = MagicMock()
mocked_row_item.data.return_value = test_image
mocked_row_item.text.return_value = ''
self.media_item.list_view.selectedItems.return_value = [mocked_row_item]
# WHEN: Calling on_delete_click
self.media_item.on_delete_click()
# THEN: delete_file should have been called twice
assert mocked_delete_file.call_count == 2, 'delete_file() should have been called twice'
def test_create_item_from_id(self):
"""
Test that the create_item_from_id() method returns a valid QTreeWidgetItem with a pre-created ImageFilenames
"""
# GIVEN: An ImageFilenames that already exists in the database
image_file = ImageFilenames()
image_file.id = 1
image_file.file_path = Path('/', 'tmp', 'test_file_1.jpg')
self.media_item.manager = MagicMock()
self.media_item.manager.get_object_filtered.return_value = image_file
ImageFilenames.file_path = None
# WHEN: create_item_from_id() is called
item = self.media_item.create_item_from_id('1')
# THEN: A QTreeWidgetItem should be created with the above model object as it's data
assert isinstance(item, QtWidgets.QTreeWidgetItem)
assert 'test_file_1.jpg' == item.text(0)
item_data = item.data(0, QtCore.Qt.UserRole)
assert isinstance(item_data, ImageFilenames)
assert 1 == item_data.id
assert Path('/', 'tmp', 'test_file_1.jpg') == item_data.file_path
@patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_list')
def test_validate_and_load(mocked_load_list, mocked_media_item):
"""
Test that the validate_and_load_test() method when called without a group
"""
# GIVEN: A list of files
file_list = [Path('path1', 'image1.jpg'), Path('path2', 'image2.jpg')]
# WHEN: Calling validate_and_load with the list of files
mocked_media_item.validate_and_load(file_list)
# THEN: load_list should have been called with the file list and None,
# the directory should have been saved to the settings
mocked_load_list.assert_called_once_with(file_list, None)
Registry().get('settings').setValue.assert_called_once_with(ANY, Path('path1'))
@patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_list')
def test_validate_and_load_group(mocked_load_list, mocked_media_item):
"""
Test that the validate_and_load_test() method when called with a group
"""
# GIVEN: A list of files
file_list = [Path('path1', 'image1.jpg'), Path('path2', 'image2.jpg')]
# WHEN: Calling validate_and_load with the list of files and a group
mocked_media_item.validate_and_load(file_list, 'group')
# THEN: load_list should have been called with the file list and the group name,
# the directory should have been saved to the settings
mocked_load_list.assert_called_once_with(file_list, 'group')
Registry().get('settings').setValue.assert_called_once_with(ANY, Path('path1'))

View File

@ -0,0 +1,288 @@
# -*- coding: utf-8 -*-
##########################################################################
# OpenLP - Open Source Lyrics Projection #
# ---------------------------------------------------------------------- #
# Copyright (c) 2008-2020 OpenLP Developers #
# ---------------------------------------------------------------------- #
# 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, either version 3 of the License, or #
# (at your option) any later version. #
# #
# 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, see <https://www.gnu.org/licenses/>. #
##########################################################################
"""
This module contains tests for the lib submodule of the Images plugin.
"""
import pytest
from pathlib import Path
from unittest.mock import ANY, MagicMock, patch
from PyQt5 import QtCore, QtWidgets
from openlp.core.common.registry import Registry
from openlp.plugins.images.lib.db import ImageFilenames, ImageGroups
from openlp.plugins.images.lib.mediaitem import ImageMediaItem
@pytest.fixture
def media_item(mock_settings):
"""Local test setup"""
mocked_main_window = MagicMock()
Registry().register('service_list', MagicMock())
Registry().register('main_window', mocked_main_window)
Registry().register('live_controller', MagicMock())
mocked_plugin = MagicMock()
with patch('openlp.plugins.images.lib.mediaitem.MediaManagerItem._setup'), \
patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.setup_item'):
m_item = ImageMediaItem(None, mocked_plugin)
m_item.settings_section = 'images'
return m_item
def _recursively_delete_group_side_effect(*args, **kwargs):
"""
Side effect method that creates custom return values for the recursively_delete_group method
"""
if args[0] == ImageFilenames and args[1]:
# Create some fake objects that should be removed
returned_object1 = ImageFilenames()
returned_object1.id = 1
returned_object1.file_path = Path('/', 'tmp', 'test_file_1.jpg')
returned_object2 = ImageFilenames()
returned_object2.id = 2
returned_object2.file_path = Path('/', 'tmp', 'test_file_2.jpg')
returned_object3 = ImageFilenames()
returned_object3.id = 3
returned_object3.file_path = Path('/', 'tmp', 'test_file_3.jpg')
return [returned_object1, returned_object2, returned_object3]
if args[0] == ImageGroups and args[1]:
# Change the parent_id that is matched so we don't get into an endless loop
ImageGroups.parent_id = 0
# Create a fake group that will be used in the next run
returned_object1 = ImageGroups()
returned_object1.id = 1
return [returned_object1]
return []
@patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_full_list')
def test_save_new_images_list_empty_list(mocked_load_full_list, media_item):
"""
Test that the save_new_images_list() method handles empty lists gracefully
"""
# GIVEN: An empty image_list
image_list = []
media_item.manager = MagicMock()
# WHEN: We run save_new_images_list with the empty list
media_item.save_new_images_list(image_list)
# THEN: The save_object() method should not have been called
assert media_item.manager.save_object.call_count == 0, \
'The save_object() method should not have been called'
@patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_full_list')
def test_save_new_images_list_single_image_with_reload(mocked_load_full_list, media_item):
"""
Test that the save_new_images_list() calls load_full_list() when reload_list is set to True
"""
# GIVEN: A list with 1 image and a mocked out manager
image_list = [Path('test_image.jpg')]
ImageFilenames.file_path = None
media_item.manager = MagicMock()
# WHEN: We run save_new_images_list with reload_list=True
media_item.save_new_images_list(image_list, reload_list=True)
# THEN: load_full_list() should have been called
assert mocked_load_full_list.call_count == 1, 'load_full_list() should have been called'
# CLEANUP: Remove added attribute from ImageFilenames
delattr(ImageFilenames, 'file_path')
@patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_full_list')
def test_save_new_images_list_single_image_without_reload(mocked_load_full_list, media_item):
"""
Test that the save_new_images_list() doesn't call load_full_list() when reload_list is set to False
"""
# GIVEN: A list with 1 image and a mocked out manager
image_list = [Path('test_image.jpg')]
media_item.manager = MagicMock()
# WHEN: We run save_new_images_list with reload_list=False
media_item.save_new_images_list(image_list, reload_list=False)
# THEN: load_full_list() should not have been called
assert mocked_load_full_list.call_count == 0, 'load_full_list() should not have been called'
@patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_full_list')
def test_save_new_images_list_multiple_images(mocked_load_full_list, media_item):
"""
Test that the save_new_images_list() saves all images in the list
"""
# GIVEN: A list with 3 images
image_list = [Path('test_image_1.jpg'), Path('test_image_2.jpg'), Path('test_image_3.jpg')]
media_item.manager = MagicMock()
# WHEN: We run save_new_images_list with the list of 3 images
media_item.save_new_images_list(image_list, reload_list=False)
# THEN: load_full_list() should not have been called
assert media_item.manager.save_object.call_count == 3, \
'load_full_list() should have been called three times'
@patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_full_list')
def test_save_new_images_list_other_objects_in_list(mocked_load_full_list, media_item):
"""
Test that the save_new_images_list() ignores everything in the provided list except strings
"""
# GIVEN: A list with images and objects
image_list = [Path('test_image_1.jpg'), None, True, ImageFilenames(), Path('test_image_2.jpg')]
media_item.manager = MagicMock()
# WHEN: We run save_new_images_list with the list of images and objects
media_item.save_new_images_list(image_list, reload_list=False)
# THEN: load_full_list() should not have been called
assert media_item.manager.save_object.call_count == 2, 'load_full_list() should have been called only once'
def test_on_reset_click(media_item):
"""
Test that on_reset_click() actually resets the background
"""
# GIVEN: A mocked version of reset_action
media_item.reset_action = MagicMock()
media_item.reset_action_context = MagicMock()
# WHEN: on_reset_click is called
media_item.on_reset_click()
# THEN: the reset_action should be set visible, and the image should be reset
media_item.reset_action.setVisible.assert_called_with(False)
media_item.reset_action_context.setVisible.assert_called_with(False)
media_item.live_controller.display.reset_image.assert_called_with()
@patch('openlp.plugins.images.lib.mediaitem.delete_file')
def test_recursively_delete_group(mocked_delete_file, media_item):
"""
Test that recursively_delete_group() works
"""
# GIVEN: An ImageGroups object and mocked functions
ImageFilenames.group_id = 1
ImageGroups.parent_id = 1
media_item.manager = MagicMock()
media_item.manager.get_all_objects.side_effect = _recursively_delete_group_side_effect
media_item.service_path = Path()
test_group = ImageGroups()
test_group.id = 1
# WHEN: recursively_delete_group() is called
media_item.recursively_delete_group(test_group)
# THEN: delete_file() should have been called 12 times and manager.delete_object() 7 times.
assert mocked_delete_file.call_count == 12, 'delete_file() should have been called 12 times'
assert media_item.manager.delete_object.call_count == 7, \
'manager.delete_object() should be called exactly 7 times'
# CLEANUP: Remove added attribute from Image Filenames and ImageGroups
delattr(ImageFilenames, 'group_id')
delattr(ImageGroups, 'parent_id')
@patch('openlp.plugins.images.lib.mediaitem.delete_file')
@patch('openlp.plugins.images.lib.mediaitem.check_item_selected')
def test_on_delete_click(mocked_check_item_selected, mocked_delete_file, media_item):
"""
Test that on_delete_click() works
"""
# GIVEN: An ImageGroups object and mocked functions
mocked_check_item_selected.return_value = True
test_image = ImageFilenames()
test_image.id = 1
test_image.group_id = 1
test_image.file_path = Path('imagefile.png')
media_item.manager = MagicMock()
media_item.service_path = Path()
media_item.list_view = MagicMock()
mocked_row_item = MagicMock()
mocked_row_item.data.return_value = test_image
mocked_row_item.text.return_value = ''
media_item.list_view.selectedItems.return_value = [mocked_row_item]
# WHEN: Calling on_delete_click
media_item.on_delete_click()
# THEN: delete_file should have been called twice
assert mocked_delete_file.call_count == 2, 'delete_file() should have been called twice'
def test_create_item_from_id(media_item):
"""
Test that the create_item_from_id() method returns a valid QTreeWidgetItem with a pre-created ImageFilenames
"""
# GIVEN: An ImageFilenames that already exists in the database
image_file = ImageFilenames()
image_file.id = 1
image_file.file_path = Path('/', 'tmp', 'test_file_1.jpg')
media_item.manager = MagicMock()
media_item.manager.get_object_filtered.return_value = image_file
ImageFilenames.file_path = None
# WHEN: create_item_from_id() is called
item = media_item.create_item_from_id('1')
# THEN: A QTreeWidgetItem should be created with the above model object as it's data
assert isinstance(item, QtWidgets.QTreeWidgetItem)
assert 'test_file_1.jpg' == item.text(0)
item_data = item.data(0, QtCore.Qt.UserRole)
assert isinstance(item_data, ImageFilenames)
assert 1 == item_data.id
assert Path('/', 'tmp', 'test_file_1.jpg') == item_data.file_path
@patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_list')
def test_validate_and_load(mocked_load_list, media_item):
"""
Test that the validate_and_load_test() method when called without a group
"""
# GIVEN: A list of files
file_list = [Path('path1', 'image1.jpg'), Path('path2', 'image2.jpg')]
# WHEN: Calling validate_and_load with the list of files
media_item.validate_and_load(file_list)
# THEN: load_list should have been called with the file list and None,
# the directory should have been saved to the settings
mocked_load_list.assert_called_once_with(file_list, None)
Registry().get('settings').setValue.assert_called_once_with(ANY, Path('path1'))
@patch('openlp.plugins.images.lib.mediaitem.ImageMediaItem.load_list')
def test_validate_and_load_group(mocked_load_list, media_item):
"""
Test that the validate_and_load_test() method when called with a group
"""
# GIVEN: A list of files
file_list = [Path('path1', 'image1.jpg'), Path('path2', 'image2.jpg')]
# WHEN: Calling validate_and_load with the list of files and a group
media_item.validate_and_load(file_list, 'group')
# THEN: load_list should have been called with the file list and the group name,
# the directory should have been saved to the settings
mocked_load_list.assert_called_once_with(file_list, 'group')
Registry().get('settings').setValue.assert_called_once_with(ANY, Path('path1'))

View File

@ -21,66 +21,47 @@
"""
This module contains tests for the lib submodule of the Images plugin.
"""
import os
import pytest
import shutil
from pathlib import Path
from tempfile import mkdtemp
from unittest import TestCase, skip
from unittest.mock import patch
from sqlalchemy import create_engine
from openlp.core.common.applocation import AppLocation
from openlp.core.common.settings import Settings
from openlp.core.lib.db import Manager
from openlp.core.lib.db import upgrade_db
from openlp.plugins.images.lib import upgrade
from openlp.plugins.images.lib.db import ImageFilenames, init_schema
from tests.helpers.testmixin import TestMixin
from tests.utils.constants import TEST_RESOURCES_PATH
from tests.utils.constants import RESOURCE_PATH
__default_settings__ = {
'images/db type': 'sqlite',
'images/background color': '#000000',
}
@pytest.yield_fixture()
def temp_path():
tmp_path = Path(mkdtemp())
yield tmp_path
shutil.rmtree(tmp_path, ignore_errors=True)
class TestImageDBUpgrade(TestCase, TestMixin):
@pytest.yield_fixture()
def db_url():
tmp_path = Path(mkdtemp())
db_path = RESOURCE_PATH / 'images' / 'image-v0.sqlite'
db_tmp_path = tmp_path / 'image-v0.sqlite'
shutil.copyfile(db_path, db_tmp_path)
yield 'sqlite:///' + str(db_tmp_path)
shutil.rmtree(tmp_path, ignore_errors=True)
def test_image_filenames_table(db_url, settings):
"""
Test that the image database is upgraded correctly
Test that the ImageFilenames table is correctly upgraded to the latest version
"""
def setUp(self):
self.build_settings()
Settings().extend_default_settings(__default_settings__)
self.tmp_folder = mkdtemp()
# GIVEN: An unversioned image database
with patch.object(AppLocation, 'get_data_path', return_value=Path('/', 'test', 'dir')):
# WHEN: Initalising the database manager
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault
"""
self.destroy_settings()
# Ignore errors since windows can have problems with locked files
shutil.rmtree(self.tmp_folder, ignore_errors=True)
upgrade_db(db_url, upgrade)
@skip
# Broken due to Path issues.
def test_image_filenames_table(self):
"""
Test that the ImageFilenames table is correctly upgraded to the latest version
"""
# GIVEN: An unversioned image database
temp_db_name = os.path.join(self.tmp_folder, 'image-v0.sqlite')
shutil.copyfile(os.path.join(TEST_RESOURCES_PATH, 'images', 'image-v0.sqlite'), temp_db_name)
with patch.object(AppLocation, 'get_data_path', return_value=Path('/', 'test', 'dir')):
# WHEN: Initalising the database manager
manager = Manager('images', init_schema, db_file_path=Path(temp_db_name), upgrade_mod=upgrade)
# THEN: The database should have been upgraded and image_filenames.file_path should return Path objects
upgraded_results = manager.get_all_objects(ImageFilenames)
expected_result_data = {1: Path('/', 'test', 'image1.jpg'),
2: Path('/', 'test', 'dir', 'image2.jpg'),
3: Path('/', 'test', 'dir', 'subdir', 'image3.jpg')}
assert len(upgraded_results) == 3
for result in upgraded_results:
assert expected_result_data[result.id] == result.file_path
engine = create_engine(db_url)
conn = engine.connect()
assert conn.execute('SELECT * FROM metadata WHERE key = "version"').first().value == '2'

View File

@ -21,67 +21,48 @@
"""
Test the media plugin
"""
import pytest
from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, patch
from PyQt5 import QtCore
from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings
from openlp.plugins.media.lib.mediaitem import MediaMediaItem
from tests.helpers.testmixin import TestMixin
__default_settings__ = {
'media/media auto start': QtCore.Qt.Unchecked,
'media/media files': []
}
@pytest.fixture
def media_item(settings):
"""Local test setup"""
mocked_main_window = MagicMock()
Registry().register('service_list', MagicMock())
Registry().register('main_window', mocked_main_window)
Registry().register('live_controller', MagicMock())
mocked_plugin = MagicMock()
with patch('openlp.plugins.media.lib.mediaitem.MediaManagerItem._setup'), \
patch('openlp.plugins.media.lib.mediaitem.MediaMediaItem.setup_item'):
m_item = MediaMediaItem(None, mocked_plugin)
m_item.settings_section = 'media'
return m_item
class MediaItemTest(TestCase, TestMixin):
def test_search_found(media_item):
"""
Test the media item for Media
Media Remote Search Successful find
"""
# GIVEN: The Mediaitem set up a list of media
media_item.settings.setValue(media_item.settings_section + '/media files', [Path('test.mp3'), Path('test.mp4')])
# WHEN: Retrieving the test file
result = media_item.search('test.mp4', False)
# THEN: a file should be found
assert result == [['test.mp4', 'test.mp4']], 'The result file contain the file name'
def setUp(self):
"""
Set up the components need for all tests.
"""
with patch('openlp.plugins.media.lib.mediaitem.MediaManagerItem.__init__'),\
patch('openlp.plugins.media.lib.mediaitem.MediaMediaItem.setup'):
self.media_item = MediaMediaItem(None, MagicMock())
self.media_item.settings_section = 'media'
self.setup_application()
self.build_settings()
Registry.create()
self.settings = Settings()
Registry().register('settings', self.settings)
def tearDown(self):
"""
Clean up after the tests
"""
self.destroy_settings()
def test_search_found(self):
"""
Media Remote Search Successful find
"""
# GIVEN: The Mediaitem set up a list of media
self.settings.setValue(self.media_item.settings_section + '/media files', [Path('test.mp3'), Path('test.mp4')])
# WHEN: Retrieving the test file
result = self.media_item.search('test.mp4', False)
# THEN: a file should be found
assert result == [['test.mp4', 'test.mp4']], 'The result file contain the file name'
def test_search_not_found(self):
"""
Media Remote Search not find
"""
# GIVEN: The Mediaitem set up a list of media
self.settings.setValue(self.media_item.settings_section + '/media files', [Path('test.mp3'), Path('test.mp4')])
# WHEN: Retrieving the test file
result = self.media_item.search('test.mpx', False)
# THEN: a file should be found
assert result == [], 'The result file should be empty'
def test_search_not_found(media_item):
"""
Media Remote Search not find
"""
# GIVEN: The Mediaitem set up a list of media
media_item.settings.setValue(media_item.settings_section + '/media files', [Path('test.mp3'), Path('test.mp4')])
# WHEN: Retrieving the test file
result = media_item.search('test.mpx', False)
# THEN: a file should be found
assert result == [], 'The result file should be empty'

View File

@ -21,43 +21,30 @@
"""
Test the media plugin
"""
from unittest import TestCase
from unittest.mock import patch
from openlp.core.state import State
from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings
from openlp.plugins.media.mediaplugin import MediaPlugin
from tests.helpers.testmixin import TestMixin
class TestMediaPlugin(TestCase, TestMixin):
@patch('openlp.plugins.media.mediaplugin.Plugin.initialise')
def test_initialise(mock_initialise, state, settings):
"""
Test the media plugin
Test that the initialise() method overwrites the built-in one, but still calls it
"""
def setUp(self):
Registry.create()
Registry().register('settings', Settings())
State().load_settings()
# GIVEN: A media plugin instance
media_plugin = MediaPlugin()
@patch('openlp.plugins.media.mediaplugin.Plugin.initialise')
def test_initialise(self, mocked_initialise):
"""
Test that the initialise() method overwrites the built-in one, but still calls it
"""
# GIVEN: A media plugin instance
media_plugin = MediaPlugin()
# WHEN: initialise() is called
media_plugin.initialise()
# WHEN: initialise() is called
media_plugin.initialise()
# THEN: The the base initialise() method should be called
mock_initialise.assert_called_with()
# THEN: The the base initialise() method should be called
mocked_initialise.assert_called_with()
def test_about_text(self):
# GIVEN: The MediaPlugin
# WHEN: Retrieving the about text
# THEN: about() should return a string object
assert isinstance(MediaPlugin.about(), str)
# THEN: about() should return a non-empty string
assert len(MediaPlugin.about()) != 0
def test_about_text():
# GIVEN: The MediaPlugin
# WHEN: Retrieving the about text
# THEN: about() should return a string object
assert isinstance(MediaPlugin.about(), str)
# THEN: about() should return a non-empty string
assert len(MediaPlugin.about()) != 0

View File

@ -81,6 +81,7 @@ class TestPdfController(TestCase, TestMixin):
"""
Set up the components need for all tests.
"""
Registry().create()
self.setup_application()
self.build_settings()
# Mocked out desktop object

View File

@ -91,6 +91,8 @@ class TestPowerpointDocument(TestCase, TestMixin):
"""
Set up the patches and mocks need for all tests.
"""
Registry.create()
Registry().register('settings', Settings())
self.setup_application()
self.build_settings()
self.mock_plugin = MagicMock()
@ -111,8 +113,6 @@ class TestPowerpointDocument(TestCase, TestMixin):
self.file_name = os.path.join(TEST_RESOURCES_PATH, 'presentations', 'test.pptx')
self.real_controller = PowerpointController(self.mock_plugin)
Settings().extend_default_settings(__default_settings__)
Registry.create()
Registry().register('settings', Settings())
def tearDown(self):
"""

View File

@ -26,6 +26,8 @@ from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, call, patch
from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings
from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument
@ -37,6 +39,8 @@ class TestPresentationController(TestCase):
Test the PresentationController.
"""
def setUp(self):
Registry().create()
Registry().register('settings', Settings())
self.get_thumbnail_folder_patcher = \
patch('openlp.plugins.presentations.lib.presentationcontroller.PresentationDocument.get_thumbnail_folder',
return_value=Path())
@ -162,6 +166,7 @@ class TestPresentationDocument(TestCase):
"""
Set up the patches and mocks need for all tests.
"""
Registry().create()
self.create_paths_patcher = \
patch('openlp.plugins.presentations.lib.presentationcontroller.create_paths')
self.get_thumbnail_folder_patcher = \

View File

@ -42,10 +42,11 @@ class TestEditSongForm(TestCase, TestMixin):
Registry.create()
Registry().register('service_list', MagicMock())
Registry().register('main_window', MagicMock())
with patch('openlp.plugins.songs.forms.editsongform.EditSongForm.__init__', return_value=None):
self.edit_song_form = EditSongForm(None, MagicMock(), MagicMock())
self.setup_application()
self.build_settings()
Registry().register('settings', self.setting)
with patch('openlp.plugins.songs.forms.editsongform.EditSongForm.__init__', return_value=None):
self.edit_song_form = EditSongForm(None, MagicMock(), MagicMock())
QtCore.QLocale.setDefault(QtCore.QLocale('en_GB'))
def tearDown(self):

View File

@ -21,7 +21,7 @@
"""
This module contains tests for the SongShow Plus song importer.
"""
from unittest import TestCase
from unittest import skip
from unittest.mock import MagicMock, patch
from openlp.plugins.songs.lib import VerseType
@ -54,119 +54,120 @@ class TestSongShowPlusFileImport(SongImportTestHelper):
self.load_external_result_data(TEST_PATH / 'cleanse-me.json'))
class TestSongShowPlusImport(TestCase):
def test_create_importer(registry):
"""
Test the functions in the :mod:`songshowplusimport` module.
Test creating an instance of the SongShow Plus file importer
"""
def test_create_importer(self):
"""
Test creating an instance of the SongShow Plus file importer
"""
# GIVEN: A mocked out SongImport class, and a mocked out "manager"
with patch('openlp.plugins.songs.lib.importers.songshowplus.SongImport'):
mocked_manager = MagicMock()
# GIVEN: A mocked out SongImport class, and a mocked out "manager"
with patch('openlp.plugins.songs.lib.importers.songshowplus.SongImport'):
mocked_manager = MagicMock()
# WHEN: An importer object is created
importer = SongShowPlusImport(mocked_manager, file_paths=[])
# WHEN: An importer object is created
importer = SongShowPlusImport(mocked_manager, file_paths=[])
# THEN: The importer object should not be None
assert importer is not None, 'Import should not be none'
# THEN: The importer object should not be None
assert importer is not None, 'Import should not be none'
def test_invalid_import_source(self):
"""
Test SongShowPlusImport.do_import handles different invalid import_source values
"""
# GIVEN: A mocked out SongImport class, and a mocked out "manager"
with patch('openlp.plugins.songs.lib.importers.songshowplus.SongImport'):
mocked_manager = MagicMock()
mocked_import_wizard = MagicMock()
importer = SongShowPlusImport(mocked_manager, file_paths=[])
importer.import_wizard = mocked_import_wizard
importer.stop_import_flag = True
# WHEN: Import source is not a list
for source in ['not a list', 0]:
importer.import_source = source
def test_invalid_import_source(registry):
"""
Test SongShowPlusImport.do_import handles different invalid import_source values
"""
# GIVEN: A mocked out SongImport class, and a mocked out "manager"
with patch('openlp.plugins.songs.lib.importers.songshowplus.SongImport'):
mocked_manager = MagicMock()
mocked_import_wizard = MagicMock()
importer = SongShowPlusImport(mocked_manager, file_paths=[])
importer.import_wizard = mocked_import_wizard
importer.stop_import_flag = True
# THEN: do_import should return none and the progress bar maximum should not be set.
assert importer.do_import() is None, 'do_import should return None when import_source is not a list'
assert mocked_import_wizard.progress_bar.setMaximum.called is False, \
'setMaximum on import_wizard.progress_bar should not have been called'
# WHEN: Import source is not a list
for source in ['not a list', 0]:
importer.import_source = source
def test_valid_import_source(self):
"""
Test SongShowPlusImport.do_import handles different invalid import_source values
"""
# GIVEN: A mocked out SongImport class, and a mocked out "manager"
with patch('openlp.plugins.songs.lib.importers.songshowplus.SongImport'):
mocked_manager = MagicMock()
mocked_import_wizard = MagicMock()
importer = SongShowPlusImport(mocked_manager, file_paths=[])
importer.import_wizard = mocked_import_wizard
importer.stop_import_flag = True
# THEN: do_import should return none and the progress bar maximum should not be set.
assert importer.do_import() is None, 'do_import should return None when import_source is not a list'
assert mocked_import_wizard.progress_bar.setMaximum.called is False, \
'setMaximum on import_wizard.progress_bar should not have been called'
# WHEN: Import source is a list
importer.import_source = ['List', 'of', 'files']
# THEN: do_import should return none and the progress bar setMaximum should be called with the length of
# import_source.
assert importer.do_import() is None, \
'do_import should return None when import_source is a list and stop_import_flag is True'
mocked_import_wizard.progress_bar.setMaximum.assert_called_with(len(importer.import_source))
def test_valid_import_source(registry):
"""
Test SongShowPlusImport.do_import handles different invalid import_source values
"""
# GIVEN: A mocked out SongImport class, and a mocked out "manager"
with patch('openlp.plugins.songs.lib.importers.songshowplus.SongImport'):
mocked_manager = MagicMock()
mocked_import_wizard = MagicMock()
importer = SongShowPlusImport(mocked_manager, file_paths=[])
importer.import_wizard = mocked_import_wizard
importer.stop_import_flag = True
def test_to_openlp_verse_tag(self):
"""
Test to_openlp_verse_tag method by simulating adding a verse
"""
# GIVEN: A mocked out SongImport class, and a mocked out "manager"
with patch('openlp.plugins.songs.lib.importers.songshowplus.SongImport'):
mocked_manager = MagicMock()
importer = SongShowPlusImport(mocked_manager, file_paths=[])
# WHEN: Import source is a list
importer.import_source = ['List', 'of', 'files']
# WHEN: Supplied with the following arguments replicating verses being added
test_values = [
('Verse 1', VerseType.tags[VerseType.Verse] + '1'),
('Verse 2', VerseType.tags[VerseType.Verse] + '2'),
('verse1', VerseType.tags[VerseType.Verse] + '1'),
('Verse', VerseType.tags[VerseType.Verse] + '1'),
('Verse1', VerseType.tags[VerseType.Verse] + '1'),
('chorus 1', VerseType.tags[VerseType.Chorus] + '1'),
('bridge 1', VerseType.tags[VerseType.Bridge] + '1'),
('pre-chorus 1', VerseType.tags[VerseType.PreChorus] + '1'),
('different 1', VerseType.tags[VerseType.Other] + '1'),
('random 1', VerseType.tags[VerseType.Other] + '2')]
# THEN: do_import should return none and the progress bar setMaximum should be called with the length of
# import_source.
assert importer.do_import() is None, \
'do_import should return None when import_source is a list and stop_import_flag is True'
mocked_import_wizard.progress_bar.setMaximum.assert_called_with(len(importer.import_source))
# THEN: The returned value should should correlate with the input arguments
for original_tag, openlp_tag in test_values:
assert importer.to_openlp_verse_tag(original_tag) == openlp_tag, \
'SongShowPlusImport.to_openlp_verse_tag should return "%s" when called with "%s"' % \
(openlp_tag, original_tag)
def test_to_openlp_verse_tag_verse_order(self):
"""
Test to_openlp_verse_tag method by simulating adding a verse to the verse order
"""
# GIVEN: A mocked out SongImport class, and a mocked out "manager"
with patch('openlp.plugins.songs.lib.importers.songshowplus.SongImport'):
mocked_manager = MagicMock()
importer = SongShowPlusImport(mocked_manager, file_paths=[])
def test_to_openlp_verse_tag_unique(registry):
"""
Test to_openlp_verse_tag method by simulating adding a verse
"""
# GIVEN: A mocked out SongImport class, and a mocked out "manager"
with patch('openlp.plugins.songs.lib.importers.songshowplus.SongImport'):
mocked_manager = MagicMock()
importer = SongShowPlusImport(mocked_manager, file_paths=[])
# WHEN: Supplied with the following arguments replicating a verse order being added
test_values = [
('Verse 1', VerseType.tags[VerseType.Verse] + '1'),
('Verse 2', VerseType.tags[VerseType.Verse] + '2'),
('verse1', VerseType.tags[VerseType.Verse] + '1'),
('Verse', VerseType.tags[VerseType.Verse] + '1'),
('Verse1', VerseType.tags[VerseType.Verse] + '1'),
('chorus 1', VerseType.tags[VerseType.Chorus] + '1'),
('bridge 1', VerseType.tags[VerseType.Bridge] + '1'),
('pre-chorus 1', VerseType.tags[VerseType.PreChorus] + '1'),
('different 1', VerseType.tags[VerseType.Other] + '1'),
('random 1', VerseType.tags[VerseType.Other] + '2'),
('unused 2', None)]
# WHEN: Supplied with the following arguments replicating verses being added
test_values = [
('Verse 1', VerseType.tags[VerseType.Verse] + '1'),
('Verse 2', VerseType.tags[VerseType.Verse] + '2'),
('verse1', VerseType.tags[VerseType.Verse] + '1'),
('Verse', VerseType.tags[VerseType.Verse] + '1'),
('Verse1', VerseType.tags[VerseType.Verse] + '1'),
('chorus 1', VerseType.tags[VerseType.Chorus] + '1'),
('bridge 1', VerseType.tags[VerseType.Bridge] + '1'),
('pre-chorus 1', VerseType.tags[VerseType.PreChorus] + '1'),
('different 1', VerseType.tags[VerseType.Other] + '1'),
('random 1', VerseType.tags[VerseType.Other] + '2')]
# THEN: The returned value should should correlate with the input arguments
for original_tag, openlp_tag in test_values:
assert importer.to_openlp_verse_tag(original_tag, ignore_unique=True) == openlp_tag, \
'SongShowPlusImport.to_openlp_verse_tag should return "%s" when called with "%s"' % \
(openlp_tag, original_tag)
# THEN: The returned value should should correlate with the input arguments
for original_tag, openlp_tag in test_values:
assert importer.to_openlp_verse_tag(original_tag) == openlp_tag, \
'SongShowPlusImport.to_openlp_verse_tag should return "%s" when called with "%s"' % \
(openlp_tag, original_tag)
@skip('Broken never worked')
def test_to_openlp_verse_tag_verse_order(registry):
"""
Test to_openlp_verse_tag method by simulating adding a verse to the verse order
"""
# GIVEN: A mocked out SongImport class, and a mocked out "manager"
with patch('openlp.plugins.songs.lib.importers.songshowplus.SongImport'):
mocked_manager = MagicMock()
importer = SongShowPlusImport(mocked_manager, file_paths=[])
# WHEN: Supplied with the following arguments replicating a verse order being added
test_values = [
('Verse 1', VerseType.tags[VerseType.Verse] + '1'),
('Verse 2', VerseType.tags[VerseType.Verse] + '2'),
('verse1', VerseType.tags[VerseType.Verse] + '1'),
('Verse', VerseType.tags[VerseType.Verse] + '1'),
('Verse1', VerseType.tags[VerseType.Verse] + '1'),
('chorus 1', VerseType.tags[VerseType.Chorus] + '1'),
('bridge 1', VerseType.tags[VerseType.Bridge] + '1'),
('pre-chorus 1', VerseType.tags[VerseType.PreChorus] + '1'),
('different 1', VerseType.tags[VerseType.Other] + '1'),
('random 1', VerseType.tags[VerseType.Other] + '2'),
('unused 2', None)]
# THEN: The returned value should should correlate with the input arguments
for original_tag, openlp_tag in test_values:
assert importer.to_openlp_verse_tag(original_tag, ignore_unique=True) == openlp_tag, \
'SongShowPlusImport.to_openlp_verse_tag should return "%s" when called with "%s"' % \
(openlp_tag, original_tag)

View File

@ -42,7 +42,7 @@ def test_about_text(state, mock_settings):
@patch('openlp.plugins.songusage.songusageplugin.Manager')
def test_song_usage_init(MockedManager, settings):
def test_song_usage_init(MockedManager, settings, state):
"""
Test the initialisation of the SongUsagePlugin class
"""
@ -60,7 +60,7 @@ def test_song_usage_init(MockedManager, settings):
@patch('openlp.plugins.songusage.songusageplugin.Manager')
def test_check_pre_conditions(MockedManager, settings):
def test_check_pre_conditions(MockedManager, settings, state):
"""
Test that check_pre_condition returns true for valid manager session
"""
@ -78,7 +78,7 @@ def test_check_pre_conditions(MockedManager, settings):
@patch('openlp.plugins.songusage.songusageplugin.Manager')
def test_toggle_song_usage_state(MockedManager, settings):
def test_toggle_song_usage_state(MockedManager, settings, state):
"""
Test that toggle_song_usage_state does toggle song_usage_state
"""

View File

@ -42,14 +42,14 @@ class SongImportTestHelper(TestCase):
self.importer_module = __import__('openlp.plugins.songs.lib.importers.%s' %
self.importer_module_name, fromlist=[self.importer_class_name])
self.importer_class = getattr(self.importer_module, self.importer_class_name)
Registry.create()
Registry().register('settings', MagicMock())
self.settings = Registry().get('settings')
def setUp(self):
"""
Patch and set up the mocks required.
"""
Registry.create()
Registry().register('settings', MagicMock())
self.settings = Registry().get('settings')
self.add_copyright_patcher = patch('openlp.plugins.songs.lib.importers.%s.%s.add_copyright' %
(self.importer_module_name, self.importer_class_name))
self.add_verse_patcher = patch('openlp.plugins.songs.lib.importers.%s.%s.add_verse' %

View File

@ -21,10 +21,10 @@
"""
Package to test the openlp.core.ui.themeform package.
"""
# from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, patch
from openlp.core.common.registry import Registry
from openlp.core.ui.themeprogressform import ThemeProgressForm
from tests.helpers.testmixin import TestMixin
@ -102,6 +102,9 @@ class TestThemeProgressForm(TestCase, TestMixin):
def test_get_preview(self):
"""Test that the get_preview() method returns a preview image"""
# GIVEN: ThemeProgressForm object
Registry.create()
mocked_renderer = MagicMock()
Registry().register('renderer', mocked_renderer)
test_theme_name = 'Test Theme'
test_theme_data = {'name': test_theme_name}
form = self._get_theme_progress_form()