openlp/tests/functional/openlp_core/ui/test_firsttimeform.py

320 lines
17 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
2019-02-14 15:09:09 +00:00
# Copyright (c) 2008-2019 OpenLP Developers #
# --------------------------------------------------------------------------- #
# 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; version 2 of the License. #
# #
# 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, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
Package to test the openlp.core.ui.firsttimeform package.
"""
import os
2015-02-17 21:27:51 +00:00
import tempfile
from unittest import TestCase
from unittest.mock import MagicMock, call, patch, DEFAULT
from openlp.core.common.path import Path
2017-12-28 08:22:55 +00:00
from openlp.core.common.registry import Registry
from openlp.core.ui.firsttimeform import FirstTimeForm, ThemeListWidgetItem
2014-04-15 20:51:55 +00:00
from tests.helpers.testmixin import TestMixin
2018-10-02 04:39:42 +00:00
INVALID_CONFIG = """
{
"_comments": "The most recent version should be added to https://openlp.org/files/frw/download_3.0.json",
"_meta": {
}
"""
class TestThemeListWidgetItem(TestCase):
"""
Test the :class:`ThemeListWidgetItem` class
"""
def setUp(self):
self.sample_theme_data = {'file_name': 'BlueBurst.otz', 'sha256': 'sha_256_hash',
'thumbnail': 'BlueBurst.png', 'title': 'Blue Burst'}
download_worker_patcher = patch('openlp.core.ui.firsttimeform.DownloadWorker')
self.addCleanup(download_worker_patcher.stop)
self.mocked_download_worker = download_worker_patcher.start()
run_thread_patcher = patch('openlp.core.ui.firsttimeform.run_thread')
self.addCleanup(run_thread_patcher.stop)
self.mocked_run_thread = run_thread_patcher.start()
def test_init_sample_data(self):
"""
Test that the theme data is loaded correctly in to a ThemeListWidgetItem object when instantiated
"""
# GIVEN: A sample theme dictanary object
# WHEN: Creating an instance of `ThemeListWidgetItem`
instance = ThemeListWidgetItem('url', self.sample_theme_data, MagicMock())
# THEN: The data should have been set correctly
assert instance.file_name == 'BlueBurst.otz'
assert instance.sha256 == 'sha_256_hash'
assert instance.text() == 'Blue Burst'
assert instance.toolTip() == 'Blue Burst'
self.mocked_download_worker.assert_called_once_with('url', 'BlueBurst.png')
def test_init_download_worker(self):
"""
Test that the `DownloadWorker` worker is set up correctly and that the thread is started.
"""
# GIVEN: A sample theme dictanary object
mocked_ftw = MagicMock(spec=FirstTimeForm)
mocked_ftw.thumbnail_download_threads = []
# WHEN: Creating an instance of `ThemeListWidgetItem`
instance = ThemeListWidgetItem('url', self.sample_theme_data, mocked_ftw)
# THEN: The `DownloadWorker` should have been set up with the appropriate data
self.mocked_download_worker.assert_called_once_with('url', 'BlueBurst.png')
self.mocked_download_worker.download_failed.connect.called_once_with(instance._on_download_failed())
self.mocked_download_worker.download_succeeded.connect.called_once_with(instance._on_thumbnail_downloaded)
self.mocked_run_thread.assert_called_once_with(
self.mocked_download_worker(), 'thumbnail_download_BlueBurst.png')
assert mocked_ftw.thumbnail_download_threads == ['thumbnail_download_BlueBurst.png']
class TestFirstTimeForm(TestCase, TestMixin):
def setUp(self):
self.setup_application()
self.app.setApplicationVersion('0.0')
# Set up a fake "set_normal_cursor" method since we're not dealing with an actual OpenLP application object
self.app.set_normal_cursor = lambda: None
2014-12-12 20:57:42 +00:00
self.app.process_events = lambda: None
Registry.create()
Registry().register('application', self.app)
2015-02-17 21:27:51 +00:00
self.tempfile = os.path.join(tempfile.gettempdir(), 'testfile')
def tearDown(self):
if os.path.isfile(self.tempfile):
os.remove(self.tempfile)
2016-05-31 21:40:13 +00:00
def test_initialise(self):
"""
Test if we can intialise the FirstTimeForm
"""
# GIVEN: A First Time Wizard and an expected screen object
frw = FirstTimeForm(None)
expected_screens = MagicMock()
# WHEN: The First Time Wizard is initialised
frw.initialize(expected_screens)
# THEN: The screens should be set up, and the default values initialised
2017-12-20 17:37:58 +00:00
assert expected_screens == frw.screens, 'The screens should be correct'
assert frw.web_access is True, 'The default value of self.web_access should be True'
assert frw.was_cancelled is False, 'The default value of self.was_cancelled should be False'
assert [] == frw.thumbnail_download_threads, 'The list of threads should be empty'
2017-12-20 17:37:58 +00:00
assert frw.has_run_wizard is False, 'has_run_wizard should be False'
2016-05-31 21:40:13 +00:00
def test_set_defaults(self):
"""
Test that the default values are set when set_defaults() is run
"""
# GIVEN: An initialised FRW and a whole lot of stuff mocked out
frw = FirstTimeForm(None)
frw.initialize(MagicMock())
2019-02-11 21:21:22 +00:00
mocked_settings = MagicMock()
mocked_settings.value.side_effect = lambda key: {'core/has run wizard': False}[key]
with patch.object(frw, 'restart') as mocked_restart, \
patch.object(frw, 'cancel_button') as mocked_cancel_button, \
patch.object(frw, 'no_internet_finish_button') as mocked_no_internet_finish_btn, \
patch.object(frw, 'currentIdChanged') as mocked_currentIdChanged, \
2019-02-11 21:21:22 +00:00
patch.object(frw, 'theme_combo_box') as mocked_theme_combo_box, \
patch.object(frw, 'songs_check_box') as mocked_songs_check_box, \
patch.object(Registry, 'register_function') as mocked_register_function, \
2019-02-11 21:21:22 +00:00
patch('openlp.core.ui.firsttimeform.Settings', return_value=mocked_settings), \
patch('openlp.core.ui.firsttimeform.gettempdir', return_value='temp') as mocked_gettempdir, \
2017-10-07 07:05:07 +00:00
patch('openlp.core.ui.firsttimeform.create_paths') as mocked_create_paths, \
2017-09-20 16:55:21 +00:00
patch.object(frw.application, 'set_normal_cursor'):
2019-02-11 21:21:22 +00:00
mocked_theme_manager = MagicMock()
Registry().register('theme_manager', mocked_theme_manager)
# WHEN: The set_defaults() method is run
frw.set_defaults()
# THEN: The default values should have been set
2019-02-11 21:21:22 +00:00
mocked_restart.assert_called_once()
2019-02-15 22:44:13 +00:00
assert 'https://get.openlp.org/ftw/' == frw.web, 'The default URL should be set'
2019-02-11 21:21:22 +00:00
mocked_cancel_button.clicked.connect.assert_called_once_with(frw.on_cancel_button_clicked)
mocked_no_internet_finish_btn.clicked.connect.assert_called_once_with(
frw.on_no_internet_finish_button_clicked)
mocked_currentIdChanged.connect.assert_called_once_with(frw.on_current_id_changed)
mocked_register_function.assert_called_once_with('config_screen_changed', frw.screen_selection_widget.load)
mocked_no_internet_finish_btn.setVisible.assert_called_once_with(False)
mocked_settings.value.assert_has_calls([call('core/has run wizard')])
mocked_gettempdir.assert_called_once()
mocked_create_paths.assert_called_once_with(Path('temp', 'openlp'))
mocked_theme_combo_box.clear.assert_called_once()
mocked_theme_manager.assert_not_called()
mocked_songs_check_box.assert_not_called()
2019-02-11 21:21:22 +00:00
def test_set_defaults_rerun(self):
"""
2019-02-11 21:21:22 +00:00
Test that the default values are set when set_defaults() is run
"""
2019-02-11 21:21:22 +00:00
# GIVEN: An initialised FRW and a whole lot of stuff mocked out
frw = FirstTimeForm(None)
2019-02-11 21:21:22 +00:00
frw.initialize(MagicMock())
mocked_settings = MagicMock()
mocked_settings.value.side_effect = \
lambda key: {'core/has run wizard': True, 'themes/global theme': 'Default Theme'}[key]
with patch.object(frw, 'restart') as mocked_restart, \
patch.object(frw, 'cancel_button') as mocked_cancel_button, \
patch.object(frw, 'no_internet_finish_button') as mocked_no_internet_finish_btn, \
patch.object(frw, 'currentIdChanged') as mocked_currentIdChanged, \
patch.object(frw, 'theme_combo_box', **{'findText.return_value': 3}) as mocked_theme_combo_box, \
patch.multiple(frw, songs_check_box=DEFAULT, bible_check_box=DEFAULT, presentation_check_box=DEFAULT,
image_check_box=DEFAULT, media_check_box=DEFAULT, custom_check_box=DEFAULT,
2019-02-15 20:47:09 +00:00
song_usage_check_box=DEFAULT, alert_check_box=DEFAULT), \
2019-02-11 21:21:22 +00:00
patch.object(Registry, 'register_function') as mocked_register_function, \
patch('openlp.core.ui.firsttimeform.Settings', return_value=mocked_settings), \
patch('openlp.core.ui.firsttimeform.gettempdir', return_value='temp') as mocked_gettempdir, \
patch('openlp.core.ui.firsttimeform.create_paths') as mocked_create_paths, \
patch.object(frw.application, 'set_normal_cursor'):
mocked_plugin_manager = MagicMock()
mocked_theme_manager = MagicMock(**{'get_themes.return_value': ['b', 'a', 'c']})
Registry().register('plugin_manager', mocked_plugin_manager)
2019-02-11 21:21:22 +00:00
Registry().register('theme_manager', mocked_theme_manager)
# WHEN: The set_defaults() method is run
frw.set_defaults()
# THEN: The default values should have been set
mocked_restart.assert_called_once()
2019-02-15 22:44:13 +00:00
assert 'https://get.openlp.org/ftw/' == frw.web, 'The default URL should be set'
2019-02-11 21:21:22 +00:00
mocked_cancel_button.clicked.connect.assert_called_once_with(frw.on_cancel_button_clicked)
mocked_no_internet_finish_btn.clicked.connect.assert_called_once_with(
frw.on_no_internet_finish_button_clicked)
mocked_currentIdChanged.connect.assert_called_once_with(frw.on_current_id_changed)
mocked_register_function.assert_called_once_with('config_screen_changed', frw.screen_selection_widget.load)
mocked_no_internet_finish_btn.setVisible.assert_called_once_with(False)
mocked_settings.value.assert_has_calls([call('core/has run wizard'), call('themes/global theme')])
mocked_gettempdir.assert_called_once()
mocked_create_paths.assert_called_once_with(Path('temp', 'openlp'))
mocked_theme_manager.get_themes.assert_called_once()
2019-02-11 21:21:22 +00:00
mocked_theme_combo_box.clear.assert_called_once()
mocked_plugin_manager.get_plugin_by_name.assert_has_calls(
[call('songs'), call('bibles'), call('presentations'), call('images'), call('media'), call('custom'),
call('songusage'), call('alerts')], any_order=True)
mocked_plugin_manager.get_plugin_by_name.assert_has_calls([call().is_active()] * 8, any_order=True)
mocked_theme_combo_box.addItems.assert_called_once_with(['a', 'b', 'c'])
2019-02-11 21:21:22 +00:00
mocked_theme_combo_box.findText.assert_called_once_with('Default Theme')
mocked_theme_combo_box.setCurrentIndex(3)
2018-01-04 06:01:35 +00:00
@patch('openlp.core.ui.firsttimeform.time')
@patch('openlp.core.ui.firsttimeform.get_thread_worker')
@patch('openlp.core.ui.firsttimeform.is_thread_finished')
def test_on_cancel_button_clicked(self, mocked_is_thread_finished, mocked_get_thread_worker, mocked_time):
"""
Test that the cancel button click slot shuts down the threads correctly
"""
# GIVEN: A FRW, some mocked threads and workers (that isn't quite done) and other mocked stuff
2018-01-04 06:01:35 +00:00
mocked_worker = MagicMock()
mocked_get_thread_worker.return_value = mocked_worker
mocked_is_thread_finished.side_effect = [False, True]
frw = FirstTimeForm(None)
frw.initialize(MagicMock())
frw.thumbnail_download_threads = ['test_thread']
2018-01-04 06:01:35 +00:00
with patch.object(frw.application, 'set_normal_cursor') as mocked_set_normal_cursor:
# WHEN: on_cancel_button_clicked() is called
frw.on_cancel_button_clicked()
# THEN: The right things should be called in the right order
2017-12-20 17:37:58 +00:00
assert frw.was_cancelled is True, 'The was_cancelled property should have been set to True'
2018-01-04 06:01:35 +00:00
mocked_get_thread_worker.assert_called_once_with('test_thread')
mocked_worker.cancel_download.assert_called_once()
2018-01-04 06:01:35 +00:00
mocked_is_thread_finished.assert_called_with('test_thread')
assert mocked_is_thread_finished.call_count == 2, 'isRunning() should have been called twice'
mocked_time.sleep.assert_called_once_with(0.1)
mocked_set_normal_cursor.assert_called_once_with()
@patch('openlp.core.ui.firsttimeform.critical_error_message_box')
def test__parse_config_invalid_config(self, mocked_critical_error_message_box):
"""
Test `FirstTimeForm._parse_config` when called with invalid data
"""
# GIVEN: An instance of `FirstTimeForm`
first_time_form = FirstTimeForm(None)
# WHEN: Calling _parse_config with a string containing invalid data
result = first_time_form._parse_config(INVALID_CONFIG)
# THEN: _parse_data should return False and the user should have should have been informed.
assert result is False
mocked_critical_error_message_box.assert_called_once()
2015-01-13 19:03:05 +00:00
@patch('openlp.core.ui.firsttimeform.get_web_page')
2015-11-07 00:49:40 +00:00
@patch('openlp.core.ui.firsttimeform.QtWidgets.QMessageBox')
2016-05-31 21:40:13 +00:00
def test_network_error(self, mocked_message_box, mocked_get_web_page):
2015-01-13 19:03:05 +00:00
"""
Test we catch a network error in First Time Wizard - bug 1409627
"""
# GIVEN: Initial setup and mocks
first_time_form = FirstTimeForm(None)
first_time_form.initialize(MagicMock())
2017-09-20 16:55:21 +00:00
mocked_get_web_page.side_effect = ConnectionError('')
mocked_message_box.Ok = 'OK'
2015-01-13 19:03:05 +00:00
# WHEN: the First Time Wizard calls to get the initial configuration
first_time_form._download_index()
# THEN: the critical_error_message_box should have been called
2017-09-20 16:55:21 +00:00
mocked_message_box.critical.assert_called_once_with(
first_time_form, 'Network Error', 'There was a network error attempting to connect to retrieve '
'initial configuration information', 'OK')
@patch('openlp.core.ui.firsttimewizard.Settings')
def test_on_projectors_check_box_checked(self, MockSettings):
"""
Test that the projector panel is shown when the checkbox in the first time wizard is checked
"""
# GIVEN: A First Time Wizard and a mocked settings object
frw = FirstTimeForm(None)
mocked_settings = MagicMock()
mocked_settings.value.return_value = True
MockSettings.return_value = mocked_settings
# WHEN: on_projectors_check_box_clicked() is called
frw.on_projectors_check_box_clicked()
# THEN: The visibility of the projects panel should have been set
mocked_settings.value.assert_called_once_with('projector/show after wizard')
mocked_settings.setValue.assert_called_once_with('projector/show after wizard', False)
@patch('openlp.core.ui.firsttimewizard.Settings')
def test_on_projectors_check_box_unchecked(self, MockSettings):
"""
Test that the projector panel is shown when the checkbox in the first time wizard is checked
"""
# GIVEN: A First Time Wizard and a mocked settings object
frw = FirstTimeForm(None)
mocked_settings = MagicMock()
mocked_settings.value.return_value = False
MockSettings.return_value = mocked_settings
# WHEN: on_projectors_check_box_clicked() is called
frw.on_projectors_check_box_clicked()
# THEN: The visibility of the projects panel should have been set
mocked_settings.value.assert_called_once_with('projector/show after wizard')
mocked_settings.setValue.assert_called_once_with('projector/show after wizard', True)