forked from openlp/openlp
Merge branch 'tests_3' into 'master'
Tests 3 - Finish UI and Widgets See merge request openlp/openlp!139
This commit is contained in:
commit
62b89ecec4
@ -82,11 +82,11 @@ def settings(qapp, registry):
|
||||
def mock_settings(registry):
|
||||
"""A Mock Settings() instance"""
|
||||
# Create and register a mock settings object to work with
|
||||
mock_settings = MagicMock()
|
||||
Registry().register('settings', mock_settings)
|
||||
yield mock_settings
|
||||
mk_settings = MagicMock()
|
||||
Registry().register('settings', mk_settings)
|
||||
yield mk_settings
|
||||
Registry().remove('settings')
|
||||
del mock_settings
|
||||
del mk_settings
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -21,103 +21,100 @@
|
||||
"""
|
||||
Package to test the openlp.core.lib.mediamanageritem package.
|
||||
"""
|
||||
from unittest import TestCase
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from openlp.core.common.registry import Registry
|
||||
from openlp.core.lib.mediamanageritem import MediaManagerItem
|
||||
from tests.helpers.testmixin import TestMixin
|
||||
|
||||
|
||||
class TestMediaManagerItem(TestCase, TestMixin):
|
||||
@pytest.yield_fixture
|
||||
def media_env():
|
||||
setup_patcher = patch('openlp.core.lib.mediamanageritem.MediaManagerItem._setup')
|
||||
setup_patcher.start()
|
||||
yield
|
||||
setup_patcher.stop
|
||||
|
||||
|
||||
@patch('openlp.core.lib.mediamanageritem.MediaManagerItem.on_preview_click')
|
||||
def test_on_double_clicked(mocked_on_preview_click, media_env, registry):
|
||||
"""
|
||||
Test the MediaManagerItem class
|
||||
Test that when an item is double-clicked then the item is previewed
|
||||
"""
|
||||
def setUp(self):
|
||||
"""
|
||||
Mock out stuff for all the tests
|
||||
"""
|
||||
Registry.create()
|
||||
self.setup_patcher = patch('openlp.core.lib.mediamanageritem.MediaManagerItem._setup')
|
||||
self.mocked_setup = self.setup_patcher.start()
|
||||
self.addCleanup(self.setup_patcher.stop)
|
||||
# GIVEN: A setting to enable "Double-click to go live" and a media manager item
|
||||
mocked_settings = MagicMock()
|
||||
mocked_settings.value.return_value = False
|
||||
Registry().register('settings', mocked_settings)
|
||||
mmi = MediaManagerItem(None)
|
||||
mmi.can_preview = True
|
||||
mmi.can_make_live = True
|
||||
mmi.can_add_to_service = True
|
||||
|
||||
@patch('openlp.core.lib.mediamanageritem.MediaManagerItem.on_preview_click')
|
||||
def test_on_double_clicked(self, mocked_on_preview_click):
|
||||
"""
|
||||
Test that when an item is double-clicked then the item is previewed
|
||||
"""
|
||||
# GIVEN: A setting to enable "Double-click to go live" and a media manager item
|
||||
mocked_settings = MagicMock()
|
||||
mocked_settings.value.return_value = False
|
||||
Registry().register('settings', mocked_settings)
|
||||
mmi = MediaManagerItem(None)
|
||||
mmi.can_preview = True
|
||||
mmi.can_make_live = True
|
||||
mmi.can_add_to_service = True
|
||||
# WHEN: on_double_clicked() is called
|
||||
mmi.on_double_clicked()
|
||||
|
||||
# WHEN: on_double_clicked() is called
|
||||
mmi.on_double_clicked()
|
||||
# THEN: on_preview_click() should have been called
|
||||
mocked_on_preview_click.assert_called_with()
|
||||
|
||||
# THEN: on_preview_click() should have been called
|
||||
mocked_on_preview_click.assert_called_with()
|
||||
|
||||
def test_required_icons(self):
|
||||
"""
|
||||
Test the default icons for plugins
|
||||
"""
|
||||
# GIVEN: A MediaManagerItem
|
||||
mmi = MediaManagerItem(None)
|
||||
# WHEN: Object is created
|
||||
mmi.required_icons()
|
||||
# THEN: Default icons should be populated
|
||||
assert mmi.has_import_icon is False, 'There should be no import icon by default'
|
||||
assert mmi.has_new_icon is True, 'By default a new icon should be present'
|
||||
assert mmi.has_file_icon is False, 'There should be no file icon by default'
|
||||
assert mmi.has_delete_icon is True, 'By default a delete icon should be present'
|
||||
assert mmi.add_to_service_item is False, 'There should be no add_to_service icon by default'
|
||||
assert mmi.can_preview is True, 'There should be a preview icon by default'
|
||||
assert mmi.can_make_live is True, 'There should be a make live by default'
|
||||
assert mmi.can_add_to_service is True, 'There should be a add to service icon by default'
|
||||
def test_required_icons(media_env):
|
||||
"""
|
||||
Test the default icons for plugins
|
||||
"""
|
||||
# GIVEN: A MediaManagerItem
|
||||
mmi = MediaManagerItem(None)
|
||||
# WHEN: Object is created
|
||||
mmi.required_icons()
|
||||
# THEN: Default icons should be populated
|
||||
assert mmi.has_import_icon is False, 'There should be no import icon by default'
|
||||
assert mmi.has_new_icon is True, 'By default a new icon should be present'
|
||||
assert mmi.has_file_icon is False, 'There should be no file icon by default'
|
||||
assert mmi.has_delete_icon is True, 'By default a delete icon should be present'
|
||||
assert mmi.add_to_service_item is False, 'There should be no add_to_service icon by default'
|
||||
assert mmi.can_preview is True, 'There should be a preview icon by default'
|
||||
assert mmi.can_make_live is True, 'There should be a make live by default'
|
||||
assert mmi.can_add_to_service is True, 'There should be a add to service icon by default'
|
||||
|
||||
@patch('openlp.core.lib.mediamanageritem.MediaManagerItem.on_live_click')
|
||||
def test_on_double_clicked_go_live(self, mocked_on_live_click):
|
||||
"""
|
||||
Test that when "Double-click to go live" is enabled that the item goes live
|
||||
"""
|
||||
# GIVEN: A setting to enable "Double-click to go live" and a media manager item
|
||||
mocked_settings = MagicMock()
|
||||
mocked_settings.value.side_effect = lambda x: x == 'advanced/double click live'
|
||||
Registry().register('settings', mocked_settings)
|
||||
mmi = MediaManagerItem(None)
|
||||
mmi.can_preview = True
|
||||
mmi.can_make_live = True
|
||||
mmi.can_add_to_service = True
|
||||
|
||||
# WHEN: on_double_clicked() is called
|
||||
mmi.on_double_clicked()
|
||||
@patch('openlp.core.lib.mediamanageritem.MediaManagerItem.on_live_click')
|
||||
def test_on_double_clicked_go_live(mocked_on_live_click, media_env, registry):
|
||||
"""
|
||||
Test that when "Double-click to go live" is enabled that the item goes live
|
||||
"""
|
||||
# GIVEN: A setting to enable "Double-click to go live" and a media manager item
|
||||
mocked_settings = MagicMock()
|
||||
mocked_settings.value.side_effect = lambda x: x == 'advanced/double click live'
|
||||
Registry().register('settings', mocked_settings)
|
||||
mmi = MediaManagerItem(None)
|
||||
mmi.can_preview = True
|
||||
mmi.can_make_live = True
|
||||
mmi.can_add_to_service = True
|
||||
|
||||
# THEN: on_live_click() should have been called
|
||||
mocked_on_live_click.assert_called_with()
|
||||
# WHEN: on_double_clicked() is called
|
||||
mmi.on_double_clicked()
|
||||
|
||||
@patch('openlp.core.lib.mediamanageritem.MediaManagerItem.on_live_click')
|
||||
@patch('openlp.core.lib.mediamanageritem.MediaManagerItem.on_preview_click')
|
||||
def test_on_double_clicked_single_click_preview(self, mocked_on_preview_click, mocked_on_live_click):
|
||||
"""
|
||||
Test that when "Single-click preview" is enabled then nothing happens on double-click
|
||||
"""
|
||||
# GIVEN: A setting to enable "Double-click to go live" and a media manager item
|
||||
mocked_settings = MagicMock()
|
||||
mocked_settings.value.side_effect = lambda x: x == 'advanced/single click preview'
|
||||
Registry().register('settings', mocked_settings)
|
||||
mmi = MediaManagerItem(None)
|
||||
mmi.can_preview = True
|
||||
mmi.can_make_live = True
|
||||
mmi.can_add_to_service = True
|
||||
# THEN: on_live_click() should have been called
|
||||
mocked_on_live_click.assert_called_with()
|
||||
|
||||
# WHEN: on_double_clicked() is called
|
||||
mmi.on_double_clicked()
|
||||
|
||||
# THEN: on_live_click() should have been called
|
||||
assert 0 == mocked_on_live_click.call_count, 'on_live_click() should not have been called'
|
||||
assert 0 == mocked_on_preview_click.call_count, 'on_preview_click() should not have been called'
|
||||
@patch('openlp.core.lib.mediamanageritem.MediaManagerItem.on_live_click')
|
||||
@patch('openlp.core.lib.mediamanageritem.MediaManagerItem.on_preview_click')
|
||||
def test_on_double_clicked_single_click_preview(mocked_on_preview_click, mocked_on_live_click, media_env, registry):
|
||||
"""
|
||||
Test that when "Single-click preview" is enabled then nothing happens on double-click
|
||||
"""
|
||||
# GIVEN: A setting to enable "Double-click to go live" and a media manager item
|
||||
mocked_settings = MagicMock()
|
||||
mocked_settings.value.side_effect = lambda x: x == 'advanced/single click preview'
|
||||
Registry().register('settings', mocked_settings)
|
||||
mmi = MediaManagerItem(None)
|
||||
mmi.can_preview = True
|
||||
mmi.can_make_live = True
|
||||
mmi.can_add_to_service = True
|
||||
|
||||
# WHEN: on_double_clicked() is called
|
||||
mmi.on_double_clicked()
|
||||
|
||||
# THEN: on_live_click() should have been called
|
||||
assert 0 == mocked_on_live_click.call_count, 'on_live_click() should not have been called'
|
||||
assert 0 == mocked_on_preview_click.call_count, 'on_preview_click() should not have been called'
|
||||
|
@ -21,7 +21,7 @@
|
||||
"""
|
||||
Package to test the openlp.core.lib.pluginmanager package.
|
||||
"""
|
||||
from unittest import TestCase
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from openlp.core.state import State
|
||||
@ -31,477 +31,491 @@ from openlp.core.lib.plugin import PluginStatus
|
||||
from openlp.core.lib.pluginmanager import PluginManager
|
||||
|
||||
|
||||
class TestPluginManager(TestCase):
|
||||
@pytest.fixture()
|
||||
def plugin_manager_env(registry, state):
|
||||
mocked_main_window = MagicMock()
|
||||
mocked_main_window.file_import_menu.return_value = None
|
||||
mocked_main_window.file_export_menu.return_value = None
|
||||
mocked_main_window.file_export_menu.return_value = None
|
||||
mocked_settings_form = MagicMock()
|
||||
Registry().register('service_list', MagicMock())
|
||||
Registry().register('main_window', mocked_main_window)
|
||||
Registry().register('settings_form', mocked_settings_form)
|
||||
Registry().register('settings', MagicMock())
|
||||
|
||||
|
||||
def test_bootstrap_initialise(settings, state):
|
||||
"""
|
||||
Test the PluginManager class
|
||||
Test the PluginManager.bootstrap_initialise() method
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Some pre-test setup required.
|
||||
"""
|
||||
self.mocked_main_window = MagicMock()
|
||||
self.mocked_main_window.file_import_menu.return_value = None
|
||||
self.mocked_main_window.file_export_menu.return_value = None
|
||||
self.mocked_main_window.file_export_menu.return_value = None
|
||||
self.mocked_settings_form = MagicMock()
|
||||
Registry.create()
|
||||
State().load_settings()
|
||||
Registry().register('service_list', MagicMock())
|
||||
Registry().register('main_window', self.mocked_main_window)
|
||||
Registry().register('settings_form', self.mocked_settings_form)
|
||||
Registry().register('settings', MagicMock())
|
||||
|
||||
def test_bootstrap_initialise(self):
|
||||
"""
|
||||
Test the PluginManager.bootstrap_initialise() method
|
||||
"""
|
||||
# GIVEN: A plugin manager with some mocked out methods
|
||||
manager = PluginManager()
|
||||
|
||||
with patch.object(manager, 'hook_settings_tabs') as mocked_hook_settings_tabs, \
|
||||
patch.object(manager, 'hook_media_manager') as mocked_hook_media_manager, \
|
||||
patch.object(manager, 'hook_import_menu') as mocked_hook_import_menu, \
|
||||
patch.object(manager, 'hook_export_menu') as mocked_hook_export_menu, \
|
||||
patch.object(manager, 'hook_tools_menu') as mocked_hook_tools_menu, \
|
||||
patch.object(manager, 'initialise_plugins') as mocked_initialise_plugins:
|
||||
# WHEN: bootstrap_initialise() is called
|
||||
manager.bootstrap_initialise()
|
||||
manager.bootstrap_post_set_up()
|
||||
|
||||
# THEN: The hook methods should have been called
|
||||
mocked_hook_settings_tabs.assert_called_with()
|
||||
mocked_hook_media_manager.assert_called_with()
|
||||
mocked_hook_import_menu.assert_called_with()
|
||||
mocked_hook_export_menu.assert_called_with()
|
||||
mocked_hook_tools_menu.assert_called_with()
|
||||
mocked_initialise_plugins.assert_called_with()
|
||||
|
||||
def test_hook_media_manager_with_disabled_plugin(self):
|
||||
"""
|
||||
Test running the hook_media_manager() method with a disabled plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Disabled
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Disabled)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run hook_media_manager()
|
||||
plugin_manager.hook_media_manager()
|
||||
|
||||
# THEN: The create_media_manager_item() method should have been called
|
||||
assert 0 == mocked_plugin.create_media_manager_item.call_count, \
|
||||
'The create_media_manager_item() method should not have been called.'
|
||||
|
||||
def test_hook_media_manager_with_active_plugin(self):
|
||||
"""
|
||||
Test running the hook_media_manager() method with an active plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Active
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run hook_media_manager()
|
||||
plugin_manager.hook_media_manager()
|
||||
|
||||
# THEN: The create_media_manager_item() method should have been called
|
||||
mocked_plugin.create_media_manager_item.assert_called_with()
|
||||
|
||||
def test_hook_settings_tabs_with_disabled_plugin_and_no_form(self):
|
||||
"""
|
||||
Test running the hook_settings_tabs() method with a disabled plugin and no form
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Disabled
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run hook_settings_tabs()
|
||||
plugin_manager.hook_settings_tabs()
|
||||
|
||||
# THEN: The hook_settings_tabs() method should have been called
|
||||
assert 0 == mocked_plugin.create_media_manager_item.call_count, \
|
||||
'The create_media_manager_item() method should not have been called.'
|
||||
|
||||
def test_hook_settings_tabs_with_disabled_plugin_and_mocked_form(self):
|
||||
"""
|
||||
Test running the hook_settings_tabs() method with a disabled plugin and a mocked form
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Disabled
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
mocked_settings_form = MagicMock()
|
||||
# Replace the autoloaded plugin with the version for testing in real code this would error
|
||||
mocked_settings_form.plugin_manager = plugin_manager
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run hook_settings_tabs()
|
||||
plugin_manager.hook_settings_tabs()
|
||||
|
||||
# THEN: The create_settings_tab() method should not have been called, but the plugins lists should be the same
|
||||
assert 0 == mocked_plugin.create_settings_tab.call_count, \
|
||||
'The create_media_manager_item() method should not have been called.'
|
||||
assert mocked_settings_form.plugin_manager.plugins == plugin_manager.plugins, \
|
||||
'The plugins on the settings form should be the same as the plugins in the plugin manager'
|
||||
|
||||
def test_hook_settings_tabs_with_active_plugin_and_mocked_form(self):
|
||||
"""
|
||||
Test running the hook_settings_tabs() method with an active plugin and a mocked settings form
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Active
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
mocked_settings_form = MagicMock()
|
||||
# Replace the autoloaded plugin with the version for testing in real code this would error
|
||||
mocked_settings_form.plugin_manager = plugin_manager
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run hook_settings_tabs()
|
||||
plugin_manager.hook_settings_tabs()
|
||||
|
||||
# THEN: The create_media_manager_item() method should have been called with the mocked settings form
|
||||
assert 1 == mocked_plugin.create_settings_tab.call_count, \
|
||||
'The create_media_manager_item() method should have been called once.'
|
||||
assert plugin_manager.plugins == mocked_settings_form.plugin_manager.plugins, \
|
||||
'The plugins on the settings form should be the same as the plugins in the plugin manager'
|
||||
|
||||
def test_hook_settings_tabs_with_active_plugin_and_no_form(self):
|
||||
"""
|
||||
Test running the hook_settings_tabs() method with an active plugin and no settings form
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Active
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run hook_settings_tabs()
|
||||
plugin_manager.hook_settings_tabs()
|
||||
|
||||
# THEN: The create_settings_tab() method should have been called
|
||||
mocked_plugin.create_settings_tab.assert_called_with(self.mocked_settings_form)
|
||||
|
||||
def test_hook_import_menu_with_disabled_plugin(self):
|
||||
"""
|
||||
Test running the hook_import_menu() method with a disabled plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Disabled
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run hook_import_menu()
|
||||
plugin_manager.hook_import_menu()
|
||||
|
||||
# THEN: The create_media_manager_item() method should have been called
|
||||
assert 0 == mocked_plugin.add_import_menu_item.call_count, \
|
||||
'The add_import_menu_item() method should not have been called.'
|
||||
|
||||
def test_hook_import_menu_with_active_plugin(self):
|
||||
"""
|
||||
Test running the hook_import_menu() method with an active plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Active
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run hook_import_menu()
|
||||
plugin_manager.hook_import_menu()
|
||||
|
||||
# THEN: The add_import_menu_item() method should have been called
|
||||
mocked_plugin.add_import_menu_item.assert_called_with(self.mocked_main_window.file_import_menu)
|
||||
|
||||
def test_hook_export_menu_with_disabled_plugin(self):
|
||||
"""
|
||||
Test running the hook_export_menu() method with a disabled plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Disabled
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run hook_export_menu()
|
||||
plugin_manager.hook_export_menu()
|
||||
|
||||
# THEN: The add_export_menu_item() method should not have been called
|
||||
assert 0 == mocked_plugin.add_export_menu_item.call_count, \
|
||||
'The add_export_menu_item() method should not have been called.'
|
||||
|
||||
def test_hook_export_menu_with_active_plugin(self):
|
||||
"""
|
||||
Test running the hook_export_menu() method with an active plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Active
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run hook_export_menu()
|
||||
plugin_manager.hook_export_menu()
|
||||
|
||||
# THEN: The add_export_menu_item() method should have been called
|
||||
mocked_plugin.add_export_menu_item.assert_called_with(self.mocked_main_window.file_export_menu)
|
||||
|
||||
def test_hook_upgrade_plugin_settings_with_disabled_plugin(self):
|
||||
"""
|
||||
Test running the hook_upgrade_plugin_settings() method with a disabled plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Disabled
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
settings = Settings()
|
||||
|
||||
# WHEN: We run hook_upgrade_plugin_settings()
|
||||
plugin_manager.hook_upgrade_plugin_settings(settings)
|
||||
|
||||
# THEN: The upgrade_settings() method should not have been called
|
||||
assert 0 == mocked_plugin.upgrade_settings.call_count, \
|
||||
'The upgrade_settings() method should not have been called.'
|
||||
|
||||
def test_hook_upgrade_plugin_settings_with_active_plugin(self):
|
||||
"""
|
||||
Test running the hook_upgrade_plugin_settings() method with an active plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Active
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
settings = Settings()
|
||||
|
||||
# WHEN: We run hook_upgrade_plugin_settings()
|
||||
plugin_manager.hook_upgrade_plugin_settings(settings)
|
||||
|
||||
# THEN: The add_export_menu_item() method should have been called
|
||||
mocked_plugin.upgrade_settings.assert_called_with(settings)
|
||||
|
||||
def test_hook_tools_menu_with_disabled_plugin(self):
|
||||
"""
|
||||
Test running the hook_tools_menu() method with a disabled plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Disabled
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run hook_tools_menu()
|
||||
plugin_manager.hook_tools_menu()
|
||||
|
||||
# THEN: The add_tools_menu_item() method should have been called
|
||||
assert 0 == mocked_plugin.add_tools_menu_item.call_count, \
|
||||
'The add_tools_menu_item() method should not have been called.'
|
||||
|
||||
def test_hook_tools_menu_with_active_plugin(self):
|
||||
"""
|
||||
Test running the hook_tools_menu() method with an active plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Active
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run hook_tools_menu()
|
||||
plugin_manager.hook_tools_menu()
|
||||
|
||||
# THEN: The add_tools_menu_item() method should have been called
|
||||
mocked_plugin.add_tools_menu_item.assert_called_with(self.mocked_main_window.tools_menu)
|
||||
|
||||
def test_initialise_plugins_with_disabled_plugin(self):
|
||||
"""
|
||||
Test running the initialise_plugins() method with a disabled plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Disabled
|
||||
mocked_plugin.is_active.return_value = False
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run initialise_plugins()
|
||||
plugin_manager.initialise_plugins()
|
||||
|
||||
# THEN: The is_active() method should have been called, and initialise() method should NOT have been called
|
||||
mocked_plugin.is_active.assert_called_with()
|
||||
assert 0 == mocked_plugin.initialise.call_count, 'The initialise() method should not have been called.'
|
||||
|
||||
def test_initialise_plugins_with_active_plugin(self):
|
||||
"""
|
||||
Test running the initialise_plugins() method with an active plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Active
|
||||
mocked_plugin.is_active.return_value = True
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run initialise_plugins()
|
||||
plugin_manager.initialise_plugins()
|
||||
|
||||
# THEN: The is_active() and initialise() methods should have been called
|
||||
mocked_plugin.is_active.assert_called_with()
|
||||
mocked_plugin.initialise.assert_called_with()
|
||||
|
||||
def test_finalise_plugins_with_disabled_plugin(self):
|
||||
"""
|
||||
Test running the finalise_plugins() method with a disabled plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Disabled
|
||||
mocked_plugin.is_active.return_value = False
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run finalise_plugins()
|
||||
plugin_manager.finalise_plugins()
|
||||
|
||||
# THEN: The is_active() method should have been called, and initialise() method should NOT have been called
|
||||
mocked_plugin.is_active.assert_called_with()
|
||||
assert 0 == mocked_plugin.finalise.call_count, 'The finalise() method should not have been called.'
|
||||
|
||||
def test_finalise_plugins_with_active_plugin(self):
|
||||
"""
|
||||
Test running the finalise_plugins() method with an active plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Active
|
||||
mocked_plugin.is_active.return_value = True
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run finalise_plugins()
|
||||
plugin_manager.finalise_plugins()
|
||||
|
||||
# THEN: The is_active() and finalise() methods should have been called
|
||||
mocked_plugin.is_active.assert_called_with()
|
||||
mocked_plugin.finalise.assert_called_with()
|
||||
|
||||
def test_get_plugin_by_name_does_not_exist(self):
|
||||
"""
|
||||
Test running the get_plugin_by_name() method to find a plugin that does not exist
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.name = 'Mocked Plugin'
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run finalise_plugins()
|
||||
result = plugin_manager.get_plugin_by_name('Missing Plugin')
|
||||
|
||||
# THEN: The is_active() and finalise() methods should have been called
|
||||
assert result is None, 'The result for get_plugin_by_name should be None'
|
||||
|
||||
def test_get_plugin_by_name_exists(self):
|
||||
"""
|
||||
Test running the get_plugin_by_name() method to find a plugin that exists
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.name = 'Mocked Plugin'
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run finalise_plugins()
|
||||
result = plugin_manager.get_plugin_by_name('Mocked Plugin')
|
||||
|
||||
# THEN: The is_active() and finalise() methods should have been called
|
||||
assert result == mocked_plugin, 'The result for get_plugin_by_name should be the mocked plugin'
|
||||
|
||||
def test_new_service_created_with_disabled_plugin(self):
|
||||
"""
|
||||
Test running the new_service_created() method with a disabled plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Disabled
|
||||
mocked_plugin.is_active.return_value = False
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run finalise_plugins()
|
||||
plugin_manager.new_service_created()
|
||||
|
||||
# THEN: The isActive() method should have been called, and initialise() method should NOT have been called
|
||||
mocked_plugin.is_active.assert_called_with()
|
||||
assert 0 == mocked_plugin.new_service_created.call_count, \
|
||||
'The new_service_created() method should not have been called.'
|
||||
|
||||
def test_new_service_created_with_active_plugin(self):
|
||||
"""
|
||||
Test running the new_service_created() method with an active plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Active
|
||||
mocked_plugin.is_active.return_value = True
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run new_service_created()
|
||||
plugin_manager.new_service_created()
|
||||
|
||||
# THEN: The is_active() and finalise() methods should have been called
|
||||
mocked_plugin.is_active.assert_called_with()
|
||||
mocked_plugin.new_service_created.assert_called_with()
|
||||
# GIVEN: A plugin manager with some mocked out methods
|
||||
manager = PluginManager()
|
||||
|
||||
with patch.object(manager, 'hook_settings_tabs') as mocked_hook_settings_tabs, \
|
||||
patch.object(manager, 'hook_media_manager') as mocked_hook_media_manager, \
|
||||
patch.object(manager, 'hook_import_menu') as mocked_hook_import_menu, \
|
||||
patch.object(manager, 'hook_export_menu') as mocked_hook_export_menu, \
|
||||
patch.object(manager, 'hook_tools_menu') as mocked_hook_tools_menu, \
|
||||
patch.object(manager, 'initialise_plugins') as mocked_initialise_plugins:
|
||||
# WHEN: bootstrap_initialise() is called
|
||||
manager.bootstrap_initialise()
|
||||
manager.bootstrap_post_set_up()
|
||||
|
||||
# THEN: The hook methods should have been called
|
||||
mocked_hook_settings_tabs.assert_called_with()
|
||||
mocked_hook_media_manager.assert_called_with()
|
||||
mocked_hook_import_menu.assert_called_with()
|
||||
mocked_hook_export_menu.assert_called_with()
|
||||
mocked_hook_tools_menu.assert_called_with()
|
||||
mocked_initialise_plugins.assert_called_with()
|
||||
|
||||
|
||||
def test_hook_media_manager_with_disabled_plugin(registry, state):
|
||||
"""
|
||||
Test running the hook_media_manager() method with a disabled plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Disabled
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Disabled)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run hook_media_manager()
|
||||
plugin_manager.hook_media_manager()
|
||||
|
||||
# THEN: The create_media_manager_item() method should have been called
|
||||
assert 0 == mocked_plugin.create_media_manager_item.call_count, \
|
||||
'The create_media_manager_item() method should not have been called.'
|
||||
|
||||
|
||||
def test_hook_media_manager_with_active_plugin(registry, state):
|
||||
"""
|
||||
Test running the hook_media_manager() method with an active plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Active
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run hook_media_manager()
|
||||
plugin_manager.hook_media_manager()
|
||||
|
||||
# THEN: The create_media_manager_item() method should have been called
|
||||
mocked_plugin.create_media_manager_item.assert_called_with()
|
||||
|
||||
|
||||
def test_hook_settings_tabs_with_disabled_plugin_and_no_form(registry, state):
|
||||
"""
|
||||
Test running the hook_settings_tabs() method with a disabled plugin and no form
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Disabled
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run hook_settings_tabs()
|
||||
plugin_manager.hook_settings_tabs()
|
||||
|
||||
# THEN: The hook_settings_tabs() method should have been called
|
||||
assert 0 == mocked_plugin.create_media_manager_item.call_count, \
|
||||
'The create_media_manager_item() method should not have been called.'
|
||||
|
||||
|
||||
def test_hook_settings_tabs_with_disabled_plugin_and_mocked_form(registry, state):
|
||||
"""
|
||||
Test running the hook_settings_tabs() method with a disabled plugin and a mocked form
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Disabled
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
mocked_settings_form = MagicMock()
|
||||
# Replace the autoloaded plugin with the version for testing in real code this would error
|
||||
mocked_settings_form.plugin_manager = plugin_manager
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run hook_settings_tabs()
|
||||
plugin_manager.hook_settings_tabs()
|
||||
|
||||
# THEN: The create_settings_tab() method should not have been called, but the plugins lists should be the same
|
||||
assert 0 == mocked_plugin.create_settings_tab.call_count, \
|
||||
'The create_media_manager_item() method should not have been called.'
|
||||
assert mocked_settings_form.plugin_manager.plugins == plugin_manager.plugins, \
|
||||
'The plugins on the settings form should be the same as the plugins in the plugin manager'
|
||||
|
||||
|
||||
def test_hook_settings_tabs_with_active_plugin_and_mocked_form(registry, state):
|
||||
"""
|
||||
Test running the hook_settings_tabs() method with an active plugin and a mocked settings form
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Active
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
mocked_settings_form = MagicMock()
|
||||
# Replace the autoloaded plugin with the version for testing in real code this would error
|
||||
mocked_settings_form.plugin_manager = plugin_manager
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run hook_settings_tabs()
|
||||
plugin_manager.hook_settings_tabs()
|
||||
|
||||
# THEN: The create_media_manager_item() method should have been called with the mocked settings form
|
||||
assert 1 == mocked_plugin.create_settings_tab.call_count, \
|
||||
'The create_media_manager_item() method should have been called once.'
|
||||
assert plugin_manager.plugins == mocked_settings_form.plugin_manager.plugins, \
|
||||
'The plugins on the settings form should be the same as the plugins in the plugin manager'
|
||||
|
||||
|
||||
def test_hook_settings_tabs_with_active_plugin_and_no_form(plugin_manager_env):
|
||||
"""
|
||||
Test running the hook_settings_tabs() method with an active plugin and no settings form
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Active
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run hook_settings_tabs()
|
||||
plugin_manager.hook_settings_tabs()
|
||||
|
||||
# THEN: The create_settings_tab() method should have been called
|
||||
mocked_plugin.create_settings_tab.assert_called_with(Registry().get('settings_form'))
|
||||
|
||||
|
||||
def test_hook_import_menu_with_disabled_plugin(registry, state):
|
||||
"""
|
||||
Test running the hook_import_menu() method with a disabled plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Disabled
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run hook_import_menu()
|
||||
plugin_manager.hook_import_menu()
|
||||
|
||||
# THEN: The create_media_manager_item() method should have been called
|
||||
assert 0 == mocked_plugin.add_import_menu_item.call_count, \
|
||||
'The add_import_menu_item() method should not have been called.'
|
||||
|
||||
|
||||
def test_hook_import_menu_with_active_plugin(plugin_manager_env):
|
||||
"""
|
||||
Test running the hook_import_menu() method with an active plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Active
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run hook_import_menu()
|
||||
plugin_manager.hook_import_menu()
|
||||
|
||||
# THEN: The add_import_menu_item() method should have been called
|
||||
mocked_plugin.add_import_menu_item.assert_called_with(Registry().get('main_window').file_import_menu)
|
||||
|
||||
|
||||
def test_hook_export_menu_with_disabled_plugin(registry, state):
|
||||
"""
|
||||
Test running the hook_export_menu() method with a disabled plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Disabled
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run hook_export_menu()
|
||||
plugin_manager.hook_export_menu()
|
||||
|
||||
# THEN: The add_export_menu_item() method should not have been called
|
||||
assert 0 == mocked_plugin.add_export_menu_item.call_count, \
|
||||
'The add_export_menu_item() method should not have been called.'
|
||||
|
||||
|
||||
def test_hook_export_menu_with_active_plugin(plugin_manager_env):
|
||||
"""
|
||||
Test running the hook_export_menu() method with an active plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Active
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run hook_export_menu()
|
||||
plugin_manager.hook_export_menu()
|
||||
|
||||
# THEN: The add_export_menu_item() method should have been called
|
||||
mocked_plugin.add_export_menu_item.assert_called_with(Registry().get('main_window').file_export_menu)
|
||||
|
||||
|
||||
def test_hook_upgrade_plugin_settings_with_disabled_plugin(registry, state):
|
||||
"""
|
||||
Test running the hook_upgrade_plugin_settings() method with a disabled plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Disabled
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
settings = Settings()
|
||||
|
||||
# WHEN: We run hook_upgrade_plugin_settings()
|
||||
plugin_manager.hook_upgrade_plugin_settings(settings)
|
||||
|
||||
# THEN: The upgrade_settings() method should not have been called
|
||||
assert 0 == mocked_plugin.upgrade_settings.call_count, \
|
||||
'The upgrade_settings() method should not have been called.'
|
||||
|
||||
|
||||
def test_hook_upgrade_plugin_settings_with_active_plugin(registry, state):
|
||||
"""
|
||||
Test running the hook_upgrade_plugin_settings() method with an active plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Active
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
settings = Settings()
|
||||
|
||||
# WHEN: We run hook_upgrade_plugin_settings()
|
||||
plugin_manager.hook_upgrade_plugin_settings(settings)
|
||||
|
||||
# THEN: The add_export_menu_item() method should have been called
|
||||
mocked_plugin.upgrade_settings.assert_called_with(settings)
|
||||
|
||||
|
||||
def test_hook_tools_menu_with_disabled_plugin(registry, state):
|
||||
"""
|
||||
Test running the hook_tools_menu() method with a disabled plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Disabled
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run hook_tools_menu()
|
||||
plugin_manager.hook_tools_menu()
|
||||
|
||||
# THEN: The add_tools_menu_item() method should have been called
|
||||
assert 0 == mocked_plugin.add_tools_menu_item.call_count, \
|
||||
'The add_tools_menu_item() method should not have been called.'
|
||||
|
||||
|
||||
def test_hook_tools_menu_with_active_plugin(plugin_manager_env):
|
||||
"""
|
||||
Test running the hook_tools_menu() method with an active plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Active
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run hook_tools_menu()
|
||||
plugin_manager.hook_tools_menu()
|
||||
|
||||
# THEN: The add_tools_menu_item() method should have been called
|
||||
mocked_plugin.add_tools_menu_item.assert_called_with(Registry().get('main_window').tools_menu)
|
||||
|
||||
|
||||
def test_initialise_plugins_with_disabled_plugin(registry, state):
|
||||
"""
|
||||
Test running the initialise_plugins() method with a disabled plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Disabled
|
||||
mocked_plugin.is_active.return_value = False
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run initialise_plugins()
|
||||
plugin_manager.initialise_plugins()
|
||||
|
||||
# THEN: The is_active() method should have been called, and initialise() method should NOT have been called
|
||||
mocked_plugin.is_active.assert_called_with()
|
||||
assert 0 == mocked_plugin.initialise.call_count, 'The initialise() method should not have been called.'
|
||||
|
||||
|
||||
def test_initialise_plugins_with_active_plugin(registry, state):
|
||||
"""
|
||||
Test running the initialise_plugins() method with an active plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Active
|
||||
mocked_plugin.is_active.return_value = True
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run initialise_plugins()
|
||||
plugin_manager.initialise_plugins()
|
||||
|
||||
# THEN: The is_active() and initialise() methods should have been called
|
||||
mocked_plugin.is_active.assert_called_with()
|
||||
mocked_plugin.initialise.assert_called_with()
|
||||
|
||||
|
||||
def test_finalise_plugins_with_disabled_plugin(registry, state):
|
||||
"""
|
||||
Test running the finalise_plugins() method with a disabled plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Disabled
|
||||
mocked_plugin.is_active.return_value = False
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run finalise_plugins()
|
||||
plugin_manager.finalise_plugins()
|
||||
|
||||
# THEN: The is_active() method should have been called, and initialise() method should NOT have been called
|
||||
mocked_plugin.is_active.assert_called_with()
|
||||
assert 0 == mocked_plugin.finalise.call_count, 'The finalise() method should not have been called.'
|
||||
|
||||
|
||||
def test_finalise_plugins_with_active_plugin(registry, state):
|
||||
"""
|
||||
Test running the finalise_plugins() method with an active plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Active
|
||||
mocked_plugin.is_active.return_value = True
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run finalise_plugins()
|
||||
plugin_manager.finalise_plugins()
|
||||
|
||||
# THEN: The is_active() and finalise() methods should have been called
|
||||
mocked_plugin.is_active.assert_called_with()
|
||||
mocked_plugin.finalise.assert_called_with()
|
||||
|
||||
|
||||
def test_get_plugin_by_name_does_not_exist(registry, state):
|
||||
"""
|
||||
Test running the get_plugin_by_name() method to find a plugin that does not exist
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.name = 'Mocked Plugin'
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run finalise_plugins()
|
||||
result = plugin_manager.get_plugin_by_name('Missing Plugin')
|
||||
|
||||
# THEN: The is_active() and finalise() methods should have been called
|
||||
assert result is None, 'The result for get_plugin_by_name should be None'
|
||||
|
||||
|
||||
def test_get_plugin_by_name_exists(registry, state):
|
||||
"""
|
||||
Test running the get_plugin_by_name() method to find a plugin that exists
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.name = 'Mocked Plugin'
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run finalise_plugins()
|
||||
result = plugin_manager.get_plugin_by_name('Mocked Plugin')
|
||||
|
||||
# THEN: The is_active() and finalise() methods should have been called
|
||||
assert result == mocked_plugin, 'The result for get_plugin_by_name should be the mocked plugin'
|
||||
|
||||
|
||||
def test_new_service_created_with_disabled_plugin(registry, state):
|
||||
"""
|
||||
Test running the new_service_created() method with a disabled plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Disabled
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Disabled
|
||||
mocked_plugin.is_active.return_value = False
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run finalise_plugins()
|
||||
plugin_manager.new_service_created()
|
||||
|
||||
# THEN: The isActive() method should have been called, and initialise() method should NOT have been called
|
||||
mocked_plugin.is_active.assert_called_with()
|
||||
assert 0 == mocked_plugin.new_service_created.call_count, \
|
||||
'The new_service_created() method should not have been called.'
|
||||
|
||||
|
||||
def test_new_service_created_with_active_plugin(registry, state):
|
||||
"""
|
||||
Test running the new_service_created() method with an active plugin
|
||||
"""
|
||||
# GIVEN: A PluginManager instance and a list with a mocked up plugin whose status is set to Active
|
||||
mocked_plugin = MagicMock()
|
||||
mocked_plugin.status = PluginStatus.Active
|
||||
mocked_plugin.is_active.return_value = True
|
||||
plugin_manager = PluginManager()
|
||||
Registry().register('mock_plugin', mocked_plugin)
|
||||
State().add_service("mock", 1, is_plugin=True, status=PluginStatus.Active)
|
||||
State().flush_preconditions()
|
||||
|
||||
# WHEN: We run new_service_created()
|
||||
plugin_manager.new_service_created()
|
||||
|
||||
# THEN: The is_active() and finalise() methods should have been called
|
||||
mocked_plugin.is_active.assert_called_with()
|
||||
mocked_plugin.new_service_created.assert_called_with()
|
||||
|
@ -22,18 +22,16 @@
|
||||
Package to test the openlp.core.lib package.
|
||||
"""
|
||||
import os
|
||||
import pytest
|
||||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
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
|
||||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.lib.formattingtags import FormattingTags
|
||||
from openlp.core.lib.serviceitem import ItemCapabilities, ServiceItem
|
||||
from tests.helpers.testmixin import TestMixin
|
||||
from tests.utils import convert_file_service_item
|
||||
from tests.utils.constants import RESOURCE_PATH
|
||||
|
||||
@ -63,407 +61,411 @@ RENDERED_VERSE = 'The Lord said to <span style="-webkit-text-fill-color:red">Noa
|
||||
FOOTER = ['Arky Arky (Unknown)', 'Public Domain', 'CCLI 123456']
|
||||
TEST_PATH = RESOURCE_PATH / 'service'
|
||||
|
||||
__default_settings__ = {
|
||||
'songs/enable chords': True,
|
||||
}
|
||||
|
||||
@pytest.fixture()
|
||||
def state_env(state):
|
||||
State().add_service("media", 0)
|
||||
State().update_pre_conditions("media", True)
|
||||
State().flush_preconditions()
|
||||
|
||||
|
||||
class TestServiceItem(TestCase, TestMixin):
|
||||
@pytest.fixture()
|
||||
def service_item_env(state):
|
||||
# Mock the renderer and its format_slide method
|
||||
mocked_renderer = MagicMock()
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Set up the Registry
|
||||
"""
|
||||
self.build_settings()
|
||||
self.setting.extend_default_settings(__default_settings__)
|
||||
self.setting.setValue('songs/chord notation', 'english')
|
||||
Registry.create()
|
||||
Registry().register('settings', self.setting)
|
||||
# Mock the renderer and its format_slide method
|
||||
mocked_renderer = MagicMock()
|
||||
def side_effect_return_arg(arg1, arg2):
|
||||
return [arg1]
|
||||
|
||||
def side_effect_return_arg(arg1, arg2):
|
||||
return [arg1]
|
||||
mocked_slide_formater = MagicMock(side_effect=side_effect_return_arg)
|
||||
mocked_renderer.format_slide = mocked_slide_formater
|
||||
Registry().register('renderer', mocked_renderer)
|
||||
Registry().register('image_manager', MagicMock())
|
||||
mocked_slide_formater = MagicMock(side_effect=side_effect_return_arg)
|
||||
mocked_renderer.format_slide = mocked_slide_formater
|
||||
Registry().register('renderer', mocked_renderer)
|
||||
Registry().register('image_manager', MagicMock())
|
||||
|
||||
def tearDown(self):
|
||||
"""
|
||||
Clean up
|
||||
"""
|
||||
self.destroy_settings()
|
||||
|
||||
def test_service_item_basic(self):
|
||||
"""
|
||||
Test the Service Item - basic test
|
||||
"""
|
||||
# GIVEN: A new service item
|
||||
def test_service_item_basic():
|
||||
"""
|
||||
Test the Service Item - basic test
|
||||
"""
|
||||
# GIVEN: A new service item
|
||||
|
||||
# WHEN: A service item is created (without a plugin)
|
||||
service_item = ServiceItem(None)
|
||||
# WHEN: A service item is created (without a plugin)
|
||||
service_item = ServiceItem(None)
|
||||
|
||||
# THEN: We should get back a valid service item
|
||||
assert service_item.is_valid is True, 'The new service item should be valid'
|
||||
assert service_item.missing_frames() is True, 'There should not be any frames in the service item'
|
||||
# THEN: We should get back a valid service item
|
||||
assert service_item.is_valid is True, 'The new service item should be valid'
|
||||
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(self):
|
||||
"""
|
||||
Test the Service Item - adding a custom slide from a saved service
|
||||
"""
|
||||
# GIVEN: A new service item and a mocked add icon function
|
||||
service_item = ServiceItem(None)
|
||||
service_item.add_icon = MagicMock()
|
||||
FormattingTags.load_tags()
|
||||
|
||||
# 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)
|
||||
def test_service_item_load_custom_from_service(state_env, settings, service_item_env):
|
||||
"""
|
||||
Test the Service Item - adding a custom slide from a saved service
|
||||
"""
|
||||
# GIVEN: A new service item and a mocked add icon function
|
||||
service_item = ServiceItem(None)
|
||||
service_item.add_icon = MagicMock()
|
||||
FormattingTags.load_tags()
|
||||
|
||||
# THEN: We should get back a valid service item
|
||||
assert service_item.is_valid is True, 'The new service item should be valid'
|
||||
assert len(service_item.get_frames()) == 2, 'The service item should have 2 display frames'
|
||||
assert len(service_item.capabilities) == 5, 'There should be 5 default custom item capabilities'
|
||||
# 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: The frames should also be valid
|
||||
assert 'Test Custom' == service_item.get_display_title(), 'The title should be "Test Custom"'
|
||||
assert 'Slide 1' == service_item.get_frames()[0]['text']
|
||||
assert 'Slide 2' == service_item.get_rendered_frame(1)
|
||||
assert 'Slide 1' == service_item.get_frame_title(0), '"Slide 1" has been returned as the title'
|
||||
assert 'Slide 2' == service_item.get_frame_title(1), '"Slide 2" has been returned as the title'
|
||||
assert '' == service_item.get_frame_title(2), 'Blank has been returned as the title of slide 3'
|
||||
# THEN: We should get back a valid service item
|
||||
assert service_item.is_valid is True, 'The new service item should be valid'
|
||||
assert len(service_item.get_frames()) == 2, 'The service item should have 2 display frames'
|
||||
assert len(service_item.capabilities) == 5, 'There should be 5 default custom item capabilities'
|
||||
|
||||
def test_service_item_load_image_from_service(self):
|
||||
"""
|
||||
Test the Service Item - adding an image from a saved service
|
||||
"""
|
||||
# GIVEN: A new service item and a mocked add icon function
|
||||
image_name = 'image_1.jpg'
|
||||
test_file = TEST_PATH / image_name
|
||||
frame_array = {'path': test_file, 'title': image_name}
|
||||
# THEN: The frames should also be valid
|
||||
assert 'Test Custom' == service_item.get_display_title(), 'The title should be "Test Custom"'
|
||||
assert 'Slide 1' == service_item.get_frames()[0]['text']
|
||||
assert 'Slide 2' == service_item.get_rendered_frame(1)
|
||||
assert 'Slide 1' == service_item.get_frame_title(0), '"Slide 1" has been returned as the title'
|
||||
assert 'Slide 2' == service_item.get_frame_title(1), '"Slide 2" has been returned as the title'
|
||||
assert '' == service_item.get_frame_title(2), 'Blank has been returned as the title of slide 3'
|
||||
|
||||
service_item = ServiceItem(None)
|
||||
service_item.add_icon = MagicMock()
|
||||
|
||||
# WHEN: adding an image from a saved Service and mocked exists
|
||||
line = convert_file_service_item(TEST_PATH, 'serviceitem_image_1.osj')
|
||||
with patch('openlp.core.ui.servicemanager.os.path.exists') as mocked_exists,\
|
||||
patch('openlp.core.lib.serviceitem.AppLocation.get_section_data_path') as \
|
||||
mocked_get_section_data_path:
|
||||
mocked_exists.return_value = True
|
||||
mocked_get_section_data_path.return_value = Path('/path/')
|
||||
service_item.set_from_service(line, TEST_PATH)
|
||||
def test_service_item_load_image_from_service(state_env, settings):
|
||||
"""
|
||||
Test the Service Item - adding an image from a saved service
|
||||
"""
|
||||
# GIVEN: A new service item and a mocked add icon function
|
||||
image_name = 'image_1.jpg'
|
||||
test_file = TEST_PATH / image_name
|
||||
frame_array = {'path': test_file, 'title': image_name}
|
||||
|
||||
# THEN: We should get back a valid service item
|
||||
assert service_item.is_valid is True, 'The new service item should be valid'
|
||||
assert test_file == service_item.get_rendered_frame(0), 'The first frame should match the path to the image'
|
||||
assert frame_array == service_item.get_frames()[0], 'The return should match frame array1'
|
||||
assert test_file == service_item.get_frame_path(0), \
|
||||
'The frame path should match the full path to the image'
|
||||
assert image_name == service_item.get_frame_title(0), 'The frame title should match the image name'
|
||||
assert image_name == service_item.get_display_title(), 'The display title should match the first image name'
|
||||
assert service_item.is_image() is True, 'This service item should be of an "image" type'
|
||||
assert service_item.is_capable(ItemCapabilities.CanMaintain) is True, \
|
||||
'This service item should be able to be Maintained'
|
||||
assert service_item.is_capable(ItemCapabilities.CanPreview) is True, \
|
||||
'This service item should be able to be be Previewed'
|
||||
assert service_item.is_capable(ItemCapabilities.CanLoop) is True, \
|
||||
'This service item should be able to be run in a can be made to Loop'
|
||||
assert service_item.is_capable(ItemCapabilities.CanAppend) is True, \
|
||||
'This service item should be able to have new items added to it'
|
||||
service_item = ServiceItem(None)
|
||||
service_item.add_icon = MagicMock()
|
||||
|
||||
@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(self, mocked_get_section_data_path, mocked_exists):
|
||||
"""
|
||||
Test the Service Item - adding an image from a saved local service
|
||||
"""
|
||||
# GIVEN: A new service item and a mocked add icon function
|
||||
mocked_get_section_data_path.return_value = Path('/path')
|
||||
# WHEN: adding an image from a saved Service and mocked exists
|
||||
line = convert_file_service_item(TEST_PATH, 'serviceitem_image_1.osj')
|
||||
with patch('openlp.core.ui.servicemanager.os.path.exists') as mocked_exists,\
|
||||
patch('openlp.core.lib.serviceitem.AppLocation.get_section_data_path') as \
|
||||
mocked_get_section_data_path:
|
||||
mocked_exists.return_value = True
|
||||
image_name1 = 'image_1.jpg'
|
||||
image_name2 = 'image_2.jpg'
|
||||
test_file1 = os.path.join('/home', 'openlp', image_name1)
|
||||
test_file2 = os.path.join('/home', 'openlp', image_name2)
|
||||
frame_array1 = {'path': test_file1, 'title': image_name1}
|
||||
frame_array2 = {'path': test_file2, 'title': image_name2}
|
||||
service_item = ServiceItem(None)
|
||||
service_item.add_icon = MagicMock()
|
||||
service_item2 = ServiceItem(None)
|
||||
service_item2.add_icon = MagicMock()
|
||||
mocked_get_section_data_path.return_value = Path('/path/')
|
||||
service_item.set_from_service(line, TEST_PATH)
|
||||
|
||||
# WHEN: adding an image from a saved Service and mocked exists
|
||||
line = convert_file_service_item(TEST_PATH, 'serviceitem_image_2.osj')
|
||||
line2 = convert_file_service_item(TEST_PATH, 'serviceitem_image_2.osj', 1)
|
||||
service_item2.set_from_service(line2)
|
||||
# THEN: We should get back a valid service item
|
||||
assert service_item.is_valid is True, 'The new service item should be valid'
|
||||
assert test_file == service_item.get_rendered_frame(0), 'The first frame should match the path to the image'
|
||||
assert frame_array == service_item.get_frames()[0], 'The return should match frame array1'
|
||||
assert test_file == service_item.get_frame_path(0), \
|
||||
'The frame path should match the full path to the image'
|
||||
assert image_name == service_item.get_frame_title(0), 'The frame title should match the image name'
|
||||
assert image_name == service_item.get_display_title(), 'The display title should match the first image name'
|
||||
assert service_item.is_image() is True, 'This service item should be of an "image" type'
|
||||
assert service_item.is_capable(ItemCapabilities.CanMaintain) is True, \
|
||||
'This service item should be able to be Maintained'
|
||||
assert service_item.is_capable(ItemCapabilities.CanPreview) is True, \
|
||||
'This service item should be able to be be Previewed'
|
||||
assert service_item.is_capable(ItemCapabilities.CanLoop) is True, \
|
||||
'This service item should be able to be run in a can be made to Loop'
|
||||
assert service_item.is_capable(ItemCapabilities.CanAppend) is True, \
|
||||
'This service item should be able to have new items added to it'
|
||||
|
||||
|
||||
@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):
|
||||
"""
|
||||
Test the Service Item - adding an image from a saved local service
|
||||
"""
|
||||
# GIVEN: A new service item and a mocked add icon function
|
||||
mocked_get_section_data_path.return_value = Path('/path')
|
||||
mocked_exists.return_value = True
|
||||
image_name1 = 'image_1.jpg'
|
||||
image_name2 = 'image_2.jpg'
|
||||
test_file1 = os.path.join('/home', 'openlp', image_name1)
|
||||
test_file2 = os.path.join('/home', 'openlp', image_name2)
|
||||
frame_array1 = {'path': test_file1, 'title': image_name1}
|
||||
frame_array2 = {'path': test_file2, 'title': image_name2}
|
||||
service_item = ServiceItem(None)
|
||||
service_item.add_icon = MagicMock()
|
||||
service_item2 = ServiceItem(None)
|
||||
service_item2.add_icon = MagicMock()
|
||||
|
||||
# WHEN: adding an image from a saved Service and mocked exists
|
||||
line = convert_file_service_item(TEST_PATH, 'serviceitem_image_2.osj')
|
||||
line2 = convert_file_service_item(TEST_PATH, 'serviceitem_image_2.osj', 1)
|
||||
service_item2.set_from_service(line2)
|
||||
service_item.set_from_service(line)
|
||||
|
||||
# THEN: We should get back a valid service item
|
||||
assert service_item.is_valid is True, 'The first service item should be valid'
|
||||
assert service_item2.is_valid is True, 'The second service item should be valid'
|
||||
# These test will fail on windows due to the difference in folder seperators
|
||||
if os.name != 'nt':
|
||||
assert test_file1 == service_item.get_rendered_frame(0), \
|
||||
'The first frame should match the path to the image'
|
||||
assert test_file2 == service_item2.get_rendered_frame(0), \
|
||||
'The Second frame should match the path to the image'
|
||||
assert frame_array1 == service_item.get_frames()[0], 'The return should match the frame array1'
|
||||
assert frame_array2 == service_item2.get_frames()[0], 'The return should match the frame array2'
|
||||
assert test_file1 == str(service_item.get_frame_path(0)), \
|
||||
'The frame path should match the full path to the image'
|
||||
assert test_file2 == str(service_item2.get_frame_path(0)), \
|
||||
'The frame path should match the full path to the image'
|
||||
assert image_name1 == service_item.get_frame_title(0), 'The 1st frame title should match the image name'
|
||||
assert image_name2 == service_item2.get_frame_title(0), 'The 2nd frame title should match the image name'
|
||||
assert service_item.name == service_item.title.lower(), \
|
||||
'The plugin name should match the display title, as there are > 1 Images'
|
||||
assert service_item.is_image() is True, 'This service item should be of an "image" type'
|
||||
assert service_item.is_capable(ItemCapabilities.CanMaintain) is True, \
|
||||
'This service item should be able to be Maintained'
|
||||
assert service_item.is_capable(ItemCapabilities.CanPreview) is True, \
|
||||
'This service item should be able to be be Previewed'
|
||||
assert service_item.is_capable(ItemCapabilities.CanLoop) is True, \
|
||||
'This service item should be able to be run in a can be made to Loop'
|
||||
assert service_item.is_capable(ItemCapabilities.CanAppend) is True, \
|
||||
'This service item should be able to have new items added to it'
|
||||
|
||||
|
||||
def test_add_from_command_for_a_presentation():
|
||||
"""
|
||||
Test the Service Item - adding a presentation
|
||||
"""
|
||||
# GIVEN: A service item, a mocked icon and presentation data
|
||||
service_item = ServiceItem(None)
|
||||
presentation_name = 'test.pptx'
|
||||
image = MagicMock()
|
||||
display_title = 'DisplayTitle'
|
||||
notes = 'Note1\nNote2\n'
|
||||
frame = {'title': presentation_name, 'image': image, 'path': TEST_PATH,
|
||||
'display_title': display_title, 'notes': notes, 'thumbnail': image}
|
||||
|
||||
# WHEN: adding presentation to service_item
|
||||
service_item.add_from_command(TEST_PATH, presentation_name, image, display_title, notes)
|
||||
|
||||
# THEN: verify that it is setup as a Command and that the frame data matches
|
||||
assert service_item.service_item_type == ServiceItemType.Command, 'It should be a Command'
|
||||
assert service_item.get_frames()[0] == frame, 'Frames should match'
|
||||
|
||||
|
||||
def test_add_from_command_without_display_title_and_notes():
|
||||
"""
|
||||
Test the Service Item - add from command, but not presentation
|
||||
"""
|
||||
# GIVEN: A new service item, a mocked icon and image data
|
||||
service_item = ServiceItem(None)
|
||||
image_name = 'test.img'
|
||||
image = MagicMock()
|
||||
frame = {'title': image_name, 'image': image, 'path': TEST_PATH,
|
||||
'display_title': None, 'notes': None, 'thumbnail': image}
|
||||
|
||||
# WHEN: adding image to service_item
|
||||
service_item.add_from_command(TEST_PATH, image_name, image)
|
||||
|
||||
# THEN: verify that it is setup as a Command and that the frame data matches
|
||||
assert service_item.service_item_type == ServiceItemType.Command, 'It should be a Command'
|
||||
assert service_item.get_frames()[0] == frame, 'Frames should match'
|
||||
|
||||
|
||||
@patch(u'openlp.core.lib.serviceitem.ServiceItem.image_manager')
|
||||
@patch('openlp.core.lib.serviceitem.AppLocation.get_section_data_path')
|
||||
def test_add_from_command_for_a_presentation_thumb(mocked_get_section_data_path, mocked_image_manager):
|
||||
"""
|
||||
Test the Service Item - adding a presentation, updating the thumb path & adding the thumb to image_manager
|
||||
"""
|
||||
# GIVEN: A service item, a mocked AppLocation and presentation data
|
||||
mocked_get_section_data_path.return_value = Path('mocked') / 'section' / 'path'
|
||||
service_item = ServiceItem(None)
|
||||
service_item.add_capability(ItemCapabilities.HasThumbnails)
|
||||
service_item.has_original_files = False
|
||||
service_item.name = 'presentations'
|
||||
presentation_name = 'test.pptx'
|
||||
thumb = Path('tmp') / 'test' / 'thumb.png'
|
||||
display_title = 'DisplayTitle'
|
||||
notes = 'Note1\nNote2\n'
|
||||
expected_thumb_path = Path('mocked') / 'section' / 'path' / 'thumbnails' / \
|
||||
md5_hash(str(TEST_PATH / presentation_name).encode('utf8')) / 'thumb.png'
|
||||
frame = {'title': presentation_name, 'image': str(expected_thumb_path), 'path': str(TEST_PATH),
|
||||
'display_title': display_title, 'notes': notes, 'thumbnail': str(expected_thumb_path)}
|
||||
|
||||
# WHEN: adding presentation to service_item
|
||||
service_item.add_from_command(str(TEST_PATH), presentation_name, thumb, display_title, notes)
|
||||
|
||||
# THEN: verify that it is setup as a Command and that the frame data matches
|
||||
assert service_item.service_item_type == ServiceItemType.Command, 'It should be a Command'
|
||||
assert service_item.get_frames()[0] == frame, 'Frames should match'
|
||||
# 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):
|
||||
"""
|
||||
Test the Service Item - load an optical media item
|
||||
"""
|
||||
# GIVEN: A new service item and a mocked add icon function
|
||||
service_item = ServiceItem(None)
|
||||
service_item.add_icon = MagicMock()
|
||||
|
||||
# WHEN: We load a serviceitem with optical media
|
||||
line = convert_file_service_item(TEST_PATH, 'serviceitem-dvd.osj')
|
||||
with patch('openlp.core.ui.servicemanager.os.path.exists') as mocked_exists:
|
||||
mocked_exists.return_value = True
|
||||
service_item.set_from_service(line)
|
||||
|
||||
# THEN: We should get back a valid service item
|
||||
assert service_item.is_valid is True, 'The first service item should be valid'
|
||||
assert service_item2.is_valid is True, 'The second service item should be valid'
|
||||
# These test will fail on windows due to the difference in folder seperators
|
||||
if os.name != 'nt':
|
||||
assert test_file1 == service_item.get_rendered_frame(0), \
|
||||
'The first frame should match the path to the image'
|
||||
assert test_file2 == service_item2.get_rendered_frame(0), \
|
||||
'The Second frame should match the path to the image'
|
||||
assert frame_array1 == service_item.get_frames()[0], 'The return should match the frame array1'
|
||||
assert frame_array2 == service_item2.get_frames()[0], 'The return should match the frame array2'
|
||||
assert test_file1 == str(service_item.get_frame_path(0)), \
|
||||
'The frame path should match the full path to the image'
|
||||
assert test_file2 == str(service_item2.get_frame_path(0)), \
|
||||
'The frame path should match the full path to the image'
|
||||
assert image_name1 == service_item.get_frame_title(0), 'The 1st frame title should match the image name'
|
||||
assert image_name2 == service_item2.get_frame_title(0), 'The 2nd frame title should match the image name'
|
||||
assert service_item.name == service_item.title.lower(), \
|
||||
'The plugin name should match the display title, as there are > 1 Images'
|
||||
assert service_item.is_image() is True, 'This service item should be of an "image" type'
|
||||
assert service_item.is_capable(ItemCapabilities.CanMaintain) is True, \
|
||||
'This service item should be able to be Maintained'
|
||||
assert service_item.is_capable(ItemCapabilities.CanPreview) is True, \
|
||||
'This service item should be able to be be Previewed'
|
||||
assert service_item.is_capable(ItemCapabilities.CanLoop) is True, \
|
||||
'This service item should be able to be run in a can be made to Loop'
|
||||
assert service_item.is_capable(ItemCapabilities.CanAppend) is True, \
|
||||
'This service item should be able to have new items added to it'
|
||||
# THEN: We should get back a valid service item with optical media info
|
||||
assert service_item.is_valid is True, 'The service item should be valid'
|
||||
assert service_item.is_capable(ItemCapabilities.IsOptical) is True, 'The item should be Optical'
|
||||
assert service_item.start_time == 654.375, 'Start time should be 654.375'
|
||||
assert service_item.end_time == 672.069, 'End time should be 672.069'
|
||||
assert service_item.media_length == 17.694, 'Media length should be 17.694'
|
||||
|
||||
def test_add_from_command_for_a_presentation(self):
|
||||
"""
|
||||
Test the Service Item - adding a presentation
|
||||
"""
|
||||
# GIVEN: A service item, a mocked icon and presentation data
|
||||
service_item = ServiceItem(None)
|
||||
presentation_name = 'test.pptx'
|
||||
image = MagicMock()
|
||||
display_title = 'DisplayTitle'
|
||||
notes = 'Note1\nNote2\n'
|
||||
frame = {'title': presentation_name, 'image': image, 'path': TEST_PATH,
|
||||
'display_title': display_title, 'notes': notes, 'thumbnail': image}
|
||||
|
||||
# WHEN: adding presentation to service_item
|
||||
service_item.add_from_command(TEST_PATH, presentation_name, image, display_title, notes)
|
||||
def test_service_item_load_song_and_audio_from_service(state_env, settings, service_item_env):
|
||||
"""
|
||||
Test the Service Item - adding a song slide from a saved service
|
||||
"""
|
||||
# GIVEN: A new service item and a mocked add icon function
|
||||
service_item = ServiceItem(None)
|
||||
service_item.add_icon = MagicMock()
|
||||
FormattingTags.load_tags()
|
||||
|
||||
# THEN: verify that it is setup as a Command and that the frame data matches
|
||||
assert service_item.service_item_type == ServiceItemType.Command, 'It should be a Command'
|
||||
assert service_item.get_frames()[0] == frame, 'Frames should match'
|
||||
# WHEN: We add a custom from a saved service
|
||||
line = convert_file_service_item(TEST_PATH, 'serviceitem-song-linked-audio.osj')
|
||||
service_item.set_from_service(line, Path('/test/'))
|
||||
|
||||
def test_add_from_command_without_display_title_and_notes(self):
|
||||
"""
|
||||
Test the Service Item - add from command, but not presentation
|
||||
"""
|
||||
# GIVEN: A new service item, a mocked icon and image data
|
||||
service_item = ServiceItem(None)
|
||||
image_name = 'test.img'
|
||||
image = MagicMock()
|
||||
frame = {'title': image_name, 'image': image, 'path': TEST_PATH,
|
||||
'display_title': None, 'notes': None, 'thumbnail': image}
|
||||
# THEN: We should get back a valid service item
|
||||
assert service_item.is_valid is True, 'The new service item should be valid'
|
||||
assert len(service_item.display_slides) == 6, 'The service item should have 6 display slides'
|
||||
assert len(service_item.capabilities) == 7, 'There should be 7 default custom item capabilities'
|
||||
assert 'Amazing Grace' == service_item.get_display_title(), 'The title should be "Amazing Grace"'
|
||||
assert CLEANED_VERSE[:-1] == service_item.get_frames()[0]['text'], \
|
||||
'The returned text matches the input, except the last line feed'
|
||||
assert 'Amazing Grace! how sweet the s' == service_item.get_frame_title(0), \
|
||||
'"Amazing Grace! how sweet the s" has been returned as the title'
|
||||
assert '’Twas grace that taught my hea' == service_item.get_frame_title(1), \
|
||||
'"’Twas grace that taught my hea" has been returned as the title'
|
||||
assert Path('/test/amazing_grace.mp3') == service_item.background_audio[0], \
|
||||
'"/test/amazing_grace.mp3" should be in the background_audio list'
|
||||
|
||||
# WHEN: adding image to service_item
|
||||
service_item.add_from_command(TEST_PATH, image_name, image)
|
||||
|
||||
# THEN: verify that it is setup as a Command and that the frame data matches
|
||||
assert service_item.service_item_type == ServiceItemType.Command, 'It should be a Command'
|
||||
assert service_item.get_frames()[0] == frame, 'Frames should match'
|
||||
def test_service_item_get_theme_data_global_level(settings):
|
||||
"""
|
||||
Test the service item - get theme data when set to global theme level
|
||||
"""
|
||||
# GIVEN: A service item with a theme and theme level set to global
|
||||
service_item = ServiceItem(None)
|
||||
service_item.theme = 'song_theme'
|
||||
mocked_theme_manager = MagicMock()
|
||||
mocked_theme_manager.global_theme = 'global_theme'
|
||||
mocked_theme_manager.get_theme_data = Mock(side_effect=lambda value: value)
|
||||
Registry().register('theme_manager', mocked_theme_manager)
|
||||
settings.setValue('servicemanager/service theme', 'service_theme')
|
||||
settings.setValue('themes/theme level', ThemeLevel.Global)
|
||||
|
||||
@patch(u'openlp.core.lib.serviceitem.ServiceItem.image_manager')
|
||||
@patch('openlp.core.lib.serviceitem.AppLocation.get_section_data_path')
|
||||
def test_add_from_command_for_a_presentation_thumb(self, mocked_get_section_data_path, mocked_image_manager):
|
||||
"""
|
||||
Test the Service Item - adding a presentation, updating the thumb path & adding the thumb to image_manager
|
||||
"""
|
||||
# GIVEN: A service item, a mocked AppLocation and presentation data
|
||||
mocked_get_section_data_path.return_value = Path('mocked') / 'section' / 'path'
|
||||
service_item = ServiceItem(None)
|
||||
service_item.add_capability(ItemCapabilities.HasThumbnails)
|
||||
service_item.has_original_files = False
|
||||
service_item.name = 'presentations'
|
||||
presentation_name = 'test.pptx'
|
||||
thumb = Path('tmp') / 'test' / 'thumb.png'
|
||||
display_title = 'DisplayTitle'
|
||||
notes = 'Note1\nNote2\n'
|
||||
expected_thumb_path = Path('mocked') / 'section' / 'path' / 'thumbnails' / \
|
||||
md5_hash(str(TEST_PATH / presentation_name).encode('utf8')) / 'thumb.png'
|
||||
frame = {'title': presentation_name, 'image': str(expected_thumb_path), 'path': str(TEST_PATH),
|
||||
'display_title': display_title, 'notes': notes, 'thumbnail': str(expected_thumb_path)}
|
||||
# WHEN: Get theme data is run
|
||||
theme = service_item.get_theme_data()
|
||||
|
||||
# WHEN: adding presentation to service_item
|
||||
service_item.add_from_command(str(TEST_PATH), presentation_name, thumb, display_title, notes)
|
||||
# THEN: theme should be the global theme
|
||||
assert theme == mocked_theme_manager.global_theme
|
||||
|
||||
# THEN: verify that it is setup as a Command and that the frame data matches
|
||||
assert service_item.service_item_type == ServiceItemType.Command, 'It should be a Command'
|
||||
assert service_item.get_frames()[0] == frame, 'Frames should match'
|
||||
# assert 1 == mocked_image_manager.add_image.call_count, 'image_manager should be used'
|
||||
|
||||
def test_service_item_load_optical_media_from_service(self):
|
||||
"""
|
||||
Test the Service Item - load an optical media item
|
||||
"""
|
||||
# GIVEN: A new service item and a mocked add icon function
|
||||
service_item = ServiceItem(None)
|
||||
service_item.add_icon = MagicMock()
|
||||
def test_service_item_get_theme_data_service_level_service_undefined(settings):
|
||||
"""
|
||||
Test the service item - get theme data when set to service theme level
|
||||
"""
|
||||
# GIVEN: A service item with a theme and theme level set to service
|
||||
service_item = ServiceItem(None)
|
||||
service_item.theme = 'song_theme'
|
||||
mocked_theme_manager = MagicMock()
|
||||
mocked_theme_manager.global_theme = 'global_theme'
|
||||
mocked_theme_manager.get_theme_data = Mock(side_effect=lambda value: value)
|
||||
Registry().register('theme_manager', mocked_theme_manager)
|
||||
settings.setValue('servicemanager/service theme', 'service_theme')
|
||||
settings.setValue('themes/theme level', ThemeLevel.Service)
|
||||
|
||||
# WHEN: We load a serviceitem with optical media
|
||||
line = convert_file_service_item(TEST_PATH, 'serviceitem-dvd.osj')
|
||||
with patch('openlp.core.ui.servicemanager.os.path.exists') as mocked_exists:
|
||||
mocked_exists.return_value = True
|
||||
service_item.set_from_service(line)
|
||||
# WHEN: Get theme data is run
|
||||
theme = service_item.get_theme_data()
|
||||
|
||||
# THEN: We should get back a valid service item with optical media info
|
||||
assert service_item.is_valid is True, 'The service item should be valid'
|
||||
assert service_item.is_capable(ItemCapabilities.IsOptical) is True, 'The item should be Optical'
|
||||
assert service_item.start_time == 654.375, 'Start time should be 654.375'
|
||||
assert service_item.end_time == 672.069, 'End time should be 672.069'
|
||||
assert service_item.media_length == 17.694, 'Media length should be 17.694'
|
||||
# THEN: theme should be the global theme
|
||||
assert theme == mocked_theme_manager.global_theme
|
||||
|
||||
def test_service_item_load_song_and_audio_from_service(self):
|
||||
"""
|
||||
Test the Service Item - adding a song slide from a saved service
|
||||
"""
|
||||
# GIVEN: A new service item and a mocked add icon function
|
||||
service_item = ServiceItem(None)
|
||||
service_item.add_icon = MagicMock()
|
||||
FormattingTags.load_tags()
|
||||
|
||||
# WHEN: We add a custom from a saved service
|
||||
line = convert_file_service_item(TEST_PATH, 'serviceitem-song-linked-audio.osj')
|
||||
service_item.set_from_service(line, Path('/test/'))
|
||||
def test_service_item_get_theme_data_service_level_service_defined(settings):
|
||||
"""
|
||||
Test the service item - get theme data when set to service theme level
|
||||
"""
|
||||
# GIVEN: A service item with a theme and theme level set to service
|
||||
service_item = ServiceItem(None)
|
||||
service_item.theme = 'song_theme'
|
||||
service_item.from_service = True
|
||||
mocked_theme_manager = MagicMock()
|
||||
mocked_theme_manager.global_theme = 'global_theme'
|
||||
mocked_theme_manager.get_theme_data = Mock(side_effect=lambda value: value)
|
||||
Registry().register('theme_manager', mocked_theme_manager)
|
||||
settings.setValue('servicemanager/service theme', 'service_theme')
|
||||
settings.setValue('themes/theme level', ThemeLevel.Service)
|
||||
|
||||
# THEN: We should get back a valid service item
|
||||
assert service_item.is_valid is True, 'The new service item should be valid'
|
||||
assert len(service_item.display_slides) == 6, 'The service item should have 6 display slides'
|
||||
assert len(service_item.capabilities) == 7, 'There should be 7 default custom item capabilities'
|
||||
assert 'Amazing Grace' == service_item.get_display_title(), 'The title should be "Amazing Grace"'
|
||||
assert CLEANED_VERSE[:-1] == service_item.get_frames()[0]['text'], \
|
||||
'The returned text matches the input, except the last line feed'
|
||||
assert 'Amazing Grace! how sweet the s' == service_item.get_frame_title(0), \
|
||||
'"Amazing Grace! how sweet the s" has been returned as the title'
|
||||
assert '’Twas grace that taught my hea' == service_item.get_frame_title(1), \
|
||||
'"’Twas grace that taught my hea" has been returned as the title'
|
||||
assert Path('/test/amazing_grace.mp3') == service_item.background_audio[0], \
|
||||
'"/test/amazing_grace.mp3" should be in the background_audio list'
|
||||
# WHEN: Get theme data is run
|
||||
theme = service_item.get_theme_data()
|
||||
|
||||
def test_service_item_get_theme_data_global_level(self):
|
||||
"""
|
||||
Test the service item - get theme data when set to global theme level
|
||||
"""
|
||||
# GIVEN: A service item with a theme and theme level set to global
|
||||
service_item = ServiceItem(None)
|
||||
service_item.theme = 'song_theme'
|
||||
mocked_theme_manager = MagicMock()
|
||||
mocked_theme_manager.global_theme = 'global_theme'
|
||||
mocked_theme_manager.get_theme_data = Mock(side_effect=lambda value: value)
|
||||
Registry().register('theme_manager', mocked_theme_manager)
|
||||
Settings().setValue('servicemanager/service theme', 'service_theme')
|
||||
Settings().setValue('themes/theme level', ThemeLevel.Global)
|
||||
# THEN: theme should be the service theme
|
||||
assert theme == settings.value('servicemanager/service theme')
|
||||
|
||||
# WHEN: Get theme data is run
|
||||
theme = service_item.get_theme_data()
|
||||
|
||||
# THEN: theme should be the global theme
|
||||
assert theme == mocked_theme_manager.global_theme
|
||||
def test_service_item_get_theme_data_song_level(settings):
|
||||
"""
|
||||
Test the service item - get theme data when set to song theme level
|
||||
"""
|
||||
# GIVEN: A service item with a theme and theme level set to song
|
||||
service_item = ServiceItem(None)
|
||||
service_item.theme = 'song_theme'
|
||||
mocked_theme_manager = MagicMock()
|
||||
mocked_theme_manager.global_theme = 'global_theme'
|
||||
mocked_theme_manager.get_theme_data = Mock(side_effect=lambda value: value)
|
||||
Registry().register('theme_manager', mocked_theme_manager)
|
||||
settings.setValue('servicemanager/service theme', 'service_theme')
|
||||
settings.setValue('themes/theme level', ThemeLevel.Song)
|
||||
|
||||
def test_service_item_get_theme_data_service_level_service_undefined(self):
|
||||
"""
|
||||
Test the service item - get theme data when set to service theme level
|
||||
"""
|
||||
# GIVEN: A service item with a theme and theme level set to service
|
||||
service_item = ServiceItem(None)
|
||||
service_item.theme = 'song_theme'
|
||||
mocked_theme_manager = MagicMock()
|
||||
mocked_theme_manager.global_theme = 'global_theme'
|
||||
mocked_theme_manager.get_theme_data = Mock(side_effect=lambda value: value)
|
||||
Registry().register('theme_manager', mocked_theme_manager)
|
||||
Settings().setValue('servicemanager/service theme', 'service_theme')
|
||||
Settings().setValue('themes/theme level', ThemeLevel.Service)
|
||||
# WHEN: Get theme data is run
|
||||
theme = service_item.get_theme_data()
|
||||
|
||||
# WHEN: Get theme data is run
|
||||
theme = service_item.get_theme_data()
|
||||
# THEN: theme should be the song theme
|
||||
assert theme == service_item.theme
|
||||
|
||||
# THEN: theme should be the global theme
|
||||
assert theme == mocked_theme_manager.global_theme
|
||||
|
||||
def test_service_item_get_theme_data_service_level_service_defined(self):
|
||||
"""
|
||||
Test the service item - get theme data when set to service theme level
|
||||
"""
|
||||
# GIVEN: A service item with a theme and theme level set to service
|
||||
service_item = ServiceItem(None)
|
||||
service_item.theme = 'song_theme'
|
||||
service_item.from_service = True
|
||||
mocked_theme_manager = MagicMock()
|
||||
mocked_theme_manager.global_theme = 'global_theme'
|
||||
mocked_theme_manager.get_theme_data = Mock(side_effect=lambda value: value)
|
||||
Registry().register('theme_manager', mocked_theme_manager)
|
||||
Settings().setValue('servicemanager/service theme', 'service_theme')
|
||||
Settings().setValue('themes/theme level', ThemeLevel.Service)
|
||||
def test_service_item_get_theme_data_song_level_service_fallback(settings):
|
||||
"""
|
||||
Test the service item - get theme data when set to song theme level
|
||||
but the song theme doesn't exist
|
||||
"""
|
||||
# GIVEN: A service item with a theme and theme level set to song
|
||||
service_item = ServiceItem(None)
|
||||
service_item.from_service = True
|
||||
mocked_theme_manager = MagicMock()
|
||||
mocked_theme_manager.global_theme = 'global_theme'
|
||||
mocked_theme_manager.get_theme_data = Mock(side_effect=lambda value: value)
|
||||
Registry().register('theme_manager', mocked_theme_manager)
|
||||
settings.setValue('servicemanager/service theme', 'service_theme')
|
||||
settings.setValue('themes/theme level', ThemeLevel.Song)
|
||||
|
||||
# WHEN: Get theme data is run
|
||||
theme = service_item.get_theme_data()
|
||||
# WHEN: Get theme data is run
|
||||
theme = service_item.get_theme_data()
|
||||
|
||||
# THEN: theme should be the service theme
|
||||
assert theme == Settings().value('servicemanager/service theme')
|
||||
# THEN: theme should be the serice theme
|
||||
assert theme == settings.value('servicemanager/service theme')
|
||||
|
||||
def test_service_item_get_theme_data_song_level(self):
|
||||
"""
|
||||
Test the service item - get theme data when set to song theme level
|
||||
"""
|
||||
# GIVEN: A service item with a theme and theme level set to song
|
||||
service_item = ServiceItem(None)
|
||||
service_item.theme = 'song_theme'
|
||||
mocked_theme_manager = MagicMock()
|
||||
mocked_theme_manager.global_theme = 'global_theme'
|
||||
mocked_theme_manager.get_theme_data = Mock(side_effect=lambda value: value)
|
||||
Registry().register('theme_manager', mocked_theme_manager)
|
||||
Settings().setValue('servicemanager/service theme', 'service_theme')
|
||||
Settings().setValue('themes/theme level', ThemeLevel.Song)
|
||||
|
||||
# WHEN: Get theme data is run
|
||||
theme = service_item.get_theme_data()
|
||||
def test_service_item_get_theme_data_song_level_global_fallback(settings):
|
||||
"""
|
||||
Test the service item - get theme data when set to song theme level
|
||||
but the song and service theme don't exist
|
||||
"""
|
||||
# GIVEN: A service item with a theme and theme level set to song
|
||||
service_item = ServiceItem(None)
|
||||
mocked_theme_manager = MagicMock()
|
||||
mocked_theme_manager.global_theme = 'global_theme'
|
||||
mocked_theme_manager.get_theme_data = Mock(side_effect=lambda value: value)
|
||||
Registry().register('theme_manager', mocked_theme_manager)
|
||||
settings.setValue('servicemanager/service theme', 'service_theme')
|
||||
settings.setValue('themes/theme level', ThemeLevel.Song)
|
||||
|
||||
# THEN: theme should be the song theme
|
||||
assert theme == service_item.theme
|
||||
# WHEN: Get theme data is run
|
||||
theme = service_item.get_theme_data()
|
||||
|
||||
def test_service_item_get_theme_data_song_level_service_fallback(self):
|
||||
"""
|
||||
Test the service item - get theme data when set to song theme level
|
||||
but the song theme doesn't exist
|
||||
"""
|
||||
# GIVEN: A service item with a theme and theme level set to song
|
||||
service_item = ServiceItem(None)
|
||||
service_item.from_service = True
|
||||
mocked_theme_manager = MagicMock()
|
||||
mocked_theme_manager.global_theme = 'global_theme'
|
||||
mocked_theme_manager.get_theme_data = Mock(side_effect=lambda value: value)
|
||||
Registry().register('theme_manager', mocked_theme_manager)
|
||||
Settings().setValue('servicemanager/service theme', 'service_theme')
|
||||
Settings().setValue('themes/theme level', ThemeLevel.Song)
|
||||
|
||||
# WHEN: Get theme data is run
|
||||
theme = service_item.get_theme_data()
|
||||
|
||||
# THEN: theme should be the serice theme
|
||||
assert theme == Settings().value('servicemanager/service theme')
|
||||
|
||||
def test_service_item_get_theme_data_song_level_global_fallback(self):
|
||||
"""
|
||||
Test the service item - get theme data when set to song theme level
|
||||
but the song and service theme don't exist
|
||||
"""
|
||||
# GIVEN: A service item with a theme and theme level set to song
|
||||
service_item = ServiceItem(None)
|
||||
mocked_theme_manager = MagicMock()
|
||||
mocked_theme_manager.global_theme = 'global_theme'
|
||||
mocked_theme_manager.get_theme_data = Mock(side_effect=lambda value: value)
|
||||
Registry().register('theme_manager', mocked_theme_manager)
|
||||
Settings().setValue('servicemanager/service theme', 'service_theme')
|
||||
Settings().setValue('themes/theme level', ThemeLevel.Song)
|
||||
|
||||
# WHEN: Get theme data is run
|
||||
theme = service_item.get_theme_data()
|
||||
|
||||
# THEN: theme should be the global theme
|
||||
assert theme == mocked_theme_manager.global_theme
|
||||
# THEN: theme should be the global theme
|
||||
assert theme == mocked_theme_manager.global_theme
|
||||
|
@ -22,319 +22,324 @@
|
||||
Package to test the openlp.core.lib.theme package.
|
||||
"""
|
||||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from openlp.core.lib.theme import BackgroundType, BackgroundGradientType, TransitionType, TransitionSpeed, Theme
|
||||
|
||||
|
||||
class ThemeEnumerationTypes(TestCase):
|
||||
def test_background_type_to_string():
|
||||
"""
|
||||
Test the theme enum methods.
|
||||
Test the to_string method of :class:`BackgroundType`
|
||||
"""
|
||||
def test_background_type_to_string(self):
|
||||
"""
|
||||
Test the to_string method of :class:`BackgroundType`
|
||||
"""
|
||||
# GIVEN: The BackgroundType members
|
||||
background_type_solid = BackgroundType.Solid
|
||||
background_type_gradient = BackgroundType.Gradient
|
||||
background_type_image = BackgroundType.Image
|
||||
background_type_transparent = BackgroundType.Transparent
|
||||
background_type_video = BackgroundType.Video
|
||||
background_type_stream = BackgroundType.Stream
|
||||
# GIVEN: The BackgroundType members
|
||||
background_type_solid = BackgroundType.Solid
|
||||
background_type_gradient = BackgroundType.Gradient
|
||||
background_type_image = BackgroundType.Image
|
||||
background_type_transparent = BackgroundType.Transparent
|
||||
background_type_video = BackgroundType.Video
|
||||
background_type_stream = BackgroundType.Stream
|
||||
|
||||
# WHEN: Calling BackgroundType.to_string
|
||||
# THEN: The string equivalents should be returned
|
||||
assert BackgroundType.to_string(background_type_solid) == 'solid'
|
||||
assert BackgroundType.to_string(background_type_gradient) == 'gradient'
|
||||
assert BackgroundType.to_string(background_type_image) == 'image'
|
||||
assert BackgroundType.to_string(background_type_transparent) == 'transparent'
|
||||
assert BackgroundType.to_string(background_type_video) == 'video'
|
||||
assert BackgroundType.to_string(background_type_stream) == 'stream'
|
||||
|
||||
def test_background_type_from_string(self):
|
||||
"""
|
||||
Test the from_string method of :class:`BackgroundType`
|
||||
"""
|
||||
# GIVEN: The BackgroundType strings
|
||||
background_type_solid = 'solid'
|
||||
background_type_gradient = 'gradient'
|
||||
background_type_image = 'image'
|
||||
background_type_transparent = 'transparent'
|
||||
background_type_video = 'video'
|
||||
background_type_stream = 'stream'
|
||||
|
||||
# WHEN: Calling BackgroundType.from_string
|
||||
# THEN: The enum equivalents should be returned
|
||||
assert BackgroundType.from_string(background_type_solid) == BackgroundType.Solid
|
||||
assert BackgroundType.from_string(background_type_gradient) == BackgroundType.Gradient
|
||||
assert BackgroundType.from_string(background_type_image) == BackgroundType.Image
|
||||
assert BackgroundType.from_string(background_type_transparent) == BackgroundType.Transparent
|
||||
assert BackgroundType.from_string(background_type_video) == BackgroundType.Video
|
||||
assert BackgroundType.from_string(background_type_stream) == BackgroundType.Stream
|
||||
|
||||
def test_background_gradient_type_to_string(self):
|
||||
"""
|
||||
Test the to_string method of :class:`BackgroundGradientType`
|
||||
"""
|
||||
# GIVEN: The BackgroundGradientType member
|
||||
background_gradient_horizontal = BackgroundGradientType.Horizontal
|
||||
background_gradient_vertical = BackgroundGradientType.Vertical
|
||||
background_gradient_circular = BackgroundGradientType.Circular
|
||||
background_gradient_left_top = BackgroundGradientType.LeftTop
|
||||
background_gradient_left_bottom = BackgroundGradientType.LeftBottom
|
||||
|
||||
# WHEN: Calling BackgroundGradientType.to_string
|
||||
# THEN: The string equivalents should be returned
|
||||
assert BackgroundGradientType.to_string(background_gradient_horizontal) == 'horizontal'
|
||||
assert BackgroundGradientType.to_string(background_gradient_vertical) == 'vertical'
|
||||
assert BackgroundGradientType.to_string(background_gradient_circular) == 'circular'
|
||||
assert BackgroundGradientType.to_string(background_gradient_left_top) == 'leftTop'
|
||||
assert BackgroundGradientType.to_string(background_gradient_left_bottom) == 'leftBottom'
|
||||
|
||||
def test_background_gradient_type_from_string(self):
|
||||
"""
|
||||
Test the from_string method of :class:`BackgroundGradientType`
|
||||
"""
|
||||
# GIVEN: The BackgroundGradientType strings
|
||||
background_gradient_horizontal = 'horizontal'
|
||||
background_gradient_vertical = 'vertical'
|
||||
background_gradient_circular = 'circular'
|
||||
background_gradient_left_top = 'leftTop'
|
||||
background_gradient_left_bottom = 'leftBottom'
|
||||
|
||||
# WHEN: Calling BackgroundGradientType.from_string
|
||||
# THEN: The enum equivalents should be returned
|
||||
assert BackgroundGradientType.from_string(background_gradient_horizontal) == BackgroundGradientType.Horizontal
|
||||
assert BackgroundGradientType.from_string(background_gradient_vertical) == BackgroundGradientType.Vertical
|
||||
assert BackgroundGradientType.from_string(background_gradient_circular) == BackgroundGradientType.Circular
|
||||
assert BackgroundGradientType.from_string(background_gradient_left_top) == BackgroundGradientType.LeftTop
|
||||
assert BackgroundGradientType.from_string(background_gradient_left_bottom) == BackgroundGradientType.LeftBottom
|
||||
|
||||
def test_transition_type_to_string(self):
|
||||
"""
|
||||
Test the to_string method of :class:`TransitionType`
|
||||
"""
|
||||
# GIVEN: The TransitionType member
|
||||
transition_type_fade = TransitionType.Fade
|
||||
transition_type_slide = TransitionType.Slide
|
||||
transition_type_convex = TransitionType.Convex
|
||||
transition_type_concave = TransitionType.Concave
|
||||
transition_type_zoom = TransitionType.Zoom
|
||||
|
||||
# WHEN: Calling TransitionType.to_string
|
||||
# THEN: The string equivalents should be returned
|
||||
assert TransitionType.to_string(transition_type_fade) == 'fade'
|
||||
assert TransitionType.to_string(transition_type_slide) == 'slide'
|
||||
assert TransitionType.to_string(transition_type_convex) == 'convex'
|
||||
assert TransitionType.to_string(transition_type_concave) == 'concave'
|
||||
assert TransitionType.to_string(transition_type_zoom) == 'zoom'
|
||||
|
||||
def test_transition_type_from_string(self):
|
||||
"""
|
||||
Test the from_string method of :class:`TransitionType`
|
||||
"""
|
||||
# GIVEN: The TransitionType strings
|
||||
transition_type_fade = 'fade'
|
||||
transition_type_slide = 'slide'
|
||||
transition_type_convex = 'convex'
|
||||
transition_type_concave = 'concave'
|
||||
transition_type_zoom = 'zoom'
|
||||
|
||||
# WHEN: Calling TransitionType.from_string
|
||||
# THEN: The enum equivalents should be returned
|
||||
assert TransitionType.from_string(transition_type_fade) == TransitionType.Fade
|
||||
assert TransitionType.from_string(transition_type_slide) == TransitionType.Slide
|
||||
assert TransitionType.from_string(transition_type_convex) == TransitionType.Convex
|
||||
assert TransitionType.from_string(transition_type_concave) == TransitionType.Concave
|
||||
assert TransitionType.from_string(transition_type_zoom) == TransitionType.Zoom
|
||||
|
||||
def test_transition_speed_to_string(self):
|
||||
"""
|
||||
Test the to_string method of :class:`TransitionSpeed`
|
||||
"""
|
||||
# GIVEN: The TransitionSpeed member
|
||||
transition_speed_normal = TransitionSpeed.Normal
|
||||
transition_speed_fast = TransitionSpeed.Fast
|
||||
transition_speed_slow = TransitionSpeed.Slow
|
||||
|
||||
# WHEN: Calling TransitionSpeed.to_string
|
||||
# THEN: The string equivalents should be returned
|
||||
assert TransitionSpeed.to_string(transition_speed_normal) == 'normal'
|
||||
assert TransitionSpeed.to_string(transition_speed_fast) == 'fast'
|
||||
assert TransitionSpeed.to_string(transition_speed_slow) == 'slow'
|
||||
|
||||
def test_transition_speed_from_string(self):
|
||||
"""
|
||||
Test the from_string method of :class:`TransitionSpeed`
|
||||
"""
|
||||
# GIVEN: The TransitionSpeed strings
|
||||
transition_speed_normal = 'normal'
|
||||
transition_speed_fast = 'fast'
|
||||
transition_speed_slow = 'slow'
|
||||
|
||||
# WHEN: Calling TransitionSpeed.from_string
|
||||
# THEN: The enum equivalents should be returned
|
||||
assert TransitionSpeed.from_string(transition_speed_normal) == TransitionSpeed.Normal
|
||||
assert TransitionSpeed.from_string(transition_speed_fast) == TransitionSpeed.Fast
|
||||
assert TransitionSpeed.from_string(transition_speed_slow) == TransitionSpeed.Slow
|
||||
# WHEN: Calling BackgroundType.to_string
|
||||
# THEN: The string equivalents should be returned
|
||||
assert BackgroundType.to_string(background_type_solid) == 'solid'
|
||||
assert BackgroundType.to_string(background_type_gradient) == 'gradient'
|
||||
assert BackgroundType.to_string(background_type_image) == 'image'
|
||||
assert BackgroundType.to_string(background_type_transparent) == 'transparent'
|
||||
assert BackgroundType.to_string(background_type_video) == 'video'
|
||||
assert BackgroundType.to_string(background_type_stream) == 'stream'
|
||||
|
||||
|
||||
class TestTheme(TestCase):
|
||||
def test_background_type_from_string():
|
||||
"""
|
||||
Test the Theme class
|
||||
Test the from_string method of :class:`BackgroundType`
|
||||
"""
|
||||
def test_new_theme(self):
|
||||
"""
|
||||
Test the Theme constructor
|
||||
"""
|
||||
# GIVEN: The Theme class
|
||||
# WHEN: A theme object is created
|
||||
default_theme = Theme()
|
||||
# GIVEN: The BackgroundType strings
|
||||
background_type_solid = 'solid'
|
||||
background_type_gradient = 'gradient'
|
||||
background_type_image = 'image'
|
||||
background_type_transparent = 'transparent'
|
||||
background_type_video = 'video'
|
||||
background_type_stream = 'stream'
|
||||
|
||||
# THEN: The default values should be correct
|
||||
self.check_theme(default_theme)
|
||||
# WHEN: Calling BackgroundType.from_string
|
||||
# THEN: The enum equivalents should be returned
|
||||
assert BackgroundType.from_string(background_type_solid) == BackgroundType.Solid
|
||||
assert BackgroundType.from_string(background_type_gradient) == BackgroundType.Gradient
|
||||
assert BackgroundType.from_string(background_type_image) == BackgroundType.Image
|
||||
assert BackgroundType.from_string(background_type_transparent) == BackgroundType.Transparent
|
||||
assert BackgroundType.from_string(background_type_video) == BackgroundType.Video
|
||||
assert BackgroundType.from_string(background_type_stream) == BackgroundType.Stream
|
||||
|
||||
def test_expand_json(self):
|
||||
"""
|
||||
Test the expand_json method
|
||||
"""
|
||||
# GIVEN: A Theme object and some JSON to "expand"
|
||||
theme = Theme()
|
||||
theme_json = {
|
||||
'background': {
|
||||
'border_color': '#000000',
|
||||
'type': 'solid'
|
||||
|
||||
def test_background_gradient_type_to_string():
|
||||
"""
|
||||
Test the to_string method of :class:`BackgroundGradientType`
|
||||
"""
|
||||
# GIVEN: The BackgroundGradientType member
|
||||
background_gradient_horizontal = BackgroundGradientType.Horizontal
|
||||
background_gradient_vertical = BackgroundGradientType.Vertical
|
||||
background_gradient_circular = BackgroundGradientType.Circular
|
||||
background_gradient_left_top = BackgroundGradientType.LeftTop
|
||||
background_gradient_left_bottom = BackgroundGradientType.LeftBottom
|
||||
|
||||
# WHEN: Calling BackgroundGradientType.to_string
|
||||
# THEN: The string equivalents should be returned
|
||||
assert BackgroundGradientType.to_string(background_gradient_horizontal) == 'horizontal'
|
||||
assert BackgroundGradientType.to_string(background_gradient_vertical) == 'vertical'
|
||||
assert BackgroundGradientType.to_string(background_gradient_circular) == 'circular'
|
||||
assert BackgroundGradientType.to_string(background_gradient_left_top) == 'leftTop'
|
||||
assert BackgroundGradientType.to_string(background_gradient_left_bottom) == 'leftBottom'
|
||||
|
||||
|
||||
def test_background_gradient_type_from_string():
|
||||
"""
|
||||
Test the from_string method of :class:`BackgroundGradientType`
|
||||
"""
|
||||
# GIVEN: The BackgroundGradientType strings
|
||||
background_gradient_horizontal = 'horizontal'
|
||||
background_gradient_vertical = 'vertical'
|
||||
background_gradient_circular = 'circular'
|
||||
background_gradient_left_top = 'leftTop'
|
||||
background_gradient_left_bottom = 'leftBottom'
|
||||
|
||||
# WHEN: Calling BackgroundGradientType.from_string
|
||||
# THEN: The enum equivalents should be returned
|
||||
assert BackgroundGradientType.from_string(background_gradient_horizontal) == BackgroundGradientType.Horizontal
|
||||
assert BackgroundGradientType.from_string(background_gradient_vertical) == BackgroundGradientType.Vertical
|
||||
assert BackgroundGradientType.from_string(background_gradient_circular) == BackgroundGradientType.Circular
|
||||
assert BackgroundGradientType.from_string(background_gradient_left_top) == BackgroundGradientType.LeftTop
|
||||
assert BackgroundGradientType.from_string(background_gradient_left_bottom) == BackgroundGradientType.LeftBottom
|
||||
|
||||
|
||||
def test_transition_type_to_string():
|
||||
"""
|
||||
Test the to_string method of :class:`TransitionType`
|
||||
"""
|
||||
# GIVEN: The TransitionType member
|
||||
transition_type_fade = TransitionType.Fade
|
||||
transition_type_slide = TransitionType.Slide
|
||||
transition_type_convex = TransitionType.Convex
|
||||
transition_type_concave = TransitionType.Concave
|
||||
transition_type_zoom = TransitionType.Zoom
|
||||
|
||||
# WHEN: Calling TransitionType.to_string
|
||||
# THEN: The string equivalents should be returned
|
||||
assert TransitionType.to_string(transition_type_fade) == 'fade'
|
||||
assert TransitionType.to_string(transition_type_slide) == 'slide'
|
||||
assert TransitionType.to_string(transition_type_convex) == 'convex'
|
||||
assert TransitionType.to_string(transition_type_concave) == 'concave'
|
||||
assert TransitionType.to_string(transition_type_zoom) == 'zoom'
|
||||
|
||||
|
||||
def test_transition_type_from_string():
|
||||
"""
|
||||
Test the from_string method of :class:`TransitionType`
|
||||
"""
|
||||
# GIVEN: The TransitionType strings
|
||||
transition_type_fade = 'fade'
|
||||
transition_type_slide = 'slide'
|
||||
transition_type_convex = 'convex'
|
||||
transition_type_concave = 'concave'
|
||||
transition_type_zoom = 'zoom'
|
||||
|
||||
# WHEN: Calling TransitionType.from_string
|
||||
# THEN: The enum equivalents should be returned
|
||||
assert TransitionType.from_string(transition_type_fade) == TransitionType.Fade
|
||||
assert TransitionType.from_string(transition_type_slide) == TransitionType.Slide
|
||||
assert TransitionType.from_string(transition_type_convex) == TransitionType.Convex
|
||||
assert TransitionType.from_string(transition_type_concave) == TransitionType.Concave
|
||||
assert TransitionType.from_string(transition_type_zoom) == TransitionType.Zoom
|
||||
|
||||
|
||||
def test_transition_speed_to_string():
|
||||
"""
|
||||
Test the to_string method of :class:`TransitionSpeed`
|
||||
"""
|
||||
# GIVEN: The TransitionSpeed member
|
||||
transition_speed_normal = TransitionSpeed.Normal
|
||||
transition_speed_fast = TransitionSpeed.Fast
|
||||
transition_speed_slow = TransitionSpeed.Slow
|
||||
|
||||
# WHEN: Calling TransitionSpeed.to_string
|
||||
# THEN: The string equivalents should be returned
|
||||
assert TransitionSpeed.to_string(transition_speed_normal) == 'normal'
|
||||
assert TransitionSpeed.to_string(transition_speed_fast) == 'fast'
|
||||
assert TransitionSpeed.to_string(transition_speed_slow) == 'slow'
|
||||
|
||||
|
||||
def test_transition_speed_from_string():
|
||||
"""
|
||||
Test the from_string method of :class:`TransitionSpeed`
|
||||
"""
|
||||
# GIVEN: The TransitionSpeed strings
|
||||
transition_speed_normal = 'normal'
|
||||
transition_speed_fast = 'fast'
|
||||
transition_speed_slow = 'slow'
|
||||
|
||||
# WHEN: Calling TransitionSpeed.from_string
|
||||
# THEN: The enum equivalents should be returned
|
||||
assert TransitionSpeed.from_string(transition_speed_normal) == TransitionSpeed.Normal
|
||||
assert TransitionSpeed.from_string(transition_speed_fast) == TransitionSpeed.Fast
|
||||
assert TransitionSpeed.from_string(transition_speed_slow) == TransitionSpeed.Slow
|
||||
|
||||
|
||||
def test_new_theme():
|
||||
"""
|
||||
Test the Theme constructor
|
||||
"""
|
||||
# GIVEN: The Theme class
|
||||
# WHEN: A theme object is created
|
||||
default_theme = Theme()
|
||||
|
||||
# THEN: The default values should be correct
|
||||
check_theme(default_theme)
|
||||
|
||||
|
||||
def test_expand_json():
|
||||
"""
|
||||
Test the expand_json method
|
||||
"""
|
||||
# GIVEN: A Theme object and some JSON to "expand"
|
||||
theme = Theme()
|
||||
theme_json = {
|
||||
'background': {
|
||||
'border_color': '#000000',
|
||||
'type': 'solid'
|
||||
},
|
||||
'display': {
|
||||
'vertical_align': 0
|
||||
},
|
||||
'font': {
|
||||
'footer': {
|
||||
'bold': False
|
||||
},
|
||||
'display': {
|
||||
'vertical_align': 0
|
||||
},
|
||||
'font': {
|
||||
'footer': {
|
||||
'bold': False
|
||||
},
|
||||
'main': {
|
||||
'name': 'Arial'
|
||||
}
|
||||
'main': {
|
||||
'name': 'Arial'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# WHEN: Theme.expand_json() is run
|
||||
theme.expand_json(theme_json)
|
||||
# WHEN: Theme.expand_json() is run
|
||||
theme.expand_json(theme_json)
|
||||
|
||||
# THEN: The attributes should be set on the object
|
||||
self.check_theme(theme)
|
||||
# THEN: The attributes should be set on the object
|
||||
check_theme(theme)
|
||||
|
||||
def test_extend_image_filename(self):
|
||||
"""
|
||||
Test the extend_image_filename method
|
||||
"""
|
||||
# GIVEN: A theme object
|
||||
theme = Theme()
|
||||
theme.theme_name = 'MyBeautifulTheme'
|
||||
theme.background_filename = Path('video.mp4')
|
||||
theme.background_type = 'video'
|
||||
path = Path.home()
|
||||
|
||||
# WHEN: Theme.extend_image_filename is run
|
||||
theme.extend_image_filename(path)
|
||||
def test_extend_image_filename():
|
||||
"""
|
||||
Test the extend_image_filename method
|
||||
"""
|
||||
# GIVEN: A theme object
|
||||
theme = Theme()
|
||||
theme.theme_name = 'MyBeautifulTheme'
|
||||
theme.background_filename = Path('video.mp4')
|
||||
theme.background_type = 'video'
|
||||
path = Path.home()
|
||||
|
||||
# THEN: The filename of the background should be correct
|
||||
expected_filename = path / 'MyBeautifulTheme' / 'video.mp4'
|
||||
assert expected_filename == theme.background_filename
|
||||
assert 'MyBeautifulTheme' == theme.theme_name
|
||||
# WHEN: Theme.extend_image_filename is run
|
||||
theme.extend_image_filename(path)
|
||||
|
||||
def test_save_retrieve(self):
|
||||
"""
|
||||
Load a dummy theme, save it and reload it
|
||||
"""
|
||||
# GIVEN: The default Theme class
|
||||
# WHEN: A theme object is created
|
||||
default_theme = Theme()
|
||||
# THEN: The default values should be correct
|
||||
save_theme_json = default_theme.export_theme()
|
||||
lt = Theme()
|
||||
lt.load_theme(save_theme_json)
|
||||
self.check_theme(lt)
|
||||
# THEN: The filename of the background should be correct
|
||||
expected_filename = path / 'MyBeautifulTheme' / 'video.mp4'
|
||||
assert expected_filename == theme.background_filename
|
||||
assert 'MyBeautifulTheme' == theme.theme_name
|
||||
|
||||
@patch('openlp.core.display.screens.ScreenList.current')
|
||||
def test_set_default_footer(self, mock_geometry):
|
||||
"""
|
||||
Test the set_default_footer function sets the footer back to default
|
||||
(reletive to the screen)
|
||||
"""
|
||||
# GIVEN: A screen geometry object and a Theme footer with a strange area
|
||||
mock_geometry.display_geometry = MagicMock()
|
||||
mock_geometry.display_geometry.height.return_value = 600
|
||||
mock_geometry.display_geometry.width.return_value = 400
|
||||
theme = Theme()
|
||||
theme.font_main_x = 20
|
||||
theme.font_footer_x = 207
|
||||
theme.font_footer_y = 25
|
||||
theme.font_footer_width = 4253
|
||||
theme.font_footer_height = 5423
|
||||
|
||||
# WHEN: set_default_footer is called
|
||||
theme.set_default_footer()
|
||||
def test_save_retrieve():
|
||||
"""
|
||||
Load a dummy theme, save it and reload it
|
||||
"""
|
||||
# GIVEN: The default Theme class
|
||||
# WHEN: A theme object is created
|
||||
default_theme = Theme()
|
||||
# THEN: The default values should be correct
|
||||
save_theme_json = default_theme.export_theme()
|
||||
lt = Theme()
|
||||
lt.load_theme(save_theme_json)
|
||||
check_theme(lt)
|
||||
|
||||
# THEN: footer should be set, header should not have changed
|
||||
assert theme.font_main_x == 20, 'header should not have been changed'
|
||||
assert theme.font_footer_x == 10, 'x pos should be reset to default of 10'
|
||||
assert theme.font_footer_y == 540, 'y pos should be reset to (screen_size_height * 9 / 10)'
|
||||
assert theme.font_footer_width == 380, 'width should have been reset to (screen_size_width - 20)'
|
||||
assert theme.font_footer_height == 60, 'height should have been reset to (screen_size_height / 10)'
|
||||
|
||||
@patch('openlp.core.display.screens.ScreenList.current')
|
||||
def test_set_default_header(self, mock_geometry):
|
||||
"""
|
||||
Test the set_default_header function sets the header back to default
|
||||
(reletive to the screen)
|
||||
"""
|
||||
# GIVEN: A screen geometry object and a Theme header with a strange area
|
||||
mock_geometry.display_geometry = MagicMock()
|
||||
mock_geometry.display_geometry.height.return_value = 600
|
||||
mock_geometry.display_geometry.width.return_value = 400
|
||||
theme = Theme()
|
||||
theme.font_footer_x = 200
|
||||
theme.font_main_x = 687
|
||||
theme.font_main_y = 546
|
||||
theme.font_main_width = 345
|
||||
theme.font_main_height = 653
|
||||
@patch('openlp.core.display.screens.ScreenList.current')
|
||||
def test_set_default_footer(mock_geometry):
|
||||
"""
|
||||
Test the set_default_footer function sets the footer back to default
|
||||
(reletive to the screen)
|
||||
"""
|
||||
# GIVEN: A screen geometry object and a Theme footer with a strange area
|
||||
mock_geometry.display_geometry = MagicMock()
|
||||
mock_geometry.display_geometry.height.return_value = 600
|
||||
mock_geometry.display_geometry.width.return_value = 400
|
||||
theme = Theme()
|
||||
theme.font_main_x = 20
|
||||
theme.font_footer_x = 207
|
||||
theme.font_footer_y = 25
|
||||
theme.font_footer_width = 4253
|
||||
theme.font_footer_height = 5423
|
||||
|
||||
# WHEN: set_default_header is called
|
||||
theme.set_default_header()
|
||||
# WHEN: set_default_footer is called
|
||||
theme.set_default_footer()
|
||||
|
||||
# THEN: footer should be set, header should not have changed
|
||||
assert theme.font_footer_x == 200, 'footer should not have been changed'
|
||||
assert theme.font_main_x == 10, 'x pos should be reset to default of 10'
|
||||
assert theme.font_main_y == 0, 'y pos should be reset to 0'
|
||||
assert theme.font_main_width == 380, 'width should have been reset to (screen_size_width - 20)'
|
||||
assert theme.font_main_height == 540, 'height should have been reset to (screen_size_height * 9 / 10)'
|
||||
# THEN: footer should be set, header should not have changed
|
||||
assert theme.font_main_x == 20, 'header should not have been changed'
|
||||
assert theme.font_footer_x == 10, 'x pos should be reset to default of 10'
|
||||
assert theme.font_footer_y == 540, 'y pos should be reset to (screen_size_height * 9 / 10)'
|
||||
assert theme.font_footer_width == 380, 'width should have been reset to (screen_size_width - 20)'
|
||||
assert theme.font_footer_height == 60, 'height should have been reset to (screen_size_height / 10)'
|
||||
|
||||
@patch('openlp.core.display.screens.ScreenList.current')
|
||||
def test_set_default_header_footer(self, mock_geometry):
|
||||
"""
|
||||
Test the set_default_header_footer function sets the header and footer back to default
|
||||
(reletive to the screen)
|
||||
"""
|
||||
# GIVEN: A screen geometry object and a Theme header with a strange area
|
||||
mock_geometry.display_geometry = MagicMock()
|
||||
theme = Theme()
|
||||
theme.font_footer_x = 200
|
||||
theme.font_main_x = 687
|
||||
|
||||
# WHEN: set_default_header is called
|
||||
theme.set_default_header_footer()
|
||||
@patch('openlp.core.display.screens.ScreenList.current')
|
||||
def test_set_default_header(mock_geometry):
|
||||
"""
|
||||
Test the set_default_header function sets the header back to default
|
||||
(reletive to the screen)
|
||||
"""
|
||||
# GIVEN: A screen geometry object and a Theme header with a strange area
|
||||
mock_geometry.display_geometry = MagicMock()
|
||||
mock_geometry.display_geometry.height.return_value = 600
|
||||
mock_geometry.display_geometry.width.return_value = 400
|
||||
theme = Theme()
|
||||
theme.font_footer_x = 200
|
||||
theme.font_main_x = 687
|
||||
theme.font_main_y = 546
|
||||
theme.font_main_width = 345
|
||||
theme.font_main_height = 653
|
||||
|
||||
# THEN: footer should be set, header should not have changed
|
||||
assert theme.font_footer_x == 10, 'footer x pos should be reset to default of 10'
|
||||
assert theme.font_main_x == 10, 'header x pos should be reset to default of 10'
|
||||
# WHEN: set_default_header is called
|
||||
theme.set_default_header()
|
||||
|
||||
def check_theme(self, theme):
|
||||
assert '#000000' == theme.background_border_color, 'background_border_color should be "#000000"'
|
||||
assert 'solid' == theme.background_type, 'background_type should be "solid"'
|
||||
assert 0 == theme.display_vertical_align, 'display_vertical_align should be 0'
|
||||
assert theme.font_footer_bold is False, 'font_footer_bold should be False'
|
||||
assert 'Arial' == theme.font_main_name, 'font_main_name should be "Arial"'
|
||||
assert 53 == len(theme.__dict__), 'The theme should have 53 attributes'
|
||||
# THEN: footer should be set, header should not have changed
|
||||
assert theme.font_footer_x == 200, 'footer should not have been changed'
|
||||
assert theme.font_main_x == 10, 'x pos should be reset to default of 10'
|
||||
assert theme.font_main_y == 0, 'y pos should be reset to 0'
|
||||
assert theme.font_main_width == 380, 'width should have been reset to (screen_size_width - 20)'
|
||||
assert theme.font_main_height == 540, 'height should have been reset to (screen_size_height * 9 / 10)'
|
||||
|
||||
|
||||
@patch('openlp.core.display.screens.ScreenList.current')
|
||||
def test_set_default_header_footer(mock_geometry):
|
||||
"""
|
||||
Test the set_default_header_footer function sets the header and footer back to default
|
||||
(reletive to the screen)
|
||||
"""
|
||||
# GIVEN: A screen geometry object and a Theme header with a strange area
|
||||
mock_geometry.display_geometry = MagicMock()
|
||||
theme = Theme()
|
||||
theme.font_footer_x = 200
|
||||
theme.font_main_x = 687
|
||||
|
||||
# WHEN: set_default_header is called
|
||||
theme.set_default_header_footer()
|
||||
|
||||
# THEN: footer should be set, header should not have changed
|
||||
assert theme.font_footer_x == 10, 'footer x pos should be reset to default of 10'
|
||||
assert theme.font_main_x == 10, 'header x pos should be reset to default of 10'
|
||||
|
||||
|
||||
def check_theme(theme):
|
||||
assert '#000000' == theme.background_border_color, 'background_border_color should be "#000000"'
|
||||
assert 'solid' == theme.background_type, 'background_type should be "solid"'
|
||||
assert 0 == theme.display_vertical_align, 'display_vertical_align should be 0'
|
||||
assert theme.font_footer_bold is False, 'font_footer_bold should be False'
|
||||
assert 'Arial' == theme.font_main_name, 'font_main_name should be "Arial"'
|
||||
assert 53 == len(theme.__dict__), 'The theme should have 53 attributes'
|
||||
|
@ -21,7 +21,6 @@
|
||||
"""
|
||||
Package to test the openlp.core.lib.ui package.
|
||||
"""
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, call, patch
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
@ -32,287 +31,297 @@ from openlp.core.lib.ui import add_welcome_page, create_action, create_button, c
|
||||
critical_error_message_box, find_and_set_in_combo_box, set_case_insensitive_completer
|
||||
|
||||
|
||||
class TestUi(TestCase):
|
||||
def test_add_welcome_page():
|
||||
"""
|
||||
Test the functions in the ui module
|
||||
Test appending a welcome page to a wizard
|
||||
"""
|
||||
# GIVEN: A wizard
|
||||
wizard = QtWidgets.QWizard()
|
||||
|
||||
def test_add_welcome_page(self):
|
||||
"""
|
||||
Test appending a welcome page to a wizard
|
||||
"""
|
||||
# GIVEN: A wizard
|
||||
wizard = QtWidgets.QWizard()
|
||||
# WHEN: A welcome page has been added to the wizard
|
||||
add_welcome_page(wizard, ':/wizards/wizard_firsttime.bmp')
|
||||
|
||||
# WHEN: A welcome page has been added to the wizard
|
||||
add_welcome_page(wizard, ':/wizards/wizard_firsttime.bmp')
|
||||
# THEN: The wizard should have one page with a pixmap.
|
||||
assert 1 == len(wizard.pageIds()), 'The wizard should have one page.'
|
||||
assert isinstance(wizard.page(0).pixmap(QtWidgets.QWizard.WatermarkPixmap), QtGui.QPixmap)
|
||||
|
||||
# THEN: The wizard should have one page with a pixmap.
|
||||
assert 1 == len(wizard.pageIds()), 'The wizard should have one page.'
|
||||
assert isinstance(wizard.page(0).pixmap(QtWidgets.QWizard.WatermarkPixmap), QtGui.QPixmap)
|
||||
|
||||
def test_create_button_box(self):
|
||||
"""
|
||||
Test creating a button box for a dialog
|
||||
"""
|
||||
# GIVEN: A dialog
|
||||
def test_create_button_box():
|
||||
"""
|
||||
Test creating a button box for a dialog
|
||||
"""
|
||||
# GIVEN: A dialog
|
||||
dialog = QtWidgets.QDialog()
|
||||
|
||||
# WHEN: We create the button box with five buttons
|
||||
btnbox = create_button_box(dialog, 'my_btns', ['ok', 'save', 'cancel', 'close', 'defaults'])
|
||||
|
||||
# THEN: We should get a QDialogButtonBox with five buttons
|
||||
assert isinstance(btnbox, QtWidgets.QDialogButtonBox)
|
||||
assert 5 == len(btnbox.buttons())
|
||||
|
||||
# WHEN: We create the button box with a custom button
|
||||
btnbox = create_button_box(dialog, 'my_btns', None, [QtWidgets.QPushButton('Custom')])
|
||||
# THEN: We should get a QDialogButtonBox with one button
|
||||
assert isinstance(btnbox, QtWidgets.QDialogButtonBox)
|
||||
assert 1 == len(btnbox.buttons())
|
||||
|
||||
# WHEN: We create the button box with a custom button and a custom role
|
||||
btnbox = create_button_box(dialog, 'my_btns', None,
|
||||
[(QtWidgets.QPushButton('Help'), QtWidgets.QDialogButtonBox.HelpRole)])
|
||||
# THEN: We should get a QDialogButtonBox with one button with a certain role
|
||||
assert isinstance(btnbox, QtWidgets.QDialogButtonBox)
|
||||
assert 1 == len(btnbox.buttons())
|
||||
assert QtWidgets.QDialogButtonBox.HelpRole, btnbox.buttonRole(btnbox.buttons()[0])
|
||||
|
||||
|
||||
@patch('openlp.core.lib.ui.Registry')
|
||||
def test_critical_error_message_box(MockRegistry):
|
||||
"""
|
||||
Test the critical_error_message_box() function
|
||||
"""
|
||||
# GIVEN: A mocked Registry
|
||||
# WHEN: critical_error_message_box() is called
|
||||
critical_error_message_box('Error', 'This is an error')
|
||||
|
||||
# THEN: The error_message() method on the main window should be called
|
||||
MockRegistry.return_value.get.return_value.error_message.assert_called_once_with('Error', 'This is an error')
|
||||
|
||||
|
||||
@patch('openlp.core.lib.ui.QtWidgets.QMessageBox.critical')
|
||||
def test_critical_error_question(mocked_critical):
|
||||
"""
|
||||
Test the critical_error_message_box() function
|
||||
"""
|
||||
# GIVEN: A mocked critical() method and some other mocks
|
||||
mocked_parent = MagicMock()
|
||||
|
||||
# WHEN: critical_error_message_box() is called
|
||||
critical_error_message_box(None, 'This is a question', mocked_parent, True)
|
||||
|
||||
# THEN: The error_message() method on the main window should be called
|
||||
mocked_critical.assert_called_once_with(mocked_parent, 'Error', 'This is a question',
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes |
|
||||
QtWidgets.QMessageBox.No))
|
||||
|
||||
|
||||
def test_create_horizontal_adjusting_combo_box():
|
||||
"""
|
||||
Test creating a horizontal adjusting combo box
|
||||
"""
|
||||
# GIVEN: A dialog
|
||||
dialog = QtWidgets.QDialog()
|
||||
|
||||
# WHEN: We create the combobox
|
||||
combo = create_horizontal_adjusting_combo_box(dialog, 'combo1')
|
||||
|
||||
# THEN: We should get a ComboBox
|
||||
assert isinstance(combo, QtWidgets.QComboBox)
|
||||
assert combo.objectName() == 'combo1'
|
||||
assert QtWidgets.QComboBox.AdjustToMinimumContentsLength == combo.sizeAdjustPolicy()
|
||||
|
||||
|
||||
@patch('openlp.core.lib.ui.log')
|
||||
def test_create_button(mocked_log):
|
||||
"""
|
||||
Test creating a button
|
||||
"""
|
||||
# GIVEN: A dialog
|
||||
dialog = QtWidgets.QDialog()
|
||||
|
||||
# WHEN: We create a button with some attributes
|
||||
btn = create_button(dialog, 'my_btn', text='Hello', tooltip='How are you?', enabled=False, role='test', test=1)
|
||||
|
||||
# THEN: We should get a button with those attributes
|
||||
assert isinstance(btn, QtWidgets.QPushButton)
|
||||
assert btn.objectName() == 'my_btn'
|
||||
assert btn.text() == 'Hello'
|
||||
assert btn.toolTip() == 'How are you?'
|
||||
assert btn.isEnabled() is False
|
||||
assert mocked_log.warning.call_args_list == [call('The role "test" is not defined in create_push_button().'),
|
||||
call('Parameter test was not consumed in create_button().')]
|
||||
|
||||
|
||||
def test_create_tool_button():
|
||||
"""
|
||||
Test creating a toolbutton
|
||||
"""
|
||||
# GIVEN: A dialog
|
||||
dialog = QtWidgets.QDialog()
|
||||
|
||||
# WHEN: We create a toolbutton
|
||||
btn = create_button(dialog, 'my_btn', btn_class='toolbutton')
|
||||
|
||||
# THEN: We should get a toolbutton
|
||||
assert isinstance(btn, QtWidgets.QToolButton)
|
||||
assert btn.objectName() == 'my_btn'
|
||||
assert btn.isEnabled() is True
|
||||
|
||||
|
||||
@patch('openlp.core.lib.ui.log')
|
||||
def test_create_action(mocked_log):
|
||||
"""
|
||||
Test creating an action
|
||||
"""
|
||||
# GIVEN: A dialog
|
||||
dialog = QtWidgets.QDialog()
|
||||
|
||||
# WHEN: We create an action with some properties
|
||||
action = create_action(dialog, 'my_action', text='my text', icon=':/wizards/wizard_firsttime.bmp',
|
||||
tooltip='my tooltip', statustip='my statustip', test=1)
|
||||
|
||||
# THEN: These properties should be set
|
||||
assert isinstance(action, QtWidgets.QAction)
|
||||
assert action.objectName() == 'my_action'
|
||||
assert action.text() == 'my text'
|
||||
assert isinstance(action.icon(), QtGui.QIcon)
|
||||
assert action.toolTip() == 'my tooltip'
|
||||
assert action.statusTip() == 'my statustip'
|
||||
mocked_log.warning.assert_called_once_with('Parameter test was not consumed in create_action().')
|
||||
|
||||
|
||||
def test_create_action_on_mac_osx():
|
||||
"""
|
||||
Test creating an action on OS X calls the correct method
|
||||
"""
|
||||
# GIVEN: A dialog and a mocked out is_macosx() method to always return True
|
||||
with patch('openlp.core.lib.ui.is_macosx') as mocked_is_macosx, \
|
||||
patch('openlp.core.lib.ui.QtWidgets.QAction') as MockedQAction:
|
||||
mocked_is_macosx.return_value = True
|
||||
mocked_action = MagicMock()
|
||||
MockedQAction.return_value = mocked_action
|
||||
dialog = QtWidgets.QDialog()
|
||||
|
||||
# WHEN: We create the button box with five buttons
|
||||
btnbox = create_button_box(dialog, 'my_btns', ['ok', 'save', 'cancel', 'close', 'defaults'])
|
||||
# WHEN: An action is created
|
||||
create_action(dialog, 'my_action')
|
||||
|
||||
# THEN: We should get a QDialogButtonBox with five buttons
|
||||
assert isinstance(btnbox, QtWidgets.QDialogButtonBox)
|
||||
assert 5 == len(btnbox.buttons())
|
||||
# THEN: setIconVisibleInMenu should be called
|
||||
mocked_action.setIconVisibleInMenu.assert_called_with(False)
|
||||
|
||||
# WHEN: We create the button box with a custom button
|
||||
btnbox = create_button_box(dialog, 'my_btns', None, [QtWidgets.QPushButton('Custom')])
|
||||
# THEN: We should get a QDialogButtonBox with one button
|
||||
assert isinstance(btnbox, QtWidgets.QDialogButtonBox)
|
||||
assert 1 == len(btnbox.buttons())
|
||||
|
||||
# WHEN: We create the button box with a custom button and a custom role
|
||||
btnbox = create_button_box(dialog, 'my_btns', None,
|
||||
[(QtWidgets.QPushButton('Help'), QtWidgets.QDialogButtonBox.HelpRole)])
|
||||
# THEN: We should get a QDialogButtonBox with one button with a certain role
|
||||
assert isinstance(btnbox, QtWidgets.QDialogButtonBox)
|
||||
assert 1 == len(btnbox.buttons())
|
||||
assert QtWidgets.QDialogButtonBox.HelpRole, btnbox.buttonRole(btnbox.buttons()[0])
|
||||
|
||||
@patch('openlp.core.lib.ui.Registry')
|
||||
def test_critical_error_message_box(self, MockRegistry):
|
||||
"""
|
||||
Test the critical_error_message_box() function
|
||||
"""
|
||||
# GIVEN: A mocked Registry
|
||||
# WHEN: critical_error_message_box() is called
|
||||
critical_error_message_box('Error', 'This is an error')
|
||||
|
||||
# THEN: The error_message() method on the main window should be called
|
||||
MockRegistry.return_value.get.return_value.error_message.assert_called_once_with('Error', 'This is an error')
|
||||
|
||||
@patch('openlp.core.lib.ui.QtWidgets.QMessageBox.critical')
|
||||
def test_critical_error_question(self, mocked_critical):
|
||||
"""
|
||||
Test the critical_error_message_box() function
|
||||
"""
|
||||
# GIVEN: A mocked critical() method and some other mocks
|
||||
mocked_parent = MagicMock()
|
||||
|
||||
# WHEN: critical_error_message_box() is called
|
||||
critical_error_message_box(None, 'This is a question', mocked_parent, True)
|
||||
|
||||
# THEN: The error_message() method on the main window should be called
|
||||
mocked_critical.assert_called_once_with(mocked_parent, 'Error', 'This is a question',
|
||||
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes |
|
||||
QtWidgets.QMessageBox.No))
|
||||
|
||||
def test_create_horizontal_adjusting_combo_box(self):
|
||||
"""
|
||||
Test creating a horizontal adjusting combo box
|
||||
"""
|
||||
# GIVEN: A dialog
|
||||
def test_create_action_not_on_mac_osx():
|
||||
"""
|
||||
Test creating an action on something other than OS X doesn't call the method
|
||||
"""
|
||||
# GIVEN: A dialog and a mocked out is_macosx() method to always return True
|
||||
with patch('openlp.core.lib.ui.is_macosx') as mocked_is_macosx, \
|
||||
patch('openlp.core.lib.ui.QtWidgets.QAction') as MockedQAction:
|
||||
mocked_is_macosx.return_value = False
|
||||
mocked_action = MagicMock()
|
||||
MockedQAction.return_value = mocked_action
|
||||
dialog = QtWidgets.QDialog()
|
||||
|
||||
# WHEN: We create the combobox
|
||||
combo = create_horizontal_adjusting_combo_box(dialog, 'combo1')
|
||||
# WHEN: An action is created
|
||||
create_action(dialog, 'my_action')
|
||||
|
||||
# THEN: We should get a ComboBox
|
||||
assert isinstance(combo, QtWidgets.QComboBox)
|
||||
assert combo.objectName() == 'combo1'
|
||||
assert QtWidgets.QComboBox.AdjustToMinimumContentsLength == combo.sizeAdjustPolicy()
|
||||
# THEN: setIconVisibleInMenu should not be called
|
||||
assert 0 == mocked_action.setIconVisibleInMenu.call_count, \
|
||||
'setIconVisibleInMenu should not have been called'
|
||||
|
||||
@patch('openlp.core.lib.ui.log')
|
||||
def test_create_button(self, mocked_log):
|
||||
"""
|
||||
Test creating a button
|
||||
"""
|
||||
# GIVEN: A dialog
|
||||
dialog = QtWidgets.QDialog()
|
||||
|
||||
# WHEN: We create a button with some attributes
|
||||
btn = create_button(dialog, 'my_btn', text='Hello', tooltip='How are you?', enabled=False, role='test', test=1)
|
||||
def test_create_checked_disabled_invisible_action():
|
||||
"""
|
||||
Test that an invisible, disabled, checked action is created correctly
|
||||
"""
|
||||
# GIVEN: A dialog
|
||||
dialog = QtWidgets.QDialog()
|
||||
|
||||
# THEN: We should get a button with those attributes
|
||||
assert isinstance(btn, QtWidgets.QPushButton)
|
||||
assert btn.objectName() == 'my_btn'
|
||||
assert btn.text() == 'Hello'
|
||||
assert btn.toolTip() == 'How are you?'
|
||||
assert btn.isEnabled() is False
|
||||
assert mocked_log.warning.call_args_list == [call('The role "test" is not defined in create_push_button().'),
|
||||
call('Parameter test was not consumed in create_button().')]
|
||||
# WHEN: We create an action with some properties
|
||||
action = create_action(dialog, 'my_action', checked=True, enabled=False, visible=False)
|
||||
|
||||
def test_create_tool_button(self):
|
||||
"""
|
||||
Test creating a toolbutton
|
||||
"""
|
||||
# GIVEN: A dialog
|
||||
dialog = QtWidgets.QDialog()
|
||||
# THEN: These properties should be set
|
||||
assert action.isChecked() is True, 'The action should be checked'
|
||||
assert action.isEnabled() is False, 'The action should be disabled'
|
||||
assert action.isVisible() is False, 'The action should be invisble'
|
||||
|
||||
# WHEN: We create a toolbutton
|
||||
btn = create_button(dialog, 'my_btn', btn_class='toolbutton')
|
||||
|
||||
# THEN: We should get a toolbutton
|
||||
assert isinstance(btn, QtWidgets.QToolButton)
|
||||
assert btn.objectName() == 'my_btn'
|
||||
assert btn.isEnabled() is True
|
||||
def test_create_action_separator():
|
||||
"""
|
||||
Test creating an action as separator
|
||||
"""
|
||||
# GIVEN: A dialog
|
||||
dialog = QtWidgets.QDialog()
|
||||
|
||||
@patch('openlp.core.lib.ui.log')
|
||||
def test_create_action(self, mocked_log):
|
||||
"""
|
||||
Test creating an action
|
||||
"""
|
||||
# GIVEN: A dialog
|
||||
dialog = QtWidgets.QDialog()
|
||||
# WHEN: We create an action as a separator
|
||||
action = create_action(dialog, 'my_action', separator=True)
|
||||
|
||||
# WHEN: We create an action with some properties
|
||||
action = create_action(dialog, 'my_action', text='my text', icon=':/wizards/wizard_firsttime.bmp',
|
||||
tooltip='my tooltip', statustip='my statustip', test=1)
|
||||
# THEN: The action should be a separator
|
||||
assert action.isSeparator() is True, 'The action should be a separator'
|
||||
|
||||
# THEN: These properties should be set
|
||||
assert isinstance(action, QtWidgets.QAction)
|
||||
assert action.objectName() == 'my_action'
|
||||
assert action.text() == 'my text'
|
||||
assert isinstance(action.icon(), QtGui.QIcon)
|
||||
assert action.toolTip() == 'my tooltip'
|
||||
assert action.statusTip() == 'my statustip'
|
||||
mocked_log.warning.assert_called_once_with('Parameter test was not consumed in create_action().')
|
||||
|
||||
def test_create_action_on_mac_osx(self):
|
||||
"""
|
||||
Test creating an action on OS X calls the correct method
|
||||
"""
|
||||
# GIVEN: A dialog and a mocked out is_macosx() method to always return True
|
||||
with patch('openlp.core.lib.ui.is_macosx') as mocked_is_macosx, \
|
||||
patch('openlp.core.lib.ui.QtWidgets.QAction') as MockedQAction:
|
||||
mocked_is_macosx.return_value = True
|
||||
mocked_action = MagicMock()
|
||||
MockedQAction.return_value = mocked_action
|
||||
dialog = QtWidgets.QDialog()
|
||||
def test_create_valign_selection_widgets():
|
||||
"""
|
||||
Test creating a combo box for valign selection
|
||||
"""
|
||||
# GIVEN: A dialog
|
||||
dialog = QtWidgets.QDialog()
|
||||
|
||||
# WHEN: An action is created
|
||||
create_action(dialog, 'my_action')
|
||||
# WHEN: We create the widgets
|
||||
label, combo = create_valign_selection_widgets(dialog)
|
||||
|
||||
# THEN: setIconVisibleInMenu should be called
|
||||
mocked_action.setIconVisibleInMenu.assert_called_with(False)
|
||||
# THEN: We should get a label and a combobox.
|
||||
assert translate('OpenLP.Ui', '&Vertical Align:') == label.text()
|
||||
assert isinstance(combo, QtWidgets.QComboBox)
|
||||
assert combo == label.buddy()
|
||||
for text in [UiStrings().Top, UiStrings().Middle, UiStrings().Bottom]:
|
||||
assert combo.findText(text) >= 0
|
||||
|
||||
def test_create_action_not_on_mac_osx(self):
|
||||
"""
|
||||
Test creating an action on something other than OS X doesn't call the method
|
||||
"""
|
||||
# GIVEN: A dialog and a mocked out is_macosx() method to always return True
|
||||
with patch('openlp.core.lib.ui.is_macosx') as mocked_is_macosx, \
|
||||
patch('openlp.core.lib.ui.QtWidgets.QAction') as MockedQAction:
|
||||
mocked_is_macosx.return_value = False
|
||||
mocked_action = MagicMock()
|
||||
MockedQAction.return_value = mocked_action
|
||||
dialog = QtWidgets.QDialog()
|
||||
|
||||
# WHEN: An action is created
|
||||
create_action(dialog, 'my_action')
|
||||
def test_find_and_set_in_combo_box():
|
||||
"""
|
||||
Test finding a string in a combo box and setting it as the selected item if present
|
||||
"""
|
||||
# GIVEN: A ComboBox
|
||||
combo = QtWidgets.QComboBox()
|
||||
combo.addItems(['One', 'Two', 'Three'])
|
||||
combo.setCurrentIndex(1)
|
||||
|
||||
# THEN: setIconVisibleInMenu should not be called
|
||||
assert 0 == mocked_action.setIconVisibleInMenu.call_count, \
|
||||
'setIconVisibleInMenu should not have been called'
|
||||
# WHEN: We call the method with a non-existing value and set_missing=False
|
||||
find_and_set_in_combo_box(combo, 'Four', set_missing=False)
|
||||
|
||||
def test_create_checked_disabled_invisible_action(self):
|
||||
"""
|
||||
Test that an invisible, disabled, checked action is created correctly
|
||||
"""
|
||||
# GIVEN: A dialog
|
||||
dialog = QtWidgets.QDialog()
|
||||
# THEN: The index should not have changed
|
||||
assert 1 == combo.currentIndex()
|
||||
|
||||
# WHEN: We create an action with some properties
|
||||
action = create_action(dialog, 'my_action', checked=True, enabled=False, visible=False)
|
||||
# WHEN: We call the method with a non-existing value
|
||||
find_and_set_in_combo_box(combo, 'Four')
|
||||
|
||||
# THEN: These properties should be set
|
||||
assert action.isChecked() is True, 'The action should be checked'
|
||||
assert action.isEnabled() is False, 'The action should be disabled'
|
||||
assert action.isVisible() is False, 'The action should be invisble'
|
||||
# THEN: The index should have been reset
|
||||
assert 0 == combo.currentIndex()
|
||||
|
||||
def test_create_action_separator(self):
|
||||
"""
|
||||
Test creating an action as separator
|
||||
"""
|
||||
# GIVEN: A dialog
|
||||
dialog = QtWidgets.QDialog()
|
||||
# WHEN: We call the method with the default behavior
|
||||
find_and_set_in_combo_box(combo, 'Three')
|
||||
|
||||
# WHEN: We create an action as a separator
|
||||
action = create_action(dialog, 'my_action', separator=True)
|
||||
# THEN: The index should have changed
|
||||
assert 2 == combo.currentIndex()
|
||||
|
||||
# THEN: The action should be a separator
|
||||
assert action.isSeparator() is True, 'The action should be a separator'
|
||||
|
||||
def test_create_valign_selection_widgets(self):
|
||||
"""
|
||||
Test creating a combo box for valign selection
|
||||
"""
|
||||
# GIVEN: A dialog
|
||||
dialog = QtWidgets.QDialog()
|
||||
def test_create_widget_action():
|
||||
"""
|
||||
Test creating an action for a widget
|
||||
"""
|
||||
# GIVEN: A button
|
||||
button = QtWidgets.QPushButton()
|
||||
|
||||
# WHEN: We create the widgets
|
||||
label, combo = create_valign_selection_widgets(dialog)
|
||||
# WHEN: We call the function
|
||||
action = create_widget_action(button, 'some action')
|
||||
|
||||
# THEN: We should get a label and a combobox.
|
||||
assert translate('OpenLP.Ui', '&Vertical Align:') == label.text()
|
||||
assert isinstance(combo, QtWidgets.QComboBox)
|
||||
assert combo == label.buddy()
|
||||
for text in [UiStrings().Top, UiStrings().Middle, UiStrings().Bottom]:
|
||||
assert combo.findText(text) >= 0
|
||||
# THEN: The action should be returned
|
||||
assert isinstance(action, QtWidgets.QAction)
|
||||
assert action.objectName() == 'some action'
|
||||
|
||||
def test_find_and_set_in_combo_box(self):
|
||||
"""
|
||||
Test finding a string in a combo box and setting it as the selected item if present
|
||||
"""
|
||||
# GIVEN: A ComboBox
|
||||
combo = QtWidgets.QComboBox()
|
||||
combo.addItems(['One', 'Two', 'Three'])
|
||||
combo.setCurrentIndex(1)
|
||||
|
||||
# WHEN: We call the method with a non-existing value and set_missing=False
|
||||
find_and_set_in_combo_box(combo, 'Four', set_missing=False)
|
||||
def test_set_case_insensitive_completer():
|
||||
"""
|
||||
Test setting a case insensitive completer on a widget
|
||||
"""
|
||||
# GIVEN: A QComboBox and a list of completion items
|
||||
line_edit = QtWidgets.QLineEdit()
|
||||
suggestions = ['one', 'Two', 'THRee', 'FOUR']
|
||||
|
||||
# THEN: The index should not have changed
|
||||
assert 1 == combo.currentIndex()
|
||||
# WHEN: We call the function
|
||||
set_case_insensitive_completer(suggestions, line_edit)
|
||||
|
||||
# WHEN: We call the method with a non-existing value
|
||||
find_and_set_in_combo_box(combo, 'Four')
|
||||
|
||||
# THEN: The index should have been reset
|
||||
assert 0 == combo.currentIndex()
|
||||
|
||||
# WHEN: We call the method with the default behavior
|
||||
find_and_set_in_combo_box(combo, 'Three')
|
||||
|
||||
# THEN: The index should have changed
|
||||
assert 2 == combo.currentIndex()
|
||||
|
||||
def test_create_widget_action(self):
|
||||
"""
|
||||
Test creating an action for a widget
|
||||
"""
|
||||
# GIVEN: A button
|
||||
button = QtWidgets.QPushButton()
|
||||
|
||||
# WHEN: We call the function
|
||||
action = create_widget_action(button, 'some action')
|
||||
|
||||
# THEN: The action should be returned
|
||||
assert isinstance(action, QtWidgets.QAction)
|
||||
assert action.objectName() == 'some action'
|
||||
|
||||
def test_set_case_insensitive_completer(self):
|
||||
"""
|
||||
Test setting a case insensitive completer on a widget
|
||||
"""
|
||||
# GIVEN: A QComboBox and a list of completion items
|
||||
line_edit = QtWidgets.QLineEdit()
|
||||
suggestions = ['one', 'Two', 'THRee', 'FOUR']
|
||||
|
||||
# WHEN: We call the function
|
||||
set_case_insensitive_completer(suggestions, line_edit)
|
||||
|
||||
# THEN: The Combobox should have a completer which is case insensitive
|
||||
completer = line_edit.completer()
|
||||
assert isinstance(completer, QtWidgets.QCompleter)
|
||||
assert completer.caseSensitivity() == QtCore.Qt.CaseInsensitive
|
||||
# THEN: The Combobox should have a completer which is case insensitive
|
||||
completer = line_edit.completer()
|
||||
assert isinstance(completer, QtWidgets.QCompleter)
|
||||
assert completer.caseSensitivity() == QtCore.Qt.CaseInsensitive
|
||||
|
@ -21,156 +21,165 @@
|
||||
"""
|
||||
This module contains tests for the openlp.core.widgets.buttons module
|
||||
"""
|
||||
from unittest import TestCase
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, call, patch
|
||||
|
||||
from openlp.core.widgets.buttons import ColorButton
|
||||
|
||||
|
||||
class TestColorDialog(TestCase):
|
||||
@pytest.yield_fixture()
|
||||
def buttons_env():
|
||||
change_color_patcher = patch('openlp.core.widgets.buttons.ColorButton.change_color')
|
||||
clicked_patcher = patch('openlp.core.widgets.buttons.ColorButton.clicked')
|
||||
color_changed_patcher = patch('openlp.core.widgets.buttons.ColorButton.colorChanged')
|
||||
qt_gui_patcher = patch('openlp.core.widgets.buttons.QtWidgets')
|
||||
translate_patcher = patch('openlp.core.widgets.buttons.translate', **{'return_value': 'Tool Tip Text'})
|
||||
mocked_change_color = change_color_patcher.start()
|
||||
mocked_clicked = clicked_patcher.start()
|
||||
mocked_color_changed = color_changed_patcher.start()
|
||||
mocked_qt_widgets = qt_gui_patcher.start()
|
||||
translate_patcher.start()
|
||||
yield mocked_clicked, mocked_color_changed, mocked_qt_widgets, mocked_change_color
|
||||
change_color_patcher.stop()
|
||||
clicked_patcher.stop()
|
||||
color_changed_patcher.stop()
|
||||
qt_gui_patcher.stop()
|
||||
translate_patcher.stop()
|
||||
|
||||
|
||||
@patch('openlp.core.widgets.buttons.ColorButton.setToolTip')
|
||||
def test_constructor(mocked_set_tool_tip, buttons_env):
|
||||
"""
|
||||
Test the :class:`~openlp.core.lib.colorbutton.ColorButton` class
|
||||
Test that constructing a ColorButton object works correctly
|
||||
"""
|
||||
def setUp(self):
|
||||
self.change_color_patcher = patch('openlp.core.widgets.buttons.ColorButton.change_color')
|
||||
self.clicked_patcher = patch('openlp.core.widgets.buttons.ColorButton.clicked')
|
||||
self.color_changed_patcher = patch('openlp.core.widgets.buttons.ColorButton.colorChanged')
|
||||
self.qt_gui_patcher = patch('openlp.core.widgets.buttons.QtWidgets')
|
||||
self.translate_patcher = patch('openlp.core.widgets.buttons.translate', **{'return_value': 'Tool Tip Text'})
|
||||
self.addCleanup(self.change_color_patcher.stop)
|
||||
self.addCleanup(self.clicked_patcher.stop)
|
||||
self.addCleanup(self.color_changed_patcher.stop)
|
||||
self.addCleanup(self.qt_gui_patcher.stop)
|
||||
self.addCleanup(self.translate_patcher.stop)
|
||||
self.mocked_change_color = self.change_color_patcher.start()
|
||||
self.mocked_clicked = self.clicked_patcher.start()
|
||||
self.mocked_color_changed = self.color_changed_patcher.start()
|
||||
self.mocked_qt_widgets = self.qt_gui_patcher.start()
|
||||
self.mocked_translate = self.translate_patcher.start()
|
||||
|
||||
@patch('openlp.core.widgets.buttons.ColorButton.setToolTip')
|
||||
def test_constructor(self, mocked_set_tool_tip):
|
||||
"""
|
||||
Test that constructing a ColorButton object works correctly
|
||||
"""
|
||||
# GIVEN: The ColorButton class, a mocked change_color, setToolTip methods and clicked signal
|
||||
# WHEN: The ColorButton object is instantiated
|
||||
mocked_clicked = buttons_env[0]
|
||||
mocked_change_color = buttons_env[3]
|
||||
widget = ColorButton()
|
||||
|
||||
# GIVEN: The ColorButton class, a mocked change_color, setToolTip methods and clicked signal
|
||||
# WHEN: The ColorButton object is instantiated
|
||||
widget = ColorButton()
|
||||
# THEN: The widget __init__ method should have the correct properties and methods called
|
||||
assert widget.parent is None, 'The parent should be the same as the one that the class was instianted with'
|
||||
mocked_change_color.assert_called_once_with('#ffffff')
|
||||
mocked_set_tool_tip.assert_called_once_with('Tool Tip Text')
|
||||
mocked_clicked.connect.assert_called_once_with(widget.on_clicked)
|
||||
|
||||
# THEN: The widget __init__ method should have the correct properties and methods called
|
||||
assert widget.parent is None, 'The parent should be the same as the one that the class was instianted with'
|
||||
self.mocked_change_color.assert_called_once_with('#ffffff')
|
||||
mocked_set_tool_tip.assert_called_once_with('Tool Tip Text')
|
||||
self.mocked_clicked.connect.assert_called_once_with(widget.on_clicked)
|
||||
|
||||
@patch('openlp.core.widgets.buttons.ColorButton.setStyleSheet')
|
||||
def test_change_color(self, mocked_set_style_sheet):
|
||||
"""
|
||||
Test that change_color sets the new color and the stylesheet
|
||||
"""
|
||||
self.change_color_patcher.stop()
|
||||
@patch('openlp.core.widgets.buttons.ColorButton.setStyleSheet')
|
||||
def test_change_color(mocked_set_style_sheet):
|
||||
"""
|
||||
Test that change_color sets the new color and the stylesheet
|
||||
"""
|
||||
# GIVEN: An instance of the ColorButton object, and a mocked out setStyleSheet
|
||||
widget = ColorButton()
|
||||
|
||||
# GIVEN: An instance of the ColorButton object, and a mocked out setStyleSheet
|
||||
widget = ColorButton()
|
||||
# WHEN: Changing the color
|
||||
widget.change_color('#000000')
|
||||
|
||||
# WHEN: Changing the color
|
||||
widget.change_color('#000000')
|
||||
# THEN: The _color attribute should be set to #000000 and setStyleSheet should have been called twice
|
||||
assert widget._color == '#000000', '_color should have been set to #000000'
|
||||
mocked_set_style_sheet.assert_has_calls(
|
||||
[call('background-color: #ffffff'), call('background-color: #000000')])
|
||||
|
||||
# THEN: The _color attribute should be set to #000000 and setStyleSheet should have been called twice
|
||||
assert widget._color == '#000000', '_color should have been set to #000000'
|
||||
mocked_set_style_sheet.assert_has_calls(
|
||||
[call('background-color: #ffffff'), call('background-color: #000000')])
|
||||
|
||||
self.mocked_change_color = self.change_color_patcher.start()
|
||||
def test_color():
|
||||
"""
|
||||
Test that the color property method returns the set color
|
||||
"""
|
||||
# GIVEN: An instance of ColorButton, with a set _color attribute
|
||||
widget = ColorButton()
|
||||
widget._color = '#000000'
|
||||
|
||||
def test_color(self):
|
||||
"""
|
||||
Test that the color property method returns the set color
|
||||
"""
|
||||
# GIVEN: An instance of ColorButton, with a set _color attribute
|
||||
widget = ColorButton()
|
||||
widget._color = '#000000'
|
||||
# WHEN: Accesing the color property
|
||||
value = widget.color
|
||||
|
||||
# WHEN: Accesing the color property
|
||||
value = widget.color
|
||||
# THEN: The value set in _color should be returned
|
||||
assert value == '#000000', 'The value returned should be equal to the one we set'
|
||||
|
||||
# THEN: The value set in _color should be returned
|
||||
assert value == '#000000', 'The value returned should be equal to the one we set'
|
||||
|
||||
# @patch('openlp.core.widgets.buttons.ColorButton.__init__', **{'return_value': None})
|
||||
def test_color_setter(self):
|
||||
"""
|
||||
Test that the color property setter method sets the color
|
||||
"""
|
||||
# GIVEN: An instance of ColorButton, with a mocked __init__
|
||||
widget = ColorButton()
|
||||
def test_color_setter(buttons_env):
|
||||
"""
|
||||
Test that the color property setter method sets the color
|
||||
"""
|
||||
# GIVEN: An instance of ColorButton, with a mocked __init__
|
||||
mocked_change_color = buttons_env[3]
|
||||
widget = ColorButton()
|
||||
|
||||
# WHEN: Setting the color property
|
||||
widget.color = '#000000'
|
||||
# WHEN: Setting the color property
|
||||
widget.color = '#000000'
|
||||
|
||||
# THEN: Then change_color should have been called with the value we set
|
||||
self.mocked_change_color.assert_called_with('#000000')
|
||||
# THEN: Then change_color should have been called with the value we set
|
||||
mocked_change_color.assert_called_with('#000000')
|
||||
|
||||
def test_on_clicked_invalid_color(self):
|
||||
"""
|
||||
Test the on_click method when an invalid color has been supplied
|
||||
"""
|
||||
|
||||
# GIVEN: An instance of ColorButton, and a set _color attribute
|
||||
widget = ColorButton()
|
||||
self.mocked_change_color.reset_mock()
|
||||
self.mocked_color_changed.reset_mock()
|
||||
widget._color = '#000000'
|
||||
def test_on_clicked_invalid_color(buttons_env):
|
||||
"""
|
||||
Test the on_click method when an invalid color has been supplied
|
||||
"""
|
||||
# GIVEN: An instance of ColorButton, and a set _color attribute
|
||||
mocked_color_changed = buttons_env[1]
|
||||
mocked_qt_widgets = buttons_env[2]
|
||||
mocked_change_color = buttons_env[3]
|
||||
widget = ColorButton()
|
||||
mocked_change_color.reset_mock()
|
||||
mocked_color_changed.reset_mock()
|
||||
widget._color = '#000000'
|
||||
|
||||
# WHEN: The on_clicked method is called, and the color is invalid
|
||||
self.mocked_qt_widgets.QColorDialog.getColor.return_value = MagicMock(**{'isValid.return_value': False})
|
||||
widget.on_clicked()
|
||||
# WHEN: The on_clicked method is called, and the color is invalid
|
||||
mocked_qt_widgets.QColorDialog.getColor.return_value = MagicMock(**{'isValid.return_value': False})
|
||||
widget.on_clicked()
|
||||
|
||||
# THEN: change_color should not have been called and the colorChanged signal should not have been emitted
|
||||
assert self.mocked_change_color.called is False, \
|
||||
'change_color should not have been called with an invalid color'
|
||||
assert self.mocked_color_changed.emit.called is False, \
|
||||
'colorChange signal should not have been emitted with an invalid color'
|
||||
# THEN: change_color should not have been called and the colorChanged signal should not have been emitted
|
||||
assert mocked_change_color.called is False, \
|
||||
'change_color should not have been called with an invalid color'
|
||||
assert mocked_color_changed.emit.called is False, \
|
||||
'colorChange signal should not have been emitted with an invalid color'
|
||||
|
||||
def test_on_clicked_same_color(self):
|
||||
"""
|
||||
Test the on_click method when a new color has not been chosen
|
||||
"""
|
||||
|
||||
# GIVEN: An instance of ColorButton, and a set _color attribute
|
||||
widget = ColorButton()
|
||||
self.mocked_change_color.reset_mock()
|
||||
self.mocked_color_changed.reset_mock()
|
||||
widget._color = '#000000'
|
||||
def test_on_clicked_same_color(buttons_env):
|
||||
"""
|
||||
Test the on_click method when a new color has not been chosen
|
||||
"""
|
||||
# GIVEN: An instance of ColorButton, and a set _color attribute
|
||||
mocked_color_changed = buttons_env[1]
|
||||
mocked_qt_widgets = buttons_env[2]
|
||||
mocked_change_color = buttons_env[3]
|
||||
widget = ColorButton()
|
||||
mocked_change_color.reset_mock()
|
||||
mocked_color_changed.reset_mock()
|
||||
widget._color = '#000000'
|
||||
|
||||
# WHEN: The on_clicked method is called, and the color is valid, but the same as the existing color
|
||||
self.mocked_qt_widgets.QColorDialog.getColor.return_value = MagicMock(
|
||||
**{'isValid.return_value': True, 'name.return_value': '#000000'})
|
||||
widget.on_clicked()
|
||||
# WHEN: The on_clicked method is called, and the color is valid, but the same as the existing color
|
||||
mocked_qt_widgets.QColorDialog.getColor.return_value = MagicMock(
|
||||
**{'isValid.return_value': True, 'name.return_value': '#000000'})
|
||||
widget.on_clicked()
|
||||
|
||||
# THEN: change_color should not have been called and the colorChanged signal should not have been emitted
|
||||
assert self.mocked_change_color.called is False, \
|
||||
'change_color should not have been called when the color has not changed'
|
||||
assert self.mocked_color_changed.emit.called is False, \
|
||||
'colorChange signal should not have been emitted when the color has not changed'
|
||||
# THEN: change_color should not have been called and the colorChanged signal should not have been emitted
|
||||
assert mocked_change_color.called is False, \
|
||||
'change_color should not have been called when the color has not changed'
|
||||
assert mocked_color_changed.emit.called is False, \
|
||||
'colorChange signal should not have been emitted when the color has not changed'
|
||||
|
||||
def test_on_clicked_new_color(self):
|
||||
"""
|
||||
Test the on_click method when a new color has been chosen and is valid
|
||||
"""
|
||||
|
||||
# GIVEN: An instance of ColorButton, and a set _color attribute
|
||||
widget = ColorButton()
|
||||
self.mocked_change_color.reset_mock()
|
||||
self.mocked_color_changed.reset_mock()
|
||||
widget._color = '#000000'
|
||||
def test_on_clicked_new_color(buttons_env):
|
||||
"""
|
||||
Test the on_click method when a new color has been chosen and is valid
|
||||
"""
|
||||
# GIVEN: An instance of ColorButton, and a set _color attribute
|
||||
mocked_color_changed = buttons_env[1]
|
||||
mocked_qt_widgets = buttons_env[2]
|
||||
mocked_change_color = buttons_env[3]
|
||||
widget = ColorButton()
|
||||
mocked_change_color.reset_mock()
|
||||
mocked_color_changed.reset_mock()
|
||||
widget._color = '#000000'
|
||||
|
||||
# WHEN: The on_clicked method is called, and the color is valid, and different to the existing color
|
||||
self.mocked_qt_widgets.QColorDialog.getColor.return_value = MagicMock(
|
||||
**{'isValid.return_value': True, 'name.return_value': '#ffffff'})
|
||||
widget.on_clicked()
|
||||
# WHEN: The on_clicked method is called, and the color is valid, and different to the existing color
|
||||
mocked_qt_widgets.QColorDialog.getColor.return_value = MagicMock(
|
||||
**{'isValid.return_value': True, 'name.return_value': '#ffffff'})
|
||||
widget.on_clicked()
|
||||
|
||||
# THEN: change_color should have been called and the colorChanged signal should have been emitted
|
||||
self.mocked_change_color.assert_called_once_with('#ffffff')
|
||||
self.mocked_color_changed.emit.assert_called_once_with('#ffffff')
|
||||
# THEN: change_color should have been called and the colorChanged signal should have been emitted
|
||||
mocked_change_color.assert_called_once_with('#ffffff')
|
||||
mocked_color_changed.emit.assert_called_once_with('#ffffff')
|
||||
|
@ -1,5 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
##########################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# ---------------------------------------------------------------------- #
|
||||
@ -20,7 +19,6 @@
|
||||
##########################################################################
|
||||
import os
|
||||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
from unittest.mock import patch
|
||||
|
||||
from PyQt5 import QtWidgets
|
||||
@ -28,181 +26,188 @@ from PyQt5 import QtWidgets
|
||||
from openlp.core.widgets.dialogs import FileDialog
|
||||
|
||||
|
||||
class TestFileDialogPatches(TestCase):
|
||||
def test_file_dialog():
|
||||
"""
|
||||
Tests for the :mod:`openlp.core.widgets.dialogs` module
|
||||
Test that the :class:`FileDialog` instantiates correctly
|
||||
"""
|
||||
# GIVEN: The FileDialog class
|
||||
# WHEN: Creating an instance
|
||||
instance = FileDialog()
|
||||
|
||||
def test_file_dialog(self):
|
||||
"""
|
||||
Test that the :class:`FileDialog` instantiates correctly
|
||||
"""
|
||||
# GIVEN: The FileDialog class
|
||||
# WHEN: Creating an instance
|
||||
instance = FileDialog()
|
||||
# THEN: The instance should be an instance of QFileDialog
|
||||
assert isinstance(instance, QtWidgets.QFileDialog)
|
||||
|
||||
# THEN: The instance should be an instance of QFileDialog
|
||||
assert isinstance(instance, QtWidgets.QFileDialog)
|
||||
|
||||
def test_get_existing_directory_user_abort(self):
|
||||
"""
|
||||
Test that `getExistingDirectory` handles the case when the user cancels the dialog
|
||||
"""
|
||||
# GIVEN: FileDialog with a mocked QDialog.getExistingDirectory method
|
||||
# WHEN: Calling FileDialog.getExistingDirectory and the user cancels the dialog returns a empty string
|
||||
with patch('PyQt5.QtWidgets.QFileDialog.getExistingDirectory', return_value=''):
|
||||
result = FileDialog.getExistingDirectory()
|
||||
def test_get_existing_directory_user_abort():
|
||||
"""
|
||||
Test that `getExistingDirectory` handles the case when the user cancels the dialog
|
||||
"""
|
||||
# GIVEN: FileDialog with a mocked QDialog.getExistingDirectory method
|
||||
# WHEN: Calling FileDialog.getExistingDirectory and the user cancels the dialog returns a empty string
|
||||
with patch('PyQt5.QtWidgets.QFileDialog.getExistingDirectory', return_value=''):
|
||||
result = FileDialog.getExistingDirectory()
|
||||
|
||||
# THEN: The result should be None
|
||||
assert result is None
|
||||
# THEN: The result should be None
|
||||
assert result is None
|
||||
|
||||
def test_get_existing_directory_user_accepts(self):
|
||||
"""
|
||||
Test that `getExistingDirectory` handles the case when the user accepts the dialog
|
||||
"""
|
||||
# GIVEN: FileDialog with a mocked QDialog.getExistingDirectory method
|
||||
# WHEN: Calling FileDialog.getExistingDirectory, the user chooses a file and accepts the dialog (it returns a
|
||||
# string pointing to the directory)
|
||||
with patch('PyQt5.QtWidgets.QFileDialog.getExistingDirectory', return_value=os.path.join('test', 'dir')):
|
||||
result = FileDialog.getExistingDirectory()
|
||||
|
||||
# THEN: getExistingDirectory() should return a Path object pointing to the chosen file
|
||||
assert result == Path('test', 'dir')
|
||||
def test_get_existing_directory_user_accepts():
|
||||
"""
|
||||
Test that `getExistingDirectory` handles the case when the user accepts the dialog
|
||||
"""
|
||||
# GIVEN: FileDialog with a mocked QDialog.getExistingDirectory method
|
||||
# WHEN: Calling FileDialog.getExistingDirectory, the user chooses a file and accepts the dialog (it returns a
|
||||
# string pointing to the directory)
|
||||
with patch('PyQt5.QtWidgets.QFileDialog.getExistingDirectory', return_value=os.path.join('test', 'dir')):
|
||||
result = FileDialog.getExistingDirectory()
|
||||
|
||||
def test_get_existing_directory_param_order(self):
|
||||
"""
|
||||
Test that `getExistingDirectory` passes the parameters to `QFileDialog.getExistingDirectory` in the correct
|
||||
order
|
||||
"""
|
||||
# GIVEN: FileDialog
|
||||
with patch('openlp.core.widgets.dialogs.QtWidgets.QFileDialog.getExistingDirectory', return_value='') \
|
||||
as mocked_get_existing_directory:
|
||||
# THEN: getExistingDirectory() should return a Path object pointing to the chosen file
|
||||
assert result == Path('test', 'dir')
|
||||
|
||||
# WHEN: Calling the getExistingDirectory method with all parameters set
|
||||
FileDialog.getExistingDirectory('Parent', 'Caption', Path('test', 'dir'), 'Options')
|
||||
|
||||
# THEN: The `QFileDialog.getExistingDirectory` should have been called with the parameters in the correct
|
||||
# order
|
||||
mocked_get_existing_directory.assert_called_once_with('Parent', 'Caption', os.path.join('test', 'dir'),
|
||||
'Options')
|
||||
def test_get_existing_directory_param_order():
|
||||
"""
|
||||
Test that `getExistingDirectory` passes the parameters to `QFileDialog.getExistingDirectory` in the correct
|
||||
order
|
||||
"""
|
||||
# GIVEN: FileDialog
|
||||
with patch('openlp.core.widgets.dialogs.QtWidgets.QFileDialog.getExistingDirectory', return_value='') \
|
||||
as mocked_get_existing_directory:
|
||||
|
||||
def test_get_open_file_name_user_abort(self):
|
||||
"""
|
||||
Test that `getOpenFileName` handles the case when the user cancels the dialog
|
||||
"""
|
||||
# GIVEN: FileDialog with a mocked QDialog.getOpenFileName method
|
||||
# WHEN: Calling FileDialog.getOpenFileName and the user cancels the dialog (it returns a tuple with the first
|
||||
# value set as an empty string)
|
||||
with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileName', return_value=('', '')):
|
||||
result = FileDialog.getOpenFileName()
|
||||
# WHEN: Calling the getExistingDirectory method with all parameters set
|
||||
FileDialog.getExistingDirectory('Parent', 'Caption', Path('test', 'dir'), 'Options')
|
||||
|
||||
# THEN: First value should be None
|
||||
assert result[0] is None
|
||||
# THEN: The `QFileDialog.getExistingDirectory` should have been called with the parameters in the correct
|
||||
# order
|
||||
mocked_get_existing_directory.assert_called_once_with('Parent', 'Caption', os.path.join('test', 'dir'),
|
||||
'Options')
|
||||
|
||||
def test_get_open_file_name_user_accepts(self):
|
||||
"""
|
||||
Test that `getOpenFileName` handles the case when the user accepts the dialog
|
||||
"""
|
||||
# GIVEN: FileDialog with a mocked QDialog.getOpenFileName method
|
||||
# WHEN: Calling FileDialog.getOpenFileName, the user chooses a file and accepts the dialog (it returns a
|
||||
# tuple with the first value set as an string pointing to the file)
|
||||
with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileName',
|
||||
return_value=(os.path.join('test', 'chosen.file'), '')):
|
||||
result = FileDialog.getOpenFileName()
|
||||
|
||||
# THEN: getOpenFileName() should return a tuple with the first value set to a Path object pointing to the
|
||||
# chosen file
|
||||
assert result[0] == Path('test', 'chosen.file')
|
||||
def test_get_open_file_name_user_abort():
|
||||
"""
|
||||
Test that `getOpenFileName` handles the case when the user cancels the dialog
|
||||
"""
|
||||
# GIVEN: FileDialog with a mocked QDialog.getOpenFileName method
|
||||
# WHEN: Calling FileDialog.getOpenFileName and the user cancels the dialog (it returns a tuple with the first
|
||||
# value set as an empty string)
|
||||
with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileName', return_value=('', '')):
|
||||
result = FileDialog.getOpenFileName()
|
||||
|
||||
def test_get_open_file_name_selected_filter(self):
|
||||
"""
|
||||
Test that `getOpenFileName` does not modify the selectedFilter as returned by `QFileDialog.getOpenFileName`
|
||||
"""
|
||||
# GIVEN: FileDialog with a mocked QDialog.get_save_file_name method
|
||||
# WHEN: Calling FileDialog.getOpenFileName, and `QFileDialog.getOpenFileName` returns a known `selectedFilter`
|
||||
with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileName', return_value=('', 'selected filter')):
|
||||
result = FileDialog.getOpenFileName()
|
||||
# THEN: First value should be None
|
||||
assert result[0] is None
|
||||
|
||||
# THEN: getOpenFileName() should return a tuple with the second value set to a the selected filter
|
||||
assert result[1] == 'selected filter'
|
||||
|
||||
def test_get_open_file_names_user_abort(self):
|
||||
"""
|
||||
Test that `getOpenFileNames` handles the case when the user cancels the dialog
|
||||
"""
|
||||
# GIVEN: FileDialog with a mocked QDialog.getOpenFileNames method
|
||||
# WHEN: Calling FileDialog.getOpenFileNames and the user cancels the dialog (it returns a tuple with the first
|
||||
# value set as an empty list)
|
||||
with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileNames', return_value=([], '')):
|
||||
result = FileDialog.getOpenFileNames()
|
||||
def test_get_open_file_name_user_accepts():
|
||||
"""
|
||||
Test that `getOpenFileName` handles the case when the user accepts the dialog
|
||||
"""
|
||||
# GIVEN: FileDialog with a mocked QDialog.getOpenFileName method
|
||||
# WHEN: Calling FileDialog.getOpenFileName, the user chooses a file and accepts the dialog (it returns a
|
||||
# tuple with the first value set as an string pointing to the file)
|
||||
with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileName',
|
||||
return_value=(os.path.join('test', 'chosen.file'), '')):
|
||||
result = FileDialog.getOpenFileName()
|
||||
|
||||
# THEN: First value should be an empty list
|
||||
assert result[0] == []
|
||||
# THEN: getOpenFileName() should return a tuple with the first value set to a Path object pointing to the
|
||||
# chosen file
|
||||
assert result[0] == Path('test', 'chosen.file')
|
||||
|
||||
def test_get_open_file_names_user_accepts(self):
|
||||
"""
|
||||
Test that `getOpenFileNames` handles the case when the user accepts the dialog
|
||||
"""
|
||||
# GIVEN: FileDialog with a mocked QDialog.getOpenFileNames method
|
||||
# WHEN: Calling FileDialog.getOpenFileNames, the user chooses some files and accepts the dialog (it returns a
|
||||
# tuple with the first value set as a list of strings pointing to the file)
|
||||
with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileNames',
|
||||
return_value=([os.path.join('test', 'chosen.file1'), os.path.join('test', 'chosen.file2')], '')):
|
||||
result = FileDialog.getOpenFileNames()
|
||||
|
||||
# THEN: getOpenFileNames() should return a tuple with the first value set to a list of Path objects pointing
|
||||
# to the chosen file
|
||||
assert result[0] == [Path('test', 'chosen.file1'), Path('test', 'chosen.file2')]
|
||||
def test_get_open_file_name_selected_filter():
|
||||
"""
|
||||
Test that `getOpenFileName` does not modify the selectedFilter as returned by `QFileDialog.getOpenFileName`
|
||||
"""
|
||||
# GIVEN: FileDialog with a mocked QDialog.get_save_file_name method
|
||||
# WHEN: Calling FileDialog.getOpenFileName, and `QFileDialog.getOpenFileName` returns a known `selectedFilter`
|
||||
with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileName', return_value=('', 'selected filter')):
|
||||
result = FileDialog.getOpenFileName()
|
||||
|
||||
def test_get_open_file_names_selected_filter(self):
|
||||
"""
|
||||
Test that `getOpenFileNames` does not modify the selectedFilter as returned by `QFileDialog.getOpenFileNames`
|
||||
"""
|
||||
# GIVEN: FileDialog with a mocked QDialog.getOpenFileNames method
|
||||
# WHEN: Calling FileDialog.getOpenFileNames, and `QFileDialog.getOpenFileNames` returns a known
|
||||
# `selectedFilter`
|
||||
with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileNames', return_value=([], 'selected filter')):
|
||||
result = FileDialog.getOpenFileNames()
|
||||
# THEN: getOpenFileName() should return a tuple with the second value set to a the selected filter
|
||||
assert result[1] == 'selected filter'
|
||||
|
||||
# THEN: getOpenFileNames() should return a tuple with the second value set to a the selected filter
|
||||
assert result[1] == 'selected filter'
|
||||
|
||||
def test_get_save_file_name_user_abort(self):
|
||||
"""
|
||||
Test that `getSaveFileName` handles the case when the user cancels the dialog
|
||||
"""
|
||||
# GIVEN: FileDialog with a mocked QDialog.get_save_file_name method
|
||||
# WHEN: Calling FileDialog.getSaveFileName and the user cancels the dialog (it returns a tuple with the first
|
||||
# value set as an empty string)
|
||||
with patch('PyQt5.QtWidgets.QFileDialog.getSaveFileName', return_value=('', '')):
|
||||
result = FileDialog.getSaveFileName()
|
||||
def test_get_open_file_names_user_abort():
|
||||
"""
|
||||
Test that `getOpenFileNames` handles the case when the user cancels the dialog
|
||||
"""
|
||||
# GIVEN: FileDialog with a mocked QDialog.getOpenFileNames method
|
||||
# WHEN: Calling FileDialog.getOpenFileNames and the user cancels the dialog (it returns a tuple with the first
|
||||
# value set as an empty list)
|
||||
with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileNames', return_value=([], '')):
|
||||
result = FileDialog.getOpenFileNames()
|
||||
|
||||
# THEN: First value should be None
|
||||
assert result[0] is None
|
||||
# THEN: First value should be an empty list
|
||||
assert result[0] == []
|
||||
|
||||
def test_get_save_file_name_user_accepts(self):
|
||||
"""
|
||||
Test that `getSaveFileName` handles the case when the user accepts the dialog
|
||||
"""
|
||||
# GIVEN: FileDialog with a mocked QDialog.getSaveFileName method
|
||||
# WHEN: Calling FileDialog.getSaveFileName, the user chooses a file and accepts the dialog (it returns a
|
||||
# tuple with the first value set as an string pointing to the file)
|
||||
with patch('PyQt5.QtWidgets.QFileDialog.getSaveFileName',
|
||||
return_value=(os.path.join('test', 'chosen.file'), '')):
|
||||
result = FileDialog.getSaveFileName()
|
||||
|
||||
# THEN: getSaveFileName() should return a tuple with the first value set to a Path object pointing to the
|
||||
# chosen file
|
||||
assert result[0] == Path('test', 'chosen.file')
|
||||
def test_get_open_file_names_user_accepts():
|
||||
"""
|
||||
Test that `getOpenFileNames` handles the case when the user accepts the dialog
|
||||
"""
|
||||
# GIVEN: FileDialog with a mocked QDialog.getOpenFileNames method
|
||||
# WHEN: Calling FileDialog.getOpenFileNames, the user chooses some files and accepts the dialog (it returns a
|
||||
# tuple with the first value set as a list of strings pointing to the file)
|
||||
with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileNames',
|
||||
return_value=([os.path.join('test', 'chosen.file1'), os.path.join('test', 'chosen.file2')], '')):
|
||||
result = FileDialog.getOpenFileNames()
|
||||
|
||||
def test_get_save_file_name_selected_filter(self):
|
||||
"""
|
||||
Test that `getSaveFileName` does not modify the selectedFilter as returned by `QFileDialog.getSaveFileName`
|
||||
"""
|
||||
# GIVEN: FileDialog with a mocked QDialog.get_save_file_name method
|
||||
# WHEN: Calling FileDialog.getSaveFileName, and `QFileDialog.getSaveFileName` returns a known `selectedFilter`
|
||||
with patch('PyQt5.QtWidgets.QFileDialog.getSaveFileName', return_value=('', 'selected filter')):
|
||||
result = FileDialog.getSaveFileName()
|
||||
# THEN: getOpenFileNames() should return a tuple with the first value set to a list of Path objects pointing
|
||||
# to the chosen file
|
||||
assert result[0] == [Path('test', 'chosen.file1'), Path('test', 'chosen.file2')]
|
||||
|
||||
# THEN: getSaveFileName() should return a tuple with the second value set to a the selected filter
|
||||
assert result[1] == 'selected filter'
|
||||
|
||||
def test_get_open_file_names_selected_filter():
|
||||
"""
|
||||
Test that `getOpenFileNames` does not modify the selectedFilter as returned by `QFileDialog.getOpenFileNames`
|
||||
"""
|
||||
# GIVEN: FileDialog with a mocked QDialog.getOpenFileNames method
|
||||
# WHEN: Calling FileDialog.getOpenFileNames, and `QFileDialog.getOpenFileNames` returns a known
|
||||
# `selectedFilter`
|
||||
with patch('PyQt5.QtWidgets.QFileDialog.getOpenFileNames', return_value=([], 'selected filter')):
|
||||
result = FileDialog.getOpenFileNames()
|
||||
|
||||
# THEN: getOpenFileNames() should return a tuple with the second value set to a the selected filter
|
||||
assert result[1] == 'selected filter'
|
||||
|
||||
|
||||
def test_get_save_file_name_user_abort():
|
||||
"""
|
||||
Test that `getSaveFileName` handles the case when the user cancels the dialog
|
||||
"""
|
||||
# GIVEN: FileDialog with a mocked QDialog.get_save_file_name method
|
||||
# WHEN: Calling FileDialog.getSaveFileName and the user cancels the dialog (it returns a tuple with the first
|
||||
# value set as an empty string)
|
||||
with patch('PyQt5.QtWidgets.QFileDialog.getSaveFileName', return_value=('', '')):
|
||||
result = FileDialog.getSaveFileName()
|
||||
|
||||
# THEN: First value should be None
|
||||
assert result[0] is None
|
||||
|
||||
|
||||
def test_get_save_file_name_user_accepts():
|
||||
"""
|
||||
Test that `getSaveFileName` handles the case when the user accepts the dialog
|
||||
"""
|
||||
# GIVEN: FileDialog with a mocked QDialog.getSaveFileName method
|
||||
# WHEN: Calling FileDialog.getSaveFileName, the user chooses a file and accepts the dialog (it returns a
|
||||
# tuple with the first value set as an string pointing to the file)
|
||||
with patch('PyQt5.QtWidgets.QFileDialog.getSaveFileName',
|
||||
return_value=(os.path.join('test', 'chosen.file'), '')):
|
||||
result = FileDialog.getSaveFileName()
|
||||
|
||||
# THEN: getSaveFileName() should return a tuple with the first value set to a Path object pointing to the
|
||||
# chosen file
|
||||
assert result[0] == Path('test', 'chosen.file')
|
||||
|
||||
|
||||
def test_get_save_file_name_selected_filter():
|
||||
"""
|
||||
Test that `getSaveFileName` does not modify the selectedFilter as returned by `QFileDialog.getSaveFileName`
|
||||
"""
|
||||
# GIVEN: FileDialog with a mocked QDialog.get_save_file_name method
|
||||
# WHEN: Calling FileDialog.getSaveFileName, and `QFileDialog.getSaveFileName` returns a known `selectedFilter`
|
||||
with patch('PyQt5.QtWidgets.QFileDialog.getSaveFileName', return_value=('', 'selected filter')):
|
||||
result = FileDialog.getSaveFileName()
|
||||
|
||||
# THEN: getSaveFileName() should return a tuple with the second value set to a the selected filter
|
||||
assert result[1] == 'selected filter'
|
||||
|
@ -22,8 +22,8 @@
|
||||
This module contains tests for the openlp.core.widgets.edits module
|
||||
"""
|
||||
import os
|
||||
import pytest
|
||||
from pathlib import Path
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, PropertyMock, patch
|
||||
|
||||
from openlp.core.widgets.dialogs import FileDialog
|
||||
@ -31,267 +31,280 @@ from openlp.core.widgets.edits import PathEdit
|
||||
from openlp.core.widgets.enums import PathEditType
|
||||
|
||||
|
||||
class TestPathEdit(TestCase):
|
||||
@pytest.fixture()
|
||||
def widget():
|
||||
with patch('openlp.core.widgets.edits.PathEdit._setup'):
|
||||
return PathEdit()
|
||||
|
||||
|
||||
def test_path_getter(widget):
|
||||
"""
|
||||
Test the :class:`~openlp.core.widgets.edits.PathEdit` class
|
||||
Test the `path` property getter.
|
||||
"""
|
||||
def setUp(self):
|
||||
with patch('openlp.core.widgets.edits.PathEdit._setup'):
|
||||
self.widget = PathEdit()
|
||||
# GIVEN: An instance of PathEdit with the `_path` instance variable set
|
||||
widget._path = Path('getter', 'test', 'pat.h')
|
||||
|
||||
def test_path_getter(self):
|
||||
"""
|
||||
Test the `path` property getter.
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit with the `_path` instance variable set
|
||||
self.widget._path = Path('getter', 'test', 'pat.h')
|
||||
# WHEN: Reading the `path` property
|
||||
# THEN: The value that we set should be returned
|
||||
assert widget.path == Path('getter', 'test', 'pat.h')
|
||||
|
||||
# WHEN: Reading the `path` property
|
||||
# THEN: The value that we set should be returned
|
||||
assert self.widget.path == Path('getter', 'test', 'pat.h')
|
||||
|
||||
def test_path_setter(self):
|
||||
"""
|
||||
Test the `path` property setter.
|
||||
"""
|
||||
# GIVEN: An instance of the PathEdit object and a mocked `line_edit`
|
||||
self.widget.line_edit = MagicMock()
|
||||
def test_path_setter(widget):
|
||||
"""
|
||||
Test the `path` property setter.
|
||||
"""
|
||||
# GIVEN: An instance of the PathEdit object and a mocked `line_edit`
|
||||
widget.line_edit = MagicMock()
|
||||
|
||||
# WHEN: Writing to the `path` property
|
||||
self.widget.path = Path('setter', 'test', 'pat.h')
|
||||
# WHEN: Writing to the `path` property
|
||||
widget.path = Path('setter', 'test', 'pat.h')
|
||||
|
||||
# THEN: The `_path` instance variable should be set with the test data. The `line_edit` text and tooltip
|
||||
# should have also been set.
|
||||
assert self.widget._path == Path('setter', 'test', 'pat.h')
|
||||
self.widget.line_edit.setToolTip.assert_called_once_with(os.path.join('setter', 'test', 'pat.h'))
|
||||
self.widget.line_edit.setText.assert_called_once_with(os.path.join('setter', 'test', 'pat.h'))
|
||||
# THEN: The `_path` instance variable should be set with the test data. The `line_edit` text and tooltip
|
||||
# should have also been set.
|
||||
assert widget._path == Path('setter', 'test', 'pat.h')
|
||||
widget.line_edit.setToolTip.assert_called_once_with(os.path.join('setter', 'test', 'pat.h'))
|
||||
widget.line_edit.setText.assert_called_once_with(os.path.join('setter', 'test', 'pat.h'))
|
||||
|
||||
def test_path_type_getter(self):
|
||||
"""
|
||||
Test the `path_type` property getter.
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit
|
||||
# WHEN: Reading the `path` property
|
||||
# THEN: The default value should be returned
|
||||
assert self.widget.path_type == PathEditType.Files
|
||||
|
||||
def test_path_type_setter(self):
|
||||
"""
|
||||
Test the `path_type` property setter.
|
||||
"""
|
||||
# GIVEN: An instance of the PathEdit object and a mocked `update_button_tool_tips` method.
|
||||
with patch.object(self.widget, 'update_button_tool_tips') as mocked_update_button_tool_tips:
|
||||
def test_path_type_getter(widget):
|
||||
"""
|
||||
Test the `path_type` property getter.
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit
|
||||
# WHEN: Reading the `path` property
|
||||
# THEN: The default value should be returned
|
||||
assert widget.path_type == PathEditType.Files
|
||||
|
||||
# WHEN: Writing to a different value than default to the `path_type` property
|
||||
self.widget.path_type = PathEditType.Directories
|
||||
|
||||
# THEN: The `_path_type` instance variable should be set with the test data and not the default. The
|
||||
# update_button_tool_tips should have been called.
|
||||
assert self.widget._path_type == PathEditType.Directories
|
||||
mocked_update_button_tool_tips.assert_called_once_with()
|
||||
def test_path_type_setter(widget):
|
||||
"""
|
||||
Test the `path_type` property setter.
|
||||
"""
|
||||
# GIVEN: An instance of the PathEdit object and a mocked `update_button_tool_tips` method.
|
||||
with patch.object(widget, 'update_button_tool_tips') as mocked_update_button_tool_tips:
|
||||
|
||||
def test_update_button_tool_tips_directories(self):
|
||||
"""
|
||||
Test the `update_button_tool_tips` method.
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit with the `path_type` set to `Directories`
|
||||
self.widget.browse_button = MagicMock()
|
||||
self.widget.revert_button = MagicMock()
|
||||
self.widget._path_type = PathEditType.Directories
|
||||
# WHEN: Writing to a different value than default to the `path_type` property
|
||||
widget.path_type = PathEditType.Directories
|
||||
|
||||
# WHEN: Calling update_button_tool_tips
|
||||
self.widget.update_button_tool_tips()
|
||||
# THEN: The `_path_type` instance variable should be set with the test data and not the default. The
|
||||
# update_button_tool_tips should have been called.
|
||||
assert widget._path_type == PathEditType.Directories
|
||||
mocked_update_button_tool_tips.assert_called_once_with()
|
||||
|
||||
self.widget.browse_button.setToolTip.assert_called_once_with('Browse for directory.')
|
||||
self.widget.revert_button.setToolTip.assert_called_once_with('Revert to default directory.')
|
||||
|
||||
def test_update_button_tool_tips_files(self):
|
||||
"""
|
||||
Test the `update_button_tool_tips` method.
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit with the `path_type` set to `Files`
|
||||
self.widget.browse_button = MagicMock()
|
||||
self.widget.revert_button = MagicMock()
|
||||
self.widget._path_type = PathEditType.Files
|
||||
def test_update_button_tool_tips_directories(widget):
|
||||
"""
|
||||
Test the `update_button_tool_tips` method.
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit with the `path_type` set to `Directories`
|
||||
widget.browse_button = MagicMock()
|
||||
widget.revert_button = MagicMock()
|
||||
widget._path_type = PathEditType.Directories
|
||||
|
||||
# WHEN: Calling update_button_tool_tips
|
||||
self.widget.update_button_tool_tips()
|
||||
# WHEN: Calling update_button_tool_tips
|
||||
widget.update_button_tool_tips()
|
||||
|
||||
self.widget.browse_button.setToolTip.assert_called_once_with('Browse for file.')
|
||||
self.widget.revert_button.setToolTip.assert_called_once_with('Revert to default file.')
|
||||
widget.browse_button.setToolTip.assert_called_once_with('Browse for directory.')
|
||||
widget.revert_button.setToolTip.assert_called_once_with('Revert to default directory.')
|
||||
|
||||
@patch('openlp.core.widgets.edits.FileDialog.getExistingDirectory', return_value=None)
|
||||
@patch('openlp.core.widgets.edits.FileDialog.getOpenFileName')
|
||||
def test_on_browse_button_clicked_directory(self, mocked_get_open_file_name, mocked_get_existing_directory):
|
||||
"""
|
||||
Test the `browse_button` `clicked` handler on_browse_button_clicked when the `path_type` is set to Directories.
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit with the `path_type` set to `Directories` and a mocked
|
||||
# QFileDialog.getExistingDirectory
|
||||
self.widget._path_type = PathEditType.Directories
|
||||
self.widget._path = Path('test', 'path')
|
||||
|
||||
def test_update_button_tool_tips_files(widget):
|
||||
"""
|
||||
Test the `update_button_tool_tips` method.
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit with the `path_type` set to `Files`
|
||||
widget.browse_button = MagicMock()
|
||||
widget.revert_button = MagicMock()
|
||||
widget._path_type = PathEditType.Files
|
||||
|
||||
# WHEN: Calling update_button_tool_tips
|
||||
widget.update_button_tool_tips()
|
||||
|
||||
widget.browse_button.setToolTip.assert_called_once_with('Browse for file.')
|
||||
widget.revert_button.setToolTip.assert_called_once_with('Revert to default file.')
|
||||
|
||||
|
||||
@patch('openlp.core.widgets.edits.FileDialog.getExistingDirectory', return_value=None)
|
||||
@patch('openlp.core.widgets.edits.FileDialog.getOpenFileName')
|
||||
def test_on_browse_button_clicked_directory(mocked_get_open_file_name, mocked_get_existing_directory, widget):
|
||||
"""
|
||||
Test the `browse_button` `clicked` handler on_browse_button_clicked when the `path_type` is set to Directories.
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit with the `path_type` set to `Directories` and a mocked
|
||||
# QFileDialog.getExistingDirectory
|
||||
widget._path_type = PathEditType.Directories
|
||||
widget._path = Path('test', 'path')
|
||||
|
||||
# WHEN: Calling on_browse_button_clicked
|
||||
widget.on_browse_button_clicked()
|
||||
|
||||
# THEN: The FileDialog.getExistingDirectory should have been called with the default caption
|
||||
mocked_get_existing_directory.assert_called_once_with(widget, 'Select Directory',
|
||||
Path('test', 'path'),
|
||||
FileDialog.ShowDirsOnly)
|
||||
assert mocked_get_open_file_name.called is False
|
||||
|
||||
|
||||
def test_on_browse_button_clicked_directory_custom_caption(widget):
|
||||
"""
|
||||
Test the `browse_button` `clicked` handler on_browse_button_clicked when the `path_type` is set to Directories,
|
||||
and `dialog_caption` is set.
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit with the `path_type` set to `Directories` and a mocked
|
||||
# QFileDialog.getExistingDirectory with `default_caption` set.
|
||||
with patch('openlp.core.widgets.edits.FileDialog.getExistingDirectory', return_value=None) as \
|
||||
mocked_get_existing_directory, \
|
||||
patch('openlp.core.widgets.edits.FileDialog.getOpenFileName') as mocked_get_open_file_name:
|
||||
widget._path_type = PathEditType.Directories
|
||||
widget._path = Path('test', 'path')
|
||||
widget.dialog_caption = 'Directory Caption'
|
||||
|
||||
# WHEN: Calling on_browse_button_clicked
|
||||
self.widget.on_browse_button_clicked()
|
||||
widget.on_browse_button_clicked()
|
||||
|
||||
# THEN: The FileDialog.getExistingDirectory should have been called with the default caption
|
||||
mocked_get_existing_directory.assert_called_once_with(self.widget, 'Select Directory',
|
||||
# THEN: The FileDialog.getExistingDirectory should have been called with the custom caption
|
||||
mocked_get_existing_directory.assert_called_once_with(widget, 'Directory Caption',
|
||||
Path('test', 'path'),
|
||||
FileDialog.ShowDirsOnly)
|
||||
assert mocked_get_open_file_name.called is False
|
||||
|
||||
def test_on_browse_button_clicked_directory_custom_caption(self):
|
||||
"""
|
||||
Test the `browse_button` `clicked` handler on_browse_button_clicked when the `path_type` is set to Directories,
|
||||
and `dialog_caption` is set.
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit with the `path_type` set to `Directories` and a mocked
|
||||
# QFileDialog.getExistingDirectory with `default_caption` set.
|
||||
with patch('openlp.core.widgets.edits.FileDialog.getExistingDirectory', return_value=None) as \
|
||||
mocked_get_existing_directory, \
|
||||
patch('openlp.core.widgets.edits.FileDialog.getOpenFileName') as mocked_get_open_file_name:
|
||||
self.widget._path_type = PathEditType.Directories
|
||||
self.widget._path = Path('test', 'path')
|
||||
self.widget.dialog_caption = 'Directory Caption'
|
||||
|
||||
# WHEN: Calling on_browse_button_clicked
|
||||
self.widget.on_browse_button_clicked()
|
||||
def test_on_browse_button_clicked_file(widget):
|
||||
"""
|
||||
Test the `browse_button` `clicked` handler on_browse_button_clicked when the `path_type` is set to Files.
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit with the `path_type` set to `Files` and a mocked QFileDialog.getOpenFileName
|
||||
with patch('openlp.core.widgets.edits.FileDialog.getExistingDirectory') as mocked_get_existing_directory, \
|
||||
patch('openlp.core.widgets.edits.FileDialog.getOpenFileName', return_value=(None, '')) as \
|
||||
mocked_get_open_file_name:
|
||||
widget._path_type = PathEditType.Files
|
||||
widget._path = Path('test', 'pat.h')
|
||||
|
||||
# THEN: The FileDialog.getExistingDirectory should have been called with the custom caption
|
||||
mocked_get_existing_directory.assert_called_once_with(self.widget, 'Directory Caption',
|
||||
Path('test', 'path'),
|
||||
FileDialog.ShowDirsOnly)
|
||||
assert mocked_get_open_file_name.called is False
|
||||
# WHEN: Calling on_browse_button_clicked
|
||||
widget.on_browse_button_clicked()
|
||||
|
||||
def test_on_browse_button_clicked_file(self):
|
||||
"""
|
||||
Test the `browse_button` `clicked` handler on_browse_button_clicked when the `path_type` is set to Files.
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit with the `path_type` set to `Files` and a mocked QFileDialog.getOpenFileName
|
||||
with patch('openlp.core.widgets.edits.FileDialog.getExistingDirectory') as mocked_get_existing_directory, \
|
||||
patch('openlp.core.widgets.edits.FileDialog.getOpenFileName', return_value=(None, '')) as \
|
||||
mocked_get_open_file_name:
|
||||
self.widget._path_type = PathEditType.Files
|
||||
self.widget._path = Path('test', 'pat.h')
|
||||
# THEN: The FileDialog.getOpenFileName should have been called with the default caption
|
||||
mocked_get_open_file_name.assert_called_once_with(widget, 'Select File', Path('test', 'pat.h'),
|
||||
widget.filters)
|
||||
assert mocked_get_existing_directory.called is False
|
||||
|
||||
# WHEN: Calling on_browse_button_clicked
|
||||
self.widget.on_browse_button_clicked()
|
||||
|
||||
# THEN: The FileDialog.getOpenFileName should have been called with the default caption
|
||||
mocked_get_open_file_name.assert_called_once_with(self.widget, 'Select File', Path('test', 'pat.h'),
|
||||
self.widget.filters)
|
||||
assert mocked_get_existing_directory.called is False
|
||||
def test_on_browse_button_clicked_file_custom_caption(widget):
|
||||
"""
|
||||
Test the `browse_button` `clicked` handler on_browse_button_clicked when the `path_type` is set to Files and
|
||||
`dialog_caption` is set.
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit with the `path_type` set to `Files` and a mocked QFileDialog.getOpenFileName
|
||||
# with `default_caption` set.
|
||||
with patch('openlp.core.widgets.edits.FileDialog.getExistingDirectory') as mocked_get_existing_directory, \
|
||||
patch('openlp.core.widgets.edits.FileDialog.getOpenFileName', return_value=(None, '')) as \
|
||||
mocked_get_open_file_name:
|
||||
widget._path_type = PathEditType.Files
|
||||
widget._path = Path('test', 'pat.h')
|
||||
widget.dialog_caption = 'File Caption'
|
||||
|
||||
def test_on_browse_button_clicked_file_custom_caption(self):
|
||||
"""
|
||||
Test the `browse_button` `clicked` handler on_browse_button_clicked when the `path_type` is set to Files and
|
||||
`dialog_caption` is set.
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit with the `path_type` set to `Files` and a mocked QFileDialog.getOpenFileName
|
||||
# with `default_caption` set.
|
||||
with patch('openlp.core.widgets.edits.FileDialog.getExistingDirectory') as mocked_get_existing_directory, \
|
||||
patch('openlp.core.widgets.edits.FileDialog.getOpenFileName', return_value=(None, '')) as \
|
||||
mocked_get_open_file_name:
|
||||
self.widget._path_type = PathEditType.Files
|
||||
self.widget._path = Path('test', 'pat.h')
|
||||
self.widget.dialog_caption = 'File Caption'
|
||||
# WHEN: Calling on_browse_button_clicked
|
||||
widget.on_browse_button_clicked()
|
||||
|
||||
# WHEN: Calling on_browse_button_clicked
|
||||
self.widget.on_browse_button_clicked()
|
||||
# THEN: The FileDialog.getOpenFileName should have been called with the custom caption
|
||||
mocked_get_open_file_name.assert_called_once_with(widget, 'File Caption', Path('test', 'pat.h'),
|
||||
widget.filters)
|
||||
assert mocked_get_existing_directory.called is False
|
||||
|
||||
# THEN: The FileDialog.getOpenFileName should have been called with the custom caption
|
||||
mocked_get_open_file_name.assert_called_once_with(self.widget, 'File Caption', Path('test', 'pat.h'),
|
||||
self.widget.filters)
|
||||
assert mocked_get_existing_directory.called is False
|
||||
|
||||
def test_on_browse_button_clicked_user_cancels(self):
|
||||
"""
|
||||
Test the `browse_button` `clicked` handler on_browse_button_clicked when the user cancels the FileDialog (an
|
||||
empty str is returned)
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit with a mocked QFileDialog.getOpenFileName which returns an empty str for the
|
||||
# file path.
|
||||
with patch('openlp.core.widgets.edits.FileDialog.getOpenFileName', return_value=(None, '')) as \
|
||||
mocked_get_open_file_name:
|
||||
def test_on_browse_button_clicked_user_cancels(widget):
|
||||
"""
|
||||
Test the `browse_button` `clicked` handler on_browse_button_clicked when the user cancels the FileDialog (an
|
||||
empty str is returned)
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit with a mocked QFileDialog.getOpenFileName which returns an empty str for the
|
||||
# file path.
|
||||
with patch('openlp.core.widgets.edits.FileDialog.getOpenFileName', return_value=(None, '')) as \
|
||||
mocked_get_open_file_name:
|
||||
|
||||
# WHEN: Calling on_browse_button_clicked
|
||||
self.widget.on_browse_button_clicked()
|
||||
# WHEN: Calling on_browse_button_clicked
|
||||
widget.on_browse_button_clicked()
|
||||
|
||||
# THEN: normpath should not have been called
|
||||
assert mocked_get_open_file_name.called is True
|
||||
# THEN: normpath should not have been called
|
||||
assert mocked_get_open_file_name.called is True
|
||||
|
||||
def test_on_browse_button_clicked_user_accepts(self):
|
||||
"""
|
||||
Test the `browse_button` `clicked` handler on_browse_button_clicked when the user accepts the FileDialog (a path
|
||||
is returned)
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit with a mocked QFileDialog.getOpenFileName which returns a str for the file
|
||||
# path.
|
||||
with patch('openlp.core.widgets.edits.FileDialog.getOpenFileName',
|
||||
return_value=(Path('test', 'pat.h'), '')) as mocked_get_open_file_name, \
|
||||
patch.object(self.widget, 'on_new_path'):
|
||||
|
||||
# WHEN: Calling on_browse_button_clicked
|
||||
self.widget.on_browse_button_clicked()
|
||||
def test_on_browse_button_clicked_user_accepts(widget):
|
||||
"""
|
||||
Test the `browse_button` `clicked` handler on_browse_button_clicked when the user accepts the FileDialog (a path
|
||||
is returned)
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit with a mocked QFileDialog.getOpenFileName which returns a str for the file
|
||||
# path.
|
||||
with patch('openlp.core.widgets.edits.FileDialog.getOpenFileName',
|
||||
return_value=(Path('test', 'pat.h'), '')) as mocked_get_open_file_name, \
|
||||
patch.object(widget, 'on_new_path'):
|
||||
|
||||
# THEN: normpath and `on_new_path` should have been called
|
||||
assert mocked_get_open_file_name.called is True
|
||||
assert self.widget.on_new_path.called is True
|
||||
# WHEN: Calling on_browse_button_clicked
|
||||
widget.on_browse_button_clicked()
|
||||
|
||||
def test_on_revert_button_clicked(self):
|
||||
"""
|
||||
Test that the default path is set as the path when the `revert_button.clicked` handler is called.
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit with a mocked `on_new_path`, and the `default_path` set.
|
||||
with patch.object(self.widget, 'on_new_path') as mocked_on_new_path:
|
||||
self.widget.default_path = Path('default', 'pat.h')
|
||||
# THEN: normpath and `on_new_path` should have been called
|
||||
assert mocked_get_open_file_name.called is True
|
||||
assert widget.on_new_path.called is True
|
||||
|
||||
# WHEN: Calling `on_revert_button_clicked`
|
||||
self.widget.on_revert_button_clicked()
|
||||
|
||||
# THEN: on_new_path should have been called with the default path
|
||||
mocked_on_new_path.assert_called_once_with(Path('default', 'pat.h'))
|
||||
def test_on_revert_button_clicked(widget):
|
||||
"""
|
||||
Test that the default path is set as the path when the `revert_button.clicked` handler is called.
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit with a mocked `on_new_path`, and the `default_path` set.
|
||||
with patch.object(widget, 'on_new_path') as mocked_on_new_path:
|
||||
widget.default_path = Path('default', 'pat.h')
|
||||
|
||||
def test_on_line_edit_editing_finished(self):
|
||||
"""
|
||||
Test that the new path is set as the path when the `line_edit.editingFinished` handler is called.
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit with a mocked `line_edit` and `on_new_path`.
|
||||
with patch.object(self.widget, 'on_new_path') as mocked_on_new_path:
|
||||
self.widget.line_edit = MagicMock(**{'text.return_value': 'test/pat.h'})
|
||||
# WHEN: Calling `on_revert_button_clicked`
|
||||
widget.on_revert_button_clicked()
|
||||
|
||||
# WHEN: Calling `on_line_edit_editing_finished`
|
||||
self.widget.on_line_edit_editing_finished()
|
||||
# THEN: on_new_path should have been called with the default path
|
||||
mocked_on_new_path.assert_called_once_with(Path('default', 'pat.h'))
|
||||
|
||||
# THEN: on_new_path should have been called with the path enetered in `line_edit`
|
||||
mocked_on_new_path.assert_called_once_with(Path('test', 'pat.h'))
|
||||
|
||||
def test_on_new_path_no_change(self):
|
||||
"""
|
||||
Test `on_new_path` when called with a path that is the same as the existing path.
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit with a test path and mocked `pathChanged` signal
|
||||
with patch('openlp.core.widgets.edits.PathEdit.path', new_callable=PropertyMock):
|
||||
self.widget._path = Path('/old', 'test', 'pat.h')
|
||||
self.widget.pathChanged = MagicMock()
|
||||
def test_on_line_edit_editing_finished(widget):
|
||||
"""
|
||||
Test that the new path is set as the path when the `line_edit.editingFinished` handler is called.
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit with a mocked `line_edit` and `on_new_path`.
|
||||
with patch.object(widget, 'on_new_path') as mocked_on_new_path:
|
||||
widget.line_edit = MagicMock(**{'text.return_value': 'test/pat.h'})
|
||||
|
||||
# WHEN: Calling `on_new_path` with the same path as the existing path
|
||||
self.widget.on_new_path(Path('/old', 'test', 'pat.h'))
|
||||
# WHEN: Calling `on_line_edit_editing_finished`
|
||||
widget.on_line_edit_editing_finished()
|
||||
|
||||
# THEN: The `pathChanged` signal should not be emitted
|
||||
assert self.widget.pathChanged.emit.called is False
|
||||
# THEN: on_new_path should have been called with the path enetered in `line_edit`
|
||||
mocked_on_new_path.assert_called_once_with(Path('test', 'pat.h'))
|
||||
|
||||
def test_on_new_path_change(self):
|
||||
"""
|
||||
Test `on_new_path` when called with a path that is the different to the existing path.
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit with a test path and mocked `pathChanged` signal
|
||||
with patch('openlp.core.widgets.edits.PathEdit.path', new_callable=PropertyMock):
|
||||
self.widget._path = Path('/old', 'test', 'pat.h')
|
||||
self.widget.pathChanged = MagicMock()
|
||||
|
||||
# WHEN: Calling `on_new_path` with the a new path
|
||||
self.widget.on_new_path(Path('/new', 'test', 'pat.h'))
|
||||
def test_on_new_path_no_change(widget):
|
||||
"""
|
||||
Test `on_new_path` when called with a path that is the same as the existing path.
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit with a test path and mocked `pathChanged` signal
|
||||
with patch('openlp.core.widgets.edits.PathEdit.path', new_callable=PropertyMock):
|
||||
widget._path = Path('/old', 'test', 'pat.h')
|
||||
widget.pathChanged = MagicMock()
|
||||
|
||||
# THEN: The `pathChanged` signal should be emitted
|
||||
self.widget.pathChanged.emit.assert_called_once_with(Path('/new', 'test', 'pat.h'))
|
||||
# WHEN: Calling `on_new_path` with the same path as the existing path
|
||||
widget.on_new_path(Path('/old', 'test', 'pat.h'))
|
||||
|
||||
# THEN: The `pathChanged` signal should not be emitted
|
||||
assert widget.pathChanged.emit.called is False
|
||||
|
||||
|
||||
def test_on_new_path_change(widget):
|
||||
"""
|
||||
Test `on_new_path` when called with a path that is the different to the existing path.
|
||||
"""
|
||||
# GIVEN: An instance of PathEdit with a test path and mocked `pathChanged` signal
|
||||
with patch('openlp.core.widgets.edits.PathEdit.path', new_callable=PropertyMock):
|
||||
widget._path = Path('/old', 'test', 'pat.h')
|
||||
widget.pathChanged = MagicMock()
|
||||
|
||||
# WHEN: Calling `on_new_path` with the a new path
|
||||
widget.on_new_path(Path('/new', 'test', 'pat.h'))
|
||||
|
||||
# THEN: The `pathChanged` signal should be emitted
|
||||
widget.pathChanged.emit.assert_called_once_with(Path('/new', 'test', 'pat.h'))
|
||||
|
@ -24,7 +24,6 @@ Package to test the openlp.core.widgets.views package.
|
||||
import os
|
||||
import pytest
|
||||
from types import GeneratorType
|
||||
from unittest import TestCase
|
||||
from unittest.mock import MagicMock, call, patch
|
||||
|
||||
from PyQt5 import QtGui
|
||||
@ -54,56 +53,53 @@ def preview_widget_env():
|
||||
viewport_patcher.stop()
|
||||
|
||||
|
||||
class TestHandleMimeDataUrls(TestCase):
|
||||
def test_files():
|
||||
"""
|
||||
Test the :func:`openlp.core.widgets.views.handle_mime_data_urls` function.
|
||||
Test handle_mime_data_urls when the data points to some files.
|
||||
"""
|
||||
def test_files(self):
|
||||
"""
|
||||
Test handle_mime_data_urls when the data points to some files.
|
||||
"""
|
||||
# GIVEN: Some mocked objects that return True when is_file is called, and some mocked mime data
|
||||
mocked_path_instance_1 = MagicMock(**{'is_file.return_value': True})
|
||||
mocked_path_instance_2 = MagicMock(**{'is_file.return_value': True})
|
||||
with patch('openlp.core.widgets.views.Path',
|
||||
side_effect=[mocked_path_instance_1, mocked_path_instance_2]) as mocked_path:
|
||||
mocked_q_url_1 = MagicMock(**{'toLocalFile.return_value': os.path.join('file', 'test', 'path', '1.ext')})
|
||||
mocked_q_url_2 = MagicMock(**{'toLocalFile.return_value': os.path.join('file', 'test', 'path', '2.ext')})
|
||||
mocked_q_mime_data = MagicMock(**{'urls.return_value': [mocked_q_url_1, mocked_q_url_2]})
|
||||
# GIVEN: Some mocked objects that return True when is_file is called, and some mocked mime data
|
||||
mocked_path_instance_1 = MagicMock(**{'is_file.return_value': True})
|
||||
mocked_path_instance_2 = MagicMock(**{'is_file.return_value': True})
|
||||
with patch('openlp.core.widgets.views.Path',
|
||||
side_effect=[mocked_path_instance_1, mocked_path_instance_2]) as mocked_path:
|
||||
mocked_q_url_1 = MagicMock(**{'toLocalFile.return_value': os.path.join('file', 'test', 'path', '1.ext')})
|
||||
mocked_q_url_2 = MagicMock(**{'toLocalFile.return_value': os.path.join('file', 'test', 'path', '2.ext')})
|
||||
mocked_q_mime_data = MagicMock(**{'urls.return_value': [mocked_q_url_1, mocked_q_url_2]})
|
||||
|
||||
# WHEN: Calling handle_mime_data_urls with the mocked mime data
|
||||
result = handle_mime_data_urls(mocked_q_mime_data)
|
||||
# WHEN: Calling handle_mime_data_urls with the mocked mime data
|
||||
result = handle_mime_data_urls(mocked_q_mime_data)
|
||||
|
||||
# THEN: Both mocked Path objects should be returned in the list
|
||||
mocked_path.assert_has_calls([call(os.path.join('file', 'test', 'path', '1.ext')),
|
||||
call(os.path.join('file', 'test', 'path', '2.ext'))])
|
||||
assert result == [mocked_path_instance_1, mocked_path_instance_2]
|
||||
# THEN: Both mocked Path objects should be returned in the list
|
||||
mocked_path.assert_has_calls([call(os.path.join('file', 'test', 'path', '1.ext')),
|
||||
call(os.path.join('file', 'test', 'path', '2.ext'))])
|
||||
assert result == [mocked_path_instance_1, mocked_path_instance_2]
|
||||
|
||||
def test_directory(self):
|
||||
"""
|
||||
Test handle_mime_data_urls when the data points to some directories.
|
||||
"""
|
||||
# GIVEN: Some mocked objects that return True when is_dir is called, and some mocked mime data
|
||||
mocked_path_instance_1 = MagicMock()
|
||||
mocked_path_instance_2 = MagicMock()
|
||||
mocked_path_instance_3 = MagicMock()
|
||||
mocked_path_instance_4 = MagicMock(**{'is_file.return_value': False, 'is_directory.return_value': True,
|
||||
'iterdir.return_value': [mocked_path_instance_1, mocked_path_instance_2]})
|
||||
mocked_path_instance_5 = MagicMock(**{'is_file.return_value': False, 'is_directory.return_value': True,
|
||||
'iterdir.return_value': [mocked_path_instance_3]})
|
||||
with patch('openlp.core.widgets.views.Path',
|
||||
side_effect=[mocked_path_instance_4, mocked_path_instance_5]) as mocked_path:
|
||||
mocked_q_url_1 = MagicMock(**{'toLocalFile.return_value': os.path.join('file', 'test', 'path')})
|
||||
mocked_q_url_2 = MagicMock(**{'toLocalFile.return_value': os.path.join('file', 'test', 'path')})
|
||||
mocked_q_mime_data = MagicMock(**{'urls.return_value': [mocked_q_url_1, mocked_q_url_2]})
|
||||
|
||||
# WHEN: Calling handle_mime_data_urls with the mocked mime data
|
||||
result = handle_mime_data_urls(mocked_q_mime_data)
|
||||
def test_directory():
|
||||
"""
|
||||
Test handle_mime_data_urls when the data points to some directories.
|
||||
"""
|
||||
# GIVEN: Some mocked objects that return True when is_dir is called, and some mocked mime data
|
||||
mocked_path_instance_1 = MagicMock()
|
||||
mocked_path_instance_2 = MagicMock()
|
||||
mocked_path_instance_3 = MagicMock()
|
||||
mocked_path_instance_4 = MagicMock(**{'is_file.return_value': False, 'is_directory.return_value': True,
|
||||
'iterdir.return_value': [mocked_path_instance_1, mocked_path_instance_2]})
|
||||
mocked_path_instance_5 = MagicMock(**{'is_file.return_value': False, 'is_directory.return_value': True,
|
||||
'iterdir.return_value': [mocked_path_instance_3]})
|
||||
with patch('openlp.core.widgets.views.Path',
|
||||
side_effect=[mocked_path_instance_4, mocked_path_instance_5]) as mocked_path:
|
||||
mocked_q_url_1 = MagicMock(**{'toLocalFile.return_value': os.path.join('file', 'test', 'path')})
|
||||
mocked_q_url_2 = MagicMock(**{'toLocalFile.return_value': os.path.join('file', 'test', 'path')})
|
||||
mocked_q_mime_data = MagicMock(**{'urls.return_value': [mocked_q_url_1, mocked_q_url_2]})
|
||||
|
||||
# THEN: The three mocked Path file objects should be returned in the list
|
||||
mocked_path.assert_has_calls([call(os.path.join('file', 'test', 'path')),
|
||||
call(os.path.join('file', 'test', 'path'))])
|
||||
assert result == [mocked_path_instance_1, mocked_path_instance_2, mocked_path_instance_3]
|
||||
# WHEN: Calling handle_mime_data_urls with the mocked mime data
|
||||
result = handle_mime_data_urls(mocked_q_mime_data)
|
||||
|
||||
# THEN: The three mocked Path file objects should be returned in the list
|
||||
mocked_path.assert_has_calls([call(os.path.join('file', 'test', 'path')),
|
||||
call(os.path.join('file', 'test', 'path'))])
|
||||
assert result == [mocked_path_instance_1, mocked_path_instance_2, mocked_path_instance_3]
|
||||
|
||||
|
||||
def test_new_list_preview_widget(preview_widget_env, mock_settings):
|
||||
@ -578,127 +574,124 @@ def test_autoscroll_normal(mocked_slide_count, mocked_item, mocked_scrollToItem,
|
||||
mocked_item.assert_has_calls(calls)
|
||||
|
||||
|
||||
class TestListWidgetWithDnD(TestCase):
|
||||
def test_treewidgetwithdnd_clear():
|
||||
"""
|
||||
Test the :class:`~openlp.core.widgets.views.ListWidgetWithDnD` class
|
||||
Test the clear method when called without any arguments.
|
||||
"""
|
||||
def test_clear(self):
|
||||
"""
|
||||
Test the clear method when called without any arguments.
|
||||
"""
|
||||
# GIVEN: An instance of ListWidgetWithDnD
|
||||
widget = ListWidgetWithDnD()
|
||||
# GIVEN: An instance of ListWidgetWithDnD
|
||||
widget = ListWidgetWithDnD()
|
||||
|
||||
# WHEN: Calling clear with out any arguments
|
||||
widget.clear()
|
||||
# WHEN: Calling clear with out any arguments
|
||||
widget.clear()
|
||||
|
||||
# THEN: The results text should be the standard 'no results' text.
|
||||
assert widget.no_results_text == UiStrings().NoResults
|
||||
|
||||
def test_clear_search_while_typing(self):
|
||||
"""
|
||||
Test the clear method when called with the search_while_typing argument set to True
|
||||
"""
|
||||
# GIVEN: An instance of ListWidgetWithDnD
|
||||
widget = ListWidgetWithDnD()
|
||||
|
||||
# WHEN: Calling clear with search_while_typing set to True
|
||||
widget.clear(search_while_typing=True)
|
||||
|
||||
# THEN: The results text should be the 'short results' text.
|
||||
assert widget.no_results_text == UiStrings().ShortResults
|
||||
|
||||
def test_all_items_no_list_items(self):
|
||||
"""
|
||||
Test allItems when there are no items in the list widget
|
||||
"""
|
||||
# GIVEN: An instance of ListWidgetWithDnD
|
||||
widget = ListWidgetWithDnD()
|
||||
with patch.object(widget, 'count', return_value=0), \
|
||||
patch.object(widget, 'item', side_effect=lambda x: [][x]):
|
||||
|
||||
# WHEN: Calling allItems
|
||||
result = widget.allItems()
|
||||
|
||||
# THEN: An instance of a Generator object should be returned. The generator should not yeild any results
|
||||
assert isinstance(result, GeneratorType)
|
||||
assert list(result) == []
|
||||
|
||||
def test_all_items_list_items(self):
|
||||
"""
|
||||
Test allItems when the list widget contains some items.
|
||||
"""
|
||||
# GIVEN: An instance of ListWidgetWithDnD
|
||||
widget = ListWidgetWithDnD()
|
||||
with patch.object(widget, 'count', return_value=2), \
|
||||
patch.object(widget, 'item', side_effect=lambda x: [5, 3][x]):
|
||||
|
||||
# WHEN: Calling allItems
|
||||
result = widget.allItems()
|
||||
|
||||
# THEN: An instance of a Generator object should be returned. The generator should not yeild any results
|
||||
assert isinstance(result, GeneratorType)
|
||||
assert list(result) == [5, 3]
|
||||
|
||||
def test_paint_event(self):
|
||||
"""
|
||||
Test the paintEvent method when the list is not empty
|
||||
"""
|
||||
# GIVEN: An instance of ListWidgetWithDnD with a mocked out count methode which returns 1
|
||||
# (i.e the list has an item)
|
||||
widget = ListWidgetWithDnD()
|
||||
with patch('openlp.core.widgets.views.QtWidgets.QListWidget.paintEvent') as mocked_paint_event, \
|
||||
patch.object(widget, 'count', return_value=1), \
|
||||
patch.object(widget, 'viewport') as mocked_viewport:
|
||||
mocked_event = MagicMock()
|
||||
|
||||
# WHEN: Calling paintEvent
|
||||
widget.paintEvent(mocked_event)
|
||||
|
||||
# THEN: The overridden paintEvnet should have been called
|
||||
mocked_paint_event.assert_called_once_with(mocked_event)
|
||||
assert mocked_viewport.called is False
|
||||
|
||||
def test_paint_event_no_items(self):
|
||||
"""
|
||||
Test the paintEvent method when the list is empty
|
||||
"""
|
||||
# GIVEN: An instance of ListWidgetWithDnD with a mocked out count methode which returns 0
|
||||
# (i.e the list is empty)
|
||||
widget = ListWidgetWithDnD()
|
||||
mocked_painter_instance = MagicMock()
|
||||
mocked_qrect = MagicMock()
|
||||
with patch('openlp.core.widgets.views.QtWidgets.QListWidget.paintEvent') as mocked_paint_event, \
|
||||
patch.object(widget, 'count', return_value=0), \
|
||||
patch.object(widget, 'viewport'), \
|
||||
patch('openlp.core.widgets.views.QtGui.QPainter',
|
||||
return_value=mocked_painter_instance) as mocked_qpainter, \
|
||||
patch('openlp.core.widgets.views.QtCore.QRect', return_value=mocked_qrect):
|
||||
mocked_event = MagicMock()
|
||||
|
||||
# WHEN: Calling paintEvent
|
||||
widget.paintEvent(mocked_event)
|
||||
|
||||
# THEN: The overridden paintEvnet should have been called, and some text should be drawn.
|
||||
mocked_paint_event.assert_called_once_with(mocked_event)
|
||||
mocked_qpainter.assert_called_once_with(widget.viewport())
|
||||
mocked_painter_instance.drawText.assert_called_once_with(mocked_qrect, 4100, 'No Search Results')
|
||||
# THEN: The results text should be the standard 'no results' text.
|
||||
assert widget.no_results_text == UiStrings().NoResults
|
||||
|
||||
|
||||
class TestTreeWidgetWithDnD(TestCase):
|
||||
def test_clear_search_while_typing():
|
||||
"""
|
||||
Test the :class:`~openlp.core.widgets.views.TreeWidgetWithDnD` class
|
||||
Test the clear method when called with the search_while_typing argument set to True
|
||||
"""
|
||||
def test_constructor(self):
|
||||
"""
|
||||
Test the constructor
|
||||
"""
|
||||
# GIVEN: A TreeWidgetWithDnD
|
||||
# WHEN: An instance is created
|
||||
widget = TreeWidgetWithDnD(name='Test')
|
||||
# GIVEN: An instance of ListWidgetWithDnD
|
||||
widget = ListWidgetWithDnD()
|
||||
|
||||
# THEN: It should be initialised correctly
|
||||
assert widget.mime_data_text == 'Test'
|
||||
assert widget.allow_internal_dnd is False
|
||||
assert widget.indentation() == 0
|
||||
assert widget.isAnimated() is True
|
||||
# WHEN: Calling clear with search_while_typing set to True
|
||||
widget.clear(search_while_typing=True)
|
||||
|
||||
# THEN: The results text should be the 'short results' text.
|
||||
assert widget.no_results_text == UiStrings().ShortResults
|
||||
|
||||
|
||||
def test_all_items_no_list_items():
|
||||
"""
|
||||
Test allItems when there are no items in the list widget
|
||||
"""
|
||||
# GIVEN: An instance of ListWidgetWithDnD
|
||||
widget = ListWidgetWithDnD()
|
||||
with patch.object(widget, 'count', return_value=0), \
|
||||
patch.object(widget, 'item', side_effect=lambda x: [][x]):
|
||||
|
||||
# WHEN: Calling allItems
|
||||
result = widget.allItems()
|
||||
|
||||
# THEN: An instance of a Generator object should be returned. The generator should not yeild any results
|
||||
assert isinstance(result, GeneratorType)
|
||||
assert list(result) == []
|
||||
|
||||
|
||||
def test_all_items_list_items():
|
||||
"""
|
||||
Test allItems when the list widget contains some items.
|
||||
"""
|
||||
# GIVEN: An instance of ListWidgetWithDnD
|
||||
widget = ListWidgetWithDnD()
|
||||
with patch.object(widget, 'count', return_value=2), \
|
||||
patch.object(widget, 'item', side_effect=lambda x: [5, 3][x]):
|
||||
|
||||
# WHEN: Calling allItems
|
||||
result = widget.allItems()
|
||||
|
||||
# THEN: An instance of a Generator object should be returned. The generator should not yeild any results
|
||||
assert isinstance(result, GeneratorType)
|
||||
assert list(result) == [5, 3]
|
||||
|
||||
|
||||
def test_paint_event():
|
||||
"""
|
||||
Test the paintEvent method when the list is not empty
|
||||
"""
|
||||
# GIVEN: An instance of ListWidgetWithDnD with a mocked out count methode which returns 1
|
||||
# (i.e the list has an item)
|
||||
widget = ListWidgetWithDnD()
|
||||
with patch('openlp.core.widgets.views.QtWidgets.QListWidget.paintEvent') as mocked_paint_event, \
|
||||
patch.object(widget, 'count', return_value=1), \
|
||||
patch.object(widget, 'viewport') as mocked_viewport:
|
||||
mocked_event = MagicMock()
|
||||
|
||||
# WHEN: Calling paintEvent
|
||||
widget.paintEvent(mocked_event)
|
||||
|
||||
# THEN: The overridden paintEvnet should have been called
|
||||
mocked_paint_event.assert_called_once_with(mocked_event)
|
||||
assert mocked_viewport.called is False
|
||||
|
||||
|
||||
def test_paint_event_no_items():
|
||||
"""
|
||||
Test the paintEvent method when the list is empty
|
||||
"""
|
||||
# GIVEN: An instance of ListWidgetWithDnD with a mocked out count methode which returns 0
|
||||
# (i.e the list is empty)
|
||||
widget = ListWidgetWithDnD()
|
||||
mocked_painter_instance = MagicMock()
|
||||
mocked_qrect = MagicMock()
|
||||
with patch('openlp.core.widgets.views.QtWidgets.QListWidget.paintEvent') as mocked_paint_event, \
|
||||
patch.object(widget, 'count', return_value=0), \
|
||||
patch.object(widget, 'viewport'), \
|
||||
patch('openlp.core.widgets.views.QtGui.QPainter',
|
||||
return_value=mocked_painter_instance) as mocked_qpainter, \
|
||||
patch('openlp.core.widgets.views.QtCore.QRect', return_value=mocked_qrect):
|
||||
mocked_event = MagicMock()
|
||||
|
||||
# WHEN: Calling paintEvent
|
||||
widget.paintEvent(mocked_event)
|
||||
|
||||
# THEN: The overridden paintEvnet should have been called, and some text should be drawn.
|
||||
mocked_paint_event.assert_called_once_with(mocked_event)
|
||||
mocked_qpainter.assert_called_once_with(widget.viewport())
|
||||
mocked_painter_instance.drawText.assert_called_once_with(mocked_qrect, 4100, 'No Search Results')
|
||||
|
||||
|
||||
def test_treewidgetwithdnd_constructor():
|
||||
"""
|
||||
Test the constructor
|
||||
"""
|
||||
# GIVEN: A TreeWidgetWithDnD
|
||||
# WHEN: An instance is created
|
||||
widget = TreeWidgetWithDnD(name='Test')
|
||||
|
||||
# THEN: It should be initialised correctly
|
||||
assert widget.mime_data_text == 'Test'
|
||||
assert widget.allow_internal_dnd is False
|
||||
assert widget.indentation() == 0
|
||||
assert widget.isAnimated() is True
|
||||
|
Loading…
Reference in New Issue
Block a user