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
|
||||
.eggs
|
||||
.venv
|
||||
.mypy_cache
|
||||
OpenLP.egg-info
|
||||
\#*\#
|
||||
__pycache__
|
||||
|
@ -63,19 +63,6 @@ test-macos:
|
||||
only:
|
||||
- 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:
|
||||
stage: test
|
||||
image: openlp/angular
|
||||
@ -87,7 +74,7 @@ pages:
|
||||
stage: deploy
|
||||
image: openlp/debian
|
||||
script:
|
||||
- python3-coverage combine linux.coverage macos.coverage windows.coverage
|
||||
- python3-coverage combine linux.coverage macos.coverage
|
||||
- fixpaths .coverage
|
||||
- python3-coverage html
|
||||
- mv htmlcov public
|
||||
@ -99,6 +86,5 @@ pages:
|
||||
dependencies:
|
||||
- test-debian
|
||||
- test-macos
|
||||
- test-windows
|
||||
only:
|
||||
- master@openlp/openlp
|
||||
|
@ -385,17 +385,12 @@ def main():
|
||||
application.setApplicationName('OpenLP')
|
||||
set_up_logging(AppLocation.get_directory(AppLocation.CacheDir))
|
||||
# Set the libvlc environment variable if we're frozen
|
||||
if getattr(sys, 'frozen', False):
|
||||
if is_macosx():
|
||||
vlc_lib = 'libvlc.dylib'
|
||||
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
|
||||
if getattr(sys, 'frozen', False) and is_win():
|
||||
# Path to libvlc and the plugins
|
||||
os.environ['PYTHON_VLC_LIB_PATH'] = str(AppLocation.get_directory(AppLocation.AppDir) / 'vlc' / 'libvlc.dll')
|
||||
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 Plugins Path: {}'.format(os.environ['PYTHON_VLC_MODULE_PATH']))
|
||||
# Initialise the Registry
|
||||
Registry.create()
|
||||
Registry().register('application', application)
|
||||
|
@ -38,6 +38,13 @@ from PyQt5.QtCore import QCryptographicHash as QHash
|
||||
from PyQt5.QtNetwork import QAbstractSocket, QHostAddress, QNetworkInterface
|
||||
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__')
|
||||
|
||||
|
||||
@ -212,13 +219,17 @@ def is_macosx():
|
||||
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
|
||||
|
||||
:param distro: If not None, check if running that Linux distro
|
||||
: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():
|
||||
|
@ -34,6 +34,7 @@ from PyQt5 import QtCore
|
||||
|
||||
from openlp.core.state import State
|
||||
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.mixins import LogMixin, RegistryProperties
|
||||
from openlp.core.common.registry import Registry, RegistryBase
|
||||
@ -89,23 +90,35 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
self.vlc_player = VlcPlayer(self)
|
||||
State().add_service('mediacontroller', 0)
|
||||
State().add_service('media_live', 0)
|
||||
getvlc = get_vlc()
|
||||
if getvlc and pymediainfo_available:
|
||||
has_vlc = get_vlc()
|
||||
if has_vlc and pymediainfo_available:
|
||||
State().update_pre_conditions('mediacontroller', True)
|
||||
State().update_pre_conditions('media_live', True)
|
||||
else:
|
||||
if hasattr(self.main_window, 'splash') and self.main_window.splash.isVisible():
|
||||
self.main_window.splash.hide()
|
||||
text_vlc = translate('OpenLP.MediaController',
|
||||
'The media integration library is missing (python - vlc is not installed)')
|
||||
text_info = translate('OpenLP.MediaController',
|
||||
'The media integration library is missing (python - pymediainfo is not installed)')
|
||||
if not getvlc and not pymediainfo_available:
|
||||
State().missing_text('media_live', "{text}\n{base}".format(text=text_vlc, base=text_info))
|
||||
if getvlc and not pymediainfo_available:
|
||||
State().missing_text('media_live', "{text}".format(text=text_info))
|
||||
if not getvlc and pymediainfo_available:
|
||||
State().missing_text('media_live', "{text}".format(text=text_vlc))
|
||||
generic_message = translate('OpenLP.MediaController',
|
||||
'OpenLP requires the following libraries in order to show videos and other '
|
||||
'media, but they are not installed. Please install these libraries to enable '
|
||||
'media playback in OpenLP.')
|
||||
fedora_rpmfusion = translate('OpenLP.MediaController',
|
||||
'To install these libraries, you will need to enable the RPMFusion '
|
||||
'repository: https://rpmfusion.org/')
|
||||
message = ''
|
||||
if is_macosx():
|
||||
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
|
||||
|
||||
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.mixins import LogMixin, RegistryProperties
|
||||
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.window import DisplayWindow
|
||||
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,
|
||||
icon=UiIcons().clock, checked=False, can_shortcuts=True,
|
||||
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)
|
||||
else:
|
||||
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.
|
||||
"""
|
||||
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):
|
||||
"""
|
||||
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):
|
||||
"""
|
||||
@ -737,7 +736,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
||||
self.play_slides_loop.setIcon(UiIcons().clock)
|
||||
self.play_slides_loop.setText(UiStrings().PlaySlidesInLoop)
|
||||
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()):
|
||||
self.toolbar.set_widget_visible('song_menu', True)
|
||||
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.desktop_screen.setChecked(False)
|
||||
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:
|
||||
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.update_preview()
|
||||
self.on_toggle_loop()
|
||||
@ -1034,9 +1033,9 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
||||
self.theme_screen.setChecked(checked)
|
||||
self.desktop_screen.setChecked(False)
|
||||
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:
|
||||
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.update_preview()
|
||||
self.on_toggle_loop()
|
||||
@ -1056,9 +1055,9 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
||||
self.theme_screen.setChecked(False)
|
||||
self.desktop_screen.setChecked(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:
|
||||
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.update_preview()
|
||||
self.on_toggle_loop()
|
||||
@ -1145,7 +1144,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
||||
return
|
||||
# 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.
|
||||
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:
|
||||
Registry().execute('slidecontroller_live_unblank')
|
||||
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_menu.setDefaultAction(self.play_slides_loop)
|
||||
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')
|
||||
else:
|
||||
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_menu.setDefaultAction(self.play_slides_once)
|
||||
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')
|
||||
else:
|
||||
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
|
||||
"""
|
||||
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
|
||||
# playing in both at the same time.
|
||||
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.wizard import OpenLPWizard, WizardStrings
|
||||
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
|
||||
|
||||
|
||||
@ -59,7 +59,8 @@ class WebDownload(object):
|
||||
BibleGateway = 1
|
||||
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):
|
||||
@ -227,7 +228,8 @@ class BibleImportForm(OpenLPWizard):
|
||||
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.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_bible_layout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.web_source_combo_box)
|
||||
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_bible_layout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.web_translation_combo_box)
|
||||
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.setVisible(False)
|
||||
self.web_bible_layout.setWidget(3, QtWidgets.QFormLayout.SpanningRole, self.web_progress_bar)
|
||||
@ -400,8 +403,9 @@ class BibleImportForm(OpenLPWizard):
|
||||
'Crosswalk'))
|
||||
self.web_source_combo_box.setItemText(WebDownload.BibleGateway, translate('BiblesPlugin.ImportWizardForm',
|
||||
'BibleGateway'))
|
||||
self.web_source_combo_box.setItemText(WebDownload.Bibleserver, translate('BiblesPlugin.ImportWizardForm',
|
||||
'Bibleserver'))
|
||||
# NOTE: BibleServer support has been disabled since we can't currently parse it. Re-add if/when fixed.
|
||||
# self.web_source_combo_box.setItemText(WebDownload.Bibleserver, translate('BiblesPlugin.ImportWizardForm',
|
||||
# 'Bibleserver'))
|
||||
self.web_translation_label.setText(translate('BiblesPlugin.ImportWizardForm', 'Bible:'))
|
||||
self.sword_bible_label.setText(translate('BiblesPlugin.ImportWizardForm', 'Bibles:'))
|
||||
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.setValue(0)
|
||||
# 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()),
|
||||
(WebDownload.BibleGateway, BGExtract()),
|
||||
(WebDownload.Bibleserver, BSExtract())):
|
||||
(WebDownload.BibleGateway, BGExtract())):
|
||||
try:
|
||||
bibles = extractor.get_bibles_from_http()
|
||||
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)
|
||||
thumbnail_path = doc.get_thumbnail_folder() / 'slide{number:d}.png'.format(number=i)
|
||||
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
|
||||
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)
|
||||
|
@ -56,6 +56,7 @@ WIN32_MODULES = [
|
||||
LINUX_MODULES = [
|
||||
# Optical drive detection.
|
||||
'dbus',
|
||||
'distro',
|
||||
'Xlib',
|
||||
]
|
||||
|
||||
|
1
setup.py
1
setup.py
@ -101,6 +101,7 @@ using a computer and a data projector.""",
|
||||
'beautifulsoup4',
|
||||
'chardet',
|
||||
'dbus-python; platform_system=="Linux"',
|
||||
'distro; platform_system=="Linux"',
|
||||
'lxml',
|
||||
'Mako',
|
||||
'pymediainfo >= 2.2',
|
||||
|
@ -23,6 +23,7 @@ All the tests
|
||||
"""
|
||||
import os
|
||||
from tempfile import mkstemp
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
@ -39,24 +40,34 @@ def qapp():
|
||||
del app
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def registry():
|
||||
"""An instance of the Registry"""
|
||||
Registry.create()
|
||||
|
||||
|
||||
@pytest.yield_fixture
|
||||
def settings(qapp):
|
||||
def settings(qapp, registry):
|
||||
"""A Settings() instance"""
|
||||
fd, ini_file = mkstemp('.ini')
|
||||
Settings.set_filename(ini_file)
|
||||
Registry.create()
|
||||
Settings().setDefaultFormat(QtCore.QSettings.IniFormat)
|
||||
# Needed on windows to make sure a Settings object is available during the tests
|
||||
sets = Settings()
|
||||
sets.setValue('themes/global theme', 'my_theme')
|
||||
Registry().register('settings', set)
|
||||
Registry().register('settings', sets)
|
||||
yield sets
|
||||
del sets
|
||||
os.close(fd)
|
||||
os.unlink(Settings().fileName())
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def registry():
|
||||
"""An instance of the Registry"""
|
||||
Registry.create()
|
||||
@pytest.yield_fixture
|
||||
def mock_settings(registry):
|
||||
"""A Mock Settings() instance"""
|
||||
# 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.
|
||||
"""
|
||||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
from unittest import TestCase, skipUnless
|
||||
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, \
|
||||
normalize_str, path_to_module, trace_error_handler
|
||||
is_64bit_instance, normalize_str, path_to_module, trace_error_handler
|
||||
|
||||
|
||||
class TestCommonFunctions(TestCase):
|
||||
@ -243,7 +243,7 @@ class TestCommonFunctions(TestCase):
|
||||
# GIVEN: Mocked out objects
|
||||
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_sys.platform = 'linux3'
|
||||
|
||||
@ -252,6 +252,40 @@ class TestCommonFunctions(TestCase):
|
||||
assert is_win() is False, 'is_win() 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):
|
||||
# GIVEN: a string containing newlines
|
||||
string = 'something\nelse'
|
||||
|
@ -25,6 +25,7 @@ from unittest import TestCase
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
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 import ItemMediaInfo
|
||||
from tests.helpers.testmixin import TestMixin
|
||||
@ -202,3 +203,122 @@ class TestMediaController(TestCase, TestMixin):
|
||||
|
||||
# THEN you can determine the run time
|
||||
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)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -22,7 +22,7 @@
|
||||
Package to test the openlp.plugin.bible.lib.https package.
|
||||
"""
|
||||
import os
|
||||
from unittest import TestCase, skipIf
|
||||
from unittest import TestCase, skipIf, skip
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from openlp.core.common.registry import Registry
|
||||
@ -122,6 +122,7 @@ class TestBibleHTTP(TestCase):
|
||||
# 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'
|
||||
|
||||
@skip("We can't currently parse BibelServer")
|
||||
def test_bibleserver_get_bibles(self):
|
||||
"""
|
||||
Test getting list of bibles from BibleServer.com
|
||||
|
@ -35,8 +35,9 @@ class FakeIP4InterfaceEntry(QObject):
|
||||
"""
|
||||
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._is_valid = is_valid
|
||||
if name in ['localhost', 'lo']:
|
||||
self.my_ip = QNetworkAddressEntry()
|
||||
self.my_ip.setBroadcast(QHostAddress('255.0.0.0'))
|
||||
@ -75,7 +76,7 @@ class FakeIP4InterfaceEntry(QObject):
|
||||
return self.my_name
|
||||
|
||||
def isValid(self):
|
||||
return True
|
||||
return self._is_valid
|
||||
|
||||
|
||||
class TestInterfaces(TestCase, TestMixin):
|
||||
@ -92,6 +93,7 @@ class TestInterfaces(TestCase, TestMixin):
|
||||
self.fake_lo = FakeIP4InterfaceEntry()
|
||||
self.fake_localhost = FakeIP4InterfaceEntry(name='localhost')
|
||||
self.fake_address = FakeIP4InterfaceEntry(name='eth25')
|
||||
self.invalid_if = FakeIP4InterfaceEntry(name='invalid', is_valid=False)
|
||||
|
||||
def tearDown(self):
|
||||
"""
|
||||
@ -126,7 +128,7 @@ class TestInterfaces(TestCase, TestMixin):
|
||||
# GIVEN: Test environment
|
||||
call_debug = [
|
||||
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
|
||||
@ -146,7 +148,7 @@ class TestInterfaces(TestCase, TestMixin):
|
||||
# GIVEN: Test environment
|
||||
call_debug = [
|
||||
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
|
||||
@ -190,7 +192,7 @@ class TestInterfaces(TestCase, TestMixin):
|
||||
# GIVEN: Test environment
|
||||
call_debug = [
|
||||
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 address(es) protocol'),
|
||||
call('Checking for protocol == IPv4Protocol'),
|
||||
@ -205,4 +207,26 @@ class TestInterfaces(TestCase, TestMixin):
|
||||
|
||||
# THEN: There should be a fake 'eth25' interface
|
||||
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