diff --git a/openlp/core/projectors/manager.py b/openlp/core/projectors/manager.py index d526eb64f..d9134a255 100644 --- a/openlp/core/projectors/manager.py +++ b/openlp/core/projectors/manager.py @@ -31,7 +31,6 @@ from PyQt5 import QtCore, QtGui, QtWidgets from openlp.core.common.i18n import 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.lib.ui import create_widget_action from openlp.core.projectors import DialogSourceStyle from openlp.core.projectors.constants import E_AUTHENTICATION, E_ERROR, E_NETWORK, E_NOT_CONNECTED, E_SOCKET_TIMEOUT,\ @@ -361,10 +360,10 @@ class ProjectorManager(QtWidgets.QWidget, RegistryBase, UiProjectorManager, LogM Retrieve the saved settings """ log.debug('Updating ProjectorManager settings') - self.autostart = Settings().value('projector/connect on start') - self.poll_time = Settings().value('projector/poll time') - self.socket_timeout = Settings().value('projector/socket timeout') - self.source_select_dialog_type = Settings().value('projector/source dialog type') + self.autostart = self.settings.value('projector/connect on start') + self.poll_time = self.settings.value('projector/poll time') + self.socket_timeout = self.settings.value('projector/socket timeout') + self.source_select_dialog_type = self.settings.value('projector/source dialog type') def context_menu(self, point): """ diff --git a/openlp/core/projectors/pjlink.py b/openlp/core/projectors/pjlink.py index aeeec5df4..0ecb1b53f 100644 --- a/openlp/core/projectors/pjlink.py +++ b/openlp/core/projectors/pjlink.py @@ -53,7 +53,7 @@ from PyQt5 import QtCore, QtNetwork from openlp.core.common import qmd5_hash from openlp.core.common.i18n import translate -from openlp.core.common.settings import Settings +from openlp.core.common.registry import Registry from openlp.core.projectors.pjlinkcommands import process_command from openlp.core.projectors.constants import CONNECTION_ERRORS, E_AUTHENTICATION, E_CONNECTION_REFUSED, E_GENERAL, \ E_NETWORK, E_NOT_CONNECTED, E_SOCKET_TIMEOUT, PJLINK_CLASS, \ @@ -100,8 +100,9 @@ class PJLinkUDP(QtNetwork.QUdpSocket): self.search_time = 30000 # 30 seconds for allowed time self.search_timer = QtCore.QTimer() self.udp_broadcast_listen_setting = False + self.settings = Registry().get('settings') log.debug('(UDP:{port}) PJLinkUDP() Initialized'.format(port=self.port)) - if Settings().value('projector/udp broadcast listen'): + if self.settings.value('projector/udp broadcast listen'): self.udp_start() def udp_start(self): @@ -110,7 +111,7 @@ class PJLinkUDP(QtNetwork.QUdpSocket): """ log.debug('(UDP:{port}) Start called'.format(port=self.port)) self.readyRead.connect(self.get_datagram) - self.check_settings(checked=Settings().value('projector/udp broadcast listen')) + self.check_settings(checked=self.settings.value('projector/udp broadcast listen')) def udp_stop(self): """ diff --git a/openlp/core/projectors/pjlinkcommands.py b/openlp/core/projectors/pjlinkcommands.py index a63ec6b8f..fc885538b 100644 --- a/openlp/core/projectors/pjlinkcommands.py +++ b/openlp/core/projectors/pjlinkcommands.py @@ -30,7 +30,7 @@ import logging import re import string -from openlp.core.common.settings import Settings +from openlp.core.common.registry import Registry from openlp.core.projectors.constants import E_AUTHENTICATION, PJLINK_DEFAULT_CODES, PJLINK_ERRORS, \ PJLINK_ERST_DATA, PJLINK_ERST_LIST, PJLINK_ERST_STATUS, PJLINK_POWR_STATUS, PJLINK_TOKEN_SIZE, \ @@ -345,7 +345,7 @@ def process_lkup(projector, data): :param data: Data packet from remote """ log.debug('({ip}) Processing LKUP command'.format(ip=projector.entry.name)) - if Settings().value('projector/connect when LKUP received'): + if Registry().get('settings').value('projector/connect when LKUP received'): projector.connect_to_host() diff --git a/openlp/core/projectors/tab.py b/openlp/core/projectors/tab.py index f532e1a2d..ac9f12fb7 100644 --- a/openlp/core/projectors/tab.py +++ b/openlp/core/projectors/tab.py @@ -27,7 +27,6 @@ from PyQt5 import QtWidgets from openlp.core.common.i18n import UiStrings, translate from openlp.core.common.registry import Registry -from openlp.core.common.settings import Settings from openlp.core.lib.settingstab import SettingsTab from openlp.core.projectors import DialogSourceStyle from openlp.core.ui.icons import UiIcons @@ -132,23 +131,23 @@ class ProjectorTab(SettingsTab): """ Load the projector settings on startup """ - self.connect_on_startup.setChecked(Settings().value('projector/connect on start')) - self.socket_timeout_spin_box.setValue(Settings().value('projector/socket timeout')) - self.socket_poll_spin_box.setValue(Settings().value('projector/poll time')) - self.dialog_type_combo_box.setCurrentIndex(Settings().value('projector/source dialog type')) - self.udp_broadcast_listen.setChecked(Settings().value('projector/udp broadcast listen')) - self.connect_on_linkup.setChecked(Settings().value('projector/connect when LKUP received')) + self.connect_on_startup.setChecked(self.settings.value('projector/connect on start')) + self.socket_timeout_spin_box.setValue(self.settings.value('projector/socket timeout')) + self.socket_poll_spin_box.setValue(self.settings.value('projector/poll time')) + self.dialog_type_combo_box.setCurrentIndex(self.settings.value('projector/source dialog type')) + self.udp_broadcast_listen.setChecked(self.settings.value('projector/udp broadcast listen')) + self.connect_on_linkup.setChecked(self.settings.value('projector/connect when LKUP received')) def save(self): """ Save the projector settings """ - Settings().setValue('projector/connect on start', self.connect_on_startup.isChecked()) - Settings().setValue('projector/socket timeout', self.socket_timeout_spin_box.value()) - Settings().setValue('projector/poll time', self.socket_poll_spin_box.value()) - Settings().setValue('projector/source dialog type', self.dialog_type_combo_box.currentIndex()) - Settings().setValue('projector/connect when LKUP received', self.connect_on_linkup.isChecked()) - Settings().setValue('projector/udp broadcast listen', self.udp_broadcast_listen.isChecked()) + self.settings.setValue('projector/connect on start', self.connect_on_startup.isChecked()) + self.settings.setValue('projector/socket timeout', self.socket_timeout_spin_box.value()) + self.settings.setValue('projector/poll time', self.socket_poll_spin_box.value()) + self.settings.setValue('projector/source dialog type', self.dialog_type_combo_box.currentIndex()) + self.settings.setValue('projector/connect when LKUP received', self.connect_on_linkup.isChecked()) + self.settings.setValue('projector/udp broadcast listen', self.udp_broadcast_listen.isChecked()) self.call_udp_listener() def on_dialog_type_combo_box_changed(self): diff --git a/openlp/core/widgets/edits.py b/openlp/core/widgets/edits.py index 35f3043d9..c8384b6a6 100644 --- a/openlp/core/widgets/edits.py +++ b/openlp/core/widgets/edits.py @@ -30,7 +30,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets from openlp.core.common import CONTROL_CHARS from openlp.core.common.i18n import UiStrings, translate from openlp.core.common.path import path_to_str, str_to_path -from openlp.core.common.settings import Settings +from openlp.core.common.registry import Registry from openlp.core.lib.formattingtags import FormattingTags from openlp.core.lib.ui import create_action, create_widget_action from openlp.core.ui.icons import UiIcons @@ -72,6 +72,7 @@ class SearchEdit(QtWidgets.QLineEdit): self.clear_button.clicked.connect(self._on_clear_button_clicked) self.textChanged.connect(self._on_search_edit_text_changed) self._update_style_sheet() + self.settings = Registry().get('settings') self.setAcceptDrops(False) def _update_style_sheet(self): @@ -123,7 +124,8 @@ class SearchEdit(QtWidgets.QLineEdit): self.setPlaceholderText(action.placeholder_text) self.menu_button.setDefaultAction(action) self._current_search_type = identifier - Settings().setValue('{section}/last used search type'.format(section=self.settings_section), identifier) + self.settings.setValue('{section}/last used search type'. + format(section=self.settings_section), identifier) self.searchTypeChanged.emit(identifier) return True @@ -159,7 +161,7 @@ class SearchEdit(QtWidgets.QLineEdit): self.menu_button.resize(QtCore.QSize(28, 18)) self.menu_button.setMenu(menu) self.set_current_search_type( - Settings().value('{section}/last used search type'.format(section=self.settings_section))) + self.settings.value('{section}/last used search type'.format(section=self.settings_section))) self.menu_button.show() self._update_style_sheet() diff --git a/openlp/core/widgets/views.py b/openlp/core/widgets/views.py index e8afdbe82..f66f51dc0 100644 --- a/openlp/core/widgets/views.py +++ b/openlp/core/widgets/views.py @@ -30,7 +30,6 @@ from openlp.core.common import is_win from openlp.core.common.i18n import UiStrings from openlp.core.common.mixins import RegistryProperties from openlp.core.common.registry import Registry -from openlp.core.common.settings import Settings from openlp.core.lib.serviceitem import ItemCapabilities, ServiceItem from openlp.core.widgets.layouts import AspectRatioLayout @@ -120,7 +119,7 @@ class ListPreviewWidget(QtWidgets.QTableWidget, RegistryProperties): # Sort out image heights. else: height = self.viewport().width() // self.screen_ratio - max_img_row_height = Settings().value('advanced/slide max height') + max_img_row_height = self.settings.value('advanced/slide max height') # Adjust for row height cap if in use. if isinstance(max_img_row_height, int): if 0 < max_img_row_height < height: @@ -139,7 +138,7 @@ class ListPreviewWidget(QtWidgets.QTableWidget, RegistryProperties): Will scale non-image slides. """ # Only for non-text slides when row height cap in use - max_img_row_height = Settings().value('advanced/slide max height') + max_img_row_height = self.settings.value('advanced/slide max height') if self.service_item.is_text() or not isinstance(max_img_row_height, int) or max_img_row_height == 0: return # Get and validate label widget containing slide & adjust max width @@ -220,7 +219,7 @@ class ListPreviewWidget(QtWidgets.QTableWidget, RegistryProperties): layout.addWidget(label) container.setLayout(layout) slide_height = width // self.screen_ratio - max_img_row_height = Settings().value('advanced/slide max height') + max_img_row_height = self.settings.value('advanced/slide max height') if isinstance(max_img_row_height, int): if 0 < max_img_row_height < slide_height: slide_height = max_img_row_height @@ -249,7 +248,7 @@ class ListPreviewWidget(QtWidgets.QTableWidget, RegistryProperties): Switches to the given row. """ # Retrieve setting - auto_scrolling = Settings().value('advanced/autoscrolling') + auto_scrolling = self.settings.value('advanced/autoscrolling') # Check if auto-scroll disabled (None) and validate value as dict containing 'dist' and 'pos' # 'dist' represents the slide to scroll to relative to the new slide (-1 = previous, 0 = current, 1 = next) # 'pos' represents the vert position of of the slide (0 = in view, 1 = top, 2 = middle, 3 = bottom) diff --git a/openlp/core/widgets/widgets.py b/openlp/core/widgets/widgets.py index 1b7df8286..af5a8dc64 100644 --- a/openlp/core/widgets/widgets.py +++ b/openlp/core/widgets/widgets.py @@ -24,7 +24,8 @@ The :mod:`~openlp.core.widgets.widgets` module contains custom widgets used in O from PyQt5 import QtCore, QtWidgets from openlp.core.common.i18n import translate -from openlp.core.common.settings import ProxyMode, Settings +from openlp.core.common.registry import Registry +from openlp.core.common.settings import ProxyMode from openlp.core.lib.ui import critical_error_message_box @@ -57,6 +58,7 @@ class ProxyWidget(QtWidgets.QGroupBox): :param QtWidgets.QWidget | None parent: The widgets parent """ super().__init__(parent) + self.settings = Registry().get('settings') self._setup() def _setup(self): @@ -130,24 +132,22 @@ class ProxyWidget(QtWidgets.QGroupBox): """ Load the data from the settings to the widget. """ - settings = Settings() - checked_radio = self.radio_group.button(settings.value('advanced/proxy mode')) + checked_radio = self.radio_group.button(self.settings.value('advanced/proxy mode')) checked_radio.setChecked(True) - self.http_edit.setText(settings.value('advanced/proxy http')) - self.https_edit.setText(settings.value('advanced/proxy https')) - self.username_edit.setText(settings.value('advanced/proxy username')) - self.password_edit.setText(settings.value('advanced/proxy password')) + self.http_edit.setText(self.settings.value('advanced/proxy http')) + self.https_edit.setText(self.settings.value('advanced/proxy https')) + self.username_edit.setText(self.settings.value('advanced/proxy username')) + self.password_edit.setText(self.settings.value('advanced/proxy password')) def save(self): """ Save the widget data to the settings """ - settings = Settings() # TODO: Migrate from old system - settings.setValue('advanced/proxy mode', self.radio_group.checkedId()) - settings.setValue('advanced/proxy http', self.http_edit.text()) - settings.setValue('advanced/proxy https', self.https_edit.text()) - settings.setValue('advanced/proxy username', self.username_edit.text()) - settings.setValue('advanced/proxy password', self.password_edit.text()) + self.settings.setValue('advanced/proxy mode', self.radio_group.checkedId()) + self.settings.setValue('advanced/proxy http', self.http_edit.text()) + self.settings.setValue('advanced/proxy https', self.https_edit.text()) + self.settings.setValue('advanced/proxy username', self.username_edit.text()) + self.settings.setValue('advanced/proxy password', self.password_edit.text()) class ProxyDialog(QtWidgets.QDialog): @@ -380,11 +380,10 @@ class ScreenSelectionWidget(QtWidgets.QWidget): Save the screen settings """ self._save_screen(self.current_screen) - settings = Settings() screen_settings = {} for screen in self.screens: screen_settings[screen.number] = screen.to_dict() - settings.setValue('core/screens', screen_settings) + Registry().get('settings').setValue('core/screens', screen_settings) # On save update the screens as well def use_simple_view(self): diff --git a/tests/conftest.py b/tests/conftest.py index 7e8099515..c51bc2985 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -27,6 +27,8 @@ from tempfile import mkstemp from unittest.mock import MagicMock import pytest +from pytestqt.qt_compat import qt_api + from PyQt5 import QtCore, QtWidgets # noqa sys.modules['PyQt5.QtWebEngineWidgets'] = MagicMock() @@ -37,8 +39,9 @@ from openlp.core.common.settings import Settings @pytest.yield_fixture -def qapp(): +def qapp(qtbot): """An instance of QApplication""" + qt_api.QApplication.instance() app = OpenLP() yield app del app diff --git a/tests/functional/openlp_core/widgets/test_views.py b/tests/functional/openlp_core/widgets/test_views.py index 1ad6e5250..16023a2e3 100644 --- a/tests/functional/openlp_core/widgets/test_views.py +++ b/tests/functional/openlp_core/widgets/test_views.py @@ -22,6 +22,7 @@ Package to test the openlp.core.widgets.views package. """ import os +import pytest from types import GeneratorType from unittest import TestCase from unittest.mock import MagicMock, call, patch @@ -29,13 +30,30 @@ from unittest.mock import MagicMock, call, patch from PyQt5 import QtGui from openlp.core.common.i18n import UiStrings -# from openlp.core.lib import ImageSource from openlp.core.widgets.views import ListPreviewWidget, ListWidgetWithDnD, TreeWidgetWithDnD, handle_mime_data_urls from openlp.core.ui.icons import UiIcons CLAPPERBOARD = UiIcons().clapperboard +@pytest.yield_fixture +def preview_widget_env(): + """Local test setup""" + parent_patcher = patch('openlp.core.widgets.views.ListPreviewWidget.parent') + mocked_parent = parent_patcher.start() + mocked_parent.width.return_value = 100 + + # Mock self.viewport().width() + viewport_patcher = patch('openlp.core.widgets.views.ListPreviewWidget.viewport') + mocked_viewport = viewport_patcher.start() + mocked_viewport_obj = MagicMock() + mocked_viewport_obj.width.return_value = 200 + mocked_viewport.return_value = mocked_viewport_obj + yield mocked_parent, mocked_viewport_obj + parent_patcher.stop() + viewport_patcher.stop() + + class TestHandleMimeDataUrls(TestCase): """ Test the :func:`openlp.core.widgets.views.handle_mime_data_urls` function. @@ -88,473 +106,476 @@ class TestHandleMimeDataUrls(TestCase): assert result == [mocked_path_instance_1, mocked_path_instance_2, mocked_path_instance_3] -class TestListPreviewWidget(TestCase): +def test_new_list_preview_widget(preview_widget_env, mock_settings): + """ + Test that creating an instance of ListPreviewWidget works + """ + # GIVEN: A ListPreviewWidget class - def setUp(self): - """ - Mock out stuff for all the tests - """ - # Mock self.parent().width() - self.parent_patcher = patch('openlp.core.widgets.views.ListPreviewWidget.parent') - self.mocked_parent = self.parent_patcher.start() - self.mocked_parent.width.return_value = 100 - self.addCleanup(self.parent_patcher.stop) + # WHEN: An object is created + list_preview_widget = ListPreviewWidget(None, 1) - # Mock Settings().value() - self.Settings_patcher = patch('openlp.core.widgets.views.Settings') - self.mocked_Settings = self.Settings_patcher.start() - self.mocked_Settings_obj = MagicMock() - self.mocked_Settings_obj.value.return_value = None - self.mocked_Settings.return_value = self.mocked_Settings_obj - self.addCleanup(self.Settings_patcher.stop) + # THEN: The object is not None, and the _setup() method was called. + assert list_preview_widget is not None, 'The ListPreviewWidget object should not be None' + assert list_preview_widget.screen_ratio == 1, 'Should not be called' - # Mock self.viewport().width() - self.viewport_patcher = patch('openlp.core.widgets.views.ListPreviewWidget.viewport') - self.mocked_viewport = self.viewport_patcher.start() - self.mocked_viewport_obj = MagicMock() - self.mocked_viewport_obj.width.return_value = 200 - self.mocked_viewport.return_value = self.mocked_viewport_obj - self.addCleanup(self.viewport_patcher.stop) - def test_new_list_preview_widget(self): - """ - Test that creating an instance of ListPreviewWidget works - """ - # GIVEN: A ListPreviewWidget class +@patch(u'openlp.core.widgets.views.ListPreviewWidget.image_manager') +@patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents') +@patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight') +def test_replace_service_item_thumbs(mocked_setRowHeight, mocked_resizeRowsToContents, mocked_image_manager, + preview_widget_env, mock_settings): + """ + Test that thubmails for different slides are loaded properly in replace_service_item. + """ + # GIVEN: A setting to adjust "Max height for non-text slides in slide controller", + # different ServiceItem(s), an ImageManager, and a ListPreviewWidget. - # WHEN: An object is created - list_preview_widget = ListPreviewWidget(None, 1) + # Mock Settings().value('advanced/slide max height') + mock_settings.value.return_value = 0 + # Mock self.viewport().width() + mocked_viewport_obj = preview_widget_env[1] + mocked_viewport_obj.width.return_value = 200 + # Mock Image service item + mocked_img_service_item = MagicMock() + mocked_img_service_item.is_text.return_value = False + mocked_img_service_item.is_media.return_value = False + mocked_img_service_item.is_command.return_value = False + mocked_img_service_item.is_capable.return_value = False + mocked_img_service_item.get_frames.return_value = [{'title': None, 'path': 'TEST1', 'image': 'FAIL'}, + {'title': None, 'path': 'TEST2', 'image': 'FAIL'}] + # Mock Command service item + mocked_cmd_service_item = MagicMock() + mocked_cmd_service_item.is_text.return_value = False + mocked_cmd_service_item.is_media.return_value = False + mocked_cmd_service_item.is_command.return_value = True + mocked_cmd_service_item.is_capable.return_value = True + mocked_cmd_service_item.get_frames.return_value = [{'title': None, 'path': 'FAIL', 'image': 'TEST3'}, + {'title': None, 'path': 'FAIL', 'image': 'TEST4'}] + # Mock image_manager + mocked_image_manager.get_image.return_value = QtGui.QImage() - # THEN: The object is not None, and the _setup() method was called. - assert list_preview_widget is not None, 'The ListPreviewWidget object should not be None' - assert list_preview_widget.screen_ratio == 1, 'Should not be called' + # init ListPreviewWidget and load service item + list_preview_widget = ListPreviewWidget(None, 1) - @patch(u'openlp.core.widgets.views.ListPreviewWidget.image_manager') - @patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents') - @patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight') - def test_replace_service_item_thumbs(self, mocked_setRowHeight, mocked_resizeRowsToContents, - mocked_image_manager): - """ - Test that thubmails for different slides are loaded properly in replace_service_item. - """ - # GIVEN: A setting to adjust "Max height for non-text slides in slide controller", - # different ServiceItem(s), an ImageManager, and a ListPreviewWidget. + # WHEN: replace_service_item is called + list_preview_widget.replace_service_item(mocked_img_service_item, 200, 0) + list_preview_widget.replace_service_item(mocked_cmd_service_item, 200, 0) + # THEN: The ImageManager should be called in the appriopriate manner for each service item. + # assert mocked_image_manager.get_image.call_count == 4, 'Should be called once for each slide' + # calls = [call('TEST1', ImageSource.ImagePlugin), call('TEST2', ImageSource.ImagePlugin), + # call('TEST3', ImageSource.CommandPlugins), call('TEST4', ImageSource.CommandPlugins)] + # mocked_image_manager.get_image.assert_has_calls(calls) - # Mock Settings().value('advanced/slide max height') - self.mocked_Settings_obj.value.return_value = 0 - # Mock self.viewport().width() - self.mocked_viewport_obj.width.return_value = 200 - # Mock Image service item - mocked_img_service_item = MagicMock() - mocked_img_service_item.is_text.return_value = False - mocked_img_service_item.is_media.return_value = False - mocked_img_service_item.is_command.return_value = False - mocked_img_service_item.is_capable.return_value = False - mocked_img_service_item.get_frames.return_value = [{'title': None, 'path': 'TEST1', 'image': 'FAIL'}, - {'title': None, 'path': 'TEST2', 'image': 'FAIL'}] - # Mock Command service item - mocked_cmd_service_item = MagicMock() - mocked_cmd_service_item.is_text.return_value = False - mocked_cmd_service_item.is_media.return_value = False - mocked_cmd_service_item.is_command.return_value = True - mocked_cmd_service_item.is_capable.return_value = True - mocked_cmd_service_item.get_frames.return_value = [{'title': None, 'path': 'FAIL', 'image': 'TEST3'}, - {'title': None, 'path': 'FAIL', 'image': 'TEST4'}] - # Mock image_manager - mocked_image_manager.get_image.return_value = QtGui.QImage() - # init ListPreviewWidget and load service item - list_preview_widget = ListPreviewWidget(None, 1) +@patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents') +@patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight') +def test_replace_recalculate_layout_text(mocked_setRowHeight, mocked_resizeRowsToContents, + preview_widget_env, mock_settings): + """ + Test if "Max height for non-text slides..." enabled, txt slides unchanged in replace_service_item & __recalc... + """ + # GIVEN: A setting to adjust "Max height for non-text slides in slide controller", + # a text ServiceItem and a ListPreviewWidget. - # WHEN: replace_service_item is called - list_preview_widget.replace_service_item(mocked_img_service_item, 200, 0) - list_preview_widget.replace_service_item(mocked_cmd_service_item, 200, 0) - # THEN: The ImageManager should be called in the appriopriate manner for each service item. - # assert mocked_image_manager.get_image.call_count == 4, 'Should be called once for each slide' - # calls = [call('TEST1', ImageSource.ImagePlugin), call('TEST2', ImageSource.ImagePlugin), - # call('TEST3', ImageSource.CommandPlugins), call('TEST4', ImageSource.CommandPlugins)] - # mocked_image_manager.get_image.assert_has_calls(calls) + # Mock Settings().value('advanced/slide max height') + mock_settings.value.return_value = 100 + # Mock self.viewport().width() + mocked_viewport_obj = preview_widget_env[1] + mocked_viewport_obj.width.return_value = 200 + # Mock text service item + service_item = MagicMock() + service_item.is_text.return_value = True + service_item.get_frames.return_value = [{'title': None, 'text': None, 'verseTag': None}, + {'title': None, 'text': None, 'verseTag': None}] + # init ListPreviewWidget and load service item + list_preview_widget = ListPreviewWidget(None, 1) + list_preview_widget.replace_service_item(service_item, 200, 0) + # Change viewport width before forcing a resize + mocked_viewport_obj.width.return_value = 400 - @patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents') - @patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight') - def test_replace_recalculate_layout_text(self, mocked_setRowHeight, mocked_resizeRowsToContents): - """ - Test if "Max height for non-text slides..." enabled, txt slides unchanged in replace_service_item & __recalc... - """ - # GIVEN: A setting to adjust "Max height for non-text slides in slide controller", - # a text ServiceItem and a ListPreviewWidget. + # WHEN: __recalculate_layout() is called (via resizeEvent) + list_preview_widget.resizeEvent(None) - # Mock Settings().value('advanced/slide max height') - self.mocked_Settings_obj.value.return_value = 100 - # Mock self.viewport().width() - self.mocked_viewport_obj.width.return_value = 200 - # Mock text service item - service_item = MagicMock() - service_item.is_text.return_value = True - service_item.get_frames.return_value = [{'title': None, 'text': None, 'verseTag': None}, - {'title': None, 'text': None, 'verseTag': None}] - # init ListPreviewWidget and load service item - list_preview_widget = ListPreviewWidget(None, 1) - list_preview_widget.replace_service_item(service_item, 200, 0) - # Change viewport width before forcing a resize - self.mocked_viewport_obj.width.return_value = 400 + # THEN: setRowHeight() should not be called, while resizeRowsToContents() should be called twice + # (once each in __recalculate_layout and replace_service_item) + assert mocked_resizeRowsToContents.call_count == 2, 'Should be called' + assert mocked_setRowHeight.call_count == 0, 'Should not be called' - # WHEN: __recalculate_layout() is called (via resizeEvent) - list_preview_widget.resizeEvent(None) - # THEN: setRowHeight() should not be called, while resizeRowsToContents() should be called twice - # (once each in __recalculate_layout and replace_service_item) - assert mocked_resizeRowsToContents.call_count == 2, 'Should be called' - assert mocked_setRowHeight.call_count == 0, 'Should not be called' +@patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents') +@patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight') +def test_replace_recalculate_layout_img(mocked_setRowHeight, mocked_resizeRowsToContents, + preview_widget_env, mock_settings): + """ + Test if "Max height for non-text slides..." disabled, img slides unchanged in replace_service_item & __recalc... + """ + # GIVEN: A setting to adjust "Max height for non-text slides in slide controller", + # an image ServiceItem and a ListPreviewWidget. - @patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents') - @patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight') - def test_replace_recalculate_layout_img(self, mocked_setRowHeight, mocked_resizeRowsToContents): - """ - Test if "Max height for non-text slides..." disabled, img slides unchanged in replace_service_item & __recalc... - """ - # GIVEN: A setting to adjust "Max height for non-text slides in slide controller", - # an image ServiceItem and a ListPreviewWidget. + # Mock Settings().value('advanced/slide max height') + mock_settings.value.return_value = 0 + # Mock self.viewport().width() + mocked_viewport_obj = preview_widget_env[1] + mocked_viewport_obj.width.return_value = 200 + # Mock image service item + service_item = MagicMock() + service_item.is_text.return_value = False + service_item.is_capable.return_value = False + service_item.get_frames.return_value = [{'title': None, 'path': None, 'image': CLAPPERBOARD}, + {'title': None, 'path': None, 'image': CLAPPERBOARD}] + # init ListPreviewWidget and load service item + list_preview_widget = ListPreviewWidget(None, 1) + list_preview_widget.replace_service_item(service_item, 200, 0) + # Change viewport width before forcing a resize + mocked_viewport_obj.width.return_value = 400 - # Mock Settings().value('advanced/slide max height') - self.mocked_Settings_obj.value.return_value = 0 - # Mock self.viewport().width() - self.mocked_viewport_obj.width.return_value = 200 - # Mock image service item - service_item = MagicMock() - service_item.is_text.return_value = False - service_item.is_capable.return_value = False - service_item.get_frames.return_value = [{'title': None, 'path': None, 'image': CLAPPERBOARD}, - {'title': None, 'path': None, 'image': CLAPPERBOARD}] - # init ListPreviewWidget and load service item - list_preview_widget = ListPreviewWidget(None, 1) - list_preview_widget.replace_service_item(service_item, 200, 0) - # Change viewport width before forcing a resize - self.mocked_viewport_obj.width.return_value = 400 + # WHEN: __recalculate_layout() is called (via resizeEvent) + list_preview_widget.resizeEvent(None) + mock_settings.value.return_value = None + list_preview_widget.resizeEvent(None) - # WHEN: __recalculate_layout() is called (via resizeEvent) - list_preview_widget.resizeEvent(None) - self.mocked_Settings_obj.value.return_value = None - list_preview_widget.resizeEvent(None) + # THEN: resizeRowsToContents() should not be called, while setRowHeight() should be called + # twice for each slide. + assert mocked_resizeRowsToContents.call_count == 0, 'Should not be called' + assert mocked_setRowHeight.call_count == 0, 'Should not be called' + # calls = [call(0, 200), call(1, 200), call(0, 400), call(1, 400), call(0, 400), call(1, 400)] + # mocked_setRowHeight.assert_has_calls(calls) - # THEN: resizeRowsToContents() should not be called, while setRowHeight() should be called - # twice for each slide. - assert mocked_resizeRowsToContents.call_count == 0, 'Should not be called' - assert mocked_setRowHeight.call_count == 0, 'Should not be called' - # calls = [call(0, 200), call(1, 200), call(0, 400), call(1, 400), call(0, 400), call(1, 400)] - # mocked_setRowHeight.assert_has_calls(calls) - @patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents') - @patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight') - def test_replace_recalculate_layout_img_max(self, mocked_setRowHeight, mocked_resizeRowsToContents): - """ - Test if "Max height for non-text slides..." enabled, img slides resized in replace_service_item & __recalc... - """ - # GIVEN: A setting to adjust "Max height for non-text slides in slide controller", - # an image ServiceItem and a ListPreviewWidget. +@patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents') +@patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight') +def test_replace_recalculate_layout_img_max(mocked_setRowHeight, mocked_resizeRowsToContents, + preview_widget_env, mock_settings): + """ + Test if "Max height for non-text slides..." enabled, img slides resized in replace_service_item & __recalc... + """ + # GIVEN: A setting to adjust "Max height for non-text slides in slide controller", + # an image ServiceItem and a ListPreviewWidget. - # Mock Settings().value('advanced/slide max height') - self.mocked_Settings_obj.value.return_value = 100 - # Mock self.viewport().width() - self.mocked_viewport_obj.width.return_value = 200 - # Mock image service item - service_item = MagicMock() - service_item.is_text.return_value = False - service_item.is_capable.return_value = False - service_item.get_frames.return_value = [{'title': None, 'path': None, 'image': CLAPPERBOARD}, - {'title': None, 'path': None, 'image': CLAPPERBOARD}] - # init ListPreviewWidget and load service item - list_preview_widget = ListPreviewWidget(None, 1) - list_preview_widget.replace_service_item(service_item, 200, 0) - # Change viewport width before forcing a resize - self.mocked_viewport_obj.width.return_value = 400 + # Mock Settings().value('advanced/slide max height') + mock_settings.value.return_value = 100 + # Mock self.viewport().width() + mocked_viewport_obj = preview_widget_env[1] + mocked_viewport_obj.width.return_value = 200 + # Mock image service item + service_item = MagicMock() + service_item.is_text.return_value = False + service_item.is_capable.return_value = False + service_item.get_frames.return_value = [{'title': None, 'path': None, 'image': CLAPPERBOARD}, + {'title': None, 'path': None, 'image': CLAPPERBOARD}] + # init ListPreviewWidget and load service item + list_preview_widget = ListPreviewWidget(None, 1) + list_preview_widget.replace_service_item(service_item, 200, 0) + # Change viewport width before forcing a resize + mocked_viewport_obj.width.return_value = 400 - # WHEN: __recalculate_layout() is called (via resizeEvent) - list_preview_widget.resizeEvent(None) + # WHEN: __recalculate_layout() is called (via resizeEvent) + list_preview_widget.resizeEvent(None) - # THEN: resizeRowsToContents() should not be called, while setRowHeight() should be called - # twice for each slide. - assert mocked_resizeRowsToContents.call_count == 0, 'Should not be called' - assert mocked_setRowHeight.call_count == 0, 'Should not be called' - # calls = [call(0, 100), call(1, 100), call(0, 100), call(1, 100)] - # mocked_setRowHeight.assert_has_calls(calls) + # THEN: resizeRowsToContents() should not be called, while setRowHeight() should be called + # twice for each slide. + assert mocked_resizeRowsToContents.call_count == 0, 'Should not be called' + assert mocked_setRowHeight.call_count == 0, 'Should not be called' + # calls = [call(0, 100), call(1, 100), call(0, 100), call(1, 100)] + # mocked_setRowHeight.assert_has_calls(calls) - @patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents') - @patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight') - def test_replace_recalculate_layout_img_auto(self, mocked_setRowHeight, mocked_resizeRowsToContents): - """ - Test if "Max height for non-text slides..." auto, img slides resized in replace_service_item & __recalc... - """ - # GIVEN: A setting to adjust "Max height for non-text slides in slide controller", - # an image ServiceItem and a ListPreviewWidget. - # Mock Settings().value('advanced/slide max height') - self.mocked_Settings_obj.value.return_value = -4 - # Mock self.viewport().width() - self.mocked_viewport_obj.width.return_value = 200 - self.mocked_viewport_obj.height.return_value = 600 - # Mock image service item - service_item = MagicMock() - service_item.is_text.return_value = False - service_item.is_capable.return_value = False - service_item.get_frames.return_value = [{'title': None, 'path': None, 'image': CLAPPERBOARD}, - {'title': None, 'path': None, 'image': CLAPPERBOARD}] - # init ListPreviewWidget and load service item - list_preview_widget = ListPreviewWidget(None, 1) - list_preview_widget.replace_service_item(service_item, 200, 0) - # Change viewport width before forcing a resize - self.mocked_viewport_obj.width.return_value = 400 +@patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents') +@patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight') +def test_replace_recalculate_layout_img_auto(mocked_setRowHeight, mocked_resizeRowsToContents, + preview_widget_env, mock_settings): + """ + Test if "Max height for non-text slides..." auto, img slides resized in replace_service_item & __recalc... + """ + # GIVEN: A setting to adjust "Max height for non-text slides in slide controller", + # an image ServiceItem and a ListPreviewWidget. - # WHEN: __recalculate_layout() is called (via screen_size_changed) - list_preview_widget.screen_size_changed(1) - self.mocked_viewport_obj.height.return_value = 200 - list_preview_widget.screen_size_changed(1) + # Mock Settings().value('advanced/slide max height') + mock_settings.value.return_value = -4 + # Mock self.viewport().width() + mocked_viewport_obj = preview_widget_env[1] + mocked_viewport_obj.width.return_value = 200 + mocked_viewport_obj.height.return_value = 600 + # Mock image service item + service_item = MagicMock() + service_item.is_text.return_value = False + service_item.is_capable.return_value = False + service_item.get_frames.return_value = [{'title': None, 'path': None, 'image': CLAPPERBOARD}, + {'title': None, 'path': None, 'image': CLAPPERBOARD}] + # init ListPreviewWidget and load service item + list_preview_widget = ListPreviewWidget(None, 1) + list_preview_widget.replace_service_item(service_item, 200, 0) + # Change viewport width before forcing a resize + mocked_viewport_obj.width.return_value = 400 - # THEN: resizeRowsToContents() should not be called, while setRowHeight() should be called - # twice for each slide. - assert mocked_resizeRowsToContents.call_count == 0, 'Should not be called' - assert mocked_setRowHeight.call_count == 0, 'Should not be called' - # calls = [call(0, 100), call(1, 100), call(0, 150), call(1, 150), call(0, 100), call(1, 100)] - # mocked_setRowHeight.assert_has_calls(calls) + # WHEN: __recalculate_layout() is called (via screen_size_changed) + list_preview_widget.screen_size_changed(1) + mocked_viewport_obj.height.return_value = 200 + list_preview_widget.screen_size_changed(1) - @patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents') - @patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight') - @patch(u'openlp.core.widgets.views.ListPreviewWidget.cellWidget') - def test_row_resized_text(self, mocked_cellWidget, mocked_setRowHeight, mocked_resizeRowsToContents): - """ - Test if "Max height for non-text slides..." enabled, text-based slides not affected in row_resized. - """ - # GIVEN: A setting to adjust "Max height for non-text slides in slide controller", - # a text ServiceItem and a ListPreviewWidget. + # THEN: resizeRowsToContents() should not be called, while setRowHeight() should be called + # twice for each slide. + assert mocked_resizeRowsToContents.call_count == 0, 'Should not be called' + assert mocked_setRowHeight.call_count == 0, 'Should not be called' + # calls = [call(0, 100), call(1, 100), call(0, 150), call(1, 150), call(0, 100), call(1, 100)] + # mocked_setRowHeight.assert_has_calls(calls) - # Mock Settings().value('advanced/slide max height') - self.mocked_Settings_obj.value.return_value = 100 - # Mock self.viewport().width() - self.mocked_viewport_obj.width.return_value = 200 - # Mock text service item - service_item = MagicMock() - service_item.is_text.return_value = True - service_item.get_frames.return_value = [{'title': None, 'text': None, 'verseTag': None}, - {'title': None, 'text': None, 'verseTag': None}] - # Mock self.cellWidget().children().setMaximumWidth() - mocked_cellWidget_child = MagicMock() - mocked_cellWidget_obj = MagicMock() - mocked_cellWidget_obj.children.return_value = [None, mocked_cellWidget_child] - mocked_cellWidget.return_value = mocked_cellWidget_obj - # init ListPreviewWidget and load service item - list_preview_widget = ListPreviewWidget(None, 1) - list_preview_widget.replace_service_item(service_item, 200, 0) - # WHEN: row_resized() is called - list_preview_widget.row_resized(0, 100, 150) +@patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents') +@patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight') +@patch(u'openlp.core.widgets.views.ListPreviewWidget.cellWidget') +def test_row_resized_text(mocked_cellWidget, mocked_setRowHeight, mocked_resizeRowsToContents, + preview_widget_env, mock_settings): + """ + Test if "Max height for non-text slides..." enabled, text-based slides not affected in row_resized. + """ + # GIVEN: A setting to adjust "Max height for non-text slides in slide controller", + # a text ServiceItem and a ListPreviewWidget. - # THEN: self.cellWidget(row, 0).children()[1].setMaximumWidth() should not be called - assert mocked_cellWidget_child.setMaximumWidth.call_count == 0, 'Should not be called' + # Mock Settings().value('advanced/slide max height') + mock_settings.value.return_value = 100 + # Mock self.viewport().width() + mocked_viewport_obj = preview_widget_env[1] + mocked_viewport_obj.width.return_value = 200 + # Mock text service item + service_item = MagicMock() + service_item.is_text.return_value = True + service_item.get_frames.return_value = [{'title': None, 'text': None, 'verseTag': None}, + {'title': None, 'text': None, 'verseTag': None}] + # Mock self.cellWidget().children().setMaximumWidth() + mocked_cellWidget_child = MagicMock() + mocked_cellWidget_obj = MagicMock() + mocked_cellWidget_obj.children.return_value = [None, mocked_cellWidget_child] + mocked_cellWidget.return_value = mocked_cellWidget_obj + # init ListPreviewWidget and load service item + list_preview_widget = ListPreviewWidget(None, 1) + list_preview_widget.replace_service_item(service_item, 200, 0) - @patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents') - @patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight') - @patch(u'openlp.core.widgets.views.ListPreviewWidget.cellWidget') - def test_row_resized_img(self, mocked_cellWidget, mocked_setRowHeight, mocked_resizeRowsToContents): - """ - Test if "Max height for non-text slides..." disabled, image-based slides not affected in row_resized. - """ - # GIVEN: A setting to adjust "Max height for non-text slides in slide controller", - # an image ServiceItem and a ListPreviewWidget. + # WHEN: row_resized() is called + list_preview_widget.row_resized(0, 100, 150) - # Mock Settings().value('advanced/slide max height') - self.mocked_Settings_obj.value.return_value = 0 - # Mock self.viewport().width() - self.mocked_viewport_obj.width.return_value = 200 - # Mock image service item - service_item = MagicMock() - service_item.is_text.return_value = False - service_item.is_capable.return_value = False - service_item.get_frames.return_value = [{'title': None, 'path': None, 'image': CLAPPERBOARD}, - {'title': None, 'path': None, 'image': CLAPPERBOARD}] - # Mock self.cellWidget().children().setMaximumWidth() - mocked_cellWidget_child = MagicMock() - mocked_cellWidget_obj = MagicMock() - mocked_cellWidget_obj.children.return_value = [None, mocked_cellWidget_child] - mocked_cellWidget.return_value = mocked_cellWidget_obj - # init ListPreviewWidget and load service item - list_preview_widget = ListPreviewWidget(None, 1) - list_preview_widget.replace_service_item(service_item, 200, 0) + # THEN: self.cellWidget(row, 0).children()[1].setMaximumWidth() should not be called + assert mocked_cellWidget_child.setMaximumWidth.call_count == 0, 'Should not be called' - # WHEN: row_resized() is called - list_preview_widget.row_resized(0, 100, 150) - self.mocked_Settings_obj.value.return_value = None - list_preview_widget.row_resized(0, 100, 150) - # THEN: self.cellWidget(row, 0).children()[1].setMaximumWidth() should not be called - assert mocked_cellWidget_child.setMaximumWidth.call_count == 0, 'Should not be called' +@patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents') +@patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight') +@patch(u'openlp.core.widgets.views.ListPreviewWidget.cellWidget') +def test_row_resized_img(mocked_cellWidget, mocked_setRowHeight, mocked_resizeRowsToContents, + preview_widget_env, mock_settings): + """ + Test if "Max height for non-text slides..." disabled, image-based slides not affected in row_resized. + """ + # GIVEN: A setting to adjust "Max height for non-text slides in slide controller", + # an image ServiceItem and a ListPreviewWidget. - @patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents') - @patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight') - @patch(u'openlp.core.widgets.views.ListPreviewWidget.cellWidget') - def test_row_resized_img_max(self, mocked_cellWidget, mocked_setRowHeight, mocked_resizeRowsToContents): - """ - Test if "Max height for non-text slides..." enabled, image-based slides are scaled in row_resized. - """ - # GIVEN: A setting to adjust "Max height for non-text slides in slide controller", - # an image ServiceItem and a ListPreviewWidget. + # Mock Settings().value('advanced/slide max height') + mock_settings.value.return_value = 0 + # Mock self.viewport().width() + mocked_viewport_obj = preview_widget_env[1] + mocked_viewport_obj.width.return_value = 200 + # Mock image service item + service_item = MagicMock() + service_item.is_text.return_value = False + service_item.is_capable.return_value = False + service_item.get_frames.return_value = [{'title': None, 'path': None, 'image': CLAPPERBOARD}, + {'title': None, 'path': None, 'image': CLAPPERBOARD}] + # Mock self.cellWidget().children().setMaximumWidth() + mocked_cellWidget_child = MagicMock() + mocked_cellWidget_obj = MagicMock() + mocked_cellWidget_obj.children.return_value = [None, mocked_cellWidget_child] + mocked_cellWidget.return_value = mocked_cellWidget_obj + # init ListPreviewWidget and load service item + list_preview_widget = ListPreviewWidget(None, 1) + list_preview_widget.replace_service_item(service_item, 200, 0) - # Mock Settings().value('advanced/slide max height') - self.mocked_Settings_obj.value.return_value = 100 - # Mock self.viewport().width() - self.mocked_viewport_obj.width.return_value = 200 - # Mock image service item - service_item = MagicMock() - service_item.is_text.return_value = False - service_item.is_capable.return_value = False - service_item.get_frames.return_value = [{'title': None, 'path': None, 'image': CLAPPERBOARD}, - {'title': None, 'path': None, 'image': CLAPPERBOARD}] - # Mock self.cellWidget().children().setMaximumWidth() - mocked_cellWidget_child = MagicMock() - mocked_cellWidget_obj = MagicMock() - mocked_cellWidget_obj.children.return_value = [None, mocked_cellWidget_child] - mocked_cellWidget.return_value = mocked_cellWidget_obj - # init ListPreviewWidget and load service item - list_preview_widget = ListPreviewWidget(None, 1) - list_preview_widget.replace_service_item(service_item, 200, 0) + # WHEN: row_resized() is called + list_preview_widget.row_resized(0, 100, 150) + mock_settings.value.return_value = None + list_preview_widget.row_resized(0, 100, 150) - # WHEN: row_resized() is called - list_preview_widget.row_resized(0, 100, 150) + # THEN: self.cellWidget(row, 0).children()[1].setMaximumWidth() should not be called + assert mocked_cellWidget_child.setMaximumWidth.call_count == 0, 'Should not be called' - # THEN: self.cellWidget(row, 0).children()[1].setMaximumWidth() should be called - mocked_cellWidget_child.setMaximumWidth.assert_called_once_with(150) - @patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents') - @patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight') - @patch(u'openlp.core.widgets.views.ListPreviewWidget.cellWidget') - def test_row_resized_setting_changed(self, mocked_cellWidget, mocked_setRowHeight, mocked_resizeRowsToContents): - """ - Test if "Max height for non-text slides..." enabled while item live, program doesn't crash on row_resized. - """ - # GIVEN: A setting to adjust "Max height for non-text slides in slide controller", - # an image ServiceItem and a ListPreviewWidget. +@patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents') +@patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight') +@patch(u'openlp.core.widgets.views.ListPreviewWidget.cellWidget') +def test_row_resized_img_max(mocked_cellWidget, mocked_setRowHeight, mocked_resizeRowsToContents, + preview_widget_env, mock_settings): + """ + Test if "Max height for non-text slides..." enabled, image-based slides are scaled in row_resized. + """ + # GIVEN: A setting to adjust "Max height for non-text slides in slide controller", + # an image ServiceItem and a ListPreviewWidget. - # Mock Settings().value('advanced/slide max height') - self.mocked_Settings_obj.value.return_value = 0 - # Mock self.viewport().width() - self.mocked_viewport_obj.width.return_value = 200 - # Mock image service item - service_item = MagicMock() - service_item.is_text.return_value = False - service_item.is_capable.return_value = False - service_item.get_frames.return_value = [{'title': None, 'path': None, 'image': CLAPPERBOARD}, - {'title': None, 'path': None, 'image': CLAPPERBOARD}] - # Mock self.cellWidget().children() - mocked_cellWidget_obj = MagicMock() - mocked_cellWidget_obj.children.return_value = None - mocked_cellWidget.return_value = mocked_cellWidget_obj - # init ListPreviewWidget and load service item - list_preview_widget = ListPreviewWidget(None, 1) - list_preview_widget.replace_service_item(service_item, 200, 0) - self.mocked_Settings_obj.value.return_value = 100 + # Mock Settings().value('advanced/slide max height') + mock_settings.value.return_value = 100 + # Mock self.viewport().width() + mock_settings.width.return_value = 200 + # Mock image service item + service_item = MagicMock() + service_item.is_text.return_value = False + service_item.is_capable.return_value = False + service_item.get_frames.return_value = [{'title': None, 'path': None, 'image': CLAPPERBOARD}, + {'title': None, 'path': None, 'image': CLAPPERBOARD}] + # Mock self.cellWidget().children().setMaximumWidth() + mocked_cellWidget_child = MagicMock() + mocked_cellWidget_obj = MagicMock() + mocked_cellWidget_obj.children.return_value = [None, mocked_cellWidget_child] + mocked_cellWidget.return_value = mocked_cellWidget_obj + # init ListPreviewWidget and load service item + list_preview_widget = ListPreviewWidget(None, 1) + list_preview_widget.replace_service_item(service_item, 200, 0) - # WHEN: row_resized() is called - list_preview_widget.row_resized(0, 100, 150) + # WHEN: row_resized() is called + list_preview_widget.row_resized(0, 100, 150) - # THEN: self.cellWidget(row, 0).children()[1].setMaximumWidth() should fail - self.assertRaises(Exception) + # THEN: self.cellWidget(row, 0).children()[1].setMaximumWidth() should be called + mocked_cellWidget_child.setMaximumWidth.assert_called_once_with(150) - @patch(u'openlp.core.widgets.views.ListPreviewWidget.selectRow') - @patch(u'openlp.core.widgets.views.ListPreviewWidget.scrollToItem') - @patch(u'openlp.core.widgets.views.ListPreviewWidget.item') - @patch(u'openlp.core.widgets.views.ListPreviewWidget.slide_count') - def test_autoscroll_setting_invalid(self, mocked_slide_count, mocked_item, mocked_scrollToItem, mocked_selectRow): - """ - Test if 'advanced/autoscrolling' setting None or invalid, that no autoscrolling occurs on change_slide(). - """ - # GIVEN: A setting for autoscrolling and a ListPreviewWidget. - # Mock Settings().value('advanced/autoscrolling') - self.mocked_Settings_obj.value.return_value = None - # Mocked returns - mocked_slide_count.return_value = 1 - mocked_item.return_value = None - # init ListPreviewWidget and load service item - list_preview_widget = ListPreviewWidget(None, 1) - # WHEN: change_slide() is called - list_preview_widget.change_slide(0) - self.mocked_Settings_obj.value.return_value = 1 - list_preview_widget.change_slide(0) - self.mocked_Settings_obj.value.return_value = {'fail': 1} - list_preview_widget.change_slide(0) - self.mocked_Settings_obj.value.return_value = {'dist': 1, 'fail': 1} - list_preview_widget.change_slide(0) - self.mocked_Settings_obj.value.return_value = {'dist': 'fail', 'pos': 1} - list_preview_widget.change_slide(0) - self.mocked_Settings_obj.value.return_value = {'dist': 1, 'pos': 'fail'} - list_preview_widget.change_slide(0) +@patch(u'openlp.core.widgets.views.ListPreviewWidget.resizeRowsToContents') +@patch(u'openlp.core.widgets.views.ListPreviewWidget.setRowHeight') +@patch(u'openlp.core.widgets.views.ListPreviewWidget.cellWidget') +def test_row_resized_setting_changed(mocked_cellWidget, mocked_setRowHeight, mocked_resizeRowsToContents, + preview_widget_env, mock_settings): + """ + Test if "Max height for non-text slides..." enabled while item live, program doesn't crash on row_resized. + """ + # GIVEN: A setting to adjust "Max height for non-text slides in slide controller", + # an image ServiceItem and a ListPreviewWidget. - # THEN: no further functions should be called - assert mocked_slide_count.call_count == 0, 'Should not be called' - assert mocked_scrollToItem.call_count == 0, 'Should not be called' - assert mocked_selectRow.call_count == 0, 'Should not be called' - assert mocked_item.call_count == 0, 'Should not be called' + # Mock Settings().value('advanced/slide max height') + mock_settings.value.return_value = 0 + # Mock self.viewport().width() + mocked_viewport_obj = preview_widget_env[1] + mocked_viewport_obj.width.return_value = 200 + # Mock image service item + service_item = MagicMock() + service_item.is_text.return_value = False + service_item.is_capable.return_value = False + service_item.get_frames.return_value = [{'title': None, 'path': None, 'image': CLAPPERBOARD}, + {'title': None, 'path': None, 'image': CLAPPERBOARD}] + # Mock self.cellWidget().children() + mocked_cellWidget_obj = MagicMock() + mocked_cellWidget_obj.children.return_value = None + mocked_cellWidget.return_value = mocked_cellWidget_obj + # init ListPreviewWidget and load service item + list_preview_widget = ListPreviewWidget(None, 1) + list_preview_widget.replace_service_item(service_item, 200, 0) + mock_settings.value.return_value = 100 - @patch(u'openlp.core.widgets.views.ListPreviewWidget.selectRow') - @patch(u'openlp.core.widgets.views.ListPreviewWidget.scrollToItem') - @patch(u'openlp.core.widgets.views.ListPreviewWidget.item') - @patch(u'openlp.core.widgets.views.ListPreviewWidget.slide_count') - def test_autoscroll_dist_bounds(self, mocked_slide_count, mocked_item, mocked_scrollToItem, mocked_selectRow): - """ - Test if 'advanced/autoscrolling' setting asks to scroll beyond list bounds, that it does not beyond. - """ - # GIVEN: A setting for autoscrolling and a ListPreviewWidget. - # Mock Settings().value('advanced/autoscrolling') - self.mocked_Settings_obj.value.return_value = {'dist': -1, 'pos': 1} - # Mocked returns - mocked_slide_count.return_value = 1 - mocked_item.return_value = None - # init ListPreviewWidget and load service item - list_preview_widget = ListPreviewWidget(None, 1) + # WHEN: row_resized() is called + list_preview_widget.row_resized(0, 100, 150) - # WHEN: change_slide() is called - list_preview_widget.change_slide(0) - self.mocked_Settings_obj.value.return_value = {'dist': 1, 'pos': 1} - list_preview_widget.change_slide(0) + # THEN: self.cellWidget(row, 0).children()[1].setMaximumWidth() should fail + assert Exception - # THEN: no further functions should be called - assert mocked_slide_count.call_count == 3, 'Should be called' - assert mocked_scrollToItem.call_count == 2, 'Should be called' - assert mocked_selectRow.call_count == 2, 'Should be called' - assert mocked_item.call_count == 2, 'Should be called' - calls = [call(0, 0), call(0, 0)] - mocked_item.assert_has_calls(calls) - @patch(u'openlp.core.widgets.views.ListPreviewWidget.selectRow') - @patch(u'openlp.core.widgets.views.ListPreviewWidget.scrollToItem') - @patch(u'openlp.core.widgets.views.ListPreviewWidget.item') - @patch(u'openlp.core.widgets.views.ListPreviewWidget.slide_count') - def test_autoscroll_normal(self, mocked_slide_count, mocked_item, mocked_scrollToItem, mocked_selectRow): - """ - Test if 'advanced/autoscrolling' setting valid, autoscrolling called as expected. - """ - # GIVEN: A setting for autoscrolling and a ListPreviewWidget. - # Mock Settings().value('advanced/autoscrolling') - self.mocked_Settings_obj.value.return_value = {'dist': -1, 'pos': 1} - # Mocked returns - mocked_slide_count.return_value = 3 - mocked_item.return_value = None - # init ListPreviewWidget and load service item - list_preview_widget = ListPreviewWidget(None, 1) +@patch(u'openlp.core.widgets.views.ListPreviewWidget.selectRow') +@patch(u'openlp.core.widgets.views.ListPreviewWidget.scrollToItem') +@patch(u'openlp.core.widgets.views.ListPreviewWidget.item') +@patch(u'openlp.core.widgets.views.ListPreviewWidget.slide_count') +def test_autoscroll_setting_invalid(mocked_slide_count, mocked_item, mocked_scrollToItem, mocked_selectRow, + preview_widget_env, mock_settings): + """ + Test if 'advanced/autoscrolling' setting None or invalid, that no autoscrolling occurs on change_slide(). + """ + # GIVEN: A setting for autoscrolling and a ListPreviewWidget. + # Mock Settings().value('advanced/autoscrolling') + mock_settings.value.return_value = None + # Mocked returns + mocked_slide_count.return_value = 1 + mocked_item.return_value = None + # init ListPreviewWidget and load service item + list_preview_widget = ListPreviewWidget(None, 1) - # WHEN: change_slide() is called - list_preview_widget.change_slide(1) - self.mocked_Settings_obj.value.return_value = {'dist': 0, 'pos': 1} - list_preview_widget.change_slide(1) - self.mocked_Settings_obj.value.return_value = {'dist': 1, 'pos': 1} - list_preview_widget.change_slide(1) + # WHEN: change_slide() is called + list_preview_widget.change_slide(0) + mock_settings.value.return_value = 1 + list_preview_widget.change_slide(0) + mock_settings.value.return_value = {'fail': 1} + list_preview_widget.change_slide(0) + mock_settings.value.return_value = {'dist': 1, 'fail': 1} + list_preview_widget.change_slide(0) + mock_settings.value.return_value = {'dist': 'fail', 'pos': 1} + list_preview_widget.change_slide(0) + mock_settings.value.return_value = {'dist': 1, 'pos': 'fail'} + list_preview_widget.change_slide(0) - # THEN: no further functions should be called - assert mocked_slide_count.call_count == 3, 'Should be called' - assert mocked_scrollToItem.call_count == 3, 'Should be called' - assert mocked_selectRow.call_count == 3, 'Should be called' - assert mocked_item.call_count == 3, 'Should be called' - calls = [call(0, 0), call(1, 0), call(2, 0)] - mocked_item.assert_has_calls(calls) + # THEN: no further functions should be called + assert mocked_slide_count.call_count == 0, 'Should not be called' + assert mocked_scrollToItem.call_count == 0, 'Should not be called' + assert mocked_selectRow.call_count == 0, 'Should not be called' + assert mocked_item.call_count == 0, 'Should not be called' + + +@patch(u'openlp.core.widgets.views.ListPreviewWidget.selectRow') +@patch(u'openlp.core.widgets.views.ListPreviewWidget.scrollToItem') +@patch(u'openlp.core.widgets.views.ListPreviewWidget.item') +@patch(u'openlp.core.widgets.views.ListPreviewWidget.slide_count') +def test_autoscroll_dist_bounds(mocked_slide_count, mocked_item, mocked_scrollToItem, mocked_selectRow, + preview_widget_env, mock_settings): + """ + Test if 'advanced/autoscrolling' setting asks to scroll beyond list bounds, that it does not beyond. + """ + # GIVEN: A setting for autoscrolling and a ListPreviewWidget. + # Mock Settings().value('advanced/autoscrolling') + mock_settings.value.return_value = {'dist': -1, 'pos': 1} + # Mocked returns + mocked_slide_count.return_value = 1 + mocked_item.return_value = None + # init ListPreviewWidget and load service item + list_preview_widget = ListPreviewWidget(None, 1) + + # WHEN: change_slide() is called + list_preview_widget.change_slide(0) + mock_settings.value.return_value = {'dist': 1, 'pos': 1} + list_preview_widget.change_slide(0) + + # THEN: no further functions should be called + assert mocked_slide_count.call_count == 3, 'Should be called' + assert mocked_scrollToItem.call_count == 2, 'Should be called' + assert mocked_selectRow.call_count == 2, 'Should be called' + assert mocked_item.call_count == 2, 'Should be called' + calls = [call(0, 0), call(0, 0)] + mocked_item.assert_has_calls(calls) + + +@patch(u'openlp.core.widgets.views.ListPreviewWidget.selectRow') +@patch(u'openlp.core.widgets.views.ListPreviewWidget.scrollToItem') +@patch(u'openlp.core.widgets.views.ListPreviewWidget.item') +@patch(u'openlp.core.widgets.views.ListPreviewWidget.slide_count') +def test_autoscroll_normal(mocked_slide_count, mocked_item, mocked_scrollToItem, mocked_selectRow, + preview_widget_env, mock_settings): + """ + Test if 'advanced/autoscrolling' setting valid, autoscrolling called as expected. + """ + # GIVEN: A setting for autoscrolling and a ListPreviewWidget. + # Mock Settings().value('advanced/autoscrolling') + mock_settings.value.return_value = {'dist': -1, 'pos': 1} + # Mocked returns + mocked_slide_count.return_value = 3 + mocked_item.return_value = None + # init ListPreviewWidget and load service item + list_preview_widget = ListPreviewWidget(None, 1) + + # WHEN: change_slide() is called + list_preview_widget.change_slide(1) + mock_settings.value.return_value = {'dist': 0, 'pos': 1} + list_preview_widget.change_slide(1) + mock_settings.value.return_value = {'dist': 1, 'pos': 1} + list_preview_widget.change_slide(1) + + # THEN: no further functions should be called + assert mocked_slide_count.call_count == 3, 'Should be called' + assert mocked_scrollToItem.call_count == 3, 'Should be called' + assert mocked_selectRow.call_count == 3, 'Should be called' + assert mocked_item.call_count == 3, 'Should be called' + calls = [call(0, 0), call(1, 0), call(2, 0)] + mocked_item.assert_has_calls(calls) class TestListWidgetWithDnD(TestCase): diff --git a/tests/interfaces/openlp_core/widgets/test_edits.py b/tests/interfaces/openlp_core/widgets/test_edits.py index 5eea68148..47d2b7112 100644 --- a/tests/interfaces/openlp_core/widgets/test_edits.py +++ b/tests/interfaces/openlp_core/widgets/test_edits.py @@ -22,7 +22,7 @@ Module to test the EditCustomForm. """ from unittest import TestCase -from unittest.mock import MagicMock, call, patch +from unittest.mock import MagicMock, call from PyQt5 import QtCore, QtGui, QtTest, QtWidgets @@ -56,11 +56,7 @@ class TestSearchEdit(TestCase, TestMixin): self.setup_application() self.main_window = QtWidgets.QMainWindow() Registry().register('main_window', self.main_window) - - settings_patcher = patch( - 'openlp.core.widgets.edits.Settings', return_value=MagicMock(**{'value.return_value': SearchTypes.First})) - self.addCleanup(settings_patcher.stop) - self.mocked_settings = settings_patcher.start() + Registry().register('settings', MagicMock(**{'value.return_value': SearchTypes.First})) self.search_edit = SearchEdit(self.main_window, 'settings_section') # To complete set up we have to set the search types. @@ -86,7 +82,7 @@ class TestSearchEdit(TestCase, TestMixin): # settings assert self.search_edit.current_search_type() == SearchTypes.First, \ "The first search type should be selected." - self.mocked_settings().setValue.assert_called_once_with('settings_section/last used search type', 0) + Registry().get('settings').setValue.assert_called_once_with('settings_section/last used search type', 0) def test_set_current_search_type(self): """ @@ -102,7 +98,7 @@ class TestSearchEdit(TestCase, TestMixin): "The search type should be SearchTypes.Second" assert self.search_edit.placeholderText() == SECOND_PLACEHOLDER_TEXT, \ "The correct placeholder text should be 'Second Placeholder Text'." - self.mocked_settings().setValue.assert_has_calls( + Registry().get('settings').setValue.assert_has_calls( [call('settings_section/last used search type', 0), call('settings_section/last used search type', 1)]) def test_clear_button_visibility(self): diff --git a/tests/openlp_core/projectors/test_projector_pjlink_udp.py b/tests/openlp_core/projectors/test_projector_pjlink_udp.py index 408057dd1..ff0a31c20 100644 --- a/tests/openlp_core/projectors/test_projector_pjlink_udp.py +++ b/tests/openlp_core/projectors/test_projector_pjlink_udp.py @@ -26,6 +26,7 @@ from unittest import TestCase from unittest.mock import call, patch import openlp.core.projectors.pjlink +from openlp.core.common.settings import Settings from openlp.core.common.registry import Registry from openlp.core.projectors.constants import PJLINK_PORT from openlp.core.projectors.pjlink import PJLinkUDP @@ -46,6 +47,7 @@ class TestPJLinkBase(TestCase, TestMixin): self.setup_application() self.build_settings() Registry.create() + Registry().register('settings', Settings()) """ with patch('openlp.core.projectors.db.init_url') as mocked_init_url: if os.path.exists(TEST_DB): diff --git a/tests/openlp_core/widgets/test_widgets.py b/tests/openlp_core/widgets/test_widgets.py index db5f5ae17..4767bbe98 100644 --- a/tests/openlp_core/widgets/test_widgets.py +++ b/tests/openlp_core/widgets/test_widgets.py @@ -32,198 +32,175 @@ from openlp.core.widgets.widgets import ProxyWidget, ProxyDialog, ScreenButton, from tests.helpers.testmixin import TestMixin -class TestProxyWidget(TestCase, TestMixin): +def test_radio_button_exclusivity_no_proxy(settings): """ - Test the EditCustomForm. + Test that only one radio button can be checked at a time, and that the line edits are only enabled when the + `manual_proxy_radio` is checked """ - def setUp(self): - """ - Create the UI - """ - self.setup_application() + # GIVEN: An instance of the `openlp.core.common.widgets.widgets.ProxyWidget` with a radio already checked + proxy_widget = ProxyWidget() + proxy_widget.manual_proxy_radio.setChecked(True) - def test_radio_button_exclusivity_no_proxy(self): - """ - Test that only one radio button can be checked at a time, and that the line edits are only enabled when the - `manual_proxy_radio` is checked - """ - # GIVEN: An instance of the `openlp.core.common.widgets.widgets.ProxyWidget` with a radio already checked - proxy_widget = ProxyWidget() - proxy_widget.manual_proxy_radio.setChecked(True) + # WHEN: 'Checking' the `no_proxy_radio` button + proxy_widget.no_proxy_radio.setChecked(True) - # WHEN: 'Checking' the `no_proxy_radio` button - proxy_widget.no_proxy_radio.setChecked(True) - - # THEN: The other radio buttons should not be checked and the line edits should not be enabled - assert proxy_widget.use_sysem_proxy_radio.isChecked() is False - assert proxy_widget.manual_proxy_radio.isChecked() is False - assert proxy_widget.http_edit.isEnabled() is False - assert proxy_widget.https_edit.isEnabled() is False - assert proxy_widget.username_edit.isEnabled() is False - assert proxy_widget.password_edit.isEnabled() is False - - def test_radio_button_exclusivity_system_proxy(self): - """ - Test that only one radio button can be checked at a time, and that the line edits are only enabled when the - `manual_proxy_radio` is checked - """ - # GIVEN: An instance of the `openlp.core.common.widgets.widgets.ProxyWidget` with a radio already checked - proxy_widget = ProxyWidget() - proxy_widget.manual_proxy_radio.setChecked(True) - - # WHEN: 'Checking' the `use_sysem_proxy_radio` button - proxy_widget.use_sysem_proxy_radio.setChecked(True) - - # THEN: The other radio buttons should not be checked and the line edits should not be enabled - assert proxy_widget.no_proxy_radio.isChecked() is False - assert proxy_widget.manual_proxy_radio.isChecked() is False - assert proxy_widget.http_edit.isEnabled() is False - assert proxy_widget.https_edit.isEnabled() is False - assert proxy_widget.username_edit.isEnabled() is False - assert proxy_widget.password_edit.isEnabled() is False - - def test_radio_button_exclusivity_manual_proxy(self): - """ - Test that only one radio button can be checked at a time, and that the line edits are only enabled when the - `manual_proxy_radio` is checked - """ - # GIVEN: An instance of the `openlp.core.common.widgets.widgets.ProxyWidget` with a radio already checked - proxy_widget = ProxyWidget() - proxy_widget.no_proxy_radio.setChecked(True) - - # WHEN: 'Checking' the `manual_proxy_radio` button - proxy_widget.manual_proxy_radio.setChecked(True) - - # THEN: The other radio buttons should not be checked and the line edits should be enabled - assert proxy_widget.no_proxy_radio.isChecked() is False - assert proxy_widget.use_sysem_proxy_radio.isChecked() is False - assert proxy_widget.http_edit.isEnabled() is True - assert proxy_widget.https_edit.isEnabled() is True - assert proxy_widget.username_edit.isEnabled() is True - assert proxy_widget.password_edit.isEnabled() is True - - def test_proxy_widget_load_default_settings(self): - """ - Test that the default settings are loaded from the config correctly - """ - # GIVEN: And instance of the widget with default settings - proxy_widget = ProxyWidget() - - # WHEN: Calling the `load` method - proxy_widget.load() - - # THEN: The widget should be in its default state - assert proxy_widget.use_sysem_proxy_radio.isChecked() is True - assert proxy_widget.http_edit.text() == '' - assert proxy_widget.https_edit.text() == '' - assert proxy_widget.username_edit.text() == '' - assert proxy_widget.password_edit.text() == '' - - @patch.object(ProxyWidget, 'load') - @patch('openlp.core.widgets.widgets.Settings') - def test_proxy_widget_save_no_proxy_settings(self, settings_patcher, proxy_widget_load_patcher): - """ - Test that the settings are saved correctly - """ - # GIVEN: A Mocked settings instance of the proxy widget with some known values set - settings_instance = MagicMock() - settings_patcher.return_value = settings_instance - proxy_widget = ProxyWidget() - proxy_widget.no_proxy_radio.setChecked(True) - proxy_widget.http_edit.setText('') - proxy_widget.https_edit.setText('') - proxy_widget.username_edit.setText('') - proxy_widget.password_edit.setText('') - - # WHEN: Calling save - proxy_widget.save() - - # THEN: The settings should be set as expected - settings_instance.setValue.assert_has_calls( - [call('advanced/proxy mode', ProxyMode.NO_PROXY), - call('advanced/proxy http', ''), - call('advanced/proxy https', ''), - call('advanced/proxy username', ''), - call('advanced/proxy password', '')]) - - @patch.object(ProxyWidget, 'load') - @patch('openlp.core.widgets.widgets.Settings') - def test_proxy_widget_save_manual_settings(self, settings_patcher, proxy_widget_load_patcher): - """ - Test that the settings are saved correctly - """ - # GIVEN: A Mocked and instance of the proxy widget with some known values set - settings_instance = MagicMock() - settings_patcher.return_value = settings_instance - proxy_widget = ProxyWidget() - proxy_widget.manual_proxy_radio.setChecked(True) - proxy_widget.http_edit.setText('http_proxy_server:port') - proxy_widget.https_edit.setText('https_proxy_server:port') - proxy_widget.username_edit.setText('username') - proxy_widget.password_edit.setText('password') - - # WHEN: Calling save - proxy_widget.save() - - # THEN: The settings should be set as expected - settings_instance.setValue.assert_has_calls( - [call('advanced/proxy mode', ProxyMode.MANUAL_PROXY), - call('advanced/proxy http', 'http_proxy_server:port'), - call('advanced/proxy https', 'https_proxy_server:port'), - call('advanced/proxy username', 'username'), - call('advanced/proxy password', 'password')]) + # THEN: The other radio buttons should not be checked and the line edits should not be enabled + assert proxy_widget.use_sysem_proxy_radio.isChecked() is False + assert proxy_widget.manual_proxy_radio.isChecked() is False + assert proxy_widget.http_edit.isEnabled() is False + assert proxy_widget.https_edit.isEnabled() is False + assert proxy_widget.username_edit.isEnabled() is False + assert proxy_widget.password_edit.isEnabled() is False -class TestProxyDialog(TestCase, TestMixin): - """Test the ProxyDialog""" +def test_radio_button_exclusivity_system_proxy(settings): + """ + Test that only one radio button can be checked at a time, and that the line edits are only enabled when the + `manual_proxy_radio` is checked + """ + # GIVEN: An instance of the `openlp.core.common.widgets.widgets.ProxyWidget` with a radio already checked + proxy_widget = ProxyWidget() + proxy_widget.manual_proxy_radio.setChecked(True) - def setUp(self): - """Test setup""" - self.setup_application() - self.build_settings() + # WHEN: 'Checking' the `use_sysem_proxy_radio` button + proxy_widget.use_sysem_proxy_radio.setChecked(True) - def tearDown(self): - """Teardown tests""" - del self.app - - def test_init(self): - """Test that the ProxyDialog is created successfully""" - # GIVEN: ProxyDialog class - # WHEN: It is instantiated - # THEN: There should be no problems - ProxyDialog() - - def test_accept(self): - """Test that the accept() method of the ProxyDialog works correctly""" - # GIVEN: An instance of a ProxyDialog with a mocked out widget - dlg = ProxyDialog() - dlg.proxy_widget = MagicMock() - - # WHEN: accept() is called - dlg.accept() - - # THEN: The save() method on the widget should have been called - dlg.proxy_widget.save.assert_called_once() + # THEN: The other radio buttons should not be checked and the line edits should not be enabled + assert proxy_widget.no_proxy_radio.isChecked() is False + assert proxy_widget.manual_proxy_radio.isChecked() is False + assert proxy_widget.http_edit.isEnabled() is False + assert proxy_widget.https_edit.isEnabled() is False + assert proxy_widget.username_edit.isEnabled() is False + assert proxy_widget.password_edit.isEnabled() is False -class TestSceenButton(TestCase): - def test_screen_button_initialisation(self): - """ - Test the initialisation of the ScreenButton object - """ - # GIVEN: A mocked screen object - screen_mock = MagicMock(spec=Screen) - screen_mock.number = 0 - screen_mock.__str__.return_value = 'Mocked Screen Object' +def test_radio_button_exclusivity_manual_proxy(settings): + """ + Test that only one radio button can be checked at a time, and that the line edits are only enabled when the + `manual_proxy_radio` is checked + """ + # GIVEN: An instance of the `openlp.core.common.widgets.widgets.ProxyWidget` with a radio already checked + proxy_widget = ProxyWidget() + proxy_widget.no_proxy_radio.setChecked(True) - # WHEN: initialising the ScreenButton object - instance = ScreenButton(None, screen_mock) + # WHEN: 'Checking' the `manual_proxy_radio` button + proxy_widget.manual_proxy_radio.setChecked(True) - # THEN: The ScreenButton should have been initalised correctly with the data from the mocked screen object - assert isinstance(instance, QtWidgets.QPushButton) - assert instance.objectName() == 'screen_0_button' - assert instance.isCheckable() is True - assert instance.text() == 'Mocked Screen Object' + # THEN: The other radio buttons should not be checked and the line edits should be enabled + assert proxy_widget.no_proxy_radio.isChecked() is False + assert proxy_widget.use_sysem_proxy_radio.isChecked() is False + assert proxy_widget.http_edit.isEnabled() is True + assert proxy_widget.https_edit.isEnabled() is True + assert proxy_widget.username_edit.isEnabled() is True + assert proxy_widget.password_edit.isEnabled() is True + + +def test_proxy_widget_load_default_settings(settings): + """ + Test that the default settings are loaded from the config correctly + """ + # GIVEN: And instance of the widget with default settings + proxy_widget = ProxyWidget() + + # WHEN: Calling the `load` method + proxy_widget.load() + + # THEN: The widget should be in its default state + assert proxy_widget.use_sysem_proxy_radio.isChecked() is True + assert proxy_widget.http_edit.text() == '' + assert proxy_widget.https_edit.text() == '' + assert proxy_widget.username_edit.text() == '' + assert proxy_widget.password_edit.text() == '' + + +@patch.object(ProxyWidget, 'load') +def test_proxy_widget_save_no_proxy_settings(proxy_widget_load_patcher, qapp, mock_settings): + """ + Test that the settings are saved correctly + """ + # GIVEN: A Mocked settings instance of the proxy widget with some known values set + proxy_widget = ProxyWidget() + proxy_widget.no_proxy_radio.setChecked(True) + proxy_widget.http_edit.setText('') + proxy_widget.https_edit.setText('') + proxy_widget.username_edit.setText('') + proxy_widget.password_edit.setText('') + + # WHEN: Calling save + proxy_widget.save() + + # THEN: The settings should be set as expected + mock_settings.setValue.assert_has_calls( + [call('advanced/proxy mode', ProxyMode.NO_PROXY), + call('advanced/proxy http', ''), + call('advanced/proxy https', ''), + call('advanced/proxy username', ''), + call('advanced/proxy password', '')]) + + +@patch.object(ProxyWidget, 'load') +def test_proxy_widget_save_manual_settings(proxy_widget_load_patcher, qapp, mock_settings): + """ + Test that the settings are saved correctly + """ + # GIVEN: A Mocked and instance of the proxy widget with some known values set + proxy_widget = ProxyWidget() + proxy_widget.manual_proxy_radio.setChecked(True) + proxy_widget.http_edit.setText('http_proxy_server:port') + proxy_widget.https_edit.setText('https_proxy_server:port') + proxy_widget.username_edit.setText('username') + proxy_widget.password_edit.setText('password') + + # WHEN: Calling save + proxy_widget.save() + + # THEN: The settings should be set as expected + mock_settings.setValue.assert_has_calls( + [call('advanced/proxy mode', ProxyMode.MANUAL_PROXY), + call('advanced/proxy http', 'http_proxy_server:port'), + call('advanced/proxy https', 'https_proxy_server:port'), + call('advanced/proxy username', 'username'), + call('advanced/proxy password', 'password')]) + + +def test_proxy_dialog_init(settings): + """Test that the ProxyDialog is created successfully""" + # GIVEN: ProxyDialog class + # WHEN: It is instantiated + # THEN: There should be no problems + ProxyDialog() + + +def test_proxy_dialog_accept(settings): + """Test that the accept() method of the ProxyDialog works correctly""" + # GIVEN: An instance of a ProxyDialog with a mocked out widget + dlg = ProxyDialog() + dlg.proxy_widget = MagicMock() + + # WHEN: accept() is called + dlg.accept() + + # THEN: The save() method on the widget should have been called + dlg.proxy_widget.save.assert_called_once() + + +def test_screen_button_initialisation(): + """ + Test the initialisation of the ScreenButton object + """ + # GIVEN: A mocked screen object + screen_mock = MagicMock(spec=Screen) + screen_mock.number = 0 + screen_mock.__str__.return_value = 'Mocked Screen Object' + + # WHEN: initialising the ScreenButton object + instance = ScreenButton(None, screen_mock) + + # THEN: The ScreenButton should have been initalised correctly with the data from the mocked screen object + assert isinstance(instance, QtWidgets.QPushButton) + assert instance.objectName() == 'screen_0_button' + assert instance.isCheckable() is True + assert instance.text() == 'Mocked Screen Object' class TestScreenSelectionWidget(TestCase, TestMixin): @@ -405,29 +382,6 @@ class TestScreenSelectionWidget(TestCase, TestMixin): mocked_widget.deleteLater.assert_called_once() mocked_screen_button_group.removeButton.assert_called_once_with(mocked_widget) - def test_save(self): - """ - Test that the save() method saves the screens - """ - # GIVEN: A ScreenSelectionWidget and a bunch o' mocks - mocked_screen = MagicMock(**{'number': 0, 'to_dict.return_value': {'number': 0}}) - instance = ScreenSelectionWidget() - instance._save_screen = MagicMock() - instance.screens = [mocked_screen] - instance.current_screen = mocked_screen - - # WHEN: Save is called - with patch('openlp.core.widgets.widgets.Settings') as MockSettings: - mocked_settings = MagicMock() - MockSettings.return_value = mocked_settings - instance.save() - - # THEN: The right things should happen - instance._save_screen.assert_called_once_with(mocked_screen) - MockSettings.assert_called_once() - mocked_screen.to_dict.assert_called_once() - mocked_settings.setValue.assert_called_once_with('core/screens', {0: {'number': 0}}) - def test_on_identify_timer_shot(self): """ Test that the _on_identify_timer_shot() method removes the labels from the screens @@ -525,3 +479,22 @@ class TestScreenSelectionWidget(TestCase, TestMixin): 'checkbox for that screen.', parent=instance, question=False) assert instance.use_screen_check_box.isChecked() is True assert instance.display_group_box.isChecked() is True + + +def test_screen_selection_save(mock_settings): + """ + Test that the save() method saves the screens + """ + # GIVEN: A ScreenSelectionWidget and a bunch o' mocks + mocked_screen = MagicMock(**{'number': 0, 'to_dict.return_value': {'number': 0}}) + instance = ScreenSelectionWidget() + instance._save_screen = MagicMock() + instance.screens = [mocked_screen] + instance.current_screen = mocked_screen + + instance.save() + + # THEN: The right things should happen + instance._save_screen.assert_called_once_with(mocked_screen) + mocked_screen.to_dict.assert_called_once() + mock_settings.setValue.assert_called_once_with('core/screens', {0: {'number': 0}})