Merge branch 'tests_plugin_5' into 'master'

Tests plugin 5

See merge request openlp/openlp!157
This commit is contained in:
Tim Bentley 2020-03-11 21:53:41 +00:00
commit 73afe240dc
23 changed files with 782 additions and 1076 deletions

View File

@ -96,3 +96,10 @@ def mock_settings(qapp, registry):
def state():
yield State().load_settings()
State._instances = {}
@pytest.fixture()
def state_media(state):
State().add_service("media", 0)
State().update_pre_conditions("media", True)
State().flush_preconditions()

View File

@ -26,7 +26,6 @@ import pytest
from pathlib import Path
from unittest.mock import Mock, MagicMock, patch
from openlp.core.state import State
from openlp.core.common import ThemeLevel, md5_hash
from openlp.core.common.enum import ServiceItemType
from openlp.core.common.registry import Registry
@ -62,13 +61,6 @@ FOOTER = ['Arky Arky (Unknown)', 'Public Domain', 'CCLI 123456']
TEST_PATH = RESOURCE_PATH / 'service'
@pytest.fixture()
def state_env(state):
State().add_service("media", 0)
State().update_pre_conditions("media", True)
State().flush_preconditions()
@pytest.fixture()
def service_item_env(state):
# Mock the renderer and its format_slide method
@ -97,7 +89,7 @@ def test_service_item_basic():
assert service_item.missing_frames() is True, 'There should not be any frames in the service item'
def test_service_item_load_custom_from_service(state_env, settings, service_item_env):
def test_service_item_load_custom_from_service(state_media, settings, service_item_env):
"""
Test the Service Item - adding a custom slide from a saved service
"""
@ -108,9 +100,6 @@ def test_service_item_load_custom_from_service(state_env, settings, service_item
# WHEN: We add a custom from a saved serviceand set the media state
line = convert_file_service_item(TEST_PATH, 'serviceitem_custom_1.osj')
State().add_service("media", 0)
State().update_pre_conditions("media", True)
State().flush_preconditions()
service_item.set_from_service(line)
# THEN: We should get back a valid service item
@ -127,7 +116,7 @@ def test_service_item_load_custom_from_service(state_env, settings, service_item
assert '' == service_item.get_frame_title(2), 'Blank has been returned as the title of slide 3'
def test_service_item_load_image_from_service(state_env, settings):
def test_service_item_load_image_from_service(state_media, settings):
"""
Test the Service Item - adding an image from a saved service
"""
@ -169,7 +158,7 @@ def test_service_item_load_image_from_service(state_env, settings):
@patch('openlp.core.lib.serviceitem.os.path.exists')
@patch('openlp.core.lib.serviceitem.AppLocation.get_section_data_path')
def test_service_item_load_image_from_local_service(mocked_get_section_data_path, mocked_exists, settings, state_env):
def test_service_item_load_image_from_local_service(mocked_get_section_data_path, mocked_exists, settings, state_media):
"""
Test the Service Item - adding an image from a saved local service
"""
@ -293,7 +282,7 @@ def test_add_from_command_for_a_presentation_thumb(mocked_get_section_data_path,
# assert 1 == mocked_image_manager.add_image.call_count, 'image_manager should be used'
def test_service_item_load_optical_media_from_service(state_env):
def test_service_item_load_optical_media_from_service(state_media):
"""
Test the Service Item - load an optical media item
"""
@ -315,7 +304,7 @@ def test_service_item_load_optical_media_from_service(state_env):
assert service_item.media_length == 17.694, 'Media length should be 17.694'
def test_service_item_load_song_and_audio_from_service(state_env, settings, service_item_env):
def test_service_item_load_song_and_audio_from_service(state_media, settings, service_item_env):
"""
Test the Service Item - adding a song slide from a saved service
"""

View File

@ -31,25 +31,10 @@ TEST_PATH = RESOURCE_PATH / 'songs' / 'chordpro'
def test_chordpro(mock_settings):
class TestChordProFileImport(SongImportTestHelper):
def __init__(self, *args, **kwargs):
self.importer_class_name = 'ChordProImport'
self.importer_module_name = 'chordpro'
super().__init__(*args, **kwargs)
def test_song_import(self):
"""
Test that loading an ChordPro file works correctly on various files
"""
# Mock out the settings - always return False
Registry().get('settings').value.side_effect = lambda value: True \
if value == 'songs/enable chords' else False
# Do the test import
self.file_import([TEST_PATH / 'swing-low.chordpro'],
self.load_external_result_data(TEST_PATH / 'swing-low.json'))
test_file_import = TestChordProFileImport()
test_file_import = SongImportTestHelper('ChordProImport', 'chordpro')
test_file_import.setUp()
test_file_import.test_song_import()
Registry().get('settings').value.side_effect = lambda value: True if value == 'songs/enable chords' else False
# Do the test import
test_file_import.file_import([TEST_PATH / 'swing-low.chordpro'],
test_file_import.load_external_result_data(TEST_PATH / 'swing-low.json'))
test_file_import.tearDown()

View File

@ -30,23 +30,10 @@ TEST_PATH = RESOURCE_PATH / 'songs' / 'easyslides'
def test_easyslides(mock_settings):
class TestEasySlidesFileImport(SongImportTestHelper):
def __init__(self, *args, **kwargs):
self.importer_class_name = 'EasySlidesImport'
self.importer_module_name = 'easyslides'
super().__init__(*args, **kwargs)
def test_song_import(self):
"""
Test that loading an EasySlides file works correctly on various files
"""
self.file_import(TEST_PATH / 'amazing-grace.xml',
self.load_external_result_data(TEST_PATH / 'Amazing Grace.json'))
self.file_import(TEST_PATH / 'Export_2017-01-12_BB.xml',
self.load_external_result_data(TEST_PATH / 'Export_2017-01-12_BB.json'))
test_file_import = TestEasySlidesFileImport()
test_file_import = SongImportTestHelper('EasySlidesImport', 'easyslides')
test_file_import.setUp()
test_file_import.test_song_import()
test_file_import.file_import(TEST_PATH / 'amazing-grace.xml',
test_file_import.load_external_result_data(TEST_PATH / 'Amazing Grace.json'))
test_file_import.file_import(TEST_PATH / 'Export_2017-01-12_BB.xml',
test_file_import.load_external_result_data(TEST_PATH / 'Export_2017-01-12_BB.json'))
test_file_import.tearDown()

View File

@ -21,88 +21,68 @@
"""
This module contains tests for the lib submodule of the Songs plugin.
"""
from unittest import TestCase
import pytest
from unittest.mock import MagicMock, patch
from PyQt5 import QtCore
from openlp.core.common.registry import Registry
from openlp.plugins.songs.forms.editsongform import EditSongForm
from tests.helpers.testmixin import TestMixin
class TestEditSongForm(TestCase, TestMixin):
@pytest.fixture()
def edit_song_form():
with patch('openlp.plugins.songs.forms.editsongform.EditSongForm.__init__', return_value=None):
return EditSongForm(None, MagicMock(), MagicMock())
def test_validate_matching_tags(edit_song_form):
# Given a set of tags
tags = ['{r}', '{/r}', '{bl}', '{/bl}', '{su}', '{/su}']
# WHEN we validate them
valid = edit_song_form._validate_tags(tags)
# THEN they should be valid
assert valid is True, "The tags list should be valid"
def test_validate_nonmatching_tags(edit_song_form):
# Given a set of tags
tags = ['{r}', '{/r}', '{bl}', '{/bl}', '{br}', '{su}', '{/su}']
# WHEN we validate them
valid = edit_song_form._validate_tags(tags)
# THEN they should be valid
assert valid is True, "The tags list should be valid"
@patch('openlp.plugins.songs.forms.editsongform.set_case_insensitive_completer')
def test_load_objects(mocked_set_case_insensitive_completer, edit_song_form, settings):
"""
Test the functions in the :mod:`lib` module.
Test the _load_objects() method
"""
def setUp(self):
"""
Set up the components need for all tests.
"""
Registry.create()
Registry().register('service_list', MagicMock())
Registry().register('main_window', MagicMock())
self.setup_application()
self.build_settings()
Registry().register('settings', self.setting)
with patch('openlp.plugins.songs.forms.editsongform.EditSongForm.__init__', return_value=None):
self.edit_song_form = EditSongForm(None, MagicMock(), MagicMock())
QtCore.QLocale.setDefault(QtCore.QLocale('en_GB'))
# GIVEN: A song edit form and some mocked stuff
mocked_class = MagicMock()
mocked_class.name = 'Author'
mocked_combo = MagicMock()
mocked_combo.count.return_value = 0
mocked_cache = MagicMock()
mocked_object = MagicMock()
mocked_object.name = 'Charles'
mocked_object.id = 1
mocked_manager = MagicMock()
mocked_manager.get_all_objects.return_value = [mocked_object]
edit_song_form.manager = mocked_manager
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault
"""
self.destroy_settings()
# WHEN: _load_objects() is called
edit_song_form._load_objects(mocked_class, mocked_combo, mocked_cache)
def test_validate_matching_tags(self):
# Given a set of tags
tags = ['{r}', '{/r}', '{bl}', '{/bl}', '{su}', '{/su}']
# WHEN we validate them
valid = self.edit_song_form._validate_tags(tags)
# THEN they should be valid
assert valid is True, "The tags list should be valid"
def test_validate_nonmatching_tags(self):
# Given a set of tags
tags = ['{r}', '{/r}', '{bl}', '{/bl}', '{br}', '{su}', '{/su}']
# WHEN we validate them
valid = self.edit_song_form._validate_tags(tags)
# THEN they should be valid
assert valid is True, "The tags list should be valid"
@patch('openlp.plugins.songs.forms.editsongform.set_case_insensitive_completer')
def test_load_objects(self, mocked_set_case_insensitive_completer):
"""
Test the _load_objects() method
"""
# GIVEN: A song edit form and some mocked stuff
mocked_class = MagicMock()
mocked_class.name = 'Author'
mocked_combo = MagicMock()
mocked_combo.count.return_value = 0
mocked_cache = MagicMock()
mocked_object = MagicMock()
mocked_object.name = 'Charles'
mocked_object.id = 1
mocked_manager = MagicMock()
mocked_manager.get_all_objects.return_value = [mocked_object]
self.edit_song_form.manager = mocked_manager
# WHEN: _load_objects() is called
self.edit_song_form._load_objects(mocked_class, mocked_combo, mocked_cache)
# THEN: All the correct methods should have been called
self.edit_song_form.manager.get_all_objects.assert_called_once_with(mocked_class)
mocked_combo.clear.assert_called_once_with()
mocked_combo.count.assert_called_once_with()
mocked_combo.addItem.assert_called_once_with('Charles')
mocked_cache.append.assert_called_once_with('Charles')
mocked_combo.setItemData.assert_called_once_with(0, 1)
mocked_set_case_insensitive_completer.assert_called_once_with(mocked_cache, mocked_combo)
mocked_combo.setCurrentIndex.assert_called_once_with(-1)
mocked_combo.setCurrentText.assert_called_once_with('')
# THEN: All the correct methods should have been called
edit_song_form.manager.get_all_objects.assert_called_once_with(mocked_class)
mocked_combo.clear.assert_called_once_with()
mocked_combo.count.assert_called_once_with()
mocked_combo.addItem.assert_called_once_with('Charles')
mocked_cache.append.assert_called_once_with('Charles')
mocked_combo.setItemData.assert_called_once_with(0, 1)
mocked_set_case_insensitive_completer.assert_called_once_with(mocked_cache, mocked_combo)
mocked_combo.setCurrentIndex.assert_called_once_with(-1)
mocked_combo.setCurrentText.assert_called_once_with('')

View File

@ -21,94 +21,76 @@
"""
This module contains tests for the editverseform of the Songs plugin.
"""
from unittest import TestCase
import pytest
from unittest.mock import MagicMock
from PyQt5 import QtCore
from openlp.core.common.registry import Registry
from openlp.plugins.songs.forms.editverseform import EditVerseForm
from tests.helpers.testmixin import TestMixin
class TestEditVerseForm(TestCase, TestMixin):
@pytest.fixture()
def edit_verse_form(settings):
return EditVerseForm(None)
def test_update_suggested_verse_number_has_no_effect(edit_verse_form):
"""
Test the functions in the :mod:`lib` module.
Test that update_suggested_verse_number() has no effect when editing a single verse
"""
def setUp(self):
"""
Set up the components need for all tests.
"""
self.setup_application()
self.build_settings()
self.setting.setValue('songs/enable chords', True)
Registry.create()
Registry().register('settings', self.setting)
self.edit_verse_form = EditVerseForm(None)
QtCore.QLocale.setDefault(QtCore.QLocale('en_GB'))
# GIVEN some input values
edit_verse_form.has_single_verse = True
edit_verse_form.verse_type_combo_box.currentIndex = MagicMock(return_value=0)
edit_verse_form.verse_text_edit.toPlainText = MagicMock(return_value='Text')
edit_verse_form.verse_number_box.setValue(3)
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault
"""
self.destroy_settings()
# WHEN the method is called
edit_verse_form.update_suggested_verse_number()
def test_update_suggested_verse_number_has_no_effect(self):
"""
Test that update_suggested_verse_number() has no effect when editing a single verse
"""
# GIVEN some input values
self.edit_verse_form.has_single_verse = True
self.edit_verse_form.verse_type_combo_box.currentIndex = MagicMock(return_value=0)
self.edit_verse_form.verse_text_edit.toPlainText = MagicMock(return_value='Text')
self.edit_verse_form.verse_number_box.setValue(3)
# THEN the verse number must not be changed
assert 3 == edit_verse_form.verse_number_box.value(), 'The verse number should be 3'
# WHEN the method is called
self.edit_verse_form.update_suggested_verse_number()
# THEN the verse number must not be changed
assert 3 == self.edit_verse_form.verse_number_box.value(), 'The verse number should be 3'
def test_update_suggested_verse_number_different_type(edit_verse_form):
"""
Test that update_suggested_verse_number() returns 0 when editing a second verse of a different type
"""
# GIVEN some input values
edit_verse_form.has_single_verse = False
edit_verse_form.verse_type_combo_box.currentIndex = MagicMock(return_value=2)
edit_verse_form.verse_text_edit.toPlainText = MagicMock(return_value='Text')
edit_verse_form.verse_number_box.setValue(3)
def test_update_suggested_verse_number_different_type(self):
"""
Test that update_suggested_verse_number() returns 0 when editing a second verse of a different type
"""
# GIVEN some input values
self.edit_verse_form.has_single_verse = False
self.edit_verse_form.verse_type_combo_box.currentIndex = MagicMock(return_value=2)
self.edit_verse_form.verse_text_edit.toPlainText = MagicMock(return_value='Text')
self.edit_verse_form.verse_number_box.setValue(3)
# WHEN the method is called
edit_verse_form.update_suggested_verse_number()
# WHEN the method is called
self.edit_verse_form.update_suggested_verse_number()
# THEN the verse number must be changed to 1
assert 1 == edit_verse_form.verse_number_box.value(), 'The verse number should be 1'
# THEN the verse number must be changed to 1
assert 1 == self.edit_verse_form.verse_number_box.value(), 'The verse number should be 1'
def test_on_divide_split_button_clicked(self):
"""
Test that divide adds text at the correct position
"""
# GIVEN some input values
self.edit_verse_form.verse_type_combo_box.currentIndex = MagicMock(return_value=4)
self.edit_verse_form.verse_text_edit.setPlainText('Text\n')
def test_on_divide_split_button_clicked(edit_verse_form):
"""
Test that divide adds text at the correct position
"""
# GIVEN some input values
edit_verse_form.verse_type_combo_box.currentIndex = MagicMock(return_value=4)
edit_verse_form.verse_text_edit.setPlainText('Text\n')
# WHEN the method is called
self.edit_verse_form.on_forced_split_button_clicked()
# THEN the verse number must not be changed
assert '[--}{--]\nText\n' == self.edit_verse_form.verse_text_edit.toPlainText(), \
'The verse number should be [--}{--]\nText\n'
# WHEN the method is called
edit_verse_form.on_forced_split_button_clicked()
# THEN the verse number must not be changed
assert '[--}{--]\nText\n' == edit_verse_form.verse_text_edit.toPlainText(), \
'The verse number should be [--}{--]\nText\n'
def test_on_split_button_clicked(self):
"""
Test that divide adds text at the correct position
"""
# GIVEN some input values
self.edit_verse_form.verse_type_combo_box.currentIndex = MagicMock(return_value=4)
self.edit_verse_form.verse_text_edit.setPlainText('Text\n')
# WHEN the method is called
self.edit_verse_form.on_overflow_split_button_clicked()
# THEN the verse number must not be changed
assert '[---]\nText\n' == self.edit_verse_form.verse_text_edit.toPlainText(), \
'The verse number should be [---]\nText\n'
def test_on_split_button_clicked(edit_verse_form):
"""
Test that divide adds text at the correct position
"""
# GIVEN some input values
edit_verse_form.verse_type_combo_box.currentIndex = MagicMock(return_value=4)
edit_verse_form.verse_text_edit.setPlainText('Text\n')
# WHEN the method is called
edit_verse_form.on_overflow_split_button_clicked()
# THEN the verse number must not be changed
assert '[---]\nText\n' == edit_verse_form.verse_text_edit.toPlainText(), \
'The verse number should be [---]\nText\n'

View File

@ -30,25 +30,12 @@ TEST_PATH = RESOURCE_PATH / 'songs' / 'lyrix'
def test_Lyrix(mock_settings):
class TestLyrixFileImport(SongImportTestHelper):
def __init__(self, *args, **kwargs):
self.importer_class_name = 'LyrixImport'
self.importer_module_name = 'lyrix'
super(TestLyrixFileImport, self).__init__(*args, **kwargs)
def test_song_import(self):
"""
Test that loading an LyriX file works correctly on various files
"""
self.file_import([TEST_PATH / 'A06.TXT'],
self.load_external_result_data(TEST_PATH / 'Amazing Grace.json'))
self.file_import([TEST_PATH / 'A002.TXT'],
self.load_external_result_data(TEST_PATH / 'Amazing Grace2.json'))
self.file_import([TEST_PATH / 'AO05.TXT'],
self.load_external_result_data(TEST_PATH / 'in die regterhand.json'))
test_file_import = TestLyrixFileImport()
test_file_import = SongImportTestHelper('LyrixImport', 'lyrix')
test_file_import.setUp()
test_file_import.test_song_import()
test_file_import.file_import([TEST_PATH / 'A06.TXT'],
test_file_import.load_external_result_data(TEST_PATH / 'Amazing Grace.json'))
test_file_import.file_import([TEST_PATH / 'A002.TXT'],
test_file_import.load_external_result_data(TEST_PATH / 'Amazing Grace2.json'))
test_file_import.file_import([TEST_PATH / 'AO05.TXT'],
test_file_import.load_external_result_data(TEST_PATH / 'in die regterhand.json'))
test_file_import.tearDown()

View File

@ -31,23 +31,10 @@ TEST_PATH = RESOURCE_PATH / 'songs' / 'powerpraise'
def test_power_praise(mock_settings):
class TestPowerPraiseFileImport(SongImportTestHelper):
def __init__(self, *args, **kwargs):
self.importer_class_name = 'PowerPraiseImport'
self.importer_module_name = 'powerpraise'
super(TestPowerPraiseFileImport, self).__init__(*args, **kwargs)
def test_song_import(self):
"""
Test that loading a PowerPraise file works correctly
"""
self.file_import([TEST_PATH / 'Naher, mein Gott zu Dir.ppl'],
self.load_external_result_data(TEST_PATH / 'Naher, mein Gott zu Dir.json'))
self.file_import([TEST_PATH / 'You are so faithful.ppl'],
self.load_external_result_data(TEST_PATH / 'You are so faithful.json'))
test_file_import = TestPowerPraiseFileImport()
test_file_import = SongImportTestHelper('PowerPraiseImport', 'powerpraise')
test_file_import.setUp()
test_file_import.test_song_import()
test_file_import.file_import([TEST_PATH / 'Naher, mein Gott zu Dir.ppl'],
test_file_import.load_external_result_data(TEST_PATH / 'Naher, mein Gott zu Dir.json'))
test_file_import.file_import([TEST_PATH / 'You are so faithful.ppl'],
test_file_import.load_external_result_data(TEST_PATH / 'You are so faithful.json'))
test_file_import.tearDown()

View File

@ -21,9 +21,6 @@
"""
This module contains tests for the PresentationManager song importer.
"""
from unittest import skipIf
from openlp.core.common import is_macosx
from tests.helpers.songfileimport import SongImportTestHelper
from tests.utils.constants import RESOURCE_PATH
@ -33,24 +30,11 @@ TEST_PATH = RESOURCE_PATH / 'songs' / 'presentationmanager'
def test_presenter_manager(mock_settings):
class TestPresentationManagerFileImport(SongImportTestHelper):
def __init__(self, *args, **kwargs):
self.importer_class_name = 'PresentationManagerImport'
self.importer_module_name = 'presentationmanager'
super(TestPresentationManagerFileImport, self).__init__(*args, **kwargs)
@skipIf(is_macosx(), 'This test fails for an undetermined reason on macOS')
def test_song_import(self):
"""
Test that loading a PresentationManager file works correctly
"""
self.file_import([TEST_PATH / 'Great Is Thy Faithfulness.sng'],
self.load_external_result_data(TEST_PATH / 'Great Is Thy Faithfulness.json'))
self.file_import([TEST_PATH / 'Amazing Grace.sng'],
self.load_external_result_data(TEST_PATH / 'Amazing Grace.json'))
test_file_import = TestPresentationManagerFileImport()
test_file_import = SongImportTestHelper('PresentationManagerImport', 'presentationmanager')
test_file_import.setUp()
test_file_import.test_song_import()
test_file_import.file_import([TEST_PATH / 'Great Is Thy Faithfulness.sng'],
test_file_import.load_external_result_data(TEST_PATH /
'Great Is Thy Faithfulness.json'))
test_file_import.file_import([TEST_PATH / 'Amazing Grace.sng'],
test_file_import.load_external_result_data(TEST_PATH / 'Amazing Grace.json'))
test_file_import.tearDown()

View File

@ -31,21 +31,8 @@ TEST_PATH = RESOURCE_PATH / 'songs' / 'songpro'
def test_song_pro(mock_settings):
class TestSongProFileImport(SongImportTestHelper):
def __init__(self, *args, **kwargs):
self.importer_class_name = 'SongProImport'
self.importer_module_name = 'songpro'
super(TestSongProFileImport, self).__init__(*args, **kwargs)
def test_song_import(self):
"""
Test that loading an SongPro file works correctly
"""
self.file_import(TEST_PATH / 'amazing-grace.txt',
self.load_external_result_data(TEST_PATH / 'Amazing Grace.json'))
test_file_import = TestSongProFileImport()
test_file_import = SongImportTestHelper('SongProImport', 'songpro')
test_file_import.setUp()
test_file_import.test_song_import()
test_file_import.file_import(TEST_PATH / 'amazing-grace.txt',
test_file_import.load_external_result_data(TEST_PATH / 'Amazing Grace.json'))
test_file_import.tearDown()

View File

@ -35,29 +35,18 @@ TEST_PATH = RESOURCE_PATH / 'songs' / 'songshowplus'
def test_song_show_plus(mock_settings):
class TestSongShowPlusFileImport(SongImportTestHelper):
def __init__(self, *args, **kwargs):
self.importer_class_name = 'SongShowPlusImport'
self.importer_module_name = 'songshowplus'
super(TestSongShowPlusFileImport, self).__init__(*args, **kwargs)
def test_song_import(self):
"""
Test that loading a SongShow Plus file works correctly on various files
"""
self.file_import([TEST_PATH / 'Amazing Grace.sbsong'],
self.load_external_result_data(TEST_PATH / 'Amazing Grace.json'))
self.file_import([TEST_PATH / 'Beautiful Garden Of Prayer.sbsong'],
self.load_external_result_data(TEST_PATH / 'Beautiful Garden Of Prayer.json'))
self.file_import([TEST_PATH / 'a mighty fortress is our god.sbsong'],
self.load_external_result_data(TEST_PATH / 'a mighty fortress is our god.json'))
self.file_import([TEST_PATH / 'cleanse-me.sbsong'],
self.load_external_result_data(TEST_PATH / 'cleanse-me.json'))
test_file_import = TestSongShowPlusFileImport()
test_file_import = SongImportTestHelper('SongShowPlusImport', 'songshowplus')
test_file_import.setUp()
test_file_import.test_song_import()
test_file_import.file_import([TEST_PATH / 'Amazing Grace.sbsong'],
test_file_import.load_external_result_data(TEST_PATH / 'Amazing Grace.json'))
test_file_import.file_import([TEST_PATH / 'Beautiful Garden Of Prayer.sbsong'],
test_file_import.load_external_result_data(TEST_PATH /
'Beautiful Garden Of Prayer.json'))
test_file_import.file_import([TEST_PATH / 'a mighty fortress is our god.sbsong'],
test_file_import.load_external_result_data(TEST_PATH /
'a mighty fortress is our god.json'))
test_file_import.file_import([TEST_PATH / 'cleanse-me.sbsong'],
test_file_import.load_external_result_data(TEST_PATH / 'cleanse-me.json'))
test_file_import.tearDown()

View File

@ -32,24 +32,11 @@ TEST_PATH = RESOURCE_PATH / 'songs' / 'sundayplus'
def test_sunday_plus(mock_settings):
class TestSundayPlusFileImport(SongImportTestHelper):
def __init__(self, *args, **kwargs):
self.importer_class_name = 'SundayPlusImport'
self.importer_module_name = 'sundayplus'
super(TestSundayPlusFileImport, self).__init__(*args, **kwargs)
def test_song_import(self):
"""
Test that loading an SundayPlus file works correctly on various files
"""
with patch('openlp.plugins.songs.lib.importers.sundayplus.retrieve_windows_encoding') as \
mocked_retrieve_windows_encoding:
mocked_retrieve_windows_encoding.return_value = 'cp1252'
self.file_import([TEST_PATH / 'Amazing Grace.ptf'],
self.load_external_result_data(TEST_PATH / 'Amazing Grace.json'))
test_file_import = TestSundayPlusFileImport()
test_file_import = SongImportTestHelper('SundayPlusImport', 'sundayplus')
test_file_import.setUp()
test_file_import.test_song_import()
with patch('openlp.plugins.songs.lib.importers.sundayplus.retrieve_windows_encoding') as \
mocked_retrieve_windows_encoding:
mocked_retrieve_windows_encoding.return_value = 'cp1252'
test_file_import.file_import([TEST_PATH / 'Amazing Grace.ptf'],
test_file_import.load_external_result_data(TEST_PATH / 'Amazing Grace.json'))
test_file_import.tearDown()

View File

@ -31,27 +31,12 @@ TEST_PATH = RESOURCE_PATH / 'songs' / 'videopsalm'
def test_video_psalms(mock_settings):
class TestVideoPsalmFileImport(SongImportTestHelper):
def __init__(self, *args, **kwargs):
self.importer_class_name = 'VideoPsalmImport'
self.importer_module_name = 'videopsalm'
super(TestVideoPsalmFileImport, self).__init__(*args, **kwargs)
def test_song_import(self):
"""
Test that loading an VideoPsalm file works correctly on various files
"""
# Mock out the settings - always return False
Registry().get('settings').value.side_effect = lambda value: True \
if value == 'songs/enable chords' else False
# Do the test import
self.file_import(TEST_PATH / 'videopsalm-as-safe-a-stronghold.json',
self.load_external_result_data(TEST_PATH / 'as-safe-a-stronghold.json'))
self.file_import(TEST_PATH / 'videopsalm-as-safe-a-stronghold2.json',
self.load_external_result_data(TEST_PATH / 'as-safe-a-stronghold2.json'))
test_file_import = TestVideoPsalmFileImport()
test_file_import = SongImportTestHelper('VideoPsalmImport', 'videopsalm')
test_file_import.setUp()
test_file_import.test_song_import()
Registry().get('settings').value.side_effect = lambda value: True if value == 'songs/enable chords' else False
# Do the test import
test_file_import.file_import(TEST_PATH / 'videopsalm-as-safe-a-stronghold.json',
test_file_import.load_external_result_data(TEST_PATH / 'as-safe-a-stronghold.json'))
test_file_import.file_import(TEST_PATH / 'videopsalm-as-safe-a-stronghold2.json',
test_file_import.load_external_result_data(TEST_PATH / 'as-safe-a-stronghold2.json'))
test_file_import.tearDown()

View File

@ -29,26 +29,14 @@ from tests.utils.constants import RESOURCE_PATH
TEST_PATH = RESOURCE_PATH / 'songs' / 'worshipassistant'
def test_chordpro(mock_settings):
def test_worshipassistant(mock_settings):
class TestWorshipAssistantFileImport(SongImportTestHelper):
def __init__(self, *args, **kwargs):
self.importer_class_name = 'WorshipAssistantImport'
self.importer_module_name = 'worshipassistant'
super(TestWorshipAssistantFileImport, self).__init__(*args, **kwargs)
def test_song_import(self):
"""
Test that loading an Worship Assistant file works correctly
"""
self.file_import(TEST_PATH / 'du_herr.csv', self.load_external_result_data(TEST_PATH / 'du_herr.json'))
self.file_import(TEST_PATH / 'would_you_be_free.csv',
self.load_external_result_data(TEST_PATH / 'would_you_be_free.json'))
self.file_import(TEST_PATH / 'would_you_be_free2.csv',
self.load_external_result_data(TEST_PATH / 'would_you_be_free.json'))
test_file_import = TestWorshipAssistantFileImport()
test_file_import = SongImportTestHelper('WorshipAssistantImport', 'worshipassistant')
test_file_import.setUp()
test_file_import.test_song_import()
test_file_import.file_import(TEST_PATH / 'du_herr.csv',
test_file_import.load_external_result_data(TEST_PATH / 'du_herr.json'))
test_file_import.file_import(TEST_PATH / 'would_you_be_free.csv',
test_file_import.load_external_result_data(TEST_PATH / 'would_you_be_free.json'))
test_file_import.file_import(TEST_PATH / 'would_you_be_free2.csv',
test_file_import.load_external_result_data(TEST_PATH / 'would_you_be_free.json'))
test_file_import.tearDown()

View File

@ -49,20 +49,8 @@ def test_create_importer(registry):
def test_zion_wrox(mock_settings):
class TestZionWorxFileImport(SongImportTestHelper):
def __init__(self, *args, **kwargs):
self.importer_class_name = 'ZionWorxImport'
self.importer_module_name = 'zionworx'
super(TestZionWorxFileImport, self).__init__(*args, **kwargs)
def test_song_import(self):
"""
Test that loading an ZionWorx file works correctly on various files
"""
self.file_import(TEST_PATH / 'zionworx.csv', self.load_external_result_data(TEST_PATH / 'zionworx.json'))
test_file_import = TestZionWorxFileImport()
test_file_import = SongImportTestHelper('ZionWorxImport', 'zionworx')
test_file_import.setUp()
test_file_import.test_song_import()
test_file_import.file_import(TEST_PATH / 'zionworx.csv',
test_file_import.load_external_result_data(TEST_PATH / 'zionworx.json'))
test_file_import.tearDown()

View File

@ -34,7 +34,8 @@ class SongImportTestHelper(object):
This class is designed to be a helper class to reduce repetition when testing the import of song files.
"""
def __init__(self, *args, **kwargs):
super(SongImportTestHelper, self).__init__(*args, **kwargs)
self.importer_class_name = args[0]
self.importer_module_name = args[1]
self.importer_module = __import__('openlp.plugins.songs.lib.importers.%s' %
self.importer_module_name, fromlist=[self.importer_class_name])
self.importer_class = getattr(self.importer_module, self.importer_class_name)

View File

@ -21,69 +21,54 @@
"""
Package to test the openlp.core.ui package.
"""
from unittest import TestCase
import pytest
from unittest.mock import patch
from PyQt5 import QtCore, QtTest, QtWidgets
from PyQt5 import QtCore, QtTest
from openlp.core.common.registry import Registry
from openlp.core.ui import servicenoteform
from tests.helpers.testmixin import TestMixin
from openlp.core.ui.servicenoteform import ServiceNoteForm
class TestStartNoteDialog(TestCase, TestMixin):
@pytest.fixture()
def form(settings):
frm = ServiceNoteForm()
return frm
def setUp(self):
"""
Create the UI
"""
Registry.create()
self.setup_application()
self.main_window = QtWidgets.QMainWindow()
Registry().register('main_window', self.main_window)
self.form = servicenoteform.ServiceNoteForm()
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault
"""
del self.form
del self.main_window
def test_basic_display(form):
"""
Test Service Note form functionality
"""
# GIVEN: A dialog with an empty text box
form.text_edit.setPlainText('')
def test_basic_display(self):
"""
Test Service Note form functionality
"""
# GIVEN: A dialog with an empty text box
self.form.text_edit.setPlainText('')
# WHEN displaying the UI and pressing enter
with patch('PyQt5.QtWidgets.QDialog.exec'):
form.exec()
ok_widget = form.button_box.button(form.button_box.Save)
QtTest.QTest.mouseClick(ok_widget, QtCore.Qt.LeftButton)
# WHEN displaying the UI and pressing enter
with patch('PyQt5.QtWidgets.QDialog.exec'):
self.form.exec()
ok_widget = self.form.button_box.button(self.form.button_box.Save)
QtTest.QTest.mouseClick(ok_widget, QtCore.Qt.LeftButton)
# THEN the following input text is returned
assert form.text_edit.toPlainText() == '', 'The returned text should be empty'
# THEN the following input text is returned
assert self.form.text_edit.toPlainText() == '', 'The returned text should be empty'
# WHEN displaying the UI, having set the text and pressing enter
text = 'OpenLP is the best worship software'
form.text_edit.setPlainText(text)
with patch('PyQt5.QtWidgets.QDialog.exec'):
form.exec()
ok_widget = form.button_box.button(form.button_box.Save)
QtTest.QTest.mouseClick(ok_widget, QtCore.Qt.LeftButton)
# WHEN displaying the UI, having set the text and pressing enter
text = 'OpenLP is the best worship software'
self.form.text_edit.setPlainText(text)
with patch('PyQt5.QtWidgets.QDialog.exec'):
self.form.exec()
ok_widget = self.form.button_box.button(self.form.button_box.Save)
QtTest.QTest.mouseClick(ok_widget, QtCore.Qt.LeftButton)
# THEN the following text is returned
assert form.text_edit.toPlainText() == text, 'The text originally entered should still be there'
# THEN the following text is returned
assert self.form.text_edit.toPlainText() == text, 'The text originally entered should still be there'
# WHEN displaying the UI, having set the text and pressing enter
form.text_edit.setPlainText('')
with patch('PyQt5.QtWidgets.QDialog.exec'):
form.exec()
form.text_edit.setPlainText(text)
ok_widget = form.button_box.button(form.button_box.Save)
QtTest.QTest.mouseClick(ok_widget, QtCore.Qt.LeftButton)
# WHEN displaying the UI, having set the text and pressing enter
self.form.text_edit.setPlainText('')
with patch('PyQt5.QtWidgets.QDialog.exec'):
self.form.exec()
self.form.text_edit.setPlainText(text)
ok_widget = self.form.button_box.button(self.form.button_box.Save)
QtTest.QTest.mouseClick(ok_widget, QtCore.Qt.LeftButton)
# THEN the following text is returned
assert self.form.text_edit.toPlainText() == text, 'The new text should be returned'
# THEN the following text is returned
assert form.text_edit.toPlainText() == text, 'The new text should be returned'

View File

@ -21,172 +21,152 @@
"""
Package to test the openlp.core.lib.settingsform package.
"""
from unittest import TestCase
import pytest
from unittest.mock import MagicMock, patch
from PyQt5 import QtCore, QtTest
from openlp.core.common.registry import Registry
from openlp.core.display.screens import ScreenList
from openlp.core.ui import settingsform
from tests.helpers.testmixin import TestMixin
from openlp.core.ui.settingsform import SettingsForm
SCREEN = {
'primary': False,
'number': 1,
'size': QtCore.QRect(0, 0, 1024, 768)
}
@pytest.fixture()
def form(mock_settings):
frm = SettingsForm()
return frm
class TestSettingsForm(TestCase, TestMixin):
@pytest.fixture()
def dummy():
return MagicMock(), MagicMock(), MagicMock()
def test_basic_cancel(form):
"""
Test the PluginManager class
Test running the settings form and pressing Cancel
"""
# GIVEN: An initial form
def setUp(self):
"""
Some pre-test setup required.
"""
self.dummy1 = MagicMock()
self.dummy2 = MagicMock()
self.dummy3 = MagicMock()
self.desktop = MagicMock()
self.setup_application()
self.desktop.primaryScreen.return_value = SCREEN['primary']
self.desktop.screenCount.return_value = SCREEN['number']
self.desktop.screenGeometry.return_value = SCREEN['size']
Registry.create()
Registry().register('settings', MagicMock())
self.screens = ScreenList.create(self.desktop)
self.form = settingsform.SettingsForm()
# WHEN displaying the UI and pressing cancel
with patch('PyQt5.QtWidgets.QDialog.reject') as mocked_reject:
cancel_widget = form.button_box.button(form.button_box.Cancel)
QtTest.QTest.mouseClick(cancel_widget, QtCore.Qt.LeftButton)
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault
"""
del self.form
# THEN the dialog reject should have been called
assert mocked_reject.call_count == 1, 'The QDialog.reject should have been called'
def test_basic_cancel(self):
"""
Test running the settings form and pressing Cancel
"""
# GIVEN: An initial form
# WHEN displaying the UI and pressing cancel
with patch('PyQt5.QtWidgets.QDialog.reject') as mocked_reject:
cancel_widget = self.form.button_box.button(self.form.button_box.Cancel)
QtTest.QTest.mouseClick(cancel_widget, QtCore.Qt.LeftButton)
def test_basic_accept(form):
"""
Test running the settings form and pressing Ok
"""
# GIVEN: An initial form
# THEN the dialog reject should have been called
assert mocked_reject.call_count == 1, 'The QDialog.reject should have been called'
# WHEN displaying the UI and pressing Ok
with patch('PyQt5.QtWidgets.QDialog.accept') as mocked_accept:
ok_widget = form.button_box.button(form.button_box.Ok)
QtTest.QTest.mouseClick(ok_widget, QtCore.Qt.LeftButton)
def test_basic_accept(self):
"""
Test running the settings form and pressing Ok
"""
# GIVEN: An initial form
# THEN the dialog reject should have been called
assert mocked_accept.call_count == 1, 'The QDialog.accept should have been called'
# WHEN displaying the UI and pressing Ok
with patch('PyQt5.QtWidgets.QDialog.accept') as mocked_accept:
ok_widget = self.form.button_box.button(self.form.button_box.Ok)
QtTest.QTest.mouseClick(ok_widget, QtCore.Qt.LeftButton)
# THEN the dialog reject should have been called
assert mocked_accept.call_count == 1, 'The QDialog.accept should have been called'
def test_basic_register(form):
"""
Test running the settings form and adding a single function
"""
# GIVEN: An initial form add a register function
form.register_post_process('function1')
def test_basic_register(self):
"""
Test running the settings form and adding a single function
"""
# GIVEN: An initial form add a register function
self.form.register_post_process('function1')
# WHEN displaying the UI and pressing Ok
with patch('PyQt5.QtWidgets.QDialog.accept'):
ok_widget = form.button_box.button(form.button_box.Ok)
QtTest.QTest.mouseClick(ok_widget, QtCore.Qt.LeftButton)
# WHEN displaying the UI and pressing Ok
with patch('PyQt5.QtWidgets.QDialog.accept'):
ok_widget = self.form.button_box.button(self.form.button_box.Ok)
QtTest.QTest.mouseClick(ok_widget, QtCore.Qt.LeftButton)
# THEN the processing stack should be empty
assert len(form.processes) == 0, 'The one requested process should have been removed from the stack'
# THEN the processing stack should be empty
assert len(self.form.processes) == 0, 'The one requested process should have been removed from the stack'
def test_register_multiple_functions(self):
"""
Test running the settings form and adding multiple functions
"""
# GIVEN: Registering a single function
self.form.register_post_process('function1')
def test_register_multiple_functions(form):
"""
Test running the settings form and adding multiple functions
"""
# GIVEN: Registering a single function
form.register_post_process('function1')
# WHEN testing the processing stack
# THEN the processing stack should have one item
assert len(self.form.processes) == 1, 'The one requested process should have been added to the stack'
# WHEN testing the processing stack
# THEN the processing stack should have one item
assert len(form.processes) == 1, 'The one requested process should have been added to the stack'
# GIVEN: Registering a new function
self.form.register_post_process('function2')
# GIVEN: Registering a new function
form.register_post_process('function2')
# WHEN testing the processing stack
# THEN the processing stack should have two items
assert len(self.form.processes) == 2, 'The two requested processes should have been added to the stack'
# WHEN testing the processing stack
# THEN the processing stack should have two items
assert len(form.processes) == 2, 'The two requested processes should have been added to the stack'
# GIVEN: Registering a process for the second time
self.form.register_post_process('function1')
# GIVEN: Registering a process for the second time
form.register_post_process('function1')
# WHEN testing the processing stack
# THEN the processing stack should still have two items
assert len(self.form.processes) == 2, 'No new processes should have been added to the stack'
# WHEN testing the processing stack
# THEN the processing stack should still have two items
assert len(form.processes) == 2, 'No new processes should have been added to the stack'
def test_register_image_manager_trigger_one(self):
"""
Test the triggering of the image manager rebuild event from image background change
"""
# GIVEN: Three functions registered to be call
Registry().register_function('images_config_updated', self.dummy1)
Registry().register_function('config_screen_changed', self.dummy2)
Registry().register_function('images_regenerate', self.dummy3)
# WHEN: The Images have been changed and the form submitted
self.form.register_post_process('images_config_updated')
self.form.accept()
def test_register_image_manager_trigger_one(form, dummy):
"""
Test the triggering of the image manager rebuild event from image background change
"""
# GIVEN: Three functions registered to be call
Registry().register_function('images_config_updated', dummy[0])
Registry().register_function('config_screen_changed', dummy[1])
Registry().register_function('images_regenerate', dummy[2])
# THEN: images_regenerate should have been added.
assert self.dummy1.call_count == 1, 'dummy1 should have been called once'
assert self.dummy2.call_count == 0, 'dummy2 should not have been called at all'
assert self.dummy3.call_count == 1, 'dummy3 should have been called once'
# WHEN: The Images have been changed and the form submitted
form.register_post_process('images_config_updated')
form.accept()
def test_register_image_manager_trigger_two(self):
"""
Test the triggering of the image manager rebuild event from screen dimension change
"""
# GIVEN: Three functions registered to be call
Registry().register_function('images_config_updated', self.dummy1)
Registry().register_function('config_screen_changed', self.dummy2)
Registry().register_function('images_regenerate', self.dummy3)
# THEN: images_regenerate should have been added.
assert dummy[0].call_count == 1, 'dummy1 should have been called once'
assert dummy[1].call_count == 0, 'dummy2 should not have been called at all'
assert dummy[2].call_count == 1, 'dummy3 should have been called once'
# WHEN: The Images have been changed and the form submitted
self.form.register_post_process('config_screen_changed')
self.form.accept()
# THEN: images_regenerate should have been added.
assert self.dummy1.call_count == 0, 'dummy1 should not have been called at all'
assert self.dummy2.call_count == 1, 'dummy2 should have been called once'
assert self.dummy3.call_count == 1, 'dummy3 should have been called once'
def test_register_image_manager_trigger_two(form, dummy):
"""
Test the triggering of the image manager rebuild event from screen dimension change
"""
# GIVEN: Three functions registered to be call
Registry().register_function('images_config_updated', dummy[0])
Registry().register_function('config_screen_changed', dummy[1])
Registry().register_function('images_regenerate', dummy[2])
def test_register_image_manager_trigger_three(self):
"""
Test the triggering of the image manager rebuild event from image background change and a change to the
screen dimension.
"""
# GIVEN: Three functions registered to be call
Registry().register_function('images_config_updated', self.dummy1)
Registry().register_function('config_screen_changed', self.dummy2)
Registry().register_function('images_regenerate', self.dummy3)
# WHEN: The Images have been changed and the form submitted
form.register_post_process('config_screen_changed')
form.accept()
# WHEN: The Images have been changed and the form submitted
self.form.register_post_process('config_screen_changed')
self.form.register_post_process('images_config_updated')
self.form.accept()
# THEN: images_regenerate should have been added.
assert dummy[0].call_count == 0, 'dummy1 should not have been called at all'
assert dummy[1].call_count == 1, 'dummy2 should have been called once'
assert dummy[2].call_count == 1, 'dummy3 should have been called once'
# THEN: Images_regenerate should have been added.
assert self.dummy1.call_count == 1, 'dummy1 should have been called once'
assert self.dummy2.call_count == 1, 'dummy2 should have been called once'
assert self.dummy3.call_count == 1, 'dummy3 should have been called once'
def test_register_image_manager_trigger_three(form, dummy):
"""
Test the triggering of the image manager rebuild event from image background change and a change to the
screen dimension.
"""
# GIVEN: Three functions registered to be call
Registry().register_function('images_config_updated', dummy[0])
Registry().register_function('config_screen_changed', dummy[1])
Registry().register_function('images_regenerate', dummy[2])
# WHEN: The Images have been changed and the form submitted
form.register_post_process('config_screen_changed')
form.register_post_process('images_config_updated')
form.accept()
# THEN: Images_regenerate should have been added.
assert dummy[0].call_count == 1, 'dummy1 should have been called once'
assert dummy[1].call_count == 1, 'dummy2 should have been called once'
assert dummy[2].call_count == 1, 'dummy3 should have been called once'

View File

@ -21,207 +21,201 @@
"""
Package to test the openlp.core.ui.shortcutform package.
"""
from unittest import TestCase
import pytest
from unittest.mock import MagicMock, patch
from PyQt5 import QtCore, QtWidgets
from openlp.core.common.registry import Registry
from openlp.core.ui.shortcutlistform import ShortcutListForm
from tests.helpers.testmixin import TestMixin
class TestShortcutform(TestCase, TestMixin):
@pytest.fixture()
def form(mock_settings):
frm = ShortcutListForm()
return frm
def setUp(self):
"""
Create the UI
"""
Registry.create()
self.setup_application()
self.main_window = QtWidgets.QMainWindow()
Registry().register('main_window', self.main_window)
self.form = ShortcutListForm()
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault
"""
del self.form
del self.main_window
def test_adjust_button(form):
"""
Test the _adjust_button() method
"""
# GIVEN: A button.
button = QtWidgets.QPushButton()
checked = True
enabled = True
text = 'new!'
def test_adjust_button(self):
"""
Test the _adjust_button() method
"""
# GIVEN: A button.
button = QtWidgets.QPushButton()
checked = True
enabled = True
text = 'new!'
# WHEN: Call the method.
with patch('PyQt5.QtWidgets.QPushButton.setChecked') as mocked_check_method:
form._adjust_button(button, checked, enabled, text)
# WHEN: Call the method.
with patch('PyQt5.QtWidgets.QPushButton.setChecked') as mocked_check_method:
self.form._adjust_button(button, checked, enabled, text)
# THEN: The button should be changed.
assert button.text() == text, 'The text should match.'
mocked_check_method.assert_called_once_with(True)
assert button.isEnabled() == enabled, 'The button should be disabled.'
# THEN: The button should be changed.
assert button.text() == text, 'The text should match.'
mocked_check_method.assert_called_once_with(True)
assert button.isEnabled() == enabled, 'The button should be disabled.'
def test_space_key_press_event(self):
"""
Test the keyPressEvent when the spacebar was pressed
"""
# GIVEN: A key event that is a space
def test_space_key_press_event(form):
"""
Test the keyPressEvent when the spacebar was pressed
"""
# GIVEN: A key event that is a space
mocked_event = MagicMock()
mocked_event.key.return_value = QtCore.Qt.Key_Space
# WHEN: The event is handled
with patch.object(form, 'keyReleaseEvent') as mocked_key_release_event:
form.keyPressEvent(mocked_event)
# THEN: The key should be released
mocked_key_release_event.assert_called_with(mocked_event)
assert 0 == mocked_event.accept.call_count
def test_primary_push_button_checked_key_press_event(form):
"""
Test the keyPressEvent when the primary push button is checked
"""
# GIVEN: The primary push button is checked
with patch.object(form, 'keyReleaseEvent') as mocked_key_release_event, \
patch.object(form.primary_push_button, 'isChecked') as mocked_is_checked:
mocked_is_checked.return_value = True
mocked_event = MagicMock()
mocked_event.key.return_value = QtCore.Qt.Key_Space
# WHEN: The event is handled
with patch.object(self.form, 'keyReleaseEvent') as mocked_key_release_event:
self.form.keyPressEvent(mocked_event)
form.keyPressEvent(mocked_event)
# THEN: The key should be released
mocked_key_release_event.assert_called_with(mocked_event)
assert 0 == mocked_event.accept.call_count
# THEN: The key should be released
mocked_key_release_event.assert_called_with(mocked_event)
assert 0 == mocked_event.accept.call_count
def test_primary_push_button_checked_key_press_event(self):
"""
Test the keyPressEvent when the primary push button is checked
"""
# GIVEN: The primary push button is checked
with patch.object(self.form, 'keyReleaseEvent') as mocked_key_release_event, \
patch.object(self.form.primary_push_button, 'isChecked') as mocked_is_checked:
mocked_is_checked.return_value = True
mocked_event = MagicMock()
# WHEN: The event is handled
self.form.keyPressEvent(mocked_event)
# THEN: The key should be released
mocked_key_release_event.assert_called_with(mocked_event)
assert 0 == mocked_event.accept.call_count
def test_alternate_push_button_checked_key_press_event(self):
"""
Test the keyPressEvent when the alternate push button is checked
"""
# GIVEN: The primary push button is checked
with patch.object(self.form, 'keyReleaseEvent') as mocked_key_release_event, \
patch.object(self.form.alternate_push_button, 'isChecked') as mocked_is_checked:
mocked_is_checked.return_value = True
mocked_event = MagicMock()
# WHEN: The event is handled
self.form.keyPressEvent(mocked_event)
# THEN: The key should be released
mocked_key_release_event.assert_called_with(mocked_event)
assert 0 == mocked_event.accept.call_count
def test_escape_key_press_event(self):
"""
Test the keyPressEvent when the escape key was pressed
"""
# GIVEN: A key event that is an escape
def test_alternate_push_button_checked_key_press_event(form):
"""
Test the keyPressEvent when the alternate push button is checked
"""
# GIVEN: The primary push button is checked
with patch.object(form, 'keyReleaseEvent') as mocked_key_release_event, \
patch.object(form.alternate_push_button, 'isChecked') as mocked_is_checked:
mocked_is_checked.return_value = True
mocked_event = MagicMock()
mocked_event.key.return_value = QtCore.Qt.Key_Escape
# WHEN: The event is handled
with patch.object(self.form, 'close') as mocked_close:
self.form.keyPressEvent(mocked_event)
form.keyPressEvent(mocked_event)
# THEN: The key should be released
mocked_event.accept.assert_called_with()
mocked_close.assert_called_with()
# THEN: The key should be released
mocked_key_release_event.assert_called_with(mocked_event)
assert 0 == mocked_event.accept.call_count
def test_on_default_radio_button_not_toggled(self):
"""
Test that the default radio button method exits early when the button is not toggled
"""
# GIVEN: A not-toggled custom radio button
with patch.object(self.form, '_current_item_action') as mocked_current_item_action:
# WHEN: The clicked method is called
self.form.on_default_radio_button_clicked(False)
def test_escape_key_press_event(form):
"""
Test the keyPressEvent when the escape key was pressed
"""
# GIVEN: A key event that is an escape
mocked_event = MagicMock()
mocked_event.key.return_value = QtCore.Qt.Key_Escape
# THEN: The method should exit early (i.e. the rest of the methods are not called)
assert 0 == mocked_current_item_action.call_count
# WHEN: The event is handled
with patch.object(form, 'close') as mocked_close:
form.keyPressEvent(mocked_event)
def test_on_default_radio_button_clicked_no_action(self):
"""
Test that nothing happens when an action hasn't been selected and you click the default radio button
"""
# GIVEN: Some mocked out methods, a current action, and some shortcuts
with patch.object(self.form, '_current_item_action') as mocked_current_item_action, \
patch.object(self.form, '_action_shortcuts') as mocked_action_shortcuts:
mocked_current_item_action.return_value = None
# THEN: The key should be released
mocked_event.accept.assert_called_with()
mocked_close.assert_called_with()
# WHEN: The default radio button is clicked
self.form.on_default_radio_button_clicked(True)
# THEN: The method should exit early (i.e. the rest of the methods are not called)
mocked_current_item_action.assert_called_with()
assert 0 == mocked_action_shortcuts.call_count
def test_on_default_radio_button_not_toggled(form):
"""
Test that the default radio button method exits early when the button is not toggled
"""
# GIVEN: A not-toggled custom radio button
with patch.object(form, '_current_item_action') as mocked_current_item_action:
def test_on_default_radio_button_clicked(self):
"""
Test that the values are copied across correctly when the default radio button is selected
"""
# GIVEN: Some mocked out methods, a current action, and some shortcuts
with patch.object(self.form, '_current_item_action') as mocked_current_item_action, \
patch.object(self.form, '_action_shortcuts') as mocked_action_shortcuts, \
patch.object(self.form, 'refresh_shortcut_list') as mocked_refresh_shortcut_list, \
patch.object(self.form, 'get_shortcut_string') as mocked_get_shortcut_string, \
patch.object(self.form.primary_push_button, 'setText') as mocked_set_text:
mocked_action = MagicMock()
mocked_action.default_shortcuts = [QtCore.Qt.Key_Escape]
mocked_current_item_action.return_value = mocked_action
mocked_action_shortcuts.return_value = [QtCore.Qt.Key_Escape]
mocked_get_shortcut_string.return_value = 'Esc'
# WHEN: The clicked method is called
form.on_default_radio_button_clicked(False)
# WHEN: The default radio button is clicked
self.form.on_default_radio_button_clicked(True)
# THEN: The method should exit early (i.e. the rest of the methods are not called)
assert 0 == mocked_current_item_action.call_count
# THEN: The shorcuts should be copied across
mocked_current_item_action.assert_called_with()
mocked_action_shortcuts.assert_called_with(mocked_action)
mocked_refresh_shortcut_list.assert_called_with()
mocked_set_text.assert_called_with('Esc')
def test_on_custom_radio_button_not_toggled(self):
"""
Test that the custom radio button method exits early when the button is not toggled
"""
# GIVEN: A not-toggled custom radio button
with patch.object(self.form, '_current_item_action') as mocked_current_item_action:
def test_on_default_radio_button_clicked_no_action(form):
"""
Test that nothing happens when an action hasn't been selected and you click the default radio button
"""
# GIVEN: Some mocked out methods, a current action, and some shortcuts
with patch.object(form, '_current_item_action') as mocked_current_item_action, \
patch.object(form, '_action_shortcuts') as mocked_action_shortcuts:
mocked_current_item_action.return_value = None
# WHEN: The clicked method is called
self.form.on_custom_radio_button_clicked(False)
# WHEN: The default radio button is clicked
form.on_default_radio_button_clicked(True)
# THEN: The method should exit early (i.e. the rest of the methods are not called)
assert 0 == mocked_current_item_action.call_count
# THEN: The method should exit early (i.e. the rest of the methods are not called)
mocked_current_item_action.assert_called_with()
assert 0 == mocked_action_shortcuts.call_count
def test_on_custom_radio_button_clicked(self):
"""
Test that the values are copied across correctly when the custom radio button is selected
"""
# GIVEN: Some mocked out methods, a current action, and some shortcuts
with patch.object(self.form, '_current_item_action') as mocked_current_item_action, \
patch.object(self.form, '_action_shortcuts') as mocked_action_shortcuts, \
patch.object(self.form, 'refresh_shortcut_list') as mocked_refresh_shortcut_list, \
patch.object(self.form, 'get_shortcut_string') as mocked_get_shortcut_string, \
patch.object(self.form.primary_push_button, 'setText') as mocked_set_text:
mocked_action = MagicMock()
mocked_current_item_action.return_value = mocked_action
mocked_action_shortcuts.return_value = [QtCore.Qt.Key_Escape]
mocked_get_shortcut_string.return_value = 'Esc'
# WHEN: The custom radio button is clicked
self.form.on_custom_radio_button_clicked(True)
def test_on_default_radio_button_clicked(form):
"""
Test that the values are copied across correctly when the default radio button is selected
"""
# GIVEN: Some mocked out methods, a current action, and some shortcuts
with patch.object(form, '_current_item_action') as mocked_current_item_action, \
patch.object(form, '_action_shortcuts') as mocked_action_shortcuts, \
patch.object(form, 'refresh_shortcut_list') as mocked_refresh_shortcut_list, \
patch.object(form, 'get_shortcut_string') as mocked_get_shortcut_string, \
patch.object(form.primary_push_button, 'setText') as mocked_set_text:
mocked_action = MagicMock()
mocked_action.default_shortcuts = [QtCore.Qt.Key_Escape]
mocked_current_item_action.return_value = mocked_action
mocked_action_shortcuts.return_value = [QtCore.Qt.Key_Escape]
mocked_get_shortcut_string.return_value = 'Esc'
# THEN: The shorcuts should be copied across
mocked_current_item_action.assert_called_with()
mocked_action_shortcuts.assert_called_with(mocked_action)
mocked_refresh_shortcut_list.assert_called_with()
mocked_set_text.assert_called_with('Esc')
# WHEN: The default radio button is clicked
form.on_default_radio_button_clicked(True)
# THEN: The shorcuts should be copied across
mocked_current_item_action.assert_called_with()
mocked_action_shortcuts.assert_called_with(mocked_action)
mocked_refresh_shortcut_list.assert_called_with()
mocked_set_text.assert_called_with('Esc')
def test_on_custom_radio_button_not_toggled(form):
"""
Test that the custom radio button method exits early when the button is not toggled
"""
# GIVEN: A not-toggled custom radio button
with patch.object(form, '_current_item_action') as mocked_current_item_action:
# WHEN: The clicked method is called
form.on_custom_radio_button_clicked(False)
# THEN: The method should exit early (i.e. the rest of the methods are not called)
assert 0 == mocked_current_item_action.call_count
def test_on_custom_radio_button_clicked(form):
"""
Test that the values are copied across correctly when the custom radio button is selected
"""
# GIVEN: Some mocked out methods, a current action, and some shortcuts
with patch.object(form, '_current_item_action') as mocked_current_item_action, \
patch.object(form, '_action_shortcuts') as mocked_action_shortcuts, \
patch.object(form, 'refresh_shortcut_list') as mocked_refresh_shortcut_list, \
patch.object(form, 'get_shortcut_string') as mocked_get_shortcut_string, \
patch.object(form.primary_push_button, 'setText') as mocked_set_text:
mocked_action = MagicMock()
mocked_current_item_action.return_value = mocked_action
mocked_action_shortcuts.return_value = [QtCore.Qt.Key_Escape]
mocked_get_shortcut_string.return_value = 'Esc'
# WHEN: The custom radio button is clicked
form.on_custom_radio_button_clicked(True)
# THEN: The shorcuts should be copied across
mocked_current_item_action.assert_called_with()
mocked_action_shortcuts.assert_called_with(mocked_action)
mocked_refresh_shortcut_list.assert_called_with()
mocked_set_text.assert_called_with('Esc')

View File

@ -21,92 +21,78 @@
"""
Package to test the openlp.core.ui package.
"""
from unittest import TestCase
import pytest
from unittest.mock import MagicMock, patch
from PyQt5 import QtCore, QtTest, QtWidgets
from PyQt5 import QtCore, QtTest
from openlp.core.common.registry import Registry
from openlp.core.ui import starttimeform
from tests.helpers.testmixin import TestMixin
from openlp.core.ui.starttimeform import StartTimeForm
class TestStartTimeDialog(TestCase, TestMixin):
@pytest.fixture()
def form(mock_settings):
frm = StartTimeForm()
return frm
def setUp(self):
"""
Create the UI
"""
Registry.create()
self.setup_application()
self.main_window = QtWidgets.QMainWindow()
Registry().register('main_window', self.main_window)
self.form = starttimeform.StartTimeForm()
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault
"""
del self.form
del self.main_window
def test_ui_defaults(form):
"""
Test StartTimeDialog are defaults correct
"""
assert form.hour_spin_box.minimum() == 0, 'The minimum hour should stay the same as the dialog'
assert form.hour_spin_box.maximum() == 4, 'The maximum hour should stay the same as the dialog'
assert form.minute_spin_box.minimum() == 0, 'The minimum minute should stay the same as the dialog'
assert form.minute_spin_box.maximum() == 59, 'The maximum minute should stay the same as the dialog'
assert form.second_spin_box.minimum() == 0, 'The minimum second should stay the same as the dialog'
assert form.second_spin_box.maximum() == 59, 'The maximum second should stay the same as the dialog'
assert form.hour_finish_spin_box.minimum() == 0, \
'The minimum finish hour should stay the same as the dialog'
assert form.hour_finish_spin_box.maximum() == 4, \
'The maximum finish hour should stay the same as the dialog'
assert form.minute_finish_spin_box.minimum() == 0, \
'The minimum finish minute should stay the same as the dialog'
assert form.minute_finish_spin_box.maximum() == 59, \
'The maximum finish minute should stay the same as the dialog'
assert form.second_finish_spin_box.minimum() == 0, \
'The minimum finish second should stay the same as the dialog'
assert form.second_finish_spin_box.maximum() == 59, \
'The maximum finish second should stay the same as the dialog'
def test_ui_defaults(self):
"""
Test StartTimeDialog are defaults correct
"""
assert self.form.hour_spin_box.minimum() == 0, 'The minimum hour should stay the same as the dialog'
assert self.form.hour_spin_box.maximum() == 4, 'The maximum hour should stay the same as the dialog'
assert self.form.minute_spin_box.minimum() == 0, 'The minimum minute should stay the same as the dialog'
assert self.form.minute_spin_box.maximum() == 59, 'The maximum minute should stay the same as the dialog'
assert self.form.second_spin_box.minimum() == 0, 'The minimum second should stay the same as the dialog'
assert self.form.second_spin_box.maximum() == 59, 'The maximum second should stay the same as the dialog'
assert self.form.hour_finish_spin_box.minimum() == 0, \
'The minimum finish hour should stay the same as the dialog'
assert self.form.hour_finish_spin_box.maximum() == 4, \
'The maximum finish hour should stay the same as the dialog'
assert self.form.minute_finish_spin_box.minimum() == 0, \
'The minimum finish minute should stay the same as the dialog'
assert self.form.minute_finish_spin_box.maximum() == 59, \
'The maximum finish minute should stay the same as the dialog'
assert self.form.second_finish_spin_box.minimum() == 0, \
'The minimum finish second should stay the same as the dialog'
assert self.form.second_finish_spin_box.maximum() == 59, \
'The maximum finish second should stay the same as the dialog'
def test_time_display(self):
"""
Test StartTimeDialog display functionality
"""
# GIVEN: A service item with with time
mocked_serviceitem = MagicMock()
mocked_serviceitem.start_time = 61
mocked_serviceitem.end_time = 3701
mocked_serviceitem.media_length = 3701
def test_time_display(form):
"""
Test StartTimeDialog display functionality
"""
# GIVEN: A service item with with time
mocked_serviceitem = MagicMock()
mocked_serviceitem.start_time = 61
mocked_serviceitem.end_time = 3701
mocked_serviceitem.media_length = 3701
# WHEN displaying the UI and pressing enter
self.form.item = {'service_item': mocked_serviceitem}
with patch('PyQt5.QtWidgets.QDialog.exec'):
self.form.exec()
ok_widget = self.form.button_box.button(self.form.button_box.Ok)
QtTest.QTest.mouseClick(ok_widget, QtCore.Qt.LeftButton)
# WHEN displaying the UI and pressing enter
form.item = {'service_item': mocked_serviceitem}
with patch('PyQt5.QtWidgets.QDialog.exec'):
form.exec()
ok_widget = form.button_box.button(form.button_box.Ok)
QtTest.QTest.mouseClick(ok_widget, QtCore.Qt.LeftButton)
# THEN the following input values are returned
assert self.form.hour_spin_box.value() == 0
assert self.form.minute_spin_box.value() == 1
assert self.form.second_spin_box.value() == 1
assert self.form.item['service_item'].start_time == 61, 'The start time should stay the same'
# THEN the following input values are returned
assert form.hour_spin_box.value() == 0
assert form.minute_spin_box.value() == 1
assert form.second_spin_box.value() == 1
assert form.item['service_item'].start_time == 61, 'The start time should stay the same'
# WHEN displaying the UI, changing the time to 2min 3secs and pressing enter
self.form.item = {'service_item': mocked_serviceitem}
with patch('PyQt5.QtWidgets.QDialog.exec'):
self.form.exec()
self.form.minute_spin_box.setValue(2)
self.form.second_spin_box.setValue(3)
ok_widget = self.form.button_box.button(self.form.button_box.Ok)
QtTest.QTest.mouseClick(ok_widget, QtCore.Qt.LeftButton)
# WHEN displaying the UI, changing the time to 2min 3secs and pressing enter
form.item = {'service_item': mocked_serviceitem}
with patch('PyQt5.QtWidgets.QDialog.exec'):
form.exec()
form.minute_spin_box.setValue(2)
form.second_spin_box.setValue(3)
ok_widget = form.button_box.button(form.button_box.Ok)
QtTest.QTest.mouseClick(ok_widget, QtCore.Qt.LeftButton)
# THEN the following values are returned
assert self.form.hour_spin_box.value() == 0
assert self.form.minute_spin_box.value() == 2
assert self.form.second_spin_box.value() == 3
assert self.form.item['service_item'].start_time == 123, 'The start time should have changed'
# THEN the following values are returned
assert form.hour_spin_box.value() == 0
assert form.minute_spin_box.value() == 2
assert form.second_spin_box.value() == 3
assert form.item['service_item'].start_time == 123, 'The start time should have changed'

View File

@ -21,116 +21,103 @@
"""
Interface tests to test the themeManager class and related methods.
"""
import pytest
from pathlib import Path
from unittest import TestCase
from unittest.mock import MagicMock, patch
from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings
from openlp.core.ui.thememanager import ThemeManager
from tests.helpers.testmixin import TestMixin
class TestThemeManager(TestCase, TestMixin):
@pytest.fixture()
def theme_manager(settings):
thm = ThemeManager()
return thm
def test_theme_manager_initialise(theme_manager):
"""
Test the functions in the ThemeManager module
Test the thememanager initialise - basic test
"""
def setUp(self):
"""
Create the UI
"""
self.setup_application()
self.build_settings()
Registry.create()
Registry().register('settings', Settings())
self.theme_manager = ThemeManager()
# GIVEN: A new a call to initialise
theme_manager.setup_ui = MagicMock()
theme_manager.build_theme_path = MagicMock()
Settings().setValue('themes/global theme', 'my_theme')
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault
"""
self.destroy_settings()
del self.theme_manager
# WHEN: the initialisation is run
theme_manager.bootstrap_initialise()
def test_initialise(self):
"""
Test the thememanager initialise - basic test
"""
# GIVEN: A new a call to initialise
self.theme_manager.setup_ui = MagicMock()
self.theme_manager.build_theme_path = MagicMock()
Settings().setValue('themes/global theme', 'my_theme')
# THEN:
theme_manager.setup_ui.assert_called_once_with(theme_manager)
assert theme_manager.global_theme == 'my_theme'
theme_manager.build_theme_path.assert_called_once_with()
# WHEN: the initialisation is run
self.theme_manager.bootstrap_initialise()
# THEN:
self.theme_manager.setup_ui.assert_called_once_with(self.theme_manager)
assert self.theme_manager.global_theme == 'my_theme'
self.theme_manager.build_theme_path.assert_called_once_with()
@patch('openlp.core.ui.thememanager.create_paths')
@patch('openlp.core.ui.thememanager.AppLocation.get_section_data_path')
def test_build_theme_path(mocked_get_section_data_path, mocked_create_paths, theme_manager):
"""
Test the thememanager build_theme_path
"""
# GIVEN: A mocked out AppLocation.get_directory() and mocked create_paths
mocked_get_section_data_path.return_value = Path('tests/my_theme')
@patch('openlp.core.ui.thememanager.create_paths')
@patch('openlp.core.ui.thememanager.AppLocation.get_section_data_path')
def test_build_theme_path(self, mocked_get_section_data_path, mocked_create_paths):
"""
Test the thememanager build_theme_path
"""
# GIVEN: A mocked out AppLocation.get_directory() and mocked create_paths
mocked_get_section_data_path.return_value = Path('tests/my_theme')
# WHEN: the build_theme_path is run
theme_manager.build_theme_path()
# WHEN: the build_theme_path is run
self.theme_manager.build_theme_path()
# THEN: The theme path and the thumb path should be correct
assert theme_manager.theme_path == Path('tests/my_theme')
assert theme_manager.thumb_path == Path('tests/my_theme/thumbnails')
mocked_create_paths.assert_called_once_with(Path('tests/my_theme'), Path('tests/my_theme/thumbnails'))
# THEN: The theme path and the thumb path should be correct
assert self.theme_manager.theme_path == Path('tests/my_theme')
assert self.theme_manager.thumb_path == Path('tests/my_theme/thumbnails')
mocked_create_paths.assert_called_once_with(Path('tests/my_theme'), Path('tests/my_theme/thumbnails'))
def test_click_on_new_theme(self):
"""
Test the on_add_theme event handler is called by the UI
"""
# GIVEN: An initial form
Settings().setValue('themes/global theme', 'my_theme')
mocked_event = MagicMock()
self.theme_manager.on_add_theme = mocked_event
self.theme_manager.setup_ui(self.theme_manager)
def test_click_on_new_theme(theme_manager):
"""
Test the on_add_theme event handler is called by the UI
"""
# GIVEN: An initial form
Settings().setValue('themes/global theme', 'my_theme')
mocked_event = MagicMock()
theme_manager.on_add_theme = mocked_event
theme_manager.setup_ui(theme_manager)
# WHEN displaying the UI and pressing cancel
new_theme = self.theme_manager.toolbar.actions['newTheme']
new_theme.trigger()
# WHEN displaying the UI and pressing cancel
new_theme = theme_manager.toolbar.actions['newTheme']
new_theme.trigger()
assert mocked_event.call_count == 1, 'The on_add_theme method should have been called once'
assert mocked_event.call_count == 1, 'The on_add_theme method should have been called once'
@patch('openlp.core.ui.themeform.ThemeForm._setup')
@patch('openlp.core.ui.filerenameform.FileRenameForm._setup')
def test_bootstrap_post(self, mocked_rename_form, mocked_theme_form):
"""
Test the functions of bootstrap_post_setup are called.
"""
# GIVEN:
self.theme_manager.theme_path = MagicMock()
# WHEN:
with patch('openlp.core.ui.thememanager.ThemeProgressForm'):
self.theme_manager.bootstrap_post_set_up()
@patch('openlp.core.ui.themeform.ThemeForm._setup')
@patch('openlp.core.ui.filerenameform.FileRenameForm._setup')
def test_bootstrap_post(mocked_rename_form, mocked_theme_form, theme_manager):
"""
Test the functions of bootstrap_post_setup are called.
"""
# GIVEN:
theme_manager.theme_path = MagicMock()
# THEN:
assert self.theme_manager.progress_form is not None
assert self.theme_manager.theme_form is not None
assert self.theme_manager.file_rename_form is not None
# WHEN:
with patch('openlp.core.ui.thememanager.ThemeProgressForm'):
theme_manager.bootstrap_post_set_up()
def test_bootstrap_completion(self):
"""
Test the functions of bootstrap_post_setup are called.
"""
# GIVEN:
self.theme_manager.load_themes = MagicMock()
self.theme_manager.upgrade_themes = MagicMock()
# THEN:
assert theme_manager.progress_form is not None
assert theme_manager.theme_form is not None
assert theme_manager.file_rename_form is not None
# WHEN:
self.theme_manager.bootstrap_completion()
# THEN:
self.theme_manager.upgrade_themes.assert_called_once()
self.theme_manager.load_themes.assert_called_once()
def test_bootstrap_completion(theme_manager):
"""
Test the functions of bootstrap_post_setup are called.
"""
# GIVEN:
theme_manager.load_themes = MagicMock()
theme_manager.upgrade_themes = MagicMock()
# WHEN:
theme_manager.bootstrap_completion()
# THEN:
theme_manager.upgrade_themes.assert_called_once()
theme_manager.load_themes.assert_called_once()

View File

@ -21,14 +21,13 @@
"""
Module to test the EditCustomForm.
"""
from unittest import TestCase
import pytest
from unittest.mock import MagicMock, call
from PyQt5 import QtCore, QtGui, QtTest, QtWidgets
from openlp.core.common.registry import Registry
from openlp.core.widgets.edits import HistoryComboBox, SearchEdit
from tests.helpers.testmixin import TestMixin
class SearchTypes(object):
@ -44,120 +43,101 @@ SEARCH_TYPES = [(SearchTypes.First, QtGui.QIcon(), "First", "First Placeholder T
(SearchTypes.Second, QtGui.QIcon(), "Second", SECOND_PLACEHOLDER_TEXT)]
class TestSearchEdit(TestCase, TestMixin):
@pytest.fixture()
def search_edit(mock_settings):
main_window = QtWidgets.QMainWindow()
Registry().register('main_window', main_window)
Registry().remove('settings')
Registry().register('settings', MagicMock(**{'value.return_value': SearchTypes.First}))
s_edit = SearchEdit(main_window, 'settings_section')
# To complete set up we have to set the search types.
s_edit.set_search_types(SEARCH_TYPES)
return s_edit
@pytest.fixture()
def combo(mock_settings):
main_window = QtWidgets.QMainWindow()
Registry().register('main_window', main_window)
s_combo = HistoryComboBox(main_window)
return s_combo
def test_set_search_types(search_edit):
"""
Test the EditCustomForm.
Test setting the search types of the search edit.
"""
def setUp(self):
"""
Create the UI
"""
Registry.create()
self.setup_application()
self.main_window = QtWidgets.QMainWindow()
Registry().register('main_window', self.main_window)
Registry().register('settings', MagicMock(**{'value.return_value': SearchTypes.First}))
# GIVEN: The search edit with the search types set. NOTE: The set_search_types(types) is called in the setUp()
# method!
self.search_edit = SearchEdit(self.main_window, 'settings_section')
# To complete set up we have to set the search types.
self.search_edit.set_search_types(SEARCH_TYPES)
# WHEN:
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault
"""
del self.search_edit
del self.main_window
def test_set_search_types(self):
"""
Test setting the search types of the search edit.
"""
# GIVEN: The search edit with the search types set. NOTE: The set_search_types(types) is called in the setUp()
# method!
# WHEN:
# THEN: The first search type should be the first one in the list. The selected type should be saved in the
# settings
assert self.search_edit.current_search_type() == SearchTypes.First, \
"The first search type should be selected."
Registry().get('settings').setValue.assert_called_once_with('settings_section/last used search type', 0)
def test_set_current_search_type(self):
"""
Test if changing the search type works.
"""
# GIVEN:
# WHEN: Change the search type
result = self.search_edit.set_current_search_type(SearchTypes.Second)
# THEN:
assert result is True, "The call should return success (True)."
assert self.search_edit.current_search_type() == SearchTypes.Second, \
"The search type should be SearchTypes.Second"
assert self.search_edit.placeholderText() == SECOND_PLACEHOLDER_TEXT, \
"The correct placeholder text should be 'Second Placeholder Text'."
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):
"""
Test if the clear button is hidden/shown correctly.
"""
# GIVEN: Everything is left to its defaults (hidden).
assert self.search_edit.clear_button.isHidden(), "Pre condition not met. Button should be hidden."
# WHEN: Type something in the search edit.
QtTest.QTest.keyPress(self.search_edit, QtCore.Qt.Key_A)
QtTest.QTest.keyRelease(self.search_edit, QtCore.Qt.Key_A)
# THEN: The clear button should not be hidden any more.
assert not self.search_edit.clear_button.isHidden(), "The clear button should be visible."
def test_press_clear_button(self):
"""
Check if the search edit behaves correctly when pressing the clear button.
"""
# GIVEN: A search edit with text.
QtTest.QTest.keyPress(self.search_edit, QtCore.Qt.Key_A)
QtTest.QTest.keyRelease(self.search_edit, QtCore.Qt.Key_A)
# WHEN: Press the clear button.
QtTest.QTest.mouseClick(self.search_edit.clear_button, QtCore.Qt.LeftButton)
# THEN: The search edit text should be cleared and the button be hidden.
assert not self.search_edit.text(), "The search edit should not have any text."
assert self.search_edit.clear_button.isHidden(), "The clear button should be hidden."
# THEN: The first search type should be the first one in the list. The selected type should be saved in the
# settings
assert search_edit.current_search_type() == SearchTypes.First, \
"The first search type should be selected."
Registry().get('settings').setValue.assert_called_once_with('settings_section/last used search type', 0)
class TestHistoryComboBox(TestCase, TestMixin):
def setUp(self):
"""
Some pre-test setup required.
"""
Registry.create()
self.setup_application()
self.main_window = QtWidgets.QMainWindow()
Registry().register('main_window', self.main_window)
self.combo = HistoryComboBox(self.main_window)
def test_set_current_search_type(search_edit):
"""
Test if changing the search type works.
"""
# GIVEN:
# WHEN: Change the search type
result = search_edit.set_current_search_type(SearchTypes.Second)
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault
"""
del self.combo
del self.main_window
# THEN:
assert result is True, "The call should return success (True)."
assert search_edit.current_search_type() == SearchTypes.Second, \
"The search type should be SearchTypes.Second"
assert search_edit.placeholderText() == SECOND_PLACEHOLDER_TEXT, \
"The correct placeholder text should be 'Second Placeholder Text'."
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_get_items(self):
"""
Test the getItems() method
"""
# GIVEN: The combo.
# WHEN: Add two items.
self.combo.addItem('test1')
self.combo.addItem('test2')
def test_clear_button_visibility(search_edit):
"""
Test if the clear button is hidden/shown correctly.
"""
# GIVEN: Everything is left to its defaults (hidden).
assert search_edit.clear_button.isHidden(), "Pre condition not met. Button should be hidden."
# THEN: The list of items should contain both strings.
assert self.combo.getItems() == ['test1', 'test2']
# WHEN: Type something in the search edit.
QtTest.QTest.keyPress(search_edit, QtCore.Qt.Key_A)
QtTest.QTest.keyRelease(search_edit, QtCore.Qt.Key_A)
# THEN: The clear button should not be hidden any more.
assert not search_edit.clear_button.isHidden(), "The clear button should be visible."
def test_press_clear_button(search_edit):
"""
Check if the search edit behaves correctly when pressing the clear button.
"""
# GIVEN: A search edit with text.
QtTest.QTest.keyPress(search_edit, QtCore.Qt.Key_A)
QtTest.QTest.keyRelease(search_edit, QtCore.Qt.Key_A)
# WHEN: Press the clear button.
QtTest.QTest.mouseClick(search_edit.clear_button, QtCore.Qt.LeftButton)
# THEN: The search edit text should be cleared and the button be hidden.
assert not search_edit.text(), "The search edit should not have any text."
assert search_edit.clear_button.isHidden(), "The clear button should be hidden."
def test_history_combo_get_items(combo):
"""
Test the getItems() method
"""
# GIVEN: The combo.
# WHEN: Add two items.
combo.addItem('test1')
combo.addItem('test2')
# THEN: The list of items should contain both strings.
assert combo.getItems() == ['test1', 'test2']

View File

@ -21,91 +21,72 @@
"""
Package to test the openlp.core.widgets.views.
"""
from unittest import TestCase
from unittest.mock import MagicMock, patch
import pytest
from unittest.mock import patch
from PyQt5 import QtGui, QtWidgets
from PyQt5 import QtWidgets
from openlp.core.common.registry import Registry
from openlp.core.common.settings import Settings
from openlp.core.lib.serviceitem import ServiceItem
from openlp.core.state import State
from openlp.core.widgets.views import ListPreviewWidget
from tests.helpers.testmixin import TestMixin
from tests.utils.osdinteraction import read_service_from_file
class TestListPreviewWidget(TestCase, TestMixin):
@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
def setUp(self):
"""
Create the UI.
"""
Registry.create()
self.setup_application()
State().load_settings()
State().add_service("media", 0)
State().update_pre_conditions("media", True)
State().flush_preconditions()
self.main_window = QtWidgets.QMainWindow()
self.image = QtGui.QImage(1, 1, QtGui.QImage.Format_RGB32)
self.image_manager = MagicMock()
self.image_manager.get_image.return_value = self.image
Registry().register('image_manager', self.image_manager)
self.preview_widget = ListPreviewWidget(self.main_window, 2)
Registry().register('settings', Settings())
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault.
"""
del self.preview_widget
del self.main_window
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_count(self):
"""
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 self.preview_widget.slide_count() == 0, 'The slide list should be empty.'
def test_initial_slide_number(self):
"""
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 self.preview_widget.current_slide_number() == -1, 'The slide number should be -1.'
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(self):
"""
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'):
service_item.set_from_service(service[0])
# WHEN: Added to the preview widget.
self.preview_widget.replace_service_item(service_item, 1, 1)
# THEN: The slide count and number should fit.
assert self.preview_widget.slide_count() == 2, 'The slide count should be 2.'
assert self.preview_widget.current_slide_number() == 1, 'The current slide number should be 1.'
def test_change_slide(self):
"""
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'):
service_item.set_from_service(service[0])
# WHEN: Added to the preview widget and switched to the second frame.
self.preview_widget.replace_service_item(service_item, 1, 0)
self.preview_widget.change_slide(1)
# THEN: The current_slide_number should reflect the change.
assert self.preview_widget.current_slide_number() == 1, 'The current 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'):
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'):
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.'