diff --git a/openlp/core/common/settings.py b/openlp/core/common/settings.py
index a3804c1c0..8fa15abca 100644
--- a/openlp/core/common/settings.py
+++ b/openlp/core/common/settings.py
@@ -213,6 +213,7 @@ class Settings(QtCore.QSettings):
'bibles/second bibles': True,
'bibles/status': PluginStatus.Inactive,
'bibles/primary bible': '',
+ 'bibles/second bible': None,
'bibles/bible theme': '',
'bibles/verse separator': '',
'bibles/range separator': '',
diff --git a/openlp/plugins/bibles/lib/biblestab.py b/openlp/plugins/bibles/lib/biblestab.py
index 9347d8c47..502424f50 100644
--- a/openlp/plugins/bibles/lib/biblestab.py
+++ b/openlp/plugins/bibles/lib/biblestab.py
@@ -366,41 +366,45 @@ class BiblesTab(SettingsTab):
self.layout_style_combo_box.setCurrentIndex(self.layout_style)
self.bible_second_check_box.setChecked(self.second_bibles)
verse_separator = self.settings.value('bibles/verse separator')
- if (verse_separator.strip('|') == '') or (verse_separator == get_reference_separator('sep_v_default')):
+ if verse_separator.strip('|') == '':
self.verse_separator_line_edit.setText(get_reference_separator('sep_v_default'))
self.verse_separator_line_edit.setPalette(self.get_grey_text_palette(True))
self.verse_separator_check_box.setChecked(False)
else:
self.verse_separator_line_edit.setText(verse_separator)
self.verse_separator_line_edit.setPalette(self.get_grey_text_palette(False))
- self.verse_separator_check_box.setChecked(True)
+ verse_separator_set = self.settings.contains('bibles/verse separator')
+ self.verse_separator_check_box.setChecked(verse_separator_set)
range_separator = self.settings.value('bibles/range separator')
- if (range_separator.strip('|') == '') or (range_separator == get_reference_separator('sep_r_default')):
+ if range_separator.strip('|') == '':
self.range_separator_line_edit.setText(get_reference_separator('sep_r_default'))
self.range_separator_line_edit.setPalette(self.get_grey_text_palette(True))
self.range_separator_check_box.setChecked(False)
else:
self.range_separator_line_edit.setText(range_separator)
self.range_separator_line_edit.setPalette(self.get_grey_text_palette(False))
- self.range_separator_check_box.setChecked(True)
+ range_separator_set = self.settings.contains('bibles/range separator')
+ self.range_separator_check_box.setChecked(range_separator_set)
list_separator = self.settings.value('bibles/list separator')
- if (list_separator.strip('|') == '') or (list_separator == get_reference_separator('sep_l_default')):
+ if list_separator.strip('|') == '':
self.list_separator_line_edit.setText(get_reference_separator('sep_l_default'))
self.list_separator_line_edit.setPalette(self.get_grey_text_palette(True))
self.list_separator_check_box.setChecked(False)
else:
self.list_separator_line_edit.setText(list_separator)
self.list_separator_line_edit.setPalette(self.get_grey_text_palette(False))
- self.list_separator_check_box.setChecked(True)
+ list_separator_set = self.settings.contains('bibles/list separator')
+ self.list_separator_check_box.setChecked(list_separator_set)
end_separator = self.settings.value('bibles/end separator')
- if (end_separator.strip('|') == '') or (end_separator == get_reference_separator('sep_e_default')):
+ if end_separator.strip('|') == '':
self.end_separator_line_edit.setText(get_reference_separator('sep_e_default'))
self.end_separator_line_edit.setPalette(self.get_grey_text_palette(True))
self.end_separator_check_box.setChecked(False)
else:
self.end_separator_line_edit.setText(end_separator)
self.end_separator_line_edit.setPalette(self.get_grey_text_palette(False))
- self.end_separator_check_box.setChecked(True)
+ end_separator_set = self.settings.contains('bibles/end separator')
+ self.end_separator_check_box.setChecked(end_separator_set)
self.language_selection = self.settings.value('bibles/book name language')
self.language_selection_combo_box.setCurrentIndex(self.language_selection)
self.reset_to_combined_quick_search = self.settings.value('bibles/reset to combined quick search')
diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py
index 4ece90568..acfc75403 100755
--- a/openlp/plugins/bibles/lib/mediaitem.py
+++ b/openlp/plugins/bibles/lib/mediaitem.py
@@ -329,6 +329,8 @@ class BibleMediaItem(MediaManagerItem):
:return: None
"""
log.debug('Loading Bibles')
+ self.version_combo_box.blockSignals(True)
+ self.second_combo_box.blockSignals(True)
self.version_combo_box.clear()
self.second_combo_box.clear()
self.second_combo_box.addItem('', None)
@@ -336,14 +338,16 @@ class BibleMediaItem(MediaManagerItem):
bibles = self.plugin.manager.get_bibles()
bibles = [(_f, bibles[_f]) for _f in bibles if _f]
bibles.sort(key=lambda k: get_locale_key(k[0]))
- self.version_combo_box.blockSignals(True)
for bible in bibles:
self.version_combo_box.addItem(bible[0], bible[1])
self.second_combo_box.addItem(bible[0], bible[1])
self.version_combo_box.blockSignals(False)
+ self.second_combo_box.blockSignals(False)
# set the default value
bible = self.settings.value('bibles/primary bible')
+ second_bible = self.settings.value('bibles/second bible')
find_and_set_in_combo_box(self.version_combo_box, bible)
+ find_and_set_in_combo_box(self.second_combo_box, second_bible)
# make sure the selected bible ripples down to other gui elements
self.on_version_combo_box_index_changed()
@@ -591,8 +595,10 @@ class BibleMediaItem(MediaManagerItem):
self.second_bible = new_selection
if new_selection is None:
self.style_combo_box.setEnabled(True)
+ self.settings.setValue('bibles/second bible', None)
else:
self.style_combo_box.setEnabled(False)
+ self.settings.setValue('bibles/second bible', self.second_bible.name)
self.initialise_advanced_bible(self.select_book_combo_box.currentData())
def on_advanced_book_combo_box(self):
@@ -729,7 +735,7 @@ class BibleMediaItem(MediaManagerItem):
verse_refs = self.plugin.manager.parse_ref(self.bible.name, search_text)
self.search_results = self.plugin.manager.get_verses(self.bible.name, verse_refs, True)
if self.second_bible and self.search_results:
- self.search_results = self.plugin.manager.get_verses(self.second_bible.name, verse_refs, True)
+ self.second_search_results = self.plugin.manager.get_verses(self.second_bible.name, verse_refs, True)
self.display_results()
def on_text_search(self, text):
@@ -909,7 +915,7 @@ class BibleMediaItem(MediaManagerItem):
Generate the slide data. Needs to be implemented by the plugin.
:param service_item: The service item to be built on
- :param item: The Song item to be used
+ :param item: The Bible items to be used
:param remote: Triggered from remote
:param context: Why is it being generated
:param kwargs: Consume other unused args specified by the base implementation, but not use by this one.
@@ -950,6 +956,24 @@ class BibleMediaItem(MediaManagerItem):
bible_text = '{bible} {verse}{data[text]}'.format(bible=bible_text, verse=verse_text, data=data)
bible_text = bible_text.strip(' ')
old_chapter = data['chapter']
+ # Add service item data (handy things for http api)
+ # Bibles in array to make api compatible with any number of bibles.
+ bibles = []
+ if data['version']:
+ bibles.append({
+ 'version': data['version'],
+ 'copyright': data['copyright'],
+ 'permissions': data['permissions']
+ })
+ if data['second_bible']:
+ bibles.append({
+ 'version': data['second_version'],
+ 'copyright': data['second_copyright'],
+ 'permissions': data['second_permissions']
+ })
+ service_item.data_string = {
+ 'bibles': bibles
+ }
# Add footer
service_item.raw_footer.append(verses.format_verses())
if data['second_bible']:
diff --git a/tests/functional/openlp_plugins/bibles/test_mediaitem.py b/tests/functional/openlp_plugins/bibles/test_mediaitem.py
index 37ba7c325..ff9129609 100644
--- a/tests/functional/openlp_plugins/bibles/test_mediaitem.py
+++ b/tests/functional/openlp_plugins/bibles/test_mediaitem.py
@@ -322,23 +322,26 @@ def test_populate_bible_combo_boxes(media_item):
bible_1 = MagicMock()
bible_2 = MagicMock()
bible_3 = MagicMock()
- media_item.settings.value = lambda key: {'bibles/primary bible': bible_2}[key]
+ media_item.settings.value = lambda key: {'bibles/primary bible': bible_2, 'bibles/second bible': bible_3}[key]
media_item.version_combo_box = MagicMock()
media_item.second_combo_box = MagicMock()
media_item.plugin.manager.get_bibles.return_value = \
{'Bible 2': bible_2, 'Bible 1': bible_1, 'Bible 3': bible_3}
with patch('openlp.plugins.bibles.lib.mediaitem.get_locale_key', side_effect=lambda x: x), \
- patch('openlp.plugins.bibles.lib.mediaitem.find_and_set_in_combo_box'), \
+ patch('openlp.plugins.bibles.lib.mediaitem.find_and_set_in_combo_box') as mocked_set_combo_box, \
patch.object(media_item, 'on_version_combo_box_index_changed'):
# WHEN: Calling populate_bible_combo_boxes
media_item.populate_bible_combo_boxes()
# THEN: The bible combo boxes should be filled with the bible names and data, in a sorted order.
+ # Also check the correct combo box has been selected according to the settings
media_item.version_combo_box.addItem.assert_has_calls(
[call('Bible 1', bible_1), call('Bible 2', bible_2), call('Bible 3', bible_3)])
media_item.second_combo_box.addItem.assert_has_calls(
[call('', None), call('Bible 1', bible_1), call('Bible 2', bible_2), call('Bible 3', bible_3)])
+ mocked_set_combo_box.assert_has_calls(
+ [call(media_item.version_combo_box, bible_2), call(media_item.second_combo_box, bible_3)])
def test_reload_bibles(media_item):
@@ -819,6 +822,7 @@ def test_on_second_combo_box_index_changed_mode_not_changed(media_item):
assert mocked_critical_error_message_box.called is False
media_item.style_combo_box.setEnabled.assert_called_once_with(False)
assert media_item.second_bible == mocked_bible_2
+ media_item.settings.setValue.assert_called_once_with('bibles/second bible', 'Bible 2')
def test_on_second_combo_box_index_changed_single_to_dual_user_abort(media_item):
@@ -846,6 +850,7 @@ def test_on_second_combo_box_index_changed_single_to_dual_user_abort(media_item)
assert media_item.second_combo_box.setCurrentIndex.called is True
assert media_item.style_combo_box.setEnabled.called is False
assert media_item.second_bible is None
+ media_item.settings.setValue.assert_not_called()
def test_on_second_combo_box_index_changed_single_to_dual(media_item):
@@ -875,6 +880,7 @@ def test_on_second_combo_box_index_changed_single_to_dual(media_item):
media_item.style_combo_box.setEnabled.assert_called_once_with(False)
assert mocked_initialise_advanced_bible.called is True
assert media_item.second_bible == mocked_bible_1
+ media_item.settings.setValue.assert_called_once_with('bibles/second bible', 'Bible 1')
def test_on_second_combo_box_index_changed_dual_to_single(media_item):
@@ -903,6 +909,7 @@ def test_on_second_combo_box_index_changed_dual_to_single(media_item):
media_item.style_combo_box.setEnabled.assert_called_once_with(True)
assert mocked_initialise_advanced_bible.called is False
assert media_item.second_bible is None
+ media_item.settings.setValue.assert_called_once_with('bibles/second bible', None)
def test_on_advanced_book_combo_box(media_item):
@@ -1319,12 +1326,17 @@ def test_text_reference_search_dual_bible(media_item):
with patch.object(media_item, 'display_results') as mocked_display_results:
media_item.bible = mocked_bible_1
media_item.second_bible = mocked_bible_2
+ media_item.search_results = ''
+ media_item.second_search_results = ''
+ media_item.plugin.manager.get_verses.side_effect = lambda x, y, z: x
# WHEN: Calling text_reference_search with two bibles selected
media_item.text_reference_search('Search Text')
# THEN: reference_search should be called twice
assert media_item.plugin.manager.get_verses.call_count == 2
+ assert media_item.search_results == 'Bible 1'
+ assert media_item.second_search_results == 'Bible 2'
mocked_display_results.assert_called_once_with()
@@ -1580,3 +1592,82 @@ def test_set_search_option_invalid_value(media_item):
assert result is False
media_item.settings.setValue.assert_not_called()
populate_bible_combo_boxes.assert_not_called()
+
+
+def test_generate_slide_data_data_string(media_item):
+ """
+ Test that the generated_slide_data provides data values for the api
+ """
+ # GIVEN: Mocked service item and some pretend bible slide data
+ mocked_service_item = MagicMock()
+ slide_data = {
+ 'book': 'Matthew',
+ 'chapter': '1',
+ 'verse': '2',
+ 'version': 'Bible version 104',
+ 'copyright': 'copywrong',
+ 'permissions': 'all the permissions',
+ 'second_bible': 'Second bible thing',
+ 'second_copyright': 'copywrite',
+ 'second_permissions': 'no use allowed',
+ 'second_version': 'Bible version 4567',
+ 'text': 'text from matthew 1:2',
+ 'second_text': 'different text from matthew 1:2'
+ }
+ mocked_items = [MagicMock(**{'data.return_value': slide_data})]
+ media_item.format_verse = MagicMock()
+ media_item.settings_tab = MagicMock()
+
+ # WHEN: Called generate_slide_data
+ media_item.generate_slide_data(mocked_service_item, item=mocked_items)
+
+ # THEN: both primary and secondary bible info should be included in the returned service item data string
+ assert mocked_service_item.data_string == {
+ 'bibles': [
+ {
+ 'version': 'Bible version 104',
+ 'copyright': 'copywrong',
+ 'permissions': 'all the permissions'
+ },
+ {
+ 'version': 'Bible version 4567',
+ 'copyright': 'copywrite',
+ 'permissions': 'no use allowed'
+ }
+ ]
+ }
+
+
+def test_generate_slide_data_data_string_one_bible(media_item):
+ """
+ Test that the generated_slide_data provides data values for the api
+ """
+ # GIVEN: Mocked service item and some pretend bible slide data
+ mocked_service_item = MagicMock()
+ slide_data = {
+ 'book': 'Matthew',
+ 'chapter': '1',
+ 'verse': '2',
+ 'version': 'Bible version 104',
+ 'copyright': 'copywrong',
+ 'permissions': 'all the permissions',
+ 'second_bible': '',
+ 'text': 'text from matthew 1:2'
+ }
+ mocked_items = [MagicMock(**{'data.return_value': slide_data})]
+ media_item.format_verse = MagicMock()
+ media_item.settings_tab = MagicMock()
+
+ # WHEN: Called generate_slide_data
+ media_item.generate_slide_data(mocked_service_item, item=mocked_items)
+
+ # THEN: both primary and secondary bible info should be included in the returned service item data string
+ assert mocked_service_item.data_string == {
+ 'bibles': [
+ {
+ 'version': 'Bible version 104',
+ 'copyright': 'copywrong',
+ 'permissions': 'all the permissions'
+ }
+ ]
+ }
diff --git a/tests/functional/openlp_plugins/songs/test_songstab.py b/tests/functional/openlp_plugins/songs/test_songstab.py
index cc7fb399d..7bafa00f2 100644
--- a/tests/functional/openlp_plugins/songs/test_songstab.py
+++ b/tests/functional/openlp_plugins/songs/test_songstab.py
@@ -19,7 +19,7 @@
# along with this program. If not, see . #
##########################################################################
"""
-This module contains tests for the lib submodule of the Images plugin.
+This module contains tests for the lib submodule of the Songs plugin.
"""
import pytest
from unittest.mock import MagicMock, patch
diff --git a/tests/interfaces/openlp_plugins/bibles/test_lib_parse_reference.py b/tests/interfaces/openlp_plugins/bibles/test_lib_parse_reference.py
index e97a99cc3..8b63b776c 100644
--- a/tests/interfaces/openlp_plugins/bibles/test_lib_parse_reference.py
+++ b/tests/interfaces/openlp_plugins/bibles/test_lib_parse_reference.py
@@ -25,17 +25,28 @@ import pytest
from unittest.mock import MagicMock, patch
from openlp.core.common.registry import Registry
-from openlp.plugins.bibles.lib import parse_reference
+from openlp.plugins.bibles.lib import parse_reference, update_reference_separators
from openlp.plugins.bibles.lib.manager import BibleManager
from tests.utils.constants import TEST_RESOURCES_PATH
+__default_settings__ = {
+ 'bibles/verse separator': '',
+ 'bibles/range separator': '',
+ 'bibles/list separator': '',
+ 'bibles/end separator': ''
+}
+
+
@pytest.fixture()
def manager(settings):
Registry().register('service_list', MagicMock())
+ # set default separators to the empty default values
+ Registry().get('settings').extend_default_settings(__default_settings__)
with patch('openlp.core.common.applocation.AppLocation.get_section_data_path') as mocked_get_data_path, \
patch('openlp.core.common.applocation.AppLocation.get_files') as mocked_get_files:
# GIVEN: A mocked out AppLocation.get_files()
+ update_reference_separators()
mocked_get_files.return_value = ["tests.sqlite"]
mocked_get_data_path.return_value = TEST_RESOURCES_PATH + "/bibles"
return BibleManager(MagicMock())
diff --git a/tests/openlp_plugins/bibles/test_biblestab.py b/tests/openlp_plugins/bibles/test_biblestab.py
new file mode 100644
index 000000000..34e045929
--- /dev/null
+++ b/tests/openlp_plugins/bibles/test_biblestab.py
@@ -0,0 +1,84 @@
+# -*- coding: utf-8 -*-
+
+##########################################################################
+# OpenLP - Open Source Lyrics Projection #
+# ---------------------------------------------------------------------- #
+# Copyright (c) 2008-2021 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 . #
+##########################################################################
+"""
+This module contains tests for the lib submodule of the Bible plugin.
+"""
+import pytest
+from unittest.mock import MagicMock
+
+from openlp.core.common.registry import Registry
+from openlp.plugins.bibles.lib.biblestab import BiblesTab
+
+__default_settings__ = {
+ 'bibles/verse separator': 'verse separator',
+ 'bibles/range separator': 'range separator',
+ 'bibles/list separator': 'list separator',
+ 'bibles/end separator': 'end separator'
+}
+
+
+@pytest.fixture()
+def form(settings):
+ Registry().register('settings_form', MagicMock())
+ Registry().get('settings').extend_default_settings(__default_settings__)
+ frm = BiblesTab(None, 'Songs', None, None)
+ frm.settings_form.register_post_process = MagicMock()
+ return frm
+
+
+def test_load_when_seperators_set_on_default(form):
+ """
+ Test that the separator checkboxes are still checked even when the default is used
+ """
+ # GIVEN: Seperator settings set as the default
+ form.settings.setValue('bibles/verse separator', form.settings.value('bibles/verse separator'))
+ form.settings.setValue('bibles/range separator', form.settings.value('bibles/range separator'))
+ form.settings.setValue('bibles/list separator', form.settings.value('bibles/list separator'))
+ form.settings.setValue('bibles/end separator', form.settings.value('bibles/end separator'))
+
+ # WHEN: Load is invoked
+ form.load()
+
+ # THEN: The checkboxes should be checked
+ assert form.verse_separator_check_box.isChecked() is True
+ assert form.range_separator_check_box.isChecked() is True
+ assert form.list_separator_check_box.isChecked() is True
+ assert form.end_separator_check_box.isChecked() is True
+
+
+def test_load_when_seperators_unset(form):
+ """
+ Test that the separator checkboxes are not checked when the setting is not set
+ """
+ # GIVEN: Seperator settings non existant
+ form.settings.remove('bibles/verse separator')
+ form.settings.remove('bibles/range separator')
+ form.settings.remove('bibles/list separator')
+ form.settings.remove('bibles/end separator')
+
+ # WHEN: Load is invoked
+ form.load()
+
+ # THEN: The checkboxes should be checked
+ assert form.verse_separator_check_box.isChecked() is False
+ assert form.range_separator_check_box.isChecked() is False
+ assert form.list_separator_check_box.isChecked() is False
+ assert form.end_separator_check_box.isChecked() is False