Typecast presentation files from settings to Path

This commit is contained in:
Raoul Snyman 2023-01-11 03:06:17 +00:00
parent dbea8bf56b
commit 0636f2554c
9 changed files with 91 additions and 36 deletions

View File

@ -1 +1 @@
3.0.0
3.0.0.dev6+dbea8bf56

View File

@ -100,6 +100,25 @@ def trace_error_handler(logger):
logger.error(log_string)
def path_to_module(path):
"""
Convert a path to a module name (i.e openlp.core.common)
:param pathlib.Path path: The path to convert to a module name.
:return: The module name.
:rtype: str
"""
module_path = path.with_suffix('')
return 'openlp.' + '.'.join(module_path.parts)
def import_openlp_module(module_name):
"""
Refactor module import out for testability. In Python 3.11, mock.patch and import_module do not play along nicely.
"""
importlib.import_module(module_name)
def extension_loader(glob_pattern, excluded_files=None):
"""
A utility function to find and load OpenLP extensions, such as plugins, presentation and media controllers and
@ -119,25 +138,13 @@ def extension_loader(glob_pattern, excluded_files=None):
log.debug('Attempting to import %s', extension_path)
module_name = path_to_module(extension_path)
try:
importlib.import_module(module_name)
import_openlp_module(module_name)
except (ImportError, OSError):
# On some platforms importing vlc.py might cause OSError exceptions. (e.g. Mac OS X)
log.exception('Failed to import {module_name} on path {extension_path}'
.format(module_name=module_name, extension_path=extension_path))
def path_to_module(path):
"""
Convert a path to a module name (i.e openlp.core.common)
:param pathlib.Path path: The path to convert to a module name.
:return: The module name.
:rtype: str
"""
module_path = path.with_suffix('')
return 'openlp.' + '.'.join(module_path.parts)
def get_frozen_path(frozen_option, non_frozen_option):
"""
Return a path based on the system status.

View File

@ -112,6 +112,15 @@ class ServiceItemType(IntEnum):
Image = 2
Command = 3
@staticmethod
def parse(value):
if value in [1, '1', 'Text', 'ServiceItemType.Text']:
return ServiceItemType.Text
elif value in [2, '2', 'Image', 'ServiceItemType.Image']:
return ServiceItemType.Image
elif value in [3, '3', 'Command', 'ServiceItemType.Command']:
return ServiceItemType.Command
@unique
class PluginStatus(IntEnum):

View File

@ -463,7 +463,7 @@ class ServiceItem(RegistryProperties):
header = service_item['serviceitem']['header']
self.title = header['title']
self.name = header['name']
self.service_item_type = header['type']
self.service_item_type = ServiceItemType.parse(header['type'])
self.theme = header['theme']
self.add_icon()
self.raw_footer = header['footer']
@ -891,7 +891,7 @@ class ServiceItem(RegistryProperties):
data_dict = {
'title': self.title,
'name': self.name,
'type': str(self.service_item_type),
'type': self.service_item_type,
'theme': self.theme,
'footer': self.raw_footer,
'audit': self.audit,

View File

@ -24,7 +24,7 @@ presentations from a variety of document formats.
"""
import logging
import os
from pathlib import Path
from openlp.core.common import extension_loader, sha256_file_hash
from openlp.core.common.i18n import translate
@ -84,7 +84,9 @@ class PresentationPlugin(Plugin):
has_old_scheme = True
# Migrate each file
presentation_paths = self.settings.value('presentations/presentations files') or []
for path in presentation_paths:
for presentation_path in presentation_paths:
# Typecast to Path object
path = Path(presentation_path)
# check to see if the file exists before trying to process it.
if not path.exists():
continue

View File

@ -77,7 +77,7 @@ def test_extension_loader_files_found():
Path('/', 'app', 'dir', 'openlp', 'import_dir', 'file2.py'),
Path('/', 'app', 'dir', 'openlp', 'import_dir', 'file3.py'),
Path('/', 'app', 'dir', 'openlp', 'import_dir', 'file4.py')]), \
patch('openlp.core.common.importlib.import_module') as mocked_import_module:
patch('openlp.core.common.import_openlp_module') as mocked_import_module:
# WHEN: Calling `extension_loader` with a list of files to exclude
extension_loader('glob', ['file2.py', 'file3.py'])
@ -97,7 +97,7 @@ def test_extension_loader_import_error():
return_value=Path('/', 'app', 'dir', 'openlp')), \
patch.object(Path, 'glob', return_value=[
Path('/', 'app', 'dir', 'openlp', 'import_dir', 'file1.py')]), \
patch('openlp.core.common.importlib.import_module', side_effect=ImportError()), \
patch('openlp.core.common.import_openlp_module', side_effect=ImportError()), \
patch('openlp.core.common.log') as mocked_logger:
# WHEN: Calling `extension_loader`
@ -116,7 +116,7 @@ def test_extension_loader_os_error():
return_value=Path('/', 'app', 'dir', 'openlp')), \
patch.object(Path, 'glob', return_value=[
Path('/', 'app', 'dir', 'openlp', 'import_dir', 'file1.py')]), \
patch('openlp.core.common.importlib.import_module', side_effect=OSError()), \
patch('openlp.core.common.import_openlp_module', side_effect=OSError()), \
patch('openlp.core.common.log') as mocked_logger:
# WHEN: Calling `extension_loader`

View File

@ -273,7 +273,7 @@ def test_image_to_byte_base_64():
assert 'byte_array base64ified' == result, 'The result should be the return value of the mocked base64 method'
def test_create_thumb_with_size():
def test_create_thumb_with_size(registry):
"""
Test the create_thumb() function with a given size.
"""
@ -308,7 +308,7 @@ def test_create_thumb_with_size():
pass
def test_create_thumb_no_size():
def test_create_thumb_no_size(registry):
"""
Test the create_thumb() function with no size specified.
"""
@ -343,7 +343,7 @@ def test_create_thumb_no_size():
pass
def test_create_thumb_invalid_size():
def test_create_thumb_invalid_size(registry):
"""
Test the create_thumb() function with invalid size specified.
"""
@ -379,7 +379,7 @@ def test_create_thumb_invalid_size():
pass
def test_create_thumb_width_only():
def test_create_thumb_width_only(registry):
"""
Test the create_thumb() function with a size of only width specified.
"""
@ -415,7 +415,7 @@ def test_create_thumb_width_only():
pass
def test_create_thumb_height_only():
def test_create_thumb_height_only(registry):
"""
Test the create_thumb() function with a size of only height specified.
"""
@ -451,7 +451,7 @@ def test_create_thumb_height_only():
pass
def test_create_thumb_empty_img():
def test_create_thumb_empty_img(registry):
"""
Test the create_thumb() function with a size of only height specified.
"""
@ -502,7 +502,7 @@ def test_create_thumb_empty_img():
@patch('openlp.core.lib.QtGui.QImageReader')
@patch('openlp.core.lib.build_icon')
def test_create_thumb_path_fails(mocked_build_icon, MockQImageReader):
def test_create_thumb_path_fails(mocked_build_icon, MockQImageReader, registry):
"""
Test that build_icon() is run against the image_path when the thumbnail fails to be created
"""
@ -537,7 +537,7 @@ def test_check_item_selected_true():
assert result is True, 'The result should be True'
def test_check_item_selected_false():
def test_check_item_selected_false(registry):
"""
Test that the check_item_selected() function returns False when there are no selected indexes.
"""
@ -608,7 +608,7 @@ def test_validate_thumb_file_exists_and_older():
assert result is False, 'The result should be False'
def test_resize_thumb():
def test_resize_thumb(registry):
"""
Test the resize_thumb() function
"""
@ -630,7 +630,7 @@ def test_resize_thumb():
assert image.pixel(0, 0) == wanted_background_rgb, 'The background should be white.'
def test_resize_thumb_ignoring_aspect_ratio():
def test_resize_thumb_ignoring_aspect_ratio(registry):
"""
Test the resize_thumb() function ignoring aspect ratio
"""
@ -652,7 +652,7 @@ 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():
def test_resize_thumb_width_aspect_ratio(registry):
"""
Test the resize_thumb() function using the image's width as the reference
"""
@ -670,7 +670,7 @@ def test_resize_thumb_width_aspect_ratio():
assert wanted_width == result_size.width(), 'The image should have the requested width.'
def test_resize_thumb_same_aspect_ratio():
def test_resize_thumb_same_aspect_ratio(registry):
"""
Test the resize_thumb() function when the image and the wanted aspect ratio are the same
"""

View File

@ -862,7 +862,7 @@ def test_to_dict_text_item(mocked_sha256_file_hash, state_media, settings, servi
],
'theme': None,
'title': 'Amazing Grace',
'type': 'ServiceItemType.Text',
'type': ServiceItemType.Text,
'data': {'authors': 'John Newton', 'title': 'amazing grace@'}
}
assert result == expected_dict
@ -905,7 +905,7 @@ def test_to_dict_image_item(state_media, settings, service_item_env):
],
'theme': -1,
'title': 'Images',
'type': 'ServiceItemType.Image',
'type': ServiceItemType.Image,
'data': {}
}
assert result == expected_dict
@ -961,7 +961,7 @@ def test_to_dict_presentation_item(mocked_image_uri, mocked_get_data_path, state
],
'theme': None,
'title': '',
'type': 'ServiceItemType.Command',
'type': ServiceItemType.Command,
'data': {}
}
assert result == expected_dict

View File

@ -21,7 +21,14 @@
"""
This module contains tests for the plugin class Presentation plugin.
"""
from pathlib import Path
from unittest.mock import MagicMock, patch
from openlp.plugins.presentations.presentationplugin import PresentationPlugin
from openlp.plugins.presentations.lib.presentationtab import PresentationTab
TEST_RESOURCES_PATH = Path(__file__) / '..' / '..' / '..' / 'resources'
def test_plugin_about():
@ -34,3 +41,33 @@ def test_plugin_about():
'programs. The choice of available presentation programs is '
'available to the user in a drop down box.'
)
def test_creaste_settings_tab(qapp, state, registry, settings):
"""Test creating the settings tab"""
# GIVEN: A Presentations plugin
presentations_plugin = PresentationPlugin()
# WHEN: create_settings_tab is run
presentations_plugin.create_settings_tab(None)
# THEN: A settings tab should have been created
assert isinstance(presentations_plugin.settings_tab, PresentationTab)
@patch('openlp.plugins.presentations.presentationplugin.Manager')
def test_initialise(MockedManager, state, registry, mock_settings):
"""Test that initialising the plugin works correctly"""
# GIVEN: Some initial values needed for intialisation and a presentations plugin
mock_settings.setValue.side_effect = [None, [str(TEST_RESOURCES_PATH / 'presentations' / 'test.ppt')]]
mocked_main_window = MagicMock()
registry.register('main_window', mocked_main_window)
presentations_plugin = PresentationPlugin()
presentations_plugin.media_item = MagicMock()
# WHEN: initialise() is called
presentations_plugin.initialise()
# THEN: Nothing should break, and everything should be called
mock_settings.setValue.assert_called_with('presentations/thumbnail_scheme', 'sha256file')
mock_settings.remove.assert_called_once_with('presentations/presentations files')