Merge branch 'master' of gitlab.com:openlp/openlp

This commit is contained in:
Tim 2019-12-07 20:20:21 +00:00
commit 9eb645cc37
No known key found for this signature in database
GPG Key ID: 3D454289AF831A6D
16 changed files with 1292 additions and 1077 deletions

1
.gitignore vendored
View File

@ -25,6 +25,7 @@
.vscode
.eggs
.venv
.mypy_cache
OpenLP.egg-info
\#*\#
__pycache__

View File

@ -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

View File

@ -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)

View File

@ -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():

View File

@ -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):

View File

@ -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():

View File

@ -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):

View File

@ -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)

View File

@ -56,6 +56,7 @@ WIN32_MODULES = [
LINUX_MODULES = [
# Optical drive detection.
'dbus',
'distro',
'Xlib',
]

View File

@ -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',

View File

@ -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

View File

@ -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'

View File

@ -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

View File

@ -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

View File

@ -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'