openlp/tests/openlp_core/widgets/test_views.py

756 lines
35 KiB
Python
Raw Normal View History

2014-10-22 20:44:05 +00:00
# -*- coding: utf-8 -*-
2019-04-13 13:00:22 +00:00
##########################################################################
# OpenLP - Open Source Lyrics Projection #
# ---------------------------------------------------------------------- #
2022-02-01 10:10:57 +00:00
# Copyright (c) 2008-2022 OpenLP Developers #
2019-04-13 13:00:22 +00:00
# ---------------------------------------------------------------------- #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <https://www.gnu.org/licenses/>. #
##########################################################################
2014-10-22 20:44:05 +00:00
"""
2017-10-23 22:09:57 +00:00
Package to test the openlp.core.widgets.views package.
2014-10-22 20:44:05 +00:00
"""
2017-12-17 04:29:53 +00:00
import os
import pytest
2017-10-23 22:09:57 +00:00
from types import GeneratorType
2018-10-02 04:39:42 +00:00
from unittest.mock import MagicMock, call, patch
2021-04-24 16:55:38 +00:00
from PyQt5 import QtWidgets
2017-10-23 22:09:57 +00:00
from openlp.core.common.i18n import UiStrings
2021-04-24 16:55:38 +00:00
from openlp.core.common.registry import Registry
from openlp.core.lib.serviceitem import ServiceItem
2017-12-17 04:29:53 +00:00
from openlp.core.widgets.views import ListPreviewWidget, ListWidgetWithDnD, TreeWidgetWithDnD, handle_mime_data_urls
2018-12-21 15:42:12 +00:00
from openlp.core.ui.icons import UiIcons
2021-04-24 16:55:38 +00:00
from tests.utils.osdinteraction import read_service_from_file
2018-12-21 15:42:12 +00:00
@pytest.fixture
def clapperboard(mock_settings):
return UiIcons().clapperboard
2014-10-22 20:44:05 +00:00
@pytest.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()
2021-04-24 16:55:38 +00:00
@pytest.fixture()
def preview_widget(settings):
main_window = QtWidgets.QMainWindow()
Registry().register('main_window', main_window)
p_widget = ListPreviewWidget(main_window, 2)
return p_widget
2020-02-15 21:04:17 +00:00
def test_files():
"""
Test handle_mime_data_urls when the data points to some files.
"""
# GIVEN: Some mocked objects that return True when is_file is called, and some mocked mime data
mocked_path_instance_1 = MagicMock(**{'is_file.return_value': True})
mocked_path_instance_2 = MagicMock(**{'is_file.return_value': True})
with patch('openlp.core.widgets.views.Path',
side_effect=[mocked_path_instance_1, mocked_path_instance_2]) as mocked_path:
mocked_q_url_1 = MagicMock(**{'toLocalFile.return_value': os.path.join('file', 'test', 'path', '1.ext')})
mocked_q_url_2 = MagicMock(**{'toLocalFile.return_value': os.path.join('file', 'test', 'path', '2.ext')})
mocked_q_mime_data = MagicMock(**{'urls.return_value': [mocked_q_url_1, mocked_q_url_2]})
# WHEN: Calling handle_mime_data_urls with the mocked mime data
result = handle_mime_data_urls(mocked_q_mime_data)
# THEN: Both mocked Path objects should be returned in the list
mocked_path.assert_has_calls([call(os.path.join('file', 'test', 'path', '1.ext')),
call(os.path.join('file', 'test', 'path', '2.ext'))])
assert result == [mocked_path_instance_1, mocked_path_instance_2]
def test_directory():
"""
Test handle_mime_data_urls when the data points to some directories.
"""
# GIVEN: Some mocked objects that return True when is_dir is called, and some mocked mime data
mocked_path_instance_1 = MagicMock()
mocked_path_instance_2 = MagicMock()
mocked_path_instance_3 = MagicMock()
mocked_path_instance_4 = MagicMock(**{'is_file.return_value': False, 'is_directory.return_value': True,
'iterdir.return_value': [mocked_path_instance_1, mocked_path_instance_2]})
mocked_path_instance_5 = MagicMock(**{'is_file.return_value': False, 'is_directory.return_value': True,
'iterdir.return_value': [mocked_path_instance_3]})
with patch('openlp.core.widgets.views.Path',
side_effect=[mocked_path_instance_4, mocked_path_instance_5]) as mocked_path:
mocked_q_url_1 = MagicMock(**{'toLocalFile.return_value': os.path.join('file', 'test', 'path')})
mocked_q_url_2 = MagicMock(**{'toLocalFile.return_value': os.path.join('file', 'test', 'path')})
mocked_q_mime_data = MagicMock(**{'urls.return_value': [mocked_q_url_1, mocked_q_url_2]})
# WHEN: Calling handle_mime_data_urls with the mocked mime data
result = handle_mime_data_urls(mocked_q_mime_data)
# THEN: The three mocked Path file objects should be returned in the list
mocked_path.assert_has_calls([call(os.path.join('file', 'test', 'path')),
call(os.path.join('file', 'test', 'path'))])
assert result == [mocked_path_instance_1, mocked_path_instance_2, mocked_path_instance_3]
2017-12-17 04:29:53 +00:00
def test_new_list_preview_widget(preview_widget_env, mock_settings):
"""
Test that creating an instance of ListPreviewWidget works
"""
# GIVEN: A ListPreviewWidget class
2014-10-22 20:44:05 +00:00
# WHEN: An object is created
list_preview_widget = ListPreviewWidget(None, 1)
2014-10-22 20:44:05 +00:00
# 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'
2014-10-22 20:44:05 +00:00
2016-03-19 08:40:11 +00:00
@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,
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.
# 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'}]
# init ListPreviewWidget and load service item
list_preview_widget = ListPreviewWidget(None, 1)
# 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)
@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.
# 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
# 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, clapperboard):
"""
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
# WHEN: __recalculate_layout() is called (via resizeEvent)
list_preview_widget.resizeEvent(None)
mock_settings.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)
@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, clapperboard):
"""
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')
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)
# 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(mocked_setRowHeight, mocked_resizeRowsToContents,
preview_widget_env, mock_settings, clapperboard):
"""
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')
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
# 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)
# 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)
@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.
# 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)
# 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'
@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, clapperboard):
"""
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.
# 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)
# 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)
# 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_max(mocked_cellWidget, mocked_setRowHeight, mocked_resizeRowsToContents,
preview_widget_env, mock_settings, clapperboard):
"""
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 = 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)
# 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(mocked_cellWidget, mocked_setRowHeight, mocked_resizeRowsToContents,
preview_widget_env, mock_settings, clapperboard):
"""
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.
# 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
# WHEN: row_resized() is called
list_preview_widget.row_resized(0, 100, 150)
# THEN: self.cellWidget(row, 0).children()[1].setMaximumWidth() should fail
assert Exception
@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(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 == 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)
2017-10-23 22:09:57 +00:00
2020-02-15 21:04:17 +00:00
def test_treewidgetwithdnd_clear():
"""
Test the clear method when called without any arguments.
"""
# GIVEN: An instance of ListWidgetWithDnD
widget = ListWidgetWithDnD()
# WHEN: Calling clear with out any arguments
widget.clear()
# THEN: The results text should be the standard 'no results' text.
assert widget.no_results_text == UiStrings().NoResults
def test_clear_search_while_typing():
"""
Test the clear method when called with the search_while_typing argument set to True
"""
# GIVEN: An instance of ListWidgetWithDnD
widget = ListWidgetWithDnD()
# WHEN: Calling clear with search_while_typing set to True
widget.clear(search_while_typing=True)
# THEN: The results text should be the 'short results' text.
assert widget.no_results_text == UiStrings().ShortResults
def test_all_items_no_list_items():
"""
Test allItems when there are no items in the list widget
"""
# GIVEN: An instance of ListWidgetWithDnD
widget = ListWidgetWithDnD()
with patch.object(widget, 'count', return_value=0), \
patch.object(widget, 'item', side_effect=lambda x: [][x]):
# WHEN: Calling allItems
result = widget.allItems()
# THEN: An instance of a Generator object should be returned. The generator should not yeild any results
assert isinstance(result, GeneratorType)
assert list(result) == []
def test_all_items_list_items():
"""
Test allItems when the list widget contains some items.
"""
# GIVEN: An instance of ListWidgetWithDnD
widget = ListWidgetWithDnD()
with patch.object(widget, 'count', return_value=2), \
patch.object(widget, 'item', side_effect=lambda x: [5, 3][x]):
# WHEN: Calling allItems
result = widget.allItems()
# THEN: An instance of a Generator object should be returned. The generator should not yeild any results
assert isinstance(result, GeneratorType)
assert list(result) == [5, 3]
def test_paint_event():
"""
Test the paintEvent method when the list is not empty
"""
# GIVEN: An instance of ListWidgetWithDnD with a mocked out count methode which returns 1
# (i.e the list has an item)
widget = ListWidgetWithDnD()
with patch('openlp.core.widgets.views.QtWidgets.QListWidget.paintEvent') as mocked_paint_event, \
patch.object(widget, 'count', return_value=1), \
patch.object(widget, 'viewport') as mocked_viewport:
mocked_event = MagicMock()
# WHEN: Calling paintEvent
widget.paintEvent(mocked_event)
# THEN: The overridden paintEvnet should have been called
mocked_paint_event.assert_called_once_with(mocked_event)
assert mocked_viewport.called is False
def test_paint_event_no_items():
"""
Test the paintEvent method when the list is empty
"""
# GIVEN: An instance of ListWidgetWithDnD with a mocked out count methode which returns 0
# (i.e the list is empty)
widget = ListWidgetWithDnD()
mocked_painter_instance = MagicMock()
mocked_qrect = MagicMock()
with patch('openlp.core.widgets.views.QtWidgets.QListWidget.paintEvent') as mocked_paint_event, \
patch.object(widget, 'count', return_value=0), \
patch.object(widget, 'viewport'), \
patch('openlp.core.widgets.views.QtGui.QPainter',
return_value=mocked_painter_instance) as mocked_qpainter, \
patch('openlp.core.widgets.views.QtCore.QRect', return_value=mocked_qrect):
mocked_event = MagicMock()
# WHEN: Calling paintEvent
widget.paintEvent(mocked_event)
# THEN: The overridden paintEvnet should have been called, and some text should be drawn.
mocked_paint_event.assert_called_once_with(mocked_event)
mocked_qpainter.assert_called_once_with(widget.viewport())
mocked_painter_instance.drawText.assert_called_once_with(mocked_qrect, 4100, 'No Search Results')
def test_treewidgetwithdnd_constructor():
"""
Test the constructor
"""
# GIVEN: A TreeWidgetWithDnD
# WHEN: An instance is created
widget = TreeWidgetWithDnD(name='Test')
# THEN: It should be initialised correctly
assert widget.mime_data_text == 'Test'
assert widget.allow_internal_dnd is False
assert widget.indentation() == 0
assert widget.isAnimated() is True
2021-04-24 16:55:38 +00:00
def test_initial_slide_count(preview_widget):
"""
Test the initial slide count .
"""
# GIVEN: A new ListPreviewWidget instance.
# WHEN: No SlideItem has been added yet.
# THEN: The count of items should be zero.
assert preview_widget.slide_count() == 0, 'The slide list should be empty.'
def test_initial_slide_number(preview_widget):
"""
Test the initial current slide number.
"""
# GIVEN: A new ListPreviewWidget instance.
# WHEN: No SlideItem has been added yet.
# THEN: The number of the current item should be -1.
assert preview_widget.current_slide_number() == -1, 'The slide number should be -1.'
def test_replace_service_item(preview_widget, state_media):
"""
Test item counts and current number with a service item.
"""
# GIVEN: A ServiceItem with two frames.
service_item = ServiceItem(None)
service = read_service_from_file('serviceitem_image_3.osj')
with patch('os.path.exists') and patch('openlp.core.lib.serviceitem.sha256_file_hash'):
service_item.set_from_service(service[0])
# WHEN: Added to the preview widget.
preview_widget.replace_service_item(service_item, 1, 1)
# THEN: The slide count and number should fit.
assert preview_widget.slide_count() == 2, 'The slide count should be 2.'
assert preview_widget.current_slide_number() == 1, 'The current slide number should be 1.'
def test_change_slide(preview_widget, state_media):
"""
Test the change_slide method.
"""
# GIVEN: A ServiceItem with two frames content.
service_item = ServiceItem(None)
service = read_service_from_file('serviceitem_image_3.osj')
with patch('os.path.exists') and patch('openlp.core.lib.serviceitem.sha256_file_hash'):
service_item.set_from_service(service[0])
# WHEN: Added to the preview widget and switched to the second frame.
preview_widget.replace_service_item(service_item, 1, 0)
preview_widget.change_slide(1)
# THEN: The current_slide_number should reflect the change.
assert preview_widget.current_slide_number() == 1, 'The current slide number should be 1.'