Tests plugin 5

This commit is contained in:
Tim Bentley 2020-03-11 21:53:41 +00:00
parent 980c68488a
commit fa9a3c6f92
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,62 +21,42 @@
"""
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):
"""
Test the functions in the :mod:`lib` module.
"""
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)
@pytest.fixture()
def edit_song_form():
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'))
return EditSongForm(None, MagicMock(), MagicMock())
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault
"""
self.destroy_settings()
def test_validate_matching_tags(self):
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 = self.edit_song_form._validate_tags(tags)
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(self):
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 = self.edit_song_form._validate_tags(tags)
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(self, mocked_set_case_insensitive_completer):
def test_load_objects(mocked_set_case_insensitive_completer, edit_song_form, settings):
"""
Test the _load_objects() method
"""
@ -91,13 +71,13 @@ class TestEditSongForm(TestCase, TestMixin):
mocked_object.id = 1
mocked_manager = MagicMock()
mocked_manager.get_all_objects.return_value = [mocked_object]
self.edit_song_form.manager = mocked_manager
edit_song_form.manager = mocked_manager
# WHEN: _load_objects() is called
self.edit_song_form._load_objects(mocked_class, mocked_combo, mocked_cache)
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)
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')

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):
"""
Test the functions in the :mod:`lib` module.
"""
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'))
@pytest.fixture()
def edit_verse_form(settings):
return EditVerseForm(None)
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault
"""
self.destroy_settings()
def test_update_suggested_verse_number_has_no_effect(self):
def test_update_suggested_verse_number_has_no_effect(edit_verse_form):
"""
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)
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)
# WHEN the method is called
self.edit_verse_form.update_suggested_verse_number()
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'
assert 3 == edit_verse_form.verse_number_box.value(), 'The verse number should be 3'
def test_update_suggested_verse_number_different_type(self):
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
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)
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)
# WHEN the method is called
self.edit_verse_form.update_suggested_verse_number()
edit_verse_form.update_suggested_verse_number()
# 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'
assert 1 == edit_verse_form.verse_number_box.value(), 'The verse number should be 1'
def test_on_divide_split_button_clicked(self):
def test_on_divide_split_button_clicked(edit_verse_form):
"""
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')
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()
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(), \
assert '[--}{--]\nText\n' == edit_verse_form.verse_text_edit.toPlainText(), \
'The verse number should be [--}{--]\nText\n'
def test_on_split_button_clicked(self):
def test_on_split_button_clicked(edit_verse_form):
"""
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')
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_overflow_split_button_clicked()
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(), \
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
"""
test_file_import = SongImportTestHelper('SundayPlusImport', 'sundayplus')
test_file_import.setUp()
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.setUp()
test_file_import.test_song_import()
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(self):
def test_basic_display(form):
"""
Test Service Note form functionality
"""
# GIVEN: A dialog with an empty text box
self.form.text_edit.setPlainText('')
form.text_edit.setPlainText('')
# 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)
form.exec()
ok_widget = form.button_box.button(form.button_box.Save)
QtTest.QTest.mouseClick(ok_widget, QtCore.Qt.LeftButton)
# THEN the following input text is returned
assert self.form.text_edit.toPlainText() == '', 'The returned text should be empty'
assert 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'
self.form.text_edit.setPlainText(text)
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)
form.exec()
ok_widget = form.button_box.button(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 text originally entered should still be there'
assert form.text_edit.toPlainText() == text, 'The text originally entered should still be there'
# WHEN displaying the UI, having set the text and pressing enter
self.form.text_edit.setPlainText('')
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)
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)
# THEN the following text is returned
assert self.form.text_edit.toPlainText() == text, 'The new text should be returned'
assert form.text_edit.toPlainText() == text, 'The new text should be returned'

View File

@ -21,53 +21,27 @@
"""
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):
"""
Test the PluginManager class
"""
@pytest.fixture()
def dummy():
return MagicMock(), MagicMock(), MagicMock()
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()
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault
"""
del self.form
def test_basic_cancel(self):
def test_basic_cancel(form):
"""
Test running the settings form and pressing Cancel
"""
@ -75,13 +49,14 @@ class TestSettingsForm(TestCase, TestMixin):
# 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)
cancel_widget = form.button_box.button(form.button_box.Cancel)
QtTest.QTest.mouseClick(cancel_widget, QtCore.Qt.LeftButton)
# THEN the dialog reject should have been called
assert mocked_reject.call_count == 1, 'The QDialog.reject should have been called'
def test_basic_accept(self):
def test_basic_accept(form):
"""
Test running the settings form and pressing Ok
"""
@ -89,104 +64,109 @@ class TestSettingsForm(TestCase, TestMixin):
# 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)
ok_widget = form.button_box.button(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(self):
def test_basic_register(form):
"""
Test running the settings form and adding a single function
"""
# GIVEN: An initial form add a register function
self.form.register_post_process('function1')
form.register_post_process('function1')
# 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)
ok_widget = form.button_box.button(form.button_box.Ok)
QtTest.QTest.mouseClick(ok_widget, QtCore.Qt.LeftButton)
# THEN the processing stack should be empty
assert len(self.form.processes) == 0, 'The one requested process should have been removed from the stack'
assert len(form.processes) == 0, 'The one requested process should have been removed from the stack'
def test_register_multiple_functions(self):
def test_register_multiple_functions(form):
"""
Test running the settings form and adding multiple functions
"""
# GIVEN: Registering a single function
self.form.register_post_process('function1')
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'
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')
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'
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')
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'
assert len(form.processes) == 2, 'No new processes should have been added to the stack'
def test_register_image_manager_trigger_one(self):
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', self.dummy1)
Registry().register_function('config_screen_changed', self.dummy2)
Registry().register_function('images_regenerate', self.dummy3)
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
self.form.register_post_process('images_config_updated')
self.form.accept()
form.register_post_process('images_config_updated')
form.accept()
# 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'
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'
def test_register_image_manager_trigger_two(self):
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', self.dummy1)
Registry().register_function('config_screen_changed', self.dummy2)
Registry().register_function('images_regenerate', self.dummy3)
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
self.form.register_post_process('config_screen_changed')
self.form.accept()
form.register_post_process('config_screen_changed')
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'
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'
def test_register_image_manager_trigger_three(self):
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', self.dummy1)
Registry().register_function('config_screen_changed', self.dummy2)
Registry().register_function('images_regenerate', self.dummy3)
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
self.form.register_post_process('config_screen_changed')
self.form.register_post_process('images_config_updated')
self.form.accept()
form.register_post_process('config_screen_changed')
form.register_post_process('images_config_updated')
form.accept()
# 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'
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,36 +21,21 @@
"""
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(self):
def test_adjust_button(form):
"""
Test the _adjust_button() method
"""
@ -62,14 +47,15 @@ class TestShortcutform(TestCase, TestMixin):
# WHEN: Call the method.
with patch('PyQt5.QtWidgets.QPushButton.setChecked') as mocked_check_method:
self.form._adjust_button(button, checked, enabled, text)
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.'
def test_space_key_press_event(self):
def test_space_key_press_event(form):
"""
Test the keyPressEvent when the spacebar was pressed
"""
@ -78,48 +64,51 @@ class TestShortcutform(TestCase, TestMixin):
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)
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(self):
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(self.form, 'keyReleaseEvent') as mocked_key_release_event, \
patch.object(self.form.primary_push_button, 'isChecked') as mocked_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()
# WHEN: The event is handled
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
def test_alternate_push_button_checked_key_press_event(self):
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(self.form, 'keyReleaseEvent') as mocked_key_release_event, \
patch.object(self.form.alternate_push_button, 'isChecked') as mocked_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()
# WHEN: The event is handled
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
def test_escape_key_press_event(self):
def test_escape_key_press_event(form):
"""
Test the keyPressEvent when the escape key was pressed
"""
@ -128,52 +117,55 @@ class TestShortcutform(TestCase, TestMixin):
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)
with patch.object(form, 'close') as mocked_close:
form.keyPressEvent(mocked_event)
# THEN: The key should be released
mocked_event.accept.assert_called_with()
mocked_close.assert_called_with()
def test_on_default_radio_button_not_toggled(self):
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(self.form, '_current_item_action') as mocked_current_item_action:
with patch.object(form, '_current_item_action') as mocked_current_item_action:
# WHEN: The clicked method is called
self.form.on_default_radio_button_clicked(False)
form.on_default_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_default_radio_button_clicked_no_action(self):
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(self.form, '_current_item_action') as mocked_current_item_action, \
patch.object(self.form, '_action_shortcuts') as mocked_action_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 default radio button is clicked
self.form.on_default_radio_button_clicked(True)
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_clicked(self):
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(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:
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
@ -181,7 +173,7 @@ class TestShortcutform(TestCase, TestMixin):
mocked_get_shortcut_string.return_value = 'Esc'
# WHEN: The default radio button is clicked
self.form.on_default_radio_button_clicked(True)
form.on_default_radio_button_clicked(True)
# THEN: The shorcuts should be copied across
mocked_current_item_action.assert_called_with()
@ -189,36 +181,38 @@ class TestShortcutform(TestCase, TestMixin):
mocked_refresh_shortcut_list.assert_called_with()
mocked_set_text.assert_called_with('Esc')
def test_on_custom_radio_button_not_toggled(self):
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(self.form, '_current_item_action') as mocked_current_item_action:
with patch.object(form, '_current_item_action') as mocked_current_item_action:
# WHEN: The clicked method is called
self.form.on_custom_radio_button_clicked(False)
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(self):
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(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:
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
self.form.on_custom_radio_button_clicked(True)
form.on_custom_radio_button_clicked(True)
# THEN: The shorcuts should be copied across
mocked_current_item_action.assert_called_with()

View File

@ -21,59 +21,45 @@
"""
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(self):
def test_ui_defaults(form):
"""
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, \
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 self.form.hour_finish_spin_box.maximum() == 4, \
assert 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, \
assert 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, \
assert 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, \
assert 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, \
assert form.second_finish_spin_box.maximum() == 59, \
'The maximum finish second should stay the same as the dialog'
def test_time_display(self):
def test_time_display(form):
"""
Test StartTimeDialog display functionality
"""
@ -84,29 +70,29 @@ class TestStartTimeDialog(TestCase, TestMixin):
mocked_serviceitem.media_length = 3701
# WHEN displaying the UI and pressing enter
self.form.item = {'service_item': mocked_serviceitem}
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)
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'
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}
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)
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'
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,57 +21,41 @@
"""
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):
"""
Test the functions in the ThemeManager module
"""
def setUp(self):
"""
Create the UI
"""
self.setup_application()
self.build_settings()
Registry.create()
Registry().register('settings', Settings())
self.theme_manager = ThemeManager()
@pytest.fixture()
def theme_manager(settings):
thm = ThemeManager()
return thm
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
def test_initialise(self):
def test_theme_manager_initialise(theme_manager):
"""
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()
theme_manager.setup_ui = MagicMock()
theme_manager.build_theme_path = MagicMock()
Settings().setValue('themes/global theme', 'my_theme')
# WHEN: the initialisation is run
self.theme_manager.bootstrap_initialise()
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()
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()
@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):
def test_build_theme_path(mocked_get_section_data_path, mocked_create_paths, theme_manager):
"""
Test the thememanager build_theme_path
"""
@ -79,58 +63,61 @@ class TestThemeManager(TestCase, TestMixin):
mocked_get_section_data_path.return_value = Path('tests/my_theme')
# WHEN: the build_theme_path is run
self.theme_manager.build_theme_path()
theme_manager.build_theme_path()
# 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')
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'))
def test_click_on_new_theme(self):
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()
self.theme_manager.on_add_theme = mocked_event
self.theme_manager.setup_ui(self.theme_manager)
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 = theme_manager.toolbar.actions['newTheme']
new_theme.trigger()
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):
def test_bootstrap_post(mocked_rename_form, mocked_theme_form, theme_manager):
"""
Test the functions of bootstrap_post_setup are called.
"""
# GIVEN:
self.theme_manager.theme_path = MagicMock()
theme_manager.theme_path = MagicMock()
# WHEN:
with patch('openlp.core.ui.thememanager.ThemeProgressForm'):
self.theme_manager.bootstrap_post_set_up()
theme_manager.bootstrap_post_set_up()
# 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
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
def test_bootstrap_completion(self):
def test_bootstrap_completion(theme_manager):
"""
Test the functions of bootstrap_post_setup are called.
"""
# GIVEN:
self.theme_manager.load_themes = MagicMock()
self.theme_manager.upgrade_themes = MagicMock()
theme_manager.load_themes = MagicMock()
theme_manager.upgrade_themes = MagicMock()
# WHEN:
self.theme_manager.bootstrap_completion()
theme_manager.bootstrap_completion()
# THEN:
self.theme_manager.upgrade_themes.assert_called_once()
self.theme_manager.load_themes.assert_called_once()
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,32 +43,28 @@ SEARCH_TYPES = [(SearchTypes.First, QtGui.QIcon(), "First", "First Placeholder T
(SearchTypes.Second, QtGui.QIcon(), "Second", SECOND_PLACEHOLDER_TEXT)]
class TestSearchEdit(TestCase, TestMixin):
"""
Test the EditCustomForm.
"""
def setUp(self):
"""
Create the UI
"""
Registry.create()
self.setup_application()
self.main_window = QtWidgets.QMainWindow()
Registry().register('main_window', self.main_window)
@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}))
self.search_edit = SearchEdit(self.main_window, 'settings_section')
s_edit = SearchEdit(main_window, 'settings_section')
# To complete set up we have to set the search types.
self.search_edit.set_search_types(SEARCH_TYPES)
s_edit.set_search_types(SEARCH_TYPES)
return s_edit
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):
@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 setting the search types of the search edit.
"""
@ -80,84 +75,69 @@ class TestSearchEdit(TestCase, TestMixin):
# 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, \
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)
def test_set_current_search_type(self):
def test_set_current_search_type(search_edit):
"""
Test if changing the search type works.
"""
# GIVEN:
# WHEN: Change the search type
result = self.search_edit.set_current_search_type(SearchTypes.Second)
result = 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, \
assert search_edit.current_search_type() == SearchTypes.Second, \
"The search type should be SearchTypes.Second"
assert self.search_edit.placeholderText() == SECOND_PLACEHOLDER_TEXT, \
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_clear_button_visibility(self):
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 self.search_edit.clear_button.isHidden(), "Pre condition not met. Button should be hidden."
assert 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)
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 self.search_edit.clear_button.isHidden(), "The clear button should be visible."
assert not search_edit.clear_button.isHidden(), "The clear button should be visible."
def test_press_clear_button(self):
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(self.search_edit, QtCore.Qt.Key_A)
QtTest.QTest.keyRelease(self.search_edit, QtCore.Qt.Key_A)
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(self.search_edit.clear_button, QtCore.Qt.LeftButton)
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 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."
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."
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 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
def test_get_items(self):
def test_history_combo_get_items(combo):
"""
Test the getItems() method
"""
# GIVEN: The combo.
# WHEN: Add two items.
self.combo.addItem('test1')
self.combo.addItem('test2')
combo.addItem('test1')
combo.addItem('test2')
# THEN: The list of items should contain both strings.
assert self.combo.getItems() == ['test1', 'test2']
assert combo.getItems() == ['test1', 'test2']

View File

@ -21,66 +21,46 @@
"""
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(self):
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 self.preview_widget.slide_count() == 0, 'The slide list should be empty.'
assert preview_widget.slide_count() == 0, 'The slide list should be empty.'
def test_initial_slide_number(self):
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 self.preview_widget.current_slide_number() == -1, 'The slide number should be -1.'
assert preview_widget.current_slide_number() == -1, 'The slide number should be -1.'
def test_replace_service_item(self):
def test_replace_service_item(preview_widget, state_media):
"""
Test item counts and current number with a service item.
"""
@ -90,12 +70,13 @@ class TestListPreviewWidget(TestCase, TestMixin):
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)
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.'
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(self):
def test_change_slide(preview_widget, state_media):
"""
Test the change_slide method.
"""
@ -105,7 +86,7 @@ class TestListPreviewWidget(TestCase, TestMixin):
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)
preview_widget.replace_service_item(service_item, 1, 0)
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.'
assert preview_widget.current_slide_number() == 1, 'The current slide number should be 1.'