forked from openlp/openlp
Merge branch 'fix-unreadable-footer-380' into 'master'
Fix up the formatting of the contents of the help box Closes #380 See merge request openlp/openlp!163
This commit is contained in:
commit
fb006dabcd
@ -250,7 +250,7 @@ def build_icon(icon):
|
||||
pix_map = QtGui.QPixmap(icon)
|
||||
elif isinstance(icon, Path):
|
||||
pix_map = QtGui.QPixmap(str(icon))
|
||||
elif isinstance(icon, QtGui.QImage):
|
||||
elif isinstance(icon, QtGui.QImage): # pragma: no cover
|
||||
pix_map = QtGui.QPixmap.fromImage(icon)
|
||||
if pix_map:
|
||||
button_icon.addPixmap(pix_map, QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
|
@ -154,17 +154,16 @@ class SongsTab(SettingsTab):
|
||||
['ccli_number', translate('SongsPlugin.SongsTab', 'Song CCLI Number'), True, False],
|
||||
['topics', translate('SongsPlugin.SongsTab', 'Topics'), False, True],
|
||||
]
|
||||
placeholder_info = '<table style="background: #eee">\n<tr><th><b>{ph}</b></th><th><b>{desc}</b></th></tr>\n'\
|
||||
.format(ph=translate('SongsPlugin.SongsTab', 'Placeholder'),
|
||||
desc=translate('SongsPlugin.SongsTab', 'Description'))
|
||||
placeholder_info = '<table><tr><th><b>{ph}</b></th><th><b>{desc}</b></th></tr>'.format(
|
||||
ph=translate('SongsPlugin.SongsTab', 'Placeholder'), desc=translate('SongsPlugin.SongsTab', 'Description'))
|
||||
for placeholder in placeholders:
|
||||
placeholder_info += '<tr><td>${{{pl}}}</td><td>{des}{opt}</td></tr>\n'\
|
||||
.format(pl=placeholder[0], des=placeholder[1],
|
||||
opt=(' ¹' if placeholder[2] else '') +
|
||||
(' ²' if placeholder[3] else ''))
|
||||
placeholder_info += '<tr><td>${{{pl}}}</td><td>{des}{opt}</td></tr>'.format(
|
||||
pl=placeholder[0], des=placeholder[1], opt=(' <sup>1</sup>' if placeholder[2] else '') +
|
||||
(' <sup>2</sup>' if placeholder[3] else ''))
|
||||
placeholder_info += '</table>'
|
||||
placeholder_info += '\n<br/>¹ {}'.format(translate('SongsPlugin.SongsTab', 'can be empty'))
|
||||
placeholder_info += '\n<br/>² {}'.format(translate('SongsPlugin.SongsTab', 'list of entries, can be empty'))
|
||||
placeholder_info += '<p><sup>1</sup> {}<br/>'.format(translate('SongsPlugin.SongsTab', 'can be empty'))
|
||||
placeholder_info += '<sup>2</sup> {}</p>'.format(
|
||||
translate('SongsPlugin.SongsTab', 'list of entries, can be empty'))
|
||||
self.footer_placeholder_info.setHtml(placeholder_info)
|
||||
self.footer_placeholder_info.setReadOnly(True)
|
||||
|
||||
|
@ -113,6 +113,11 @@ def test_toggle_display_invalid_action(flask_client, settings):
|
||||
assert res.status_code == 400
|
||||
|
||||
|
||||
def test_toggle_display_no_data(flask_client, settings):
|
||||
res = flask_client.post('/api/v2/core/display', json={})
|
||||
assert res.status_code == 400
|
||||
|
||||
|
||||
def test_toggle_display_valid_action_updates_controller(flask_client, settings):
|
||||
class FakeController:
|
||||
class Emitter:
|
||||
|
@ -220,29 +220,30 @@ def test_build_icon_with_resource():
|
||||
# best we can do is to assert that we get back a MagicMock object.
|
||||
assert isinstance(result, MagicMock), 'The result should be a MagicMock, because we mocked it out'
|
||||
|
||||
def test_image_to_byte(self):
|
||||
"""
|
||||
Test the image_to_byte() function
|
||||
"""
|
||||
with patch('openlp.core.lib.QtCore') as MockedQtCore:
|
||||
# GIVEN: A set of mocked-out Qt classes
|
||||
mocked_byte_array = MagicMock()
|
||||
MockedQtCore.QByteArray.return_value = mocked_byte_array
|
||||
mocked_buffer = MagicMock()
|
||||
MockedQtCore.QBuffer.return_value = mocked_buffer
|
||||
MockedQtCore.QIODevice.WriteOnly = 'writeonly'
|
||||
mocked_image = MagicMock()
|
||||
|
||||
# WHEN: We convert an image to a byte array
|
||||
result = image_to_byte(mocked_image, base_64=False)
|
||||
def test_image_to_byte():
|
||||
"""
|
||||
Test the image_to_byte() function
|
||||
"""
|
||||
with patch('openlp.core.lib.QtCore') as MockedQtCore:
|
||||
# GIVEN: A set of mocked-out Qt classes
|
||||
mocked_byte_array = MagicMock()
|
||||
MockedQtCore.QByteArray.return_value = mocked_byte_array
|
||||
mocked_buffer = MagicMock()
|
||||
MockedQtCore.QBuffer.return_value = mocked_buffer
|
||||
MockedQtCore.QIODevice.WriteOnly = 'writeonly'
|
||||
mocked_image = MagicMock()
|
||||
|
||||
# THEN: We should receive the mocked_buffer
|
||||
MockedQtCore.QByteArray.assert_called_with()
|
||||
MockedQtCore.QBuffer.assert_called_with(mocked_byte_array)
|
||||
mocked_buffer.open.assert_called_with('writeonly')
|
||||
mocked_image.save.assert_called_with(mocked_buffer, "PNG")
|
||||
assert mocked_byte_array.toBase64.called is False
|
||||
assert mocked_byte_array == result, 'The mocked out byte array should be returned'
|
||||
# WHEN: We convert an image to a byte array
|
||||
result = image_to_byte(mocked_image, base_64=False)
|
||||
|
||||
# THEN: We should receive the mocked_buffer
|
||||
MockedQtCore.QByteArray.assert_called_with()
|
||||
MockedQtCore.QBuffer.assert_called_with(mocked_byte_array)
|
||||
mocked_buffer.open.assert_called_with('writeonly')
|
||||
mocked_image.save.assert_called_with(mocked_buffer, "PNG")
|
||||
assert mocked_byte_array.toBase64.called is False
|
||||
assert mocked_byte_array == result, 'The mocked out byte array should be returned'
|
||||
|
||||
|
||||
def test_image_to_byte_base_64():
|
||||
@ -498,6 +499,25 @@ def test_create_thumb_empty_img():
|
||||
pass
|
||||
|
||||
|
||||
@patch('openlp.core.lib.QtGui.QImageReader')
|
||||
@patch('openlp.core.lib.build_icon')
|
||||
def test_create_thumb_path_fails(mocked_build_icon, MockQImageReader):
|
||||
"""
|
||||
Test that build_icon() is run against the image_path when the thumbnail fails to be created
|
||||
"""
|
||||
# GIVEN: A bunch of mocks
|
||||
image_path = RESOURCE_PATH / 'church.jpg'
|
||||
thumb_path = Path('doesnotexist')
|
||||
mocked_image_reader = MagicMock()
|
||||
mocked_image_reader.size.return_value.isEmpty.return_value = True
|
||||
|
||||
# WHEN: Create the thumb
|
||||
create_thumb(image_path, thumb_path)
|
||||
|
||||
# THEN: The image path should have been used
|
||||
mocked_build_icon.assert_called_once_with(image_path)
|
||||
|
||||
|
||||
@patch('openlp.core.lib.QtWidgets', MagicMock())
|
||||
def test_check_item_selected_true():
|
||||
"""
|
||||
@ -631,6 +651,42 @@ def test_resize_thumb_ignoring_aspect_ratio():
|
||||
assert image.pixel(0, 0) == wanted_background_rgb, 'The background should be white.'
|
||||
|
||||
|
||||
def test_resize_thumb_width_aspect_ratio():
|
||||
"""
|
||||
Test the resize_thumb() function using the image's width as the reference
|
||||
"""
|
||||
# GIVEN: A path to an image.
|
||||
image_path = str(RESOURCE_PATH / 'church.jpg')
|
||||
wanted_width = 10
|
||||
wanted_height = 1000
|
||||
|
||||
# WHEN: Resize the image and add a background.
|
||||
image = resize_image(image_path, wanted_width, wanted_height)
|
||||
|
||||
# THEN: Check if the size is correct and the background was set.
|
||||
result_size = image.size()
|
||||
assert wanted_height == result_size.height(), 'The image should have the requested height.'
|
||||
assert wanted_width == result_size.width(), 'The image should have the requested width.'
|
||||
|
||||
|
||||
def test_resize_thumb_same_aspect_ratio():
|
||||
"""
|
||||
Test the resize_thumb() function when the image and the wanted aspect ratio are the same
|
||||
"""
|
||||
# GIVEN: A path to an image.
|
||||
image_path = str(RESOURCE_PATH / 'church.jpg')
|
||||
wanted_width = 1122
|
||||
wanted_height = 1544
|
||||
|
||||
# WHEN: Resize the image and add a background.
|
||||
image = resize_image(image_path, wanted_width, wanted_height)
|
||||
|
||||
# THEN: Check if the size is correct and the background was set.
|
||||
result_size = image.size()
|
||||
assert wanted_height == result_size.height(), 'The image should have the requested height.'
|
||||
assert wanted_width == result_size.width(), 'The image should have the requested width.'
|
||||
|
||||
|
||||
@patch('openlp.core.lib.QtCore.QLocale.createSeparatedList')
|
||||
def test_create_separated_list_qlocate(mocked_createSeparatedList):
|
||||
"""
|
||||
|
@ -25,10 +25,11 @@ import pytest
|
||||
from pathlib import Path
|
||||
from unittest.mock import MagicMock, call, patch, DEFAULT
|
||||
|
||||
from PyQt5 import QtWidgets
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.ui.firsttimeform import FirstTimeForm, ThemeListWidgetItem
|
||||
from openlp.core.ui.firsttimewizard import ThemeListWidget
|
||||
|
||||
|
||||
INVALID_CONFIG = """
|
||||
@ -364,3 +365,22 @@ def test_on_projectors_check_box_unchecked(mock_settings):
|
||||
# THEN: The visibility of the projects panel should have been set
|
||||
mock_settings.value.assert_called_once_with('projector/show after wizard')
|
||||
mock_settings.setValue.assert_called_once_with('projector/show after wizard', True)
|
||||
|
||||
|
||||
def test_theme_list_widget_resize(ftf_app):
|
||||
"""
|
||||
Test that the resizeEvent() method in the ThemeListWidget works correctly
|
||||
"""
|
||||
# GIVEN: An instance of the ThemeListWidget
|
||||
widget = ThemeListWidget(None)
|
||||
|
||||
# WHEN: resizeEvent() is called
|
||||
with patch.object(widget, 'viewport') as mocked_viewport, \
|
||||
patch.object(widget, 'setGridSize') as mocked_setGridSize:
|
||||
mocked_viewport.return_value.width.return_value = 600
|
||||
widget.resizeEvent(None)
|
||||
|
||||
# THEN: Check that the correct calculations were done
|
||||
mocked_setGridSize.assert_called_once_with(QtCore.QSize(149, 140))
|
||||
|
||||
# THEN: everything resizes correctly
|
||||
|
@ -26,7 +26,7 @@ from unittest.mock import MagicMock, patch
|
||||
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.plugins.bibles import lib
|
||||
from openlp.plugins.bibles.lib import SearchResults, get_reference_match
|
||||
from openlp.plugins.bibles.lib import SearchResults, get_reference_match, update_reference_separators
|
||||
|
||||
|
||||
@pytest.yield_fixture
|
||||
@ -252,3 +252,44 @@ def test_reference_matched_range_separator(mocked_bible_test):
|
||||
|
||||
# THEN: The list of references should be as the expected results
|
||||
assert references == ranges
|
||||
|
||||
|
||||
def test_update_reference_separators_custom_seps(request, settings):
|
||||
"""
|
||||
Test the update_reference_separators() function with custom separators
|
||||
"""
|
||||
# Clean up after the test
|
||||
def cleanup_references():
|
||||
lib.REFERENCE_SEPARATORS = {}
|
||||
settings.remove('bibles/verse separator')
|
||||
settings.remove('bibles/range separator')
|
||||
settings.remove('bibles/list separator')
|
||||
settings.remove('bibles/end separator')
|
||||
update_reference_separators()
|
||||
|
||||
request.addfinalizer(cleanup_references)
|
||||
|
||||
# GIVEN: A custom set of separators
|
||||
settings.setValue('bibles/verse separator', ':||v')
|
||||
settings.setValue('bibles/range separator', '-')
|
||||
settings.setValue('bibles/list separator', ',')
|
||||
settings.setValue('bibles/end separator', '.')
|
||||
|
||||
# WHEN: update_reference_separators() is called
|
||||
update_reference_separators()
|
||||
|
||||
# THEN: The reference separators should be updated and correct
|
||||
expected_separators = {
|
||||
'sep_e': '\\s*(?:\\.)\\s*',
|
||||
'sep_e_default': 'end',
|
||||
'sep_l': '\\s*(?:(?:[,‚]))\\s*',
|
||||
'sep_l_default': ',|and',
|
||||
'sep_l_display': ',',
|
||||
'sep_r': '\\s*(?:(?:[-\xad‐‑‒——−﹣-]))\\s*',
|
||||
'sep_r_default': '-|to',
|
||||
'sep_r_display': '-',
|
||||
'sep_v': '\\s*(?::|v)\\s*',
|
||||
'sep_v_default': ':|v|V|verse|verses',
|
||||
'sep_v_display': ':'
|
||||
}
|
||||
assert lib.REFERENCE_SEPARATORS == expected_separators
|
||||
|
Loading…
Reference in New Issue
Block a user