forked from openlp/openlp
Merge branch 'master' of gitlab.com:openlp/openlp
This commit is contained in:
commit
9eb645cc37
1
.gitignore
vendored
1
.gitignore
vendored
@ -25,6 +25,7 @@
|
|||||||
.vscode
|
.vscode
|
||||||
.eggs
|
.eggs
|
||||||
.venv
|
.venv
|
||||||
|
.mypy_cache
|
||||||
OpenLP.egg-info
|
OpenLP.egg-info
|
||||||
\#*\#
|
\#*\#
|
||||||
__pycache__
|
__pycache__
|
||||||
|
@ -63,19 +63,6 @@ test-macos:
|
|||||||
only:
|
only:
|
||||||
- master@openlp/openlp
|
- master@openlp/openlp
|
||||||
|
|
||||||
test-windows:
|
|
||||||
stage: test
|
|
||||||
tags:
|
|
||||||
- windows
|
|
||||||
script:
|
|
||||||
- C:\Users\raoul\GitLab-Runner\venv\Scripts\pytest.exe --color=no --disable-warnings --cov openlp
|
|
||||||
- mv .coverage windows.coverage
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- windows.coverage
|
|
||||||
only:
|
|
||||||
- master@openlp/openlp
|
|
||||||
|
|
||||||
test-display:
|
test-display:
|
||||||
stage: test
|
stage: test
|
||||||
image: openlp/angular
|
image: openlp/angular
|
||||||
@ -87,7 +74,7 @@ pages:
|
|||||||
stage: deploy
|
stage: deploy
|
||||||
image: openlp/debian
|
image: openlp/debian
|
||||||
script:
|
script:
|
||||||
- python3-coverage combine linux.coverage macos.coverage windows.coverage
|
- python3-coverage combine linux.coverage macos.coverage
|
||||||
- fixpaths .coverage
|
- fixpaths .coverage
|
||||||
- python3-coverage html
|
- python3-coverage html
|
||||||
- mv htmlcov public
|
- mv htmlcov public
|
||||||
@ -99,6 +86,5 @@ pages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
- test-debian
|
- test-debian
|
||||||
- test-macos
|
- test-macos
|
||||||
- test-windows
|
|
||||||
only:
|
only:
|
||||||
- master@openlp/openlp
|
- master@openlp/openlp
|
||||||
|
@ -385,17 +385,12 @@ def main():
|
|||||||
application.setApplicationName('OpenLP')
|
application.setApplicationName('OpenLP')
|
||||||
set_up_logging(AppLocation.get_directory(AppLocation.CacheDir))
|
set_up_logging(AppLocation.get_directory(AppLocation.CacheDir))
|
||||||
# Set the libvlc environment variable if we're frozen
|
# Set the libvlc environment variable if we're frozen
|
||||||
if getattr(sys, 'frozen', False):
|
if getattr(sys, 'frozen', False) and is_win():
|
||||||
if is_macosx():
|
# Path to libvlc and the plugins
|
||||||
vlc_lib = 'libvlc.dylib'
|
os.environ['PYTHON_VLC_LIB_PATH'] = str(AppLocation.get_directory(AppLocation.AppDir) / 'vlc' / 'libvlc.dll')
|
||||||
elif is_win():
|
|
||||||
vlc_lib = 'libvlc.dll'
|
|
||||||
# Path to libvlc
|
|
||||||
os.environ['PYTHON_VLC_LIB_PATH'] = str(AppLocation.get_directory(AppLocation.AppDir) / 'vlc' / vlc_lib)
|
|
||||||
log.debug('VLC Path: {}'.format(os.environ['PYTHON_VLC_LIB_PATH']))
|
|
||||||
# Path to VLC directory containing VLC's "plugins" directory
|
|
||||||
os.environ['PYTHON_VLC_MODULE_PATH'] = str(AppLocation.get_directory(AppLocation.AppDir) / 'vlc')
|
os.environ['PYTHON_VLC_MODULE_PATH'] = str(AppLocation.get_directory(AppLocation.AppDir) / 'vlc')
|
||||||
log.debug('VLC Path: {}'.format(os.environ['PYTHON_VLC_LIB_PATH']))
|
log.debug('VLC Path: {}'.format(os.environ['PYTHON_VLC_LIB_PATH']))
|
||||||
|
log.debug('VLC Plugins Path: {}'.format(os.environ['PYTHON_VLC_MODULE_PATH']))
|
||||||
# Initialise the Registry
|
# Initialise the Registry
|
||||||
Registry.create()
|
Registry.create()
|
||||||
Registry().register('application', application)
|
Registry().register('application', application)
|
||||||
|
@ -38,6 +38,13 @@ from PyQt5.QtCore import QCryptographicHash as QHash
|
|||||||
from PyQt5.QtNetwork import QAbstractSocket, QHostAddress, QNetworkInterface
|
from PyQt5.QtNetwork import QAbstractSocket, QHostAddress, QNetworkInterface
|
||||||
from chardet.universaldetector import UniversalDetector
|
from chardet.universaldetector import UniversalDetector
|
||||||
|
|
||||||
|
try:
|
||||||
|
from distro import id as distro_id
|
||||||
|
except ImportError:
|
||||||
|
# The distro module is only valid for Linux, so if it doesn't exist, create a function that always returns False
|
||||||
|
def distro_id():
|
||||||
|
return False
|
||||||
|
|
||||||
log = logging.getLogger(__name__ + '.__init__')
|
log = logging.getLogger(__name__ + '.__init__')
|
||||||
|
|
||||||
|
|
||||||
@ -212,13 +219,17 @@ def is_macosx():
|
|||||||
return sys.platform.startswith('darwin')
|
return sys.platform.startswith('darwin')
|
||||||
|
|
||||||
|
|
||||||
def is_linux():
|
def is_linux(distro=None):
|
||||||
"""
|
"""
|
||||||
Returns true if running on a system with a linux kernel e.g. Ubuntu, Debian, etc
|
Returns true if running on a system with a linux kernel e.g. Ubuntu, Debian, etc
|
||||||
|
|
||||||
|
:param distro: If not None, check if running that Linux distro
|
||||||
:return: True if system is running a linux kernel false otherwise
|
:return: True if system is running a linux kernel false otherwise
|
||||||
"""
|
"""
|
||||||
return sys.platform.startswith('linux')
|
result = sys.platform.startswith('linux')
|
||||||
|
if result and distro:
|
||||||
|
result = result and distro == distro_id()
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def is_64bit_instance():
|
def is_64bit_instance():
|
||||||
|
@ -34,6 +34,7 @@ from PyQt5 import QtCore
|
|||||||
|
|
||||||
from openlp.core.state import State
|
from openlp.core.state import State
|
||||||
from openlp.core.api.http import register_endpoint
|
from openlp.core.api.http import register_endpoint
|
||||||
|
from openlp.core.common import is_linux, is_macosx
|
||||||
from openlp.core.common.i18n import translate
|
from openlp.core.common.i18n import translate
|
||||||
from openlp.core.common.mixins import LogMixin, RegistryProperties
|
from openlp.core.common.mixins import LogMixin, RegistryProperties
|
||||||
from openlp.core.common.registry import Registry, RegistryBase
|
from openlp.core.common.registry import Registry, RegistryBase
|
||||||
@ -89,23 +90,35 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
|||||||
self.vlc_player = VlcPlayer(self)
|
self.vlc_player = VlcPlayer(self)
|
||||||
State().add_service('mediacontroller', 0)
|
State().add_service('mediacontroller', 0)
|
||||||
State().add_service('media_live', 0)
|
State().add_service('media_live', 0)
|
||||||
getvlc = get_vlc()
|
has_vlc = get_vlc()
|
||||||
if getvlc and pymediainfo_available:
|
if has_vlc and pymediainfo_available:
|
||||||
State().update_pre_conditions('mediacontroller', True)
|
State().update_pre_conditions('mediacontroller', True)
|
||||||
State().update_pre_conditions('media_live', True)
|
State().update_pre_conditions('media_live', True)
|
||||||
else:
|
else:
|
||||||
if hasattr(self.main_window, 'splash') and self.main_window.splash.isVisible():
|
if hasattr(self.main_window, 'splash') and self.main_window.splash.isVisible():
|
||||||
self.main_window.splash.hide()
|
self.main_window.splash.hide()
|
||||||
text_vlc = translate('OpenLP.MediaController',
|
generic_message = translate('OpenLP.MediaController',
|
||||||
'The media integration library is missing (python - vlc is not installed)')
|
'OpenLP requires the following libraries in order to show videos and other '
|
||||||
text_info = translate('OpenLP.MediaController',
|
'media, but they are not installed. Please install these libraries to enable '
|
||||||
'The media integration library is missing (python - pymediainfo is not installed)')
|
'media playback in OpenLP.')
|
||||||
if not getvlc and not pymediainfo_available:
|
fedora_rpmfusion = translate('OpenLP.MediaController',
|
||||||
State().missing_text('media_live', "{text}\n{base}".format(text=text_vlc, base=text_info))
|
'To install these libraries, you will need to enable the RPMFusion '
|
||||||
if getvlc and not pymediainfo_available:
|
'repository: https://rpmfusion.org/')
|
||||||
State().missing_text('media_live', "{text}".format(text=text_info))
|
message = ''
|
||||||
if not getvlc and pymediainfo_available:
|
if is_macosx():
|
||||||
State().missing_text('media_live', "{text}".format(text=text_vlc))
|
message = translate('OpenLP.MediaController',
|
||||||
|
'macOS is missing VLC. Please download and install from the VLC web site: '
|
||||||
|
'https://www.videolan.org/vlc/')
|
||||||
|
else:
|
||||||
|
packages = []
|
||||||
|
if not has_vlc:
|
||||||
|
packages.append('python3-vlc')
|
||||||
|
if not pymediainfo_available:
|
||||||
|
packages.append('python3-pymediainfo')
|
||||||
|
message = generic_message + '\n\n' + ', '.join(packages)
|
||||||
|
if not has_vlc and is_linux(distro='fedora'):
|
||||||
|
message += '\n\n' + fedora_rpmfusion
|
||||||
|
State().missing_text('media_live', message)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def bootstrap_post_set_up(self):
|
def bootstrap_post_set_up(self):
|
||||||
|
@ -34,7 +34,6 @@ from openlp.core.common.actions import ActionList, CategoryOrder
|
|||||||
from openlp.core.common.i18n import UiStrings, translate
|
from openlp.core.common.i18n import UiStrings, translate
|
||||||
from openlp.core.common.mixins import LogMixin, RegistryProperties
|
from openlp.core.common.mixins import LogMixin, RegistryProperties
|
||||||
from openlp.core.common.registry import Registry, RegistryBase
|
from openlp.core.common.registry import Registry, RegistryBase
|
||||||
from openlp.core.common.settings import Settings
|
|
||||||
from openlp.core.display.screens import ScreenList
|
from openlp.core.display.screens import ScreenList
|
||||||
from openlp.core.display.window import DisplayWindow
|
from openlp.core.display.window import DisplayWindow
|
||||||
from openlp.core.lib import ServiceItemAction, image_to_byte
|
from openlp.core.lib import ServiceItemAction, image_to_byte
|
||||||
@ -324,7 +323,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
|||||||
self.play_slides_once = create_action(self, 'playSlidesOnce', text=UiStrings().PlaySlidesToEnd,
|
self.play_slides_once = create_action(self, 'playSlidesOnce', text=UiStrings().PlaySlidesToEnd,
|
||||||
icon=UiIcons().clock, checked=False, can_shortcuts=True,
|
icon=UiIcons().clock, checked=False, can_shortcuts=True,
|
||||||
category=self.category, triggers=self.on_play_slides_once)
|
category=self.category, triggers=self.on_play_slides_once)
|
||||||
if Settings().value(self.main_window.advanced_settings_section + '/slide limits') == SlideLimits.Wrap:
|
if self.settings.value(self.main_window.advanced_settings_section + '/slide limits') == SlideLimits.Wrap:
|
||||||
self.play_slides_menu.setDefaultAction(self.play_slides_loop)
|
self.play_slides_menu.setDefaultAction(self.play_slides_loop)
|
||||||
else:
|
else:
|
||||||
self.play_slides_menu.setDefaultAction(self.play_slides_once)
|
self.play_slides_menu.setDefaultAction(self.play_slides_once)
|
||||||
@ -697,13 +696,13 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
|||||||
"""
|
"""
|
||||||
Adjusts the value of the ``delay_spin_box`` to the given one.
|
Adjusts the value of the ``delay_spin_box`` to the given one.
|
||||||
"""
|
"""
|
||||||
self.delay_spin_box.setValue(Settings().value('core/loop delay'))
|
self.delay_spin_box.setValue(self.settings.value('core/loop delay'))
|
||||||
|
|
||||||
def update_slide_limits(self):
|
def update_slide_limits(self):
|
||||||
"""
|
"""
|
||||||
Updates the Slide Limits variable from the settings.
|
Updates the Slide Limits variable from the settings.
|
||||||
"""
|
"""
|
||||||
self.slide_limits = Settings().value(self.main_window.advanced_settings_section + '/slide limits')
|
self.slide_limits = self.settings.value(self.main_window.advanced_settings_section + '/slide limits')
|
||||||
|
|
||||||
def enable_tool_bar(self, item):
|
def enable_tool_bar(self, item):
|
||||||
"""
|
"""
|
||||||
@ -737,7 +736,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
|||||||
self.play_slides_loop.setIcon(UiIcons().clock)
|
self.play_slides_loop.setIcon(UiIcons().clock)
|
||||||
self.play_slides_loop.setText(UiStrings().PlaySlidesInLoop)
|
self.play_slides_loop.setText(UiStrings().PlaySlidesInLoop)
|
||||||
if item.is_text():
|
if item.is_text():
|
||||||
if (Settings().value(self.main_window.songs_settings_section + '/display songbar') and
|
if (self.settings.value(self.main_window.songs_settings_section + '/display songbar') and
|
||||||
not self.song_menu.menu().isEmpty()):
|
not self.song_menu.menu().isEmpty()):
|
||||||
self.toolbar.set_widget_visible('song_menu', True)
|
self.toolbar.set_widget_visible('song_menu', True)
|
||||||
if item.is_capable(ItemCapabilities.CanLoop) and len(item.slides) > 1:
|
if item.is_capable(ItemCapabilities.CanLoop) and len(item.slides) > 1:
|
||||||
@ -1013,9 +1012,9 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
|||||||
self.theme_screen.setChecked(False)
|
self.theme_screen.setChecked(False)
|
||||||
self.desktop_screen.setChecked(False)
|
self.desktop_screen.setChecked(False)
|
||||||
if checked:
|
if checked:
|
||||||
Settings().setValue(self.main_window.general_settings_section + '/screen blank', 'blanked')
|
self.settings.setValue(self.main_window.general_settings_section + '/screen blank', 'blanked')
|
||||||
else:
|
else:
|
||||||
Settings().remove(self.main_window.general_settings_section + '/screen blank')
|
self.settings.remove(self.main_window.general_settings_section + '/screen blank')
|
||||||
self.blank_plugin()
|
self.blank_plugin()
|
||||||
self.update_preview()
|
self.update_preview()
|
||||||
self.on_toggle_loop()
|
self.on_toggle_loop()
|
||||||
@ -1034,9 +1033,9 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
|||||||
self.theme_screen.setChecked(checked)
|
self.theme_screen.setChecked(checked)
|
||||||
self.desktop_screen.setChecked(False)
|
self.desktop_screen.setChecked(False)
|
||||||
if checked:
|
if checked:
|
||||||
Settings().setValue(self.main_window.general_settings_section + '/screen blank', 'themed')
|
self.settings.setValue(self.main_window.general_settings_section + '/screen blank', 'themed')
|
||||||
else:
|
else:
|
||||||
Settings().remove(self.main_window.general_settings_section + '/screen blank')
|
self.settings.remove(self.main_window.general_settings_section + '/screen blank')
|
||||||
self.blank_plugin()
|
self.blank_plugin()
|
||||||
self.update_preview()
|
self.update_preview()
|
||||||
self.on_toggle_loop()
|
self.on_toggle_loop()
|
||||||
@ -1056,9 +1055,9 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
|||||||
self.theme_screen.setChecked(False)
|
self.theme_screen.setChecked(False)
|
||||||
self.desktop_screen.setChecked(checked)
|
self.desktop_screen.setChecked(checked)
|
||||||
if checked:
|
if checked:
|
||||||
Settings().setValue(self.main_window.general_settings_section + '/screen blank', 'hidden')
|
self.settings.setValue(self.main_window.general_settings_section + '/screen blank', 'hidden')
|
||||||
else:
|
else:
|
||||||
Settings().remove(self.main_window.general_settings_section + '/screen blank')
|
self.settings.remove(self.main_window.general_settings_section + '/screen blank')
|
||||||
self.hide_plugin(checked)
|
self.hide_plugin(checked)
|
||||||
self.update_preview()
|
self.update_preview()
|
||||||
self.on_toggle_loop()
|
self.on_toggle_loop()
|
||||||
@ -1145,7 +1144,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
|||||||
return
|
return
|
||||||
# If "click live slide to unblank" is enabled, unblank the display. And start = Item is sent to Live.
|
# If "click live slide to unblank" is enabled, unblank the display. And start = Item is sent to Live.
|
||||||
# Note: If this if statement is placed at the bottom of this function instead of top slide transitions are lost.
|
# Note: If this if statement is placed at the bottom of this function instead of top slide transitions are lost.
|
||||||
if self.is_live and Settings().value('core/click live slide to unblank'):
|
if self.is_live and self.settings.value('core/click live slide to unblank'):
|
||||||
if not start:
|
if not start:
|
||||||
Registry().execute('slidecontroller_live_unblank')
|
Registry().execute('slidecontroller_live_unblank')
|
||||||
row = self.preview_widget.current_slide_number()
|
row = self.preview_widget.current_slide_number()
|
||||||
@ -1353,7 +1352,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
|||||||
self.play_slides_once.setText(UiStrings().PlaySlidesToEnd)
|
self.play_slides_once.setText(UiStrings().PlaySlidesToEnd)
|
||||||
self.play_slides_menu.setDefaultAction(self.play_slides_loop)
|
self.play_slides_menu.setDefaultAction(self.play_slides_loop)
|
||||||
self.play_slides_once.setChecked(False)
|
self.play_slides_once.setChecked(False)
|
||||||
if Settings().value('core/click live slide to unblank'):
|
if self.settings.value('core/click live slide to unblank'):
|
||||||
Registry().execute('slidecontroller_live_unblank')
|
Registry().execute('slidecontroller_live_unblank')
|
||||||
else:
|
else:
|
||||||
self.play_slides_loop.setIcon(UiIcons().clock)
|
self.play_slides_loop.setIcon(UiIcons().clock)
|
||||||
@ -1378,7 +1377,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
|||||||
self.play_slides_loop.setText(UiStrings().PlaySlidesInLoop)
|
self.play_slides_loop.setText(UiStrings().PlaySlidesInLoop)
|
||||||
self.play_slides_menu.setDefaultAction(self.play_slides_once)
|
self.play_slides_menu.setDefaultAction(self.play_slides_once)
|
||||||
self.play_slides_loop.setChecked(False)
|
self.play_slides_loop.setChecked(False)
|
||||||
if Settings().value('core/click live slide to unblank'):
|
if self.settings.value('core/click live slide to unblank'):
|
||||||
Registry().execute('slidecontroller_live_unblank')
|
Registry().execute('slidecontroller_live_unblank')
|
||||||
else:
|
else:
|
||||||
self.play_slides_once.setIcon(UiIcons().clock)
|
self.play_slides_once.setIcon(UiIcons().clock)
|
||||||
@ -1423,7 +1422,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
|||||||
Triggered when a preview slide item is double clicked
|
Triggered when a preview slide item is double clicked
|
||||||
"""
|
"""
|
||||||
if self.service_item:
|
if self.service_item:
|
||||||
if Settings().value('advanced/double click live') and Settings().value('core/auto unblank'):
|
if self.settings.value('advanced/double click live') and self.settings.value('core/auto unblank'):
|
||||||
# Live and Preview have issues if we have video or presentations
|
# Live and Preview have issues if we have video or presentations
|
||||||
# playing in both at the same time.
|
# playing in both at the same time.
|
||||||
if self.service_item.is_command():
|
if self.service_item.is_command():
|
||||||
|
@ -43,7 +43,7 @@ from openlp.core.lib.ui import critical_error_message_box
|
|||||||
from openlp.core.widgets.edits import PathEdit
|
from openlp.core.widgets.edits import PathEdit
|
||||||
from openlp.core.widgets.wizard import OpenLPWizard, WizardStrings
|
from openlp.core.widgets.wizard import OpenLPWizard, WizardStrings
|
||||||
from openlp.plugins.bibles.lib.db import clean_filename
|
from openlp.plugins.bibles.lib.db import clean_filename
|
||||||
from openlp.plugins.bibles.lib.importers.http import BGExtract, BSExtract, CWExtract
|
from openlp.plugins.bibles.lib.importers.http import BGExtract, CWExtract
|
||||||
from openlp.plugins.bibles.lib.manager import BibleFormat
|
from openlp.plugins.bibles.lib.manager import BibleFormat
|
||||||
|
|
||||||
|
|
||||||
@ -59,7 +59,8 @@ class WebDownload(object):
|
|||||||
BibleGateway = 1
|
BibleGateway = 1
|
||||||
Bibleserver = 2
|
Bibleserver = 2
|
||||||
|
|
||||||
Names = ['Crosswalk', 'BibleGateway', 'Bibleserver']
|
# NOTE: BibleServer support has been disabled since we can't currently parse it. Re-add if/when fixed.
|
||||||
|
Names = ['Crosswalk', 'BibleGateway']
|
||||||
|
|
||||||
|
|
||||||
class BibleImportForm(OpenLPWizard):
|
class BibleImportForm(OpenLPWizard):
|
||||||
@ -227,7 +228,8 @@ class BibleImportForm(OpenLPWizard):
|
|||||||
self.web_bible_layout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.web_source_label)
|
self.web_bible_layout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.web_source_label)
|
||||||
self.web_source_combo_box = QtWidgets.QComboBox(self.web_widget)
|
self.web_source_combo_box = QtWidgets.QComboBox(self.web_widget)
|
||||||
self.web_source_combo_box.setObjectName('WebSourceComboBox')
|
self.web_source_combo_box.setObjectName('WebSourceComboBox')
|
||||||
self.web_source_combo_box.addItems(['', '', ''])
|
# NOTE: Set to 2 items since BibleServer has been disabled. Set to 3 if/when fixed
|
||||||
|
self.web_source_combo_box.addItems(['', ''])
|
||||||
self.web_source_combo_box.setEnabled(False)
|
self.web_source_combo_box.setEnabled(False)
|
||||||
self.web_bible_layout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.web_source_combo_box)
|
self.web_bible_layout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.web_source_combo_box)
|
||||||
self.web_translation_label = QtWidgets.QLabel(self.web_bible_tab)
|
self.web_translation_label = QtWidgets.QLabel(self.web_bible_tab)
|
||||||
@ -239,7 +241,8 @@ class BibleImportForm(OpenLPWizard):
|
|||||||
self.web_translation_combo_box.setEnabled(False)
|
self.web_translation_combo_box.setEnabled(False)
|
||||||
self.web_bible_layout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.web_translation_combo_box)
|
self.web_bible_layout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.web_translation_combo_box)
|
||||||
self.web_progress_bar = QtWidgets.QProgressBar(self)
|
self.web_progress_bar = QtWidgets.QProgressBar(self)
|
||||||
self.web_progress_bar.setRange(0, 3)
|
# NOTE: Set to 2 since BibleServer has been disabled. Set to 3 if/when fixed
|
||||||
|
self.web_progress_bar.setRange(0, 2)
|
||||||
self.web_progress_bar.setObjectName('WebTranslationProgressBar')
|
self.web_progress_bar.setObjectName('WebTranslationProgressBar')
|
||||||
self.web_progress_bar.setVisible(False)
|
self.web_progress_bar.setVisible(False)
|
||||||
self.web_bible_layout.setWidget(3, QtWidgets.QFormLayout.SpanningRole, self.web_progress_bar)
|
self.web_bible_layout.setWidget(3, QtWidgets.QFormLayout.SpanningRole, self.web_progress_bar)
|
||||||
@ -400,8 +403,9 @@ class BibleImportForm(OpenLPWizard):
|
|||||||
'Crosswalk'))
|
'Crosswalk'))
|
||||||
self.web_source_combo_box.setItemText(WebDownload.BibleGateway, translate('BiblesPlugin.ImportWizardForm',
|
self.web_source_combo_box.setItemText(WebDownload.BibleGateway, translate('BiblesPlugin.ImportWizardForm',
|
||||||
'BibleGateway'))
|
'BibleGateway'))
|
||||||
self.web_source_combo_box.setItemText(WebDownload.Bibleserver, translate('BiblesPlugin.ImportWizardForm',
|
# NOTE: BibleServer support has been disabled since we can't currently parse it. Re-add if/when fixed.
|
||||||
'Bibleserver'))
|
# self.web_source_combo_box.setItemText(WebDownload.Bibleserver, translate('BiblesPlugin.ImportWizardForm',
|
||||||
|
# 'Bibleserver'))
|
||||||
self.web_translation_label.setText(translate('BiblesPlugin.ImportWizardForm', 'Bible:'))
|
self.web_translation_label.setText(translate('BiblesPlugin.ImportWizardForm', 'Bible:'))
|
||||||
self.sword_bible_label.setText(translate('BiblesPlugin.ImportWizardForm', 'Bibles:'))
|
self.sword_bible_label.setText(translate('BiblesPlugin.ImportWizardForm', 'Bibles:'))
|
||||||
self.sword_folder_label.setText(translate('BiblesPlugin.ImportWizardForm', 'SWORD data folder:'))
|
self.sword_folder_label.setText(translate('BiblesPlugin.ImportWizardForm', 'SWORD data folder:'))
|
||||||
@ -578,9 +582,9 @@ class BibleImportForm(OpenLPWizard):
|
|||||||
self.web_progress_bar.setVisible(True)
|
self.web_progress_bar.setVisible(True)
|
||||||
self.web_progress_bar.setValue(0)
|
self.web_progress_bar.setValue(0)
|
||||||
# TODO: Where does critical_error_message_box get %s string from?
|
# TODO: Where does critical_error_message_box get %s string from?
|
||||||
|
# NOTE: BibleServer support has been disabled since we can't currently parse it. Re-add if/when fixed.
|
||||||
for (download_type, extractor) in ((WebDownload.Crosswalk, CWExtract()),
|
for (download_type, extractor) in ((WebDownload.Crosswalk, CWExtract()),
|
||||||
(WebDownload.BibleGateway, BGExtract()),
|
(WebDownload.BibleGateway, BGExtract())):
|
||||||
(WebDownload.Bibleserver, BSExtract())):
|
|
||||||
try:
|
try:
|
||||||
bibles = extractor.get_bibles_from_http()
|
bibles = extractor.get_bibles_from_http()
|
||||||
except (urllib.error.URLError, ConnectionError):
|
except (urllib.error.URLError, ConnectionError):
|
||||||
|
@ -310,7 +310,7 @@ class PresentationMediaItem(MediaManagerItem):
|
|||||||
image_path = doc.get_temp_folder() / 'mainslide{number:0>3d}.png'.format(number=i)
|
image_path = doc.get_temp_folder() / 'mainslide{number:0>3d}.png'.format(number=i)
|
||||||
thumbnail_path = doc.get_thumbnail_folder() / 'slide{number:d}.png'.format(number=i)
|
thumbnail_path = doc.get_thumbnail_folder() / 'slide{number:d}.png'.format(number=i)
|
||||||
while image_path.is_file():
|
while image_path.is_file():
|
||||||
service_item.add_from_image(str(image_path), file_name, thumbnail=str(thumbnail_path))
|
service_item.add_from_image(image_path, file_name, thumbnail=str(thumbnail_path))
|
||||||
i += 1
|
i += 1
|
||||||
image_path = doc.get_temp_folder() / 'mainslide{number:0>3d}.png'.format(number=i)
|
image_path = doc.get_temp_folder() / 'mainslide{number:0>3d}.png'.format(number=i)
|
||||||
thumbnail_path = doc.get_thumbnail_folder() / 'slide{number:d}.png'.format(number=i)
|
thumbnail_path = doc.get_thumbnail_folder() / 'slide{number:d}.png'.format(number=i)
|
||||||
|
@ -56,6 +56,7 @@ WIN32_MODULES = [
|
|||||||
LINUX_MODULES = [
|
LINUX_MODULES = [
|
||||||
# Optical drive detection.
|
# Optical drive detection.
|
||||||
'dbus',
|
'dbus',
|
||||||
|
'distro',
|
||||||
'Xlib',
|
'Xlib',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
1
setup.py
1
setup.py
@ -101,6 +101,7 @@ using a computer and a data projector.""",
|
|||||||
'beautifulsoup4',
|
'beautifulsoup4',
|
||||||
'chardet',
|
'chardet',
|
||||||
'dbus-python; platform_system=="Linux"',
|
'dbus-python; platform_system=="Linux"',
|
||||||
|
'distro; platform_system=="Linux"',
|
||||||
'lxml',
|
'lxml',
|
||||||
'Mako',
|
'Mako',
|
||||||
'pymediainfo >= 2.2',
|
'pymediainfo >= 2.2',
|
||||||
|
@ -23,6 +23,7 @@ All the tests
|
|||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
from tempfile import mkstemp
|
from tempfile import mkstemp
|
||||||
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from PyQt5 import QtCore, QtWidgets
|
from PyQt5 import QtCore, QtWidgets
|
||||||
@ -39,24 +40,34 @@ def qapp():
|
|||||||
del app
|
del app
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def registry():
|
||||||
|
"""An instance of the Registry"""
|
||||||
|
Registry.create()
|
||||||
|
|
||||||
|
|
||||||
@pytest.yield_fixture
|
@pytest.yield_fixture
|
||||||
def settings(qapp):
|
def settings(qapp, registry):
|
||||||
"""A Settings() instance"""
|
"""A Settings() instance"""
|
||||||
fd, ini_file = mkstemp('.ini')
|
fd, ini_file = mkstemp('.ini')
|
||||||
Settings.set_filename(ini_file)
|
Settings.set_filename(ini_file)
|
||||||
Registry.create()
|
|
||||||
Settings().setDefaultFormat(QtCore.QSettings.IniFormat)
|
Settings().setDefaultFormat(QtCore.QSettings.IniFormat)
|
||||||
# Needed on windows to make sure a Settings object is available during the tests
|
# Needed on windows to make sure a Settings object is available during the tests
|
||||||
sets = Settings()
|
sets = Settings()
|
||||||
sets.setValue('themes/global theme', 'my_theme')
|
sets.setValue('themes/global theme', 'my_theme')
|
||||||
Registry().register('settings', set)
|
Registry().register('settings', sets)
|
||||||
yield sets
|
yield sets
|
||||||
del sets
|
del sets
|
||||||
os.close(fd)
|
os.close(fd)
|
||||||
os.unlink(Settings().fileName())
|
os.unlink(Settings().fileName())
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.yield_fixture
|
||||||
def registry():
|
def mock_settings(registry):
|
||||||
"""An instance of the Registry"""
|
"""A Mock Settings() instance"""
|
||||||
Registry.create()
|
# Create and register a mock settings object to work with
|
||||||
|
mock_settings = MagicMock()
|
||||||
|
Registry().register('settings', mock_settings)
|
||||||
|
yield mock_settings
|
||||||
|
Registry().remove('settings')
|
||||||
|
del mock_settings
|
||||||
|
@ -22,11 +22,11 @@
|
|||||||
Functional tests to test the AppLocation class and related methods.
|
Functional tests to test the AppLocation class and related methods.
|
||||||
"""
|
"""
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from unittest import TestCase
|
from unittest import TestCase, skipUnless
|
||||||
from unittest.mock import MagicMock, call, patch
|
from unittest.mock import MagicMock, call, patch
|
||||||
|
|
||||||
from openlp.core.common import Singleton, clean_button_text, de_hump, extension_loader, is_linux, is_macosx, is_win, \
|
from openlp.core.common import Singleton, clean_button_text, de_hump, extension_loader, is_linux, is_macosx, is_win, \
|
||||||
normalize_str, path_to_module, trace_error_handler
|
is_64bit_instance, normalize_str, path_to_module, trace_error_handler
|
||||||
|
|
||||||
|
|
||||||
class TestCommonFunctions(TestCase):
|
class TestCommonFunctions(TestCase):
|
||||||
@ -243,7 +243,7 @@ class TestCommonFunctions(TestCase):
|
|||||||
# GIVEN: Mocked out objects
|
# GIVEN: Mocked out objects
|
||||||
with patch('openlp.core.common.os') as mocked_os, patch('openlp.core.common.sys') as mocked_sys:
|
with patch('openlp.core.common.os') as mocked_os, patch('openlp.core.common.sys') as mocked_sys:
|
||||||
|
|
||||||
# WHEN: The mocked os.name and sys.platform are set to 'posix' and 'linux3' repectivly
|
# WHEN: The mocked os.name and sys.platform are set to 'posix' and 'linux3' repectively
|
||||||
mocked_os.name = 'posix'
|
mocked_os.name = 'posix'
|
||||||
mocked_sys.platform = 'linux3'
|
mocked_sys.platform = 'linux3'
|
||||||
|
|
||||||
@ -252,6 +252,40 @@ class TestCommonFunctions(TestCase):
|
|||||||
assert is_win() is False, 'is_win() should return False'
|
assert is_win() is False, 'is_win() should return False'
|
||||||
assert is_macosx() is False, 'is_macosx() should return False'
|
assert is_macosx() is False, 'is_macosx() should return False'
|
||||||
|
|
||||||
|
@skipUnless(is_linux(), 'This can only run on Linux')
|
||||||
|
def test_is_linux_distro(self):
|
||||||
|
"""
|
||||||
|
Test the is_linux() function for a particular Linux distribution
|
||||||
|
"""
|
||||||
|
# GIVEN: Mocked out objects
|
||||||
|
with patch('openlp.core.common.os') as mocked_os, \
|
||||||
|
patch('openlp.core.common.sys') as mocked_sys, \
|
||||||
|
patch('openlp.core.common.distro_id') as mocked_distro_id:
|
||||||
|
|
||||||
|
# WHEN: The mocked os.name and sys.platform are set to 'posix' and 'linux3' repectively
|
||||||
|
# and the distro is Fedora
|
||||||
|
mocked_os.name = 'posix'
|
||||||
|
mocked_sys.platform = 'linux3'
|
||||||
|
mocked_distro_id.return_value = 'fedora'
|
||||||
|
|
||||||
|
# THEN: The three platform functions should perform properly
|
||||||
|
assert is_linux(distro='fedora') is True, 'is_linux(distro="fedora") should return True'
|
||||||
|
assert is_win() is False, 'is_win() should return False'
|
||||||
|
assert is_macosx() is False, 'is_macosx() should return False'
|
||||||
|
|
||||||
|
def test_is_64bit_instance(self):
|
||||||
|
"""
|
||||||
|
Test the is_64bit_instance() function
|
||||||
|
"""
|
||||||
|
# GIVEN: Mocked out objects
|
||||||
|
with patch('openlp.core.common.sys') as mocked_sys:
|
||||||
|
|
||||||
|
# WHEN: The mocked sys.maxsize is set to 32-bit
|
||||||
|
mocked_sys.maxsize = 2**32
|
||||||
|
|
||||||
|
# THEN: The result should be False
|
||||||
|
assert is_64bit_instance() is False, 'is_64bit_instance() should return False'
|
||||||
|
|
||||||
def test_normalize_str_leaves_newlines(self):
|
def test_normalize_str_leaves_newlines(self):
|
||||||
# GIVEN: a string containing newlines
|
# GIVEN: a string containing newlines
|
||||||
string = 'something\nelse'
|
string = 'something\nelse'
|
||||||
|
@ -25,6 +25,7 @@ from unittest import TestCase
|
|||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
from openlp.core.common.registry import Registry
|
from openlp.core.common.registry import Registry
|
||||||
|
from openlp.core.ui import DisplayControllerType
|
||||||
from openlp.core.ui.media.mediacontroller import MediaController
|
from openlp.core.ui.media.mediacontroller import MediaController
|
||||||
from openlp.core.ui.media import ItemMediaInfo
|
from openlp.core.ui.media import ItemMediaInfo
|
||||||
from tests.helpers.testmixin import TestMixin
|
from tests.helpers.testmixin import TestMixin
|
||||||
@ -202,3 +203,122 @@ class TestMediaController(TestCase, TestMixin):
|
|||||||
|
|
||||||
# THEN you can determine the run time
|
# THEN you can determine the run time
|
||||||
assert results == test_data[1], 'The correct duration is returned for ' + test_data[0]
|
assert results == test_data[1], 'The correct duration is returned for ' + test_data[0]
|
||||||
|
|
||||||
|
def test_on_media_play(self):
|
||||||
|
"""
|
||||||
|
Test the on_media_play method
|
||||||
|
"""
|
||||||
|
# GIVEN: A mocked live controller and a mocked media_play() method
|
||||||
|
mocked_live_controller = MagicMock()
|
||||||
|
Registry().register('live_controller', mocked_live_controller)
|
||||||
|
media_controller = MediaController()
|
||||||
|
media_controller.media_play = MagicMock()
|
||||||
|
|
||||||
|
# WHEN: the on_media_play() method is called
|
||||||
|
media_controller.on_media_play()
|
||||||
|
|
||||||
|
# The mocked live controller should be called
|
||||||
|
media_controller.media_play.assert_called_once_with(mocked_live_controller, False)
|
||||||
|
|
||||||
|
def test_on_media_pause(self):
|
||||||
|
"""
|
||||||
|
Test the on_media_pause method
|
||||||
|
"""
|
||||||
|
# GIVEN: A mocked live controller and a mocked media_pause() method
|
||||||
|
mocked_live_controller = MagicMock()
|
||||||
|
Registry().register('live_controller', mocked_live_controller)
|
||||||
|
media_controller = MediaController()
|
||||||
|
media_controller.media_pause = MagicMock()
|
||||||
|
|
||||||
|
# WHEN: the on_media_pause() method is called
|
||||||
|
media_controller.on_media_pause()
|
||||||
|
|
||||||
|
# The mocked live controller should be called
|
||||||
|
media_controller.media_pause.assert_called_once_with(mocked_live_controller)
|
||||||
|
|
||||||
|
def test_on_media_stop(self):
|
||||||
|
"""
|
||||||
|
Test the on_media_stop method
|
||||||
|
"""
|
||||||
|
# GIVEN: A mocked live controller and a mocked media_stop() method
|
||||||
|
mocked_live_controller = MagicMock()
|
||||||
|
Registry().register('live_controller', mocked_live_controller)
|
||||||
|
media_controller = MediaController()
|
||||||
|
media_controller.media_stop = MagicMock()
|
||||||
|
|
||||||
|
# WHEN: the on_media_stop() method is called
|
||||||
|
media_controller.on_media_stop()
|
||||||
|
|
||||||
|
# The mocked live controller should be called
|
||||||
|
media_controller.media_stop.assert_called_once_with(mocked_live_controller)
|
||||||
|
|
||||||
|
def test_display_controllers_live(self):
|
||||||
|
"""
|
||||||
|
Test that the display_controllers() method returns the live controller when requested
|
||||||
|
"""
|
||||||
|
# GIVEN: A mocked live controller
|
||||||
|
media_controller = MediaController()
|
||||||
|
mocked_live_controller = MagicMock()
|
||||||
|
mocked_preview_controller = MagicMock()
|
||||||
|
Registry().register('live_controller', mocked_live_controller)
|
||||||
|
Registry().register('preview_controller', mocked_preview_controller)
|
||||||
|
|
||||||
|
# WHEN: display_controllers() is called with DisplayControllerType.Live
|
||||||
|
controller = media_controller.display_controllers(DisplayControllerType.Live)
|
||||||
|
|
||||||
|
# THEN: the controller should be the live controller
|
||||||
|
assert controller is mocked_live_controller
|
||||||
|
|
||||||
|
def test_display_controllers_preview(self):
|
||||||
|
"""
|
||||||
|
Test that the display_controllers() method returns the preview controller when requested
|
||||||
|
"""
|
||||||
|
# GIVEN: A mocked live controller
|
||||||
|
media_controller = MediaController()
|
||||||
|
mocked_live_controller = MagicMock()
|
||||||
|
mocked_preview_controller = MagicMock()
|
||||||
|
Registry().register('live_controller', mocked_live_controller)
|
||||||
|
Registry().register('preview_controller', mocked_preview_controller)
|
||||||
|
|
||||||
|
# WHEN: display_controllers() is called with DisplayControllerType.Preview
|
||||||
|
controller = media_controller.display_controllers(DisplayControllerType.Preview)
|
||||||
|
|
||||||
|
# THEN: the controller should be the live controller
|
||||||
|
assert controller is mocked_preview_controller
|
||||||
|
|
||||||
|
def test_set_controls_visible(self):
|
||||||
|
"""
|
||||||
|
Test that "set_controls_visible" sets the media controls on the controller to be visible or not
|
||||||
|
"""
|
||||||
|
# GIVEN: A mocked controller
|
||||||
|
mocked_controller = MagicMock()
|
||||||
|
|
||||||
|
# WHEN: Set to visible
|
||||||
|
MediaController.set_controls_visible(mocked_controller, True)
|
||||||
|
|
||||||
|
# THEN: The media controls should have been set to visible
|
||||||
|
mocked_controller.mediabar.setVisible.assert_called_once_with(True)
|
||||||
|
|
||||||
|
@patch('openlp.core.ui.media.mediacontroller.ItemMediaInfo')
|
||||||
|
def test_setup_display(self, MockItemMediaInfo):
|
||||||
|
"""
|
||||||
|
Test that the display/controllers are set up correctly
|
||||||
|
"""
|
||||||
|
# GIVEN: A media controller object and some mocks
|
||||||
|
mocked_media_info = MagicMock()
|
||||||
|
MockItemMediaInfo.return_value = mocked_media_info
|
||||||
|
media_controller = MediaController()
|
||||||
|
media_controller.vlc_player = MagicMock()
|
||||||
|
mocked_display = MagicMock()
|
||||||
|
media_controller._define_display = MagicMock(return_value=mocked_display)
|
||||||
|
media_controller.vlc_player = MagicMock()
|
||||||
|
controller = MagicMock()
|
||||||
|
|
||||||
|
# WHEN: setup_display() is called
|
||||||
|
media_controller.setup_display(controller, True)
|
||||||
|
|
||||||
|
# THEN: The right calls should have been made
|
||||||
|
assert controller.media_info == mocked_media_info
|
||||||
|
assert controller.has_audio is False
|
||||||
|
media_controller._define_display.assert_called_once_with(controller)
|
||||||
|
media_controller.vlc_player.setup(controller, mocked_display, False)
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
"""
|
"""
|
||||||
Package to test the openlp.core.ui.slidecontroller package.
|
Package to test the openlp.core.ui.slidecontroller package.
|
||||||
"""
|
"""
|
||||||
from unittest import TestCase
|
|
||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
from PyQt5 import QtCore, QtGui
|
from PyQt5 import QtCore, QtGui
|
||||||
@ -32,15 +31,7 @@ from openlp.core.ui.slidecontroller import NON_TEXT_MENU, WIDE_MENU, InfoLabel,
|
|||||||
SlideController
|
SlideController
|
||||||
|
|
||||||
|
|
||||||
class TestSlideController(TestCase):
|
def test_initial_slide_controller(registry):
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
"""
|
|
||||||
Set up the components need for all tests.
|
|
||||||
"""
|
|
||||||
Registry.create()
|
|
||||||
|
|
||||||
def test_initial_slide_controller(self):
|
|
||||||
"""
|
"""
|
||||||
Test the initial slide controller state .
|
Test the initial slide controller state .
|
||||||
"""
|
"""
|
||||||
@ -51,7 +42,8 @@ class TestSlideController(TestCase):
|
|||||||
# THEN: The controller should not be a live controller.
|
# THEN: The controller should not be a live controller.
|
||||||
assert slide_controller.is_live is False, 'The base slide controller should not be a live controller'
|
assert slide_controller.is_live is False, 'The base slide controller should not be a live controller'
|
||||||
|
|
||||||
def test_text_service_item_blank(self):
|
|
||||||
|
def test_text_service_item_blank():
|
||||||
"""
|
"""
|
||||||
Test that loading a text-based service item into the slide controller sets the correct blank menu
|
Test that loading a text-based service item into the slide controller sets the correct blank menu
|
||||||
"""
|
"""
|
||||||
@ -70,7 +62,8 @@ class TestSlideController(TestCase):
|
|||||||
# THEN: the call to set the visible items on the toolbar should be correct
|
# THEN: the call to set the visible items on the toolbar should be correct
|
||||||
toolbar.set_widget_visible.assert_called_with(WIDE_MENU, True)
|
toolbar.set_widget_visible.assert_called_with(WIDE_MENU, True)
|
||||||
|
|
||||||
def test_non_text_service_item_blank(self):
|
|
||||||
|
def test_non_text_service_item_blank():
|
||||||
"""
|
"""
|
||||||
Test that loading a non-text service item into the slide controller sets the correct blank menu
|
Test that loading a non-text service item into the slide controller sets the correct blank menu
|
||||||
"""
|
"""
|
||||||
@ -89,14 +82,13 @@ class TestSlideController(TestCase):
|
|||||||
# THEN: then call set up the toolbar to blank the display screen.
|
# THEN: then call set up the toolbar to blank the display screen.
|
||||||
toolbar.set_widget_visible.assert_called_with(NON_TEXT_MENU, True)
|
toolbar.set_widget_visible.assert_called_with(NON_TEXT_MENU, True)
|
||||||
|
|
||||||
@patch('openlp.core.ui.slidecontroller.Settings')
|
|
||||||
def test_receive_spin_delay(self, MockedSettings):
|
def test_receive_spin_delay(mock_settings):
|
||||||
"""
|
"""
|
||||||
Test that the spin box is updated accordingly after a call to receive_spin_delay()
|
Test that the spin box is updated accordingly after a call to receive_spin_delay()
|
||||||
"""
|
"""
|
||||||
# GIVEN: A new SlideController instance.
|
# GIVEN: A new SlideController instance.
|
||||||
mocked_value = MagicMock(return_value=1)
|
mock_settings.value.return_value = 1
|
||||||
MockedSettings.return_value = MagicMock(value=mocked_value)
|
|
||||||
mocked_delay_spin_box = MagicMock()
|
mocked_delay_spin_box = MagicMock()
|
||||||
slide_controller = SlideController(None)
|
slide_controller = SlideController(None)
|
||||||
slide_controller.delay_spin_box = mocked_delay_spin_box
|
slide_controller.delay_spin_box = mocked_delay_spin_box
|
||||||
@ -104,11 +96,13 @@ class TestSlideController(TestCase):
|
|||||||
# WHEN: The receive_spin_delay() method is called
|
# WHEN: The receive_spin_delay() method is called
|
||||||
slide_controller.receive_spin_delay()
|
slide_controller.receive_spin_delay()
|
||||||
|
|
||||||
# THEN: The Settings()value() and delay_spin_box.setValue() methods should have been called correctly
|
# THEN: The settings value() and delay_spin_box.setValue() methods should have been called correctly
|
||||||
mocked_value.assert_called_with('core/loop delay')
|
msv = mock_settings.value
|
||||||
|
msv.assert_called_with('core/loop delay')
|
||||||
mocked_delay_spin_box.setValue.assert_called_with(1)
|
mocked_delay_spin_box.setValue.assert_called_with(1)
|
||||||
|
|
||||||
def test_toggle_display_blank(self):
|
|
||||||
|
def test_toggle_display_blank():
|
||||||
"""
|
"""
|
||||||
Check that the toggle_display('blank') method calls the on_blank_display() method
|
Check that the toggle_display('blank') method calls the on_blank_display() method
|
||||||
"""
|
"""
|
||||||
@ -129,7 +123,8 @@ class TestSlideController(TestCase):
|
|||||||
assert 0 == mocked_on_theme_display.call_count, 'on_theme_display should not have been called'
|
assert 0 == mocked_on_theme_display.call_count, 'on_theme_display should not have been called'
|
||||||
assert 0 == mocked_on_hide_display.call_count, 'on_hide_display should not have been called'
|
assert 0 == mocked_on_hide_display.call_count, 'on_hide_display should not have been called'
|
||||||
|
|
||||||
def test_toggle_display_hide(self):
|
|
||||||
|
def test_toggle_display_hide():
|
||||||
"""
|
"""
|
||||||
Check that the toggle_display('hide') method calls the on_blank_display() method
|
Check that the toggle_display('hide') method calls the on_blank_display() method
|
||||||
"""
|
"""
|
||||||
@ -150,7 +145,8 @@ class TestSlideController(TestCase):
|
|||||||
assert 0 == mocked_on_theme_display.call_count, 'on_theme_display should not have been called'
|
assert 0 == mocked_on_theme_display.call_count, 'on_theme_display should not have been called'
|
||||||
assert 0 == mocked_on_hide_display.call_count, 'on_hide_display should not have been called'
|
assert 0 == mocked_on_hide_display.call_count, 'on_hide_display should not have been called'
|
||||||
|
|
||||||
def test_toggle_display_theme(self):
|
|
||||||
|
def test_toggle_display_theme():
|
||||||
"""
|
"""
|
||||||
Check that the toggle_display('theme') method calls the on_theme_display() method
|
Check that the toggle_display('theme') method calls the on_theme_display() method
|
||||||
"""
|
"""
|
||||||
@ -171,7 +167,8 @@ class TestSlideController(TestCase):
|
|||||||
assert 0 == mocked_on_blank_display.call_count, 'on_blank_display should not have been called'
|
assert 0 == mocked_on_blank_display.call_count, 'on_blank_display should not have been called'
|
||||||
assert 0 == mocked_on_hide_display.call_count, 'on_hide_display should not have been called'
|
assert 0 == mocked_on_hide_display.call_count, 'on_hide_display should not have been called'
|
||||||
|
|
||||||
def test_toggle_display_desktop(self):
|
|
||||||
|
def test_toggle_display_desktop():
|
||||||
"""
|
"""
|
||||||
Check that the toggle_display('desktop') method calls the on_hide_display() method
|
Check that the toggle_display('desktop') method calls the on_hide_display() method
|
||||||
"""
|
"""
|
||||||
@ -192,7 +189,8 @@ class TestSlideController(TestCase):
|
|||||||
assert 0 == mocked_on_blank_display.call_count, 'on_blank_display should not have been called'
|
assert 0 == mocked_on_blank_display.call_count, 'on_blank_display should not have been called'
|
||||||
assert 0 == mocked_on_theme_display.call_count, 'on_theme_display should not have been called'
|
assert 0 == mocked_on_theme_display.call_count, 'on_theme_display should not have been called'
|
||||||
|
|
||||||
def test_toggle_display_show(self):
|
|
||||||
|
def test_toggle_display_show():
|
||||||
"""
|
"""
|
||||||
Check that the toggle_display('show') method calls all the on_X_display() methods
|
Check that the toggle_display('show') method calls all the on_X_display() methods
|
||||||
"""
|
"""
|
||||||
@ -213,7 +211,8 @@ class TestSlideController(TestCase):
|
|||||||
mocked_on_theme_display.assert_called_once_with(False)
|
mocked_on_theme_display.assert_called_once_with(False)
|
||||||
mocked_on_hide_display.assert_called_once_with(False)
|
mocked_on_hide_display.assert_called_once_with(False)
|
||||||
|
|
||||||
def test_on_go_live_preview_controller(self):
|
|
||||||
|
def test_on_go_live_preview_controller():
|
||||||
"""
|
"""
|
||||||
Test that when the on_go_preview() method is called the message is sent to the preview controller and focus is
|
Test that when the on_go_preview() method is called the message is sent to the preview controller and focus is
|
||||||
set correctly.
|
set correctly.
|
||||||
@ -240,7 +239,8 @@ class TestSlideController(TestCase):
|
|||||||
# THEN: the preview controller should have the service item and the focus set to live
|
# THEN: the preview controller should have the service item and the focus set to live
|
||||||
mocked_preview_controller.preview_widget.setFocus.assert_called_once_with()
|
mocked_preview_controller.preview_widget.setFocus.assert_called_once_with()
|
||||||
|
|
||||||
def test_on_go_live_live_controller(self):
|
|
||||||
|
def test_on_go_live_live_controller():
|
||||||
"""
|
"""
|
||||||
Test that when the on_go_live() method is called the message is sent to the live controller and focus is
|
Test that when the on_go_live() method is called the message is sent to the live controller and focus is
|
||||||
set correctly.
|
set correctly.
|
||||||
@ -268,7 +268,8 @@ class TestSlideController(TestCase):
|
|||||||
mocked_live_controller.add_service_manager_item.assert_called_once_with(mocked_service_item, 1)
|
mocked_live_controller.add_service_manager_item.assert_called_once_with(mocked_service_item, 1)
|
||||||
mocked_live_controller.preview_widget.setFocus.assert_called_once_with()
|
mocked_live_controller.preview_widget.setFocus.assert_called_once_with()
|
||||||
|
|
||||||
def test_on_go_live_service_manager(self):
|
|
||||||
|
def test_on_go_live_service_manager():
|
||||||
"""
|
"""
|
||||||
Test that when the on_go_live() method is called the message is sent to the live controller and focus is
|
Test that when the on_go_live() method is called the message is sent to the live controller and focus is
|
||||||
set correctly.
|
set correctly.
|
||||||
@ -299,7 +300,8 @@ class TestSlideController(TestCase):
|
|||||||
mocked_service_manager.preview_live.assert_called_once_with(42, 1)
|
mocked_service_manager.preview_live.assert_called_once_with(42, 1)
|
||||||
mocked_live_controller.preview_widget.setFocus.assert_called_once_with()
|
mocked_live_controller.preview_widget.setFocus.assert_called_once_with()
|
||||||
|
|
||||||
def test_service_previous(self):
|
|
||||||
|
def test_service_previous():
|
||||||
"""
|
"""
|
||||||
Check that calling the service_previous() method adds the previous key to the queue and processes the queue
|
Check that calling the service_previous() method adds the previous key to the queue and processes the queue
|
||||||
"""
|
"""
|
||||||
@ -317,7 +319,8 @@ class TestSlideController(TestCase):
|
|||||||
mocked_keypress_queue.append.assert_called_once_with(ServiceItemAction.Previous)
|
mocked_keypress_queue.append.assert_called_once_with(ServiceItemAction.Previous)
|
||||||
mocked_process_queue.assert_called_once_with()
|
mocked_process_queue.assert_called_once_with()
|
||||||
|
|
||||||
def test_service_next(self):
|
|
||||||
|
def test_service_next():
|
||||||
"""
|
"""
|
||||||
Check that calling the service_next() method adds the next key to the queue and processes the queue
|
Check that calling the service_next() method adds the next key to the queue and processes the queue
|
||||||
"""
|
"""
|
||||||
@ -335,16 +338,14 @@ class TestSlideController(TestCase):
|
|||||||
mocked_keypress_queue.append.assert_called_once_with(ServiceItemAction.Next)
|
mocked_keypress_queue.append.assert_called_once_with(ServiceItemAction.Next)
|
||||||
mocked_process_queue.assert_called_once_with()
|
mocked_process_queue.assert_called_once_with()
|
||||||
|
|
||||||
@patch('openlp.core.ui.slidecontroller.Settings')
|
|
||||||
def test_update_slide_limits(self, MockedSettings):
|
def test_update_slide_limits(mock_settings):
|
||||||
"""
|
"""
|
||||||
Test that calling the update_slide_limits() method updates the slide limits
|
Test that calling the update_slide_limits() method updates the slide limits
|
||||||
"""
|
"""
|
||||||
# GIVEN: A mocked out Settings object, a new SlideController and a mocked out main_window
|
# GIVEN: A mocked out Settings object, a new SlideController and a mocked out main_window
|
||||||
mocked_value = MagicMock(return_value=10)
|
mock_settings.value.return_value = 10
|
||||||
MockedSettings.return_value = MagicMock(value=mocked_value)
|
|
||||||
mocked_main_window = MagicMock(advanced_settings_section='advanced')
|
mocked_main_window = MagicMock(advanced_settings_section='advanced')
|
||||||
Registry.create()
|
|
||||||
Registry().register('main_window', mocked_main_window)
|
Registry().register('main_window', mocked_main_window)
|
||||||
slide_controller = SlideController(None)
|
slide_controller = SlideController(None)
|
||||||
|
|
||||||
@ -352,10 +353,12 @@ class TestSlideController(TestCase):
|
|||||||
slide_controller.update_slide_limits()
|
slide_controller.update_slide_limits()
|
||||||
|
|
||||||
# THEN: The value of slide_limits should be 10
|
# THEN: The value of slide_limits should be 10
|
||||||
mocked_value.assert_called_once_with('advanced/slide limits')
|
msv = mock_settings.value
|
||||||
|
msv.assert_called_once_with('advanced/slide limits')
|
||||||
assert 10 == slide_controller.slide_limits, 'Slide limits should have been updated to 10'
|
assert 10 == slide_controller.slide_limits, 'Slide limits should have been updated to 10'
|
||||||
|
|
||||||
def test_enable_tool_bar_live(self):
|
|
||||||
|
def test_enable_tool_bar_live():
|
||||||
"""
|
"""
|
||||||
Check that when enable_tool_bar on a live slide controller is called, enable_live_tool_bar is called
|
Check that when enable_tool_bar on a live slide controller is called, enable_live_tool_bar is called
|
||||||
"""
|
"""
|
||||||
@ -375,7 +378,8 @@ class TestSlideController(TestCase):
|
|||||||
mocked_enable_live_tool_bar.assert_called_once_with(mocked_service_item)
|
mocked_enable_live_tool_bar.assert_called_once_with(mocked_service_item)
|
||||||
assert 0 == mocked_enable_preview_tool_bar.call_count, 'The preview method should not have been called'
|
assert 0 == mocked_enable_preview_tool_bar.call_count, 'The preview method should not have been called'
|
||||||
|
|
||||||
def test_enable_tool_bar_preview(self):
|
|
||||||
|
def test_enable_tool_bar_preview():
|
||||||
"""
|
"""
|
||||||
Check that when enable_tool_bar on a preview slide controller is called, enable_preview_tool_bar is called
|
Check that when enable_tool_bar on a preview slide controller is called, enable_preview_tool_bar is called
|
||||||
"""
|
"""
|
||||||
@ -395,7 +399,8 @@ class TestSlideController(TestCase):
|
|||||||
mocked_enable_preview_tool_bar.assert_called_once_with(mocked_service_item)
|
mocked_enable_preview_tool_bar.assert_called_once_with(mocked_service_item)
|
||||||
assert 0 == mocked_enable_live_tool_bar.call_count, 'The live method should not have been called'
|
assert 0 == mocked_enable_live_tool_bar.call_count, 'The live method should not have been called'
|
||||||
|
|
||||||
def test_refresh_service_item_text(self):
|
|
||||||
|
def test_refresh_service_item_text():
|
||||||
"""
|
"""
|
||||||
Test that the refresh_service_item() method refreshes a text service item
|
Test that the refresh_service_item() method refreshes a text service item
|
||||||
"""
|
"""
|
||||||
@ -418,7 +423,8 @@ class TestSlideController(TestCase):
|
|||||||
mocked_service_item.render.assert_called_once_with()
|
mocked_service_item.render.assert_called_once_with()
|
||||||
mocked_process_item.assert_called_once_with(mocked_service_item, 5)
|
mocked_process_item.assert_called_once_with(mocked_service_item, 5)
|
||||||
|
|
||||||
def test_refresh_service_item_image(self):
|
|
||||||
|
def test_refresh_service_item_image():
|
||||||
"""
|
"""
|
||||||
Test that the refresh_service_item() method refreshes a image service item
|
Test that the refresh_service_item() method refreshes a image service item
|
||||||
"""
|
"""
|
||||||
@ -441,7 +447,8 @@ class TestSlideController(TestCase):
|
|||||||
mocked_service_item.render.assert_called_once_with()
|
mocked_service_item.render.assert_called_once_with()
|
||||||
mocked_process_item.assert_called_once_with(mocked_service_item, 5)
|
mocked_process_item.assert_called_once_with(mocked_service_item, 5)
|
||||||
|
|
||||||
def test_refresh_service_item_not_image_or_text(self):
|
|
||||||
|
def test_refresh_service_item_not_image_or_text():
|
||||||
"""
|
"""
|
||||||
Test that the refresh_service_item() method does not refresh a service item if it's neither text or an image
|
Test that the refresh_service_item() method does not refresh a service item if it's neither text or an image
|
||||||
"""
|
"""
|
||||||
@ -464,7 +471,8 @@ class TestSlideController(TestCase):
|
|||||||
assert 0 == mocked_service_item.render.call_count, 'The render() method should not have been called'
|
assert 0 == mocked_service_item.render.call_count, 'The render() method should not have been called'
|
||||||
assert 0 == mocked_process_item.call_count, 'The mocked_process_item() method should not have been called'
|
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(self):
|
|
||||||
|
def test_add_service_item_with_song_edit():
|
||||||
"""
|
"""
|
||||||
Test the add_service_item() method when song_edit is True
|
Test the add_service_item() method when song_edit is True
|
||||||
"""
|
"""
|
||||||
@ -483,7 +491,8 @@ class TestSlideController(TestCase):
|
|||||||
assert slide_controller.song_edit is False, 'song_edit should be False'
|
assert slide_controller.song_edit is False, 'song_edit should be False'
|
||||||
mocked_process_item.assert_called_once_with(mocked_item, 2)
|
mocked_process_item.assert_called_once_with(mocked_item, 2)
|
||||||
|
|
||||||
def test_add_service_item_without_song_edit(self):
|
|
||||||
|
def test_add_service_item_without_song_edit():
|
||||||
"""
|
"""
|
||||||
Test the add_service_item() method when song_edit is False
|
Test the add_service_item() method when song_edit is False
|
||||||
"""
|
"""
|
||||||
@ -502,7 +511,8 @@ class TestSlideController(TestCase):
|
|||||||
assert slide_controller.song_edit is False, 'song_edit should be False'
|
assert slide_controller.song_edit is False, 'song_edit should be False'
|
||||||
mocked_process_item.assert_called_once_with(mocked_item, 0)
|
mocked_process_item.assert_called_once_with(mocked_item, 0)
|
||||||
|
|
||||||
def test_replace_service_manager_item_different_items(self):
|
|
||||||
|
def test_replace_service_manager_item_different_items():
|
||||||
"""
|
"""
|
||||||
Test that when the service items are not the same, nothing happens
|
Test that when the service items are not the same, nothing happens
|
||||||
"""
|
"""
|
||||||
@ -523,7 +533,8 @@ class TestSlideController(TestCase):
|
|||||||
assert 0 == mocked_preview_widget.current_slide_number.call_count, \
|
assert 0 == mocked_preview_widget.current_slide_number.call_count, \
|
||||||
'The preview_widget current_slide_number.() method should not have been called'
|
'The preview_widget current_slide_number.() method should not have been called'
|
||||||
|
|
||||||
def test_replace_service_manager_item_same_item(self):
|
|
||||||
|
def test_replace_service_manager_item_same_item():
|
||||||
"""
|
"""
|
||||||
Test that when the service item is the same, the service item is reprocessed
|
Test that when the service item is the same, the service item is reprocessed
|
||||||
"""
|
"""
|
||||||
@ -544,7 +555,8 @@ class TestSlideController(TestCase):
|
|||||||
mocked_preview_widget.current_slide_number.assert_called_with()
|
mocked_preview_widget.current_slide_number.assert_called_with()
|
||||||
mocked_process_item.assert_called_once_with(mocked_item, 7)
|
mocked_process_item.assert_called_once_with(mocked_item, 7)
|
||||||
|
|
||||||
def test_on_slide_blank(self):
|
|
||||||
|
def test_on_slide_blank():
|
||||||
"""
|
"""
|
||||||
Test on_slide_blank
|
Test on_slide_blank
|
||||||
"""
|
"""
|
||||||
@ -558,7 +570,8 @@ class TestSlideController(TestCase):
|
|||||||
# THEN: on_blank_display should have been called with True
|
# THEN: on_blank_display should have been called with True
|
||||||
slide_controller.on_blank_display.assert_called_once_with(True)
|
slide_controller.on_blank_display.assert_called_once_with(True)
|
||||||
|
|
||||||
def test_on_slide_unblank(self):
|
|
||||||
|
def test_on_slide_unblank():
|
||||||
"""
|
"""
|
||||||
Test on_slide_unblank
|
Test on_slide_unblank
|
||||||
"""
|
"""
|
||||||
@ -572,7 +585,8 @@ class TestSlideController(TestCase):
|
|||||||
# THEN: on_blank_display should have been called with False
|
# THEN: on_blank_display should have been called with False
|
||||||
slide_controller.on_blank_display.assert_called_once_with(False)
|
slide_controller.on_blank_display.assert_called_once_with(False)
|
||||||
|
|
||||||
def test_on_slide_selected_index_no_service_item(self):
|
|
||||||
|
def test_on_slide_selected_index_no_service_item():
|
||||||
"""
|
"""
|
||||||
Test that when there is no service item, the on_slide_selected_index() method returns immediately
|
Test that when there is no service item, the on_slide_selected_index() method returns immediately
|
||||||
"""
|
"""
|
||||||
@ -587,8 +601,9 @@ class TestSlideController(TestCase):
|
|||||||
# THEN: It should have exited early
|
# THEN: It should have exited early
|
||||||
assert 0 == mocked_item.is_command.call_count, 'The service item should have not been called'
|
assert 0 == mocked_item.is_command.call_count, 'The service item should have not been called'
|
||||||
|
|
||||||
@patch.object(Registry, 'execute')
|
|
||||||
def test_on_slide_selected_index_service_item_command(self, mocked_execute):
|
@patch.object(Registry, 'execute')
|
||||||
|
def test_on_slide_selected_index_service_item_command(mocked_execute):
|
||||||
"""
|
"""
|
||||||
Test that when there is a command service item, the command is executed
|
Test that when there is a command service item, the command is executed
|
||||||
"""
|
"""
|
||||||
@ -617,8 +632,9 @@ class TestSlideController(TestCase):
|
|||||||
assert 0 == mocked_preview_widget.change_slide.call_count, 'Change slide should not have been called'
|
assert 0 == mocked_preview_widget.change_slide.call_count, 'Change slide should not have been called'
|
||||||
assert 0 == mocked_slide_selected.call_count, 'slide_selected should not have been called'
|
assert 0 == mocked_slide_selected.call_count, 'slide_selected should not have been called'
|
||||||
|
|
||||||
@patch.object(Registry, 'execute')
|
|
||||||
def test_on_slide_selected_index_service_item_not_command(self, mocked_execute):
|
@patch.object(Registry, 'execute')
|
||||||
|
def test_on_slide_selected_index_service_item_not_command(mocked_execute):
|
||||||
"""
|
"""
|
||||||
Test that when there is a service item but it's not a command, the preview widget is updated
|
Test that when there is a service item but it's not a command, the preview widget is updated
|
||||||
"""
|
"""
|
||||||
@ -646,8 +662,9 @@ class TestSlideController(TestCase):
|
|||||||
mocked_preview_widget.change_slide.assert_called_once_with(7)
|
mocked_preview_widget.change_slide.assert_called_once_with(7)
|
||||||
mocked_slide_selected.assert_called_once_with()
|
mocked_slide_selected.assert_called_once_with()
|
||||||
|
|
||||||
@patch.object(Registry, 'execute')
|
|
||||||
def test_process_item(self, mocked_execute):
|
@patch.object(Registry, 'execute')
|
||||||
|
def test_process_item(mocked_execute):
|
||||||
"""
|
"""
|
||||||
Test that presentation service-items is closed when followed by a media service-item
|
Test that presentation service-items is closed when followed by a media service-item
|
||||||
"""
|
"""
|
||||||
@ -667,8 +684,8 @@ class TestSlideController(TestCase):
|
|||||||
mocked_media_item.is_image.return_value = False
|
mocked_media_item.is_image.return_value = False
|
||||||
mocked_media_item.from_service = False
|
mocked_media_item.from_service = False
|
||||||
mocked_media_item.get_frames.return_value = []
|
mocked_media_item.get_frames.return_value = []
|
||||||
Registry.create()
|
|
||||||
mocked_main_window = MagicMock()
|
mocked_main_window = MagicMock()
|
||||||
|
Registry.create()
|
||||||
Registry().register('main_window', mocked_main_window)
|
Registry().register('main_window', mocked_main_window)
|
||||||
Registry().register('media_controller', MagicMock())
|
Registry().register('media_controller', MagicMock())
|
||||||
slide_controller = SlideController(None)
|
slide_controller = SlideController(None)
|
||||||
@ -693,7 +710,8 @@ class TestSlideController(TestCase):
|
|||||||
assert 'mocked_presentation_item_stop' == mocked_execute.call_args_list[1][0][0], \
|
assert 'mocked_presentation_item_stop' == mocked_execute.call_args_list[1][0][0], \
|
||||||
'The presentation should have been stopped.'
|
'The presentation should have been stopped.'
|
||||||
|
|
||||||
def test_live_stolen_focus_shortcuts(self):
|
|
||||||
|
def test_live_stolen_focus_shortcuts():
|
||||||
"""
|
"""
|
||||||
Test that all the needed shortcuts are available in scenarios where Live has stolen focus.
|
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
|
These are found under def __add_actions_to_widget(self, widget): in slidecontroller.py
|
||||||
@ -721,20 +739,19 @@ class TestSlideController(TestCase):
|
|||||||
slide_controller.theme_screen, slide_controller.blank_screen
|
slide_controller.theme_screen, slide_controller.blank_screen
|
||||||
])
|
])
|
||||||
|
|
||||||
@patch('openlp.core.ui.slidecontroller.Settings')
|
|
||||||
def test_on_preview_double_click_unblank_display(self, MockedSettings):
|
def test_on_preview_double_click_unblank_display(mock_settings):
|
||||||
# GIVEN: A slide controller, actions needed, settins set to True.
|
# GIVEN: A slide controller, actions needed, settings set to True.
|
||||||
slide_controller = SlideController(None)
|
slide_controller = SlideController(None)
|
||||||
mocked_settings = MagicMock()
|
mocked_settings = MagicMock()
|
||||||
mocked_settings.return_value = True
|
mocked_settings.return_value = True
|
||||||
MockedSettings.return_value = mocked_settings
|
mock_settings.return_value = mocked_settings
|
||||||
slide_controller.service_item = MagicMock()
|
slide_controller.service_item = MagicMock()
|
||||||
slide_controller.service_item.is_media = MagicMock()
|
slide_controller.service_item.is_media = MagicMock()
|
||||||
slide_controller.on_media_close = MagicMock()
|
slide_controller.on_media_close = MagicMock()
|
||||||
slide_controller.on_go_live = MagicMock()
|
slide_controller.on_go_live = MagicMock()
|
||||||
slide_controller.on_preview_add_to_service = MagicMock()
|
slide_controller.on_preview_add_to_service = MagicMock()
|
||||||
slide_controller.media_reset = MagicMock()
|
slide_controller.media_reset = MagicMock()
|
||||||
Registry.create()
|
|
||||||
Registry().set_flag('has doubleclick added item to service', True)
|
Registry().set_flag('has doubleclick added item to service', True)
|
||||||
|
|
||||||
# WHEN: on_preview_double_click is called
|
# WHEN: on_preview_double_click is called
|
||||||
@ -744,20 +761,17 @@ class TestSlideController(TestCase):
|
|||||||
assert 1 == slide_controller.on_go_live.call_count, 'on_go_live should have been called once.'
|
assert 1 == slide_controller.on_go_live.call_count, 'on_go_live should have been called once.'
|
||||||
assert 0 == slide_controller.on_preview_add_to_service.call_count, 'Should have not been called.'
|
assert 0 == slide_controller.on_preview_add_to_service.call_count, 'Should have not been called.'
|
||||||
|
|
||||||
@patch('openlp.core.ui.slidecontroller.Settings')
|
|
||||||
def test_on_preview_double_click_add_to_service(self, MockedSettings):
|
def test_on_preview_double_click_add_to_service(mock_settings):
|
||||||
# GIVEN: A slide controller, actions needed, settins set to False.
|
# GIVEN: A slide controller, actions needed, settings set to False.
|
||||||
slide_controller = SlideController(None)
|
slide_controller = SlideController(None)
|
||||||
mocked_settings = MagicMock()
|
mock_settings.value.return_value = False
|
||||||
mocked_settings.value.return_value = False
|
|
||||||
MockedSettings.return_value = mocked_settings
|
|
||||||
slide_controller.service_item = MagicMock()
|
slide_controller.service_item = MagicMock()
|
||||||
slide_controller.service_item.is_media = MagicMock()
|
slide_controller.service_item.is_media = MagicMock()
|
||||||
slide_controller.on_media_close = MagicMock()
|
slide_controller.on_media_close = MagicMock()
|
||||||
slide_controller.on_go_live = MagicMock()
|
slide_controller.on_go_live = MagicMock()
|
||||||
slide_controller.on_preview_add_to_service = MagicMock()
|
slide_controller.on_preview_add_to_service = MagicMock()
|
||||||
slide_controller.media_reset = MagicMock()
|
slide_controller.media_reset = MagicMock()
|
||||||
Registry.create()
|
|
||||||
Registry().set_flag('has doubleclick added item to service', False)
|
Registry().set_flag('has doubleclick added item to service', False)
|
||||||
|
|
||||||
# WHEN: on_preview_double_click is called
|
# WHEN: on_preview_double_click is called
|
||||||
@ -767,9 +781,10 @@ class TestSlideController(TestCase):
|
|||||||
assert 0 == slide_controller.on_go_live.call_count, 'on_go_live Should have not been called.'
|
assert 0 == slide_controller.on_go_live.call_count, 'on_go_live Should have not been called.'
|
||||||
assert 1 == slide_controller.on_preview_add_to_service.call_count, 'Should have been called once.'
|
assert 1 == slide_controller.on_preview_add_to_service.call_count, 'Should have been called once.'
|
||||||
|
|
||||||
@patch(u'openlp.core.ui.slidecontroller.SlideController.image_manager')
|
|
||||||
@patch(u'PyQt5.QtCore.QTimer.singleShot')
|
@patch(u'openlp.core.ui.slidecontroller.SlideController.image_manager')
|
||||||
def test_update_preview_live(self, mocked_singleShot, mocked_image_manager):
|
@patch(u'PyQt5.QtCore.QTimer.singleShot')
|
||||||
|
def test_update_preview_live(mocked_singleShot, mocked_image_manager):
|
||||||
"""
|
"""
|
||||||
Test that the preview screen is updated with a screen grab for live service items
|
Test that the preview screen is updated with a screen grab for live service items
|
||||||
"""
|
"""
|
||||||
@ -809,9 +824,10 @@ class TestSlideController(TestCase):
|
|||||||
assert 2 == mocked_singleShot.call_count, 'Timer to grab_maindisplay should have been called 2 times'
|
assert 2 == mocked_singleShot.call_count, 'Timer to grab_maindisplay should have been called 2 times'
|
||||||
assert 0 == mocked_image_manager.get_image.call_count, 'image_manager not be called'
|
assert 0 == mocked_image_manager.get_image.call_count, 'image_manager not be called'
|
||||||
|
|
||||||
@patch(u'openlp.core.ui.slidecontroller.SlideController.image_manager')
|
|
||||||
@patch(u'PyQt5.QtCore.QTimer.singleShot')
|
@patch(u'openlp.core.ui.slidecontroller.SlideController.image_manager')
|
||||||
def test_update_preview_pres(self, mocked_singleShot, mocked_image_manager):
|
@patch(u'PyQt5.QtCore.QTimer.singleShot')
|
||||||
|
def test_update_preview_pres(mocked_singleShot, mocked_image_manager):
|
||||||
"""
|
"""
|
||||||
Test that the preview screen is updated with the correct preview for presentation service items
|
Test that the preview screen is updated with the correct preview for presentation service items
|
||||||
"""
|
"""
|
||||||
@ -849,11 +865,11 @@ class TestSlideController(TestCase):
|
|||||||
# THEN: setPixmap and the image_manager should have been called
|
# THEN: setPixmap and the image_manager should have been called
|
||||||
assert 1 == slide_controller.preview_display.set_single_image.call_count, 'set_single_image should be called'
|
assert 1 == slide_controller.preview_display.set_single_image.call_count, 'set_single_image should be called'
|
||||||
assert 0 == mocked_singleShot.call_count, 'Timer to grab_maindisplay should not be called'
|
assert 0 == mocked_singleShot.call_count, 'Timer to grab_maindisplay should not be called'
|
||||||
# assert 1 == mocked_image_manager.get_image.call_count, 'image_manager should be called'
|
|
||||||
|
|
||||||
@patch(u'openlp.core.ui.slidecontroller.SlideController.image_manager')
|
|
||||||
@patch(u'PyQt5.QtCore.QTimer.singleShot')
|
@patch(u'openlp.core.ui.slidecontroller.SlideController.image_manager')
|
||||||
def test_update_preview_media(self, mocked_singleShot, mocked_image_manager):
|
@patch(u'PyQt5.QtCore.QTimer.singleShot')
|
||||||
|
def test_update_preview_media(mocked_singleShot, mocked_image_manager):
|
||||||
"""
|
"""
|
||||||
Test that the preview screen is updated with the correct preview for media service items
|
Test that the preview screen is updated with the correct preview for media service items
|
||||||
"""
|
"""
|
||||||
@ -893,9 +909,10 @@ class TestSlideController(TestCase):
|
|||||||
assert 0 == mocked_singleShot.call_count, 'Timer to grab_maindisplay should not be called'
|
assert 0 == mocked_singleShot.call_count, 'Timer to grab_maindisplay should not be called'
|
||||||
assert 0 == mocked_image_manager.get_image.call_count, 'image_manager should not be called'
|
assert 0 == mocked_image_manager.get_image.call_count, 'image_manager should not be called'
|
||||||
|
|
||||||
@patch(u'openlp.core.ui.slidecontroller.SlideController.image_manager')
|
|
||||||
@patch(u'PyQt5.QtCore.QTimer.singleShot')
|
@patch(u'openlp.core.ui.slidecontroller.SlideController.image_manager')
|
||||||
def test_update_preview_image(self, mocked_singleShot, mocked_image_manager):
|
@patch(u'PyQt5.QtCore.QTimer.singleShot')
|
||||||
|
def test_update_preview_image(mocked_singleShot, mocked_image_manager):
|
||||||
"""
|
"""
|
||||||
Test that the preview screen is updated with the correct preview for image service items
|
Test that the preview screen is updated with the correct preview for image service items
|
||||||
"""
|
"""
|
||||||
@ -935,14 +952,14 @@ class TestSlideController(TestCase):
|
|||||||
assert 0 == mocked_image_manager.get_image.call_count, 'image_manager should not be called'
|
assert 0 == mocked_image_manager.get_image.call_count, 'image_manager should not be called'
|
||||||
|
|
||||||
|
|
||||||
class TestInfoLabel(TestCase):
|
def test_paint_event_text_fits():
|
||||||
|
|
||||||
def test_paint_event_text_fits(self):
|
|
||||||
"""
|
"""
|
||||||
Test the paintEvent method when text fits the label
|
Test the paintEvent method when text fits the label
|
||||||
"""
|
"""
|
||||||
|
font = QtGui.QFont()
|
||||||
|
metrics = QtGui.QFontMetrics(font)
|
||||||
|
|
||||||
with patch('openlp.core.ui.slidecontroller.QtWidgets.QLabel'), \
|
with patch('openlp.core.ui.slidecontroller.QtWidgets.QLabel'), \
|
||||||
patch('openlp.core.ui.slidecontroller.QtGui.QFontMetrics') as MockFontMetrics, \
|
|
||||||
patch('openlp.core.ui.slidecontroller.QtGui.QPainter') as mocked_qpainter:
|
patch('openlp.core.ui.slidecontroller.QtGui.QPainter') as mocked_qpainter:
|
||||||
|
|
||||||
# GIVEN: An instance of InfoLabel, with mocked text return, width and rect methods
|
# GIVEN: An instance of InfoLabel, with mocked text return, width and rect methods
|
||||||
@ -955,28 +972,28 @@ class TestInfoLabel(TestCase):
|
|||||||
info_label.rect = mocked_rect
|
info_label.rect = mocked_rect
|
||||||
info_label.text = mocked_text
|
info_label.text = mocked_text
|
||||||
info_label.width = mocked_width
|
info_label.width = mocked_width
|
||||||
mocked_font_metrics = MagicMock()
|
|
||||||
mocked_font_metrics.elidedText.return_value = test_string
|
|
||||||
MockFontMetrics.return_value = mocked_font_metrics
|
|
||||||
|
|
||||||
# WHEN: The instance is wider than its text, and the paintEvent method is called
|
# WHEN: The instance is wider than its text, and the paintEvent method is called
|
||||||
|
info_label.width.return_value = metrics.boundingRect(test_string).width() + 20
|
||||||
info_label.paintEvent(MagicMock())
|
info_label.paintEvent(MagicMock())
|
||||||
|
|
||||||
# THEN: The text should be drawn centered with the complete test_string
|
# THEN: The text should be drawn centered with the complete test_string
|
||||||
mocked_qpainter().drawText.assert_called_once_with(mocked_rect(), QtCore.Qt.AlignCenter, test_string)
|
mocked_qpainter().drawText.assert_called_once_with(mocked_rect(), QtCore.Qt.AlignCenter, test_string)
|
||||||
|
|
||||||
def test_paint_event_text_doesnt_fit(self):
|
|
||||||
|
def test_paint_event_text_doesnt_fit():
|
||||||
"""
|
"""
|
||||||
Test the paintEvent method when text fits the label
|
Test the paintEvent method when text fits the label
|
||||||
"""
|
"""
|
||||||
|
font = QtGui.QFont()
|
||||||
|
metrics = QtGui.QFontMetrics(font)
|
||||||
|
|
||||||
with patch('openlp.core.ui.slidecontroller.QtWidgets.QLabel'), \
|
with patch('openlp.core.ui.slidecontroller.QtWidgets.QLabel'), \
|
||||||
patch('openlp.core.ui.slidecontroller.QtGui.QFontMetrics') as MockFontMetrics, \
|
|
||||||
patch('openlp.core.ui.slidecontroller.QtGui.QPainter') as mocked_qpainter:
|
patch('openlp.core.ui.slidecontroller.QtGui.QPainter') as mocked_qpainter:
|
||||||
|
|
||||||
# GIVEN: An instance of InfoLabel, with mocked text return, width and rect methods
|
# GIVEN: An instance of InfoLabel, with mocked text return, width and rect methods
|
||||||
info_label = InfoLabel()
|
info_label = InfoLabel()
|
||||||
test_string = 'Label Text'
|
test_string = 'Label Text'
|
||||||
elided_test_string = test_string[0:5] + '...'
|
|
||||||
mocked_rect = MagicMock()
|
mocked_rect = MagicMock()
|
||||||
mocked_text = MagicMock()
|
mocked_text = MagicMock()
|
||||||
mocked_width = MagicMock()
|
mocked_width = MagicMock()
|
||||||
@ -984,18 +1001,19 @@ class TestInfoLabel(TestCase):
|
|||||||
info_label.rect = mocked_rect
|
info_label.rect = mocked_rect
|
||||||
info_label.text = mocked_text
|
info_label.text = mocked_text
|
||||||
info_label.width = mocked_width
|
info_label.width = mocked_width
|
||||||
mocked_font_metrics = MagicMock()
|
|
||||||
mocked_font_metrics.elidedText.return_value = elided_test_string
|
|
||||||
MockFontMetrics.return_value = mocked_font_metrics
|
|
||||||
|
|
||||||
# WHEN: The instance is narrower than its text, and the paintEvent method is called
|
# WHEN: The instance is narrower than its text, and the paintEvent method is called
|
||||||
|
label_width = metrics.boundingRect(test_string).width() - 20
|
||||||
|
info_label.width.return_value = label_width
|
||||||
info_label.paintEvent(MagicMock())
|
info_label.paintEvent(MagicMock())
|
||||||
|
|
||||||
# THEN: The text should be drawn aligned left with an elided test_string
|
# THEN: The text should be drawn aligned left with an elided test_string
|
||||||
|
elided_test_string = metrics.elidedText(test_string, QtCore.Qt.ElideRight, label_width)
|
||||||
mocked_qpainter().drawText.assert_called_once_with(mocked_rect(), QtCore.Qt.AlignLeft, elided_test_string)
|
mocked_qpainter().drawText.assert_called_once_with(mocked_rect(), QtCore.Qt.AlignLeft, elided_test_string)
|
||||||
|
|
||||||
@patch('builtins.super')
|
|
||||||
def test_set_text(self, mocked_super):
|
@patch('builtins.super')
|
||||||
|
def test_set_text(mocked_super):
|
||||||
"""
|
"""
|
||||||
Test the reimplemented setText method
|
Test the reimplemented setText method
|
||||||
"""
|
"""
|
||||||
@ -1012,9 +1030,7 @@ class TestInfoLabel(TestCase):
|
|||||||
mocked_super().setText.assert_called_once_with('Label Text')
|
mocked_super().setText.assert_called_once_with('Label Text')
|
||||||
|
|
||||||
|
|
||||||
class TestLiveController(TestCase):
|
def test_initial_live_controller():
|
||||||
|
|
||||||
def test_initial_live_controller(self):
|
|
||||||
"""
|
"""
|
||||||
Test the initial live slide controller state .
|
Test the initial live slide controller state .
|
||||||
"""
|
"""
|
||||||
@ -1027,9 +1043,7 @@ class TestLiveController(TestCase):
|
|||||||
assert live_controller.is_live is True, 'The slide controller should be a live controller'
|
assert live_controller.is_live is True, 'The slide controller should be a live controller'
|
||||||
|
|
||||||
|
|
||||||
class TestPreviewLiveController(TestCase):
|
def test_initial_preview_controller():
|
||||||
|
|
||||||
def test_initial_preview_controller(self):
|
|
||||||
"""
|
"""
|
||||||
Test the initial preview slide controller state.
|
Test the initial preview slide controller state.
|
||||||
"""
|
"""
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
Package to test the openlp.plugin.bible.lib.https package.
|
Package to test the openlp.plugin.bible.lib.https package.
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
from unittest import TestCase, skipIf
|
from unittest import TestCase, skipIf, skip
|
||||||
from unittest.mock import MagicMock
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
from openlp.core.common.registry import Registry
|
from openlp.core.common.registry import Registry
|
||||||
@ -122,6 +122,7 @@ class TestBibleHTTP(TestCase):
|
|||||||
# THEN: We should get back a valid service item
|
# THEN: We should get back a valid service item
|
||||||
assert len(results.verse_list) == 36, 'The book of John should not have had any verses added or removed'
|
assert len(results.verse_list) == 36, 'The book of John should not have had any verses added or removed'
|
||||||
|
|
||||||
|
@skip("We can't currently parse BibelServer")
|
||||||
def test_bibleserver_get_bibles(self):
|
def test_bibleserver_get_bibles(self):
|
||||||
"""
|
"""
|
||||||
Test getting list of bibles from BibleServer.com
|
Test getting list of bibles from BibleServer.com
|
||||||
|
@ -35,8 +35,9 @@ class FakeIP4InterfaceEntry(QObject):
|
|||||||
"""
|
"""
|
||||||
Class to face an interface for testing purposes
|
Class to face an interface for testing purposes
|
||||||
"""
|
"""
|
||||||
def __init__(self, name='lo'):
|
def __init__(self, name='lo', is_valid=True):
|
||||||
self.my_name = name
|
self.my_name = name
|
||||||
|
self._is_valid = is_valid
|
||||||
if name in ['localhost', 'lo']:
|
if name in ['localhost', 'lo']:
|
||||||
self.my_ip = QNetworkAddressEntry()
|
self.my_ip = QNetworkAddressEntry()
|
||||||
self.my_ip.setBroadcast(QHostAddress('255.0.0.0'))
|
self.my_ip.setBroadcast(QHostAddress('255.0.0.0'))
|
||||||
@ -75,7 +76,7 @@ class FakeIP4InterfaceEntry(QObject):
|
|||||||
return self.my_name
|
return self.my_name
|
||||||
|
|
||||||
def isValid(self):
|
def isValid(self):
|
||||||
return True
|
return self._is_valid
|
||||||
|
|
||||||
|
|
||||||
class TestInterfaces(TestCase, TestMixin):
|
class TestInterfaces(TestCase, TestMixin):
|
||||||
@ -92,6 +93,7 @@ class TestInterfaces(TestCase, TestMixin):
|
|||||||
self.fake_lo = FakeIP4InterfaceEntry()
|
self.fake_lo = FakeIP4InterfaceEntry()
|
||||||
self.fake_localhost = FakeIP4InterfaceEntry(name='localhost')
|
self.fake_localhost = FakeIP4InterfaceEntry(name='localhost')
|
||||||
self.fake_address = FakeIP4InterfaceEntry(name='eth25')
|
self.fake_address = FakeIP4InterfaceEntry(name='eth25')
|
||||||
|
self.invalid_if = FakeIP4InterfaceEntry(name='invalid', is_valid=False)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
"""
|
"""
|
||||||
@ -126,7 +128,7 @@ class TestInterfaces(TestCase, TestMixin):
|
|||||||
# GIVEN: Test environment
|
# GIVEN: Test environment
|
||||||
call_debug = [
|
call_debug = [
|
||||||
call('Getting local IPv4 interface(es) information'),
|
call('Getting local IPv4 interface(es) information'),
|
||||||
call("Filtering out interfaces we don't care about: lo")
|
call('Filtering out interfaces we don\'t care about: lo')
|
||||||
]
|
]
|
||||||
|
|
||||||
# WHEN: get_network_interfaces() is called
|
# WHEN: get_network_interfaces() is called
|
||||||
@ -146,7 +148,7 @@ class TestInterfaces(TestCase, TestMixin):
|
|||||||
# GIVEN: Test environment
|
# GIVEN: Test environment
|
||||||
call_debug = [
|
call_debug = [
|
||||||
call('Getting local IPv4 interface(es) information'),
|
call('Getting local IPv4 interface(es) information'),
|
||||||
call("Filtering out interfaces we don't care about: localhost")
|
call('Filtering out interfaces we don\'t care about: localhost')
|
||||||
]
|
]
|
||||||
|
|
||||||
# WHEN: get_network_interfaces() is called
|
# WHEN: get_network_interfaces() is called
|
||||||
@ -190,7 +192,7 @@ class TestInterfaces(TestCase, TestMixin):
|
|||||||
# GIVEN: Test environment
|
# GIVEN: Test environment
|
||||||
call_debug = [
|
call_debug = [
|
||||||
call('Getting local IPv4 interface(es) information'),
|
call('Getting local IPv4 interface(es) information'),
|
||||||
call("Filtering out interfaces we don't care about: lo"),
|
call('Filtering out interfaces we don\'t care about: lo'),
|
||||||
call('Checking for isValid and flags == IsUP | IsRunning'),
|
call('Checking for isValid and flags == IsUP | IsRunning'),
|
||||||
call('Checking address(es) protocol'),
|
call('Checking address(es) protocol'),
|
||||||
call('Checking for protocol == IPv4Protocol'),
|
call('Checking for protocol == IPv4Protocol'),
|
||||||
@ -205,4 +207,26 @@ class TestInterfaces(TestCase, TestMixin):
|
|||||||
|
|
||||||
# THEN: There should be a fake 'eth25' interface
|
# THEN: There should be a fake 'eth25' interface
|
||||||
mock_log.debug.assert_has_calls(call_debug)
|
mock_log.debug.assert_has_calls(call_debug)
|
||||||
assert interfaces == self.fake_address.fake_data, "There should have been only 'eth25' interface listed"
|
assert interfaces == self.fake_address.fake_data, 'There should have been only "eth25" interface listed'
|
||||||
|
|
||||||
|
@patch.object(openlp.core.common, 'log')
|
||||||
|
def test_network_interfaces_invalid(self, mock_log):
|
||||||
|
"""
|
||||||
|
Test get_network_interfaces() returns an empty dictionary when there are no valid interfaces
|
||||||
|
"""
|
||||||
|
# GIVEN: Test environment
|
||||||
|
call_debug = [
|
||||||
|
call('Getting local IPv4 interface(es) information'),
|
||||||
|
call('Checking for isValid and flags == IsUP | IsRunning')
|
||||||
|
]
|
||||||
|
call_warning = [call('No active IPv4 network interfaces detected')]
|
||||||
|
|
||||||
|
# WHEN: get_network_interfaces() is called
|
||||||
|
with patch('openlp.core.common.QNetworkInterface') as mock_network_interface:
|
||||||
|
mock_network_interface.allInterfaces.return_value = [self.invalid_if]
|
||||||
|
interfaces = get_network_interfaces()
|
||||||
|
|
||||||
|
# THEN: There should be a fake 'eth25' interface
|
||||||
|
mock_log.debug.assert_has_calls(call_debug)
|
||||||
|
mock_log.warning.assert_has_calls(call_warning)
|
||||||
|
assert interfaces == {}, 'There should not be any interfaces listed'
|
||||||
|
Loading…
Reference in New Issue
Block a user