This commit is contained in:
Phill Ridout 2015-02-01 21:40:59 +00:00
commit 4c36bba911
15 changed files with 308 additions and 87 deletions

View File

@ -213,13 +213,6 @@ class MediaManagerItem(QtGui.QWidget, RegistryProperties):
icon=':/general/general_edit.png',
triggers=self.on_edit_click)
create_widget_action(self.list_view, separator=True)
if self.has_delete_icon:
create_widget_action(self.list_view,
'listView%s%sItem' % (self.plugin.name.title(), StringContent.Delete.title()),
text=self.plugin.get_string(StringContent.Delete)['title'],
icon=':/general/general_delete.png',
can_shortcuts=True, triggers=self.on_delete_click)
create_widget_action(self.list_view, separator=True)
create_widget_action(self.list_view,
'listView%s%sItem' % (self.plugin.name.title(), StringContent.Preview.title()),
text=self.plugin.get_string(StringContent.Preview)['title'],
@ -238,6 +231,13 @@ class MediaManagerItem(QtGui.QWidget, RegistryProperties):
text=self.plugin.get_string(StringContent.Service)['title'],
icon=':/general/general_add.png',
triggers=self.on_add_click)
if self.has_delete_icon:
create_widget_action(self.list_view, separator=True)
create_widget_action(self.list_view,
'listView%s%sItem' % (self.plugin.name.title(), StringContent.Delete.title()),
text=self.plugin.get_string(StringContent.Delete)['title'],
icon=':/general/general_delete.png',
can_shortcuts=True, triggers=self.on_delete_click)
if self.add_to_service_item:
create_widget_action(self.list_view, separator=True)
create_widget_action(self.list_view,

View File

@ -33,7 +33,12 @@ import cgi
import logging
from PyQt4 import QtCore, QtGui, QtWebKit, QtOpenGL
from PyQt4.phonon import Phonon
PHONON_AVAILABLE = True
try:
from PyQt4.phonon import Phonon
except ImportError:
PHONON_AVAILABLE = False
from openlp.core.common import Registry, RegistryProperties, OpenLPMixin, Settings, translate, is_macosx
from openlp.core.lib import ServiceItem, ImageSource, ScreenList, build_html, expand_tags, image_to_byte
@ -139,7 +144,7 @@ class MainDisplay(OpenLPMixin, Display, RegistryProperties):
self.override = {}
self.retranslateUi()
self.media_object = None
if self.is_live:
if self.is_live and PHONON_AVAILABLE:
self.audio_player = AudioPlayer(self)
else:
self.audio_player = None

View File

@ -22,11 +22,11 @@
"""
The :mod:`~openlp.core.ui.media.webkit` module contains our WebKit video player
"""
from PyQt4 import QtGui
from PyQt4 import QtGui, QtWebKit
import logging
from openlp.core.common import Settings, is_macosx
from openlp.core.common import Settings
from openlp.core.lib import translate
from openlp.core.ui.media import MediaState
from openlp.core.ui.media.mediaplayer import MediaPlayer
@ -222,13 +222,15 @@ class WebkitPlayer(MediaPlayer):
def check_available(self):
"""
Check the availability of the media player
Check the availability of the media player.
:return: boolean. True if available
"""
# At the moment we don't have support for webkitplayer on Mac OS X
if is_macosx():
return False
else:
return True
web = QtWebKit.QWebPage()
# This script should return '[object HTMLVideoElement]' if the html5 video is available in webkit. Otherwise it
# should return '[object HTMLUnknownElement]'
return web.mainFrame().evaluateJavaScript(
"Object.prototype.toString.call(document.createElement('video'));") == '[object HTMLVideoElement]'
def load(self, display):
"""

View File

@ -332,8 +332,7 @@ class SourceSelectTabs(QDialog):
msg = QtGui.QMessageBox()
msg.setText(translate('OpenLP.SourceSelectForm', 'Delete entries for this projector'))
msg.setInformativeText(translate('OpenLP.SourceSelectForm',
'Are you sure you want to delete ALL user-defined '),
translate('OpenLP.SourceSelectForm',
'Are you sure you want to delete ALL user-defined '
'source input text for this projector?'))
msg.setStandardButtons(msg.Cancel | msg.Ok)
msg.setDefaultButton(msg.Cancel)
@ -471,8 +470,7 @@ class SourceSelectSingle(QDialog):
msg = QtGui.QMessageBox()
msg.setText(translate('OpenLP.SourceSelectForm', 'Delete entries for this projector'))
msg.setInformativeText(translate('OpenLP.SourceSelectForm',
'Are you sure you want to delete ALL user-defined '),
translate('OpenLP.SourceSelectForm',
'Are you sure you want to delete ALL user-defined '
'source input text for this projector?'))
msg.setStandardButtons(msg.Cancel | msg.Ok)
msg.setDefaultButton(msg.Cancel)

View File

@ -580,6 +580,7 @@ class SlideController(DisplayController, RegistryProperties):
self.display.setup()
if self.is_live:
self.__add_actions_to_widget(self.display)
if self.display.audio_player:
self.display.audio_player.connectSlot(QtCore.SIGNAL('tick(qint64)'), self.on_audio_time_remaining)
# The SlidePreview's ratio.
try:
@ -834,26 +835,28 @@ class SlideController(DisplayController, RegistryProperties):
self.slide_list = {}
if self.is_live:
self.song_menu.menu().clear()
self.display.audio_player.reset()
self.set_audio_items_visibility(False)
self.audio_pause_item.setChecked(False)
# If the current item has background audio
if self.service_item.is_capable(ItemCapabilities.HasBackgroundAudio):
self.log_debug('Starting to play...')
self.display.audio_player.add_to_playlist(self.service_item.background_audio)
self.track_menu.clear()
for counter in range(len(self.service_item.background_audio)):
action = self.track_menu.addAction(os.path.basename(self.service_item.background_audio[counter]))
action.setData(counter)
action.triggered.connect(self.on_track_triggered)
self.display.audio_player.repeat = \
Settings().value(self.main_window.general_settings_section + '/audio repeat list')
if Settings().value(self.main_window.general_settings_section + '/audio start paused'):
self.audio_pause_item.setChecked(True)
self.display.audio_player.pause()
else:
self.display.audio_player.play()
self.set_audio_items_visibility(True)
if self.display.audio_player:
self.display.audio_player.reset()
self.set_audio_items_visibility(False)
self.audio_pause_item.setChecked(False)
# If the current item has background audio
if self.service_item.is_capable(ItemCapabilities.HasBackgroundAudio):
self.log_debug('Starting to play...')
self.display.audio_player.add_to_playlist(self.service_item.background_audio)
self.track_menu.clear()
for counter in range(len(self.service_item.background_audio)):
action = self.track_menu.addAction(
os.path.basename(self.service_item.background_audio[counter]))
action.setData(counter)
action.triggered.connect(self.on_track_triggered)
self.display.audio_player.repeat = \
Settings().value(self.main_window.general_settings_section + '/audio repeat list')
if Settings().value(self.main_window.general_settings_section + '/audio start paused'):
self.audio_pause_item.setChecked(True)
self.display.audio_player.pause()
else:
self.display.audio_player.play()
self.set_audio_items_visibility(True)
row = 0
width = self.main_window.control_splitter.sizes()[self.split]
for frame_number, frame in enumerate(self.service_item.get_frames()):

View File

@ -178,7 +178,7 @@ def update_reference_separators():
default_separators = [
'|'.join([
translate('BiblesPlugin', ':', 'Verse identifier e.g. Genesis 1 : 1 = Genesis Chapter 1 Verse 1'),
translate('BiblesPlugin', 'v','Verse identifier e.g. Genesis 1 v 1 = Genesis Chapter 1 Verse 1'),
translate('BiblesPlugin', 'v', 'Verse identifier e.g. Genesis 1 v 1 = Genesis Chapter 1 Verse 1'),
translate('BiblesPlugin', 'V', 'Verse identifier e.g. Genesis 1 V 1 = Genesis Chapter 1 Verse 1'),
translate('BiblesPlugin', 'verse', 'Verse identifier e.g. Genesis 1 verse 1 = Genesis Chapter 1 Verse 1'),
translate('BiblesPlugin', 'verses',

View File

@ -314,6 +314,16 @@ class ImageMediaItem(MediaManagerItem):
return True
return return_value
def generate_thumbnail_path(self, image):
"""
Generate a path to the thumbnail
:param image: An instance of ImageFileNames
:return: A path to the thumbnail of type str
"""
ext = os.path.splitext(image.filename)[1].lower()
return os.path.join(self.service_path, '{}{}'.format(str(image.id), ext))
def load_full_list(self, images, initial_load=False, open_group=None):
"""
Replace the list of images and groups in the interface.
@ -335,27 +345,26 @@ class ImageMediaItem(MediaManagerItem):
# Sort the images by its filename considering language specific.
# characters.
images.sort(key=lambda image_object: get_locale_key(os.path.split(str(image_object.filename))[1]))
for imageFile in images:
log.debug('Loading image: %s', imageFile.filename)
filename = os.path.split(imageFile.filename)[1]
ext = os.path.splitext(imageFile.filename)[1].lower()
thumb = os.path.join(self.service_path, "%s%s" % (str(imageFile.id), ext))
if not os.path.exists(imageFile.filename):
for image_file in images:
log.debug('Loading image: %s', image_file.filename)
filename = os.path.split(image_file.filename)[1]
thumb = self.generate_thumbnail_path(image_file)
if not os.path.exists(image_file.filename):
icon = build_icon(':/general/general_delete.png')
else:
if validate_thumb(imageFile.filename, thumb):
if validate_thumb(image_file.filename, thumb):
icon = build_icon(thumb)
else:
icon = create_thumb(imageFile.filename, thumb)
icon = create_thumb(image_file.filename, thumb)
item_name = QtGui.QTreeWidgetItem([filename])
item_name.setText(0, filename)
item_name.setIcon(0, icon)
item_name.setToolTip(0, imageFile.filename)
item_name.setData(0, QtCore.Qt.UserRole, imageFile)
if imageFile.group_id == 0:
item_name.setToolTip(0, image_file.filename)
item_name.setData(0, QtCore.Qt.UserRole, image_file)
if image_file.group_id == 0:
self.list_view.addTopLevelItem(item_name)
else:
group_items[imageFile.group_id].addChild(item_name)
group_items[image_file.group_id].addChild(item_name)
if not initial_load:
self.main_window.increment_progress_bar()
if not initial_load:
@ -549,24 +558,24 @@ class ImageMediaItem(MediaManagerItem):
# force a nonexistent theme
service_item.theme = -1
missing_items_file_names = []
images_file_names = []
images = []
# Expand groups to images
for bitem in items:
if isinstance(bitem.data(0, QtCore.Qt.UserRole), ImageGroups) or bitem.data(0, QtCore.Qt.UserRole) is None:
for index in range(0, bitem.childCount()):
if isinstance(bitem.child(index).data(0, QtCore.Qt.UserRole), ImageFilenames):
images_file_names.append(bitem.child(index).data(0, QtCore.Qt.UserRole).filename)
images.append(bitem.child(index).data(0, QtCore.Qt.UserRole))
elif isinstance(bitem.data(0, QtCore.Qt.UserRole), ImageFilenames):
images_file_names.append(bitem.data(0, QtCore.Qt.UserRole).filename)
images.append(bitem.data(0, QtCore.Qt.UserRole))
# Don't try to display empty groups
if not images_file_names:
if not images:
return False
# Find missing files
for filename in images_file_names:
if not os.path.exists(filename):
missing_items_file_names.append(filename)
for image in images:
if not os.path.exists(image.filename):
missing_items_file_names.append(image.filename)
# We cannot continue, as all images do not exist.
if not images_file_names:
if not images:
if not remote:
critical_error_message_box(
translate('ImagePlugin.MediaItem', 'Missing Image(s)'),
@ -582,9 +591,10 @@ class ImageMediaItem(MediaManagerItem):
QtGui.QMessageBox.No:
return False
# Continue with the existing images.
for filename in images_file_names:
name = os.path.split(filename)[1]
service_item.add_from_image(filename, name, background, os.path.join(self.service_path, name))
for image in images:
name = os.path.split(image.filename)[1]
thumbnail = self.generate_thumbnail_path(image)
service_item.add_from_image(image.filename, name, background, thumbnail)
return True
def check_group_exists(self, new_group):

View File

@ -143,7 +143,10 @@ class PresentationPlugin(Plugin):
super().app_startup()
files_from_config = Settings().value('presentations/presentations files')
for file in files_from_config:
self.media_item.clean_up_thumbnails(file)
try:
self.media_item.clean_up_thumbnails(file)
except AttributeError:
pass
self.media_item.list_view.clear()
Settings().setValue('presentations/thumbnail_scheme', 'md5')
self.media_item.validate_and_load(files_from_config)

View File

@ -128,3 +128,21 @@ class TestMainWindow(TestCase, TestMixin):
# THEN the main window's title should be set to the
self.assertEqual(self.main_window.windowTitle(), '%s - %s' % (UiStrings().OLPV2x, 'test.osz'),
'The main window\'s title should be set to "<the contents of UiStrings().OLPV2x> - test.osz"')
def mainwindow_configuration_test(self):
"""
Check that the Main Window initialises the Registry Correctly
"""
# GIVEN: A built main window
# WHEN: you check the started functions
# THEN: the following registry functions should have been registered
self.assertEqual(len(self.registry.service_list), 6, 'The registry should have 6 services.')
self.assertEqual(len(self.registry.functions_list), 16, 'The registry should have 16 functions')
self.assertTrue('application' in self.registry.service_list, 'The application should have been registered.')
self.assertTrue('main_window' in self.registry.service_list, 'The main_window should have been registered.')
self.assertTrue('media_controller' in self.registry.service_list, 'The media_controller should have been '
'registered.')
self.assertTrue('plugin_manager' in self.registry.service_list,
'The plugin_manager should have been registered.')

View File

@ -479,6 +479,34 @@ class TestSlideController(TestCase):
mocked_preview_widget.current_slide_number.assert_called_with()
mocked_process_item.assert_called_once_with(mocked_item, 7)
def on_slide_blank_test(self):
"""
Test on_slide_blank
"""
# GIVEN: An instance of SlideController and a mocked on_blank_display
slide_controller = SlideController(None)
slide_controller.on_blank_display = MagicMock()
# WHEN: Calling on_slide_blank
slide_controller.on_slide_blank()
# THEN: on_blank_display should have been called with True
slide_controller.on_blank_display.assert_called_once_with(True)
def on_slide_unblank_test(self):
"""
Test on_slide_unblank
"""
# GIVEN: An instance of SlideController and a mocked on_blank_display
slide_controller = SlideController(None)
slide_controller.on_blank_display = MagicMock()
# WHEN: Calling on_slide_unblank
slide_controller.on_slide_unblank()
# THEN: on_blank_display should have been called with False
slide_controller.on_blank_display.assert_called_once_with(False)
def on_slide_selected_index_no_service_item_test(self):
"""
Test that when there is no service item, the on_slide_selected_index() method returns immediately

View File

@ -23,7 +23,7 @@
Package to test the openlp.core.ui.media.webkitplayer package.
"""
from unittest import TestCase
from tests.functional import patch
from tests.functional import MagicMock, patch
from openlp.core.ui.media.webkitplayer import WebkitPlayer
@ -33,32 +33,36 @@ class TestWebkitPlayer(TestCase):
Test the functions in the :mod:`webkitplayer` module.
"""
def check_available_mac_test(self):
def check_available_video_disabled_test(self):
"""
Simple test of webkitplayer availability on Mac OS X
Test of webkit video unavailability
"""
# GIVEN: A WebkitPlayer and a mocked is_macosx
with patch('openlp.core.ui.media.webkitplayer.is_macosx') as mocked_is_macosx:
mocked_is_macosx.return_value = True
# GIVEN: A WebkitPlayer instance and a mocked QWebPage
mocked_qwebpage = MagicMock()
mocked_qwebpage.mainFrame().evaluateJavaScript.return_value = '[object HTMLUnknownElement]'
with patch('openlp.core.ui.media.webkitplayer.QtWebKit.QWebPage', **{'return_value': mocked_qwebpage}):
webkit_player = WebkitPlayer(None)
# WHEN: An checking if the player is available
available = webkit_player.check_available()
# THEN: The player should not be available on Mac OS X
self.assertEqual(False, available, 'The WebkitPlayer should not be available on Mac OS X.')
# THEN: The player should not be available when '[object HTMLUnknownElement]' is returned
self.assertEqual(False, available,
'The WebkitPlayer should not be available when video feature detection fails')
def check_available_non_mac_test(self):
def check_available_video_enabled_test(self):
"""
Simple test of webkitplayer availability when not on Mac OS X
Test of webkit video availability
"""
# GIVEN: A WebkitPlayer and a mocked is_macosx
with patch('openlp.core.ui.media.webkitplayer.is_macosx') as mocked_is_macosx:
mocked_is_macosx.return_value = False
# GIVEN: A WebkitPlayer instance and a mocked QWebPage
mocked_qwebpage = MagicMock()
mocked_qwebpage.mainFrame().evaluateJavaScript.return_value = '[object HTMLVideoElement]'
with patch('openlp.core.ui.media.webkitplayer.QtWebKit.QWebPage', **{'return_value': mocked_qwebpage}):
webkit_player = WebkitPlayer(None)
# WHEN: An checking if the player is available
available = webkit_player.check_available()
# THEN: The player should be available when not on Mac OS X
self.assertEqual(True, available, 'The WebkitPlayer should be available when not on Mac OS X.')
# THEN: The player should be available when '[object HTMLVideoElement]' is returned
self.assertEqual(True, available,
'The WebkitPlayer should be available when video feature detection passes')

View File

@ -25,7 +25,7 @@ Functional tests to test the AppLocation class and related methods.
import os
from unittest import TestCase
from openlp.core.utils import clean_filename, get_filesystem_encoding, get_locale_key, \
from openlp.core.utils import clean_filename, delete_file, get_filesystem_encoding, get_locale_key, \
get_natural_key, split_filename, _get_user_agent, get_web_page, get_uno_instance, add_actions
from tests.functional import MagicMock, patch
@ -184,6 +184,59 @@ class TestUtils(TestCase):
# THEN: The file name should be cleaned.
self.assertEqual(wanted_name, result, 'The file name should not contain any special characters.')
def delete_file_no_path_test(self):
""""
Test the delete_file function when called with out a valid path
"""
# GIVEN: A blank path
# WEHN: Calling delete_file
result = delete_file('')
# THEN: delete_file should return False
self.assertFalse(result, "delete_file should return False when called with ''")
def delete_file_path_success_test(self):
""""
Test the delete_file function when it successfully deletes a file
"""
# GIVEN: A mocked os which returns True when os.path.exists is called
with patch('openlp.core.utils.os', **{'path.exists.return_value': False}):
# WHEN: Calling delete_file with a file path
result = delete_file('path/file.ext')
# THEN: delete_file should return True
self.assertTrue(result, 'delete_file should return True when it successfully deletes a file')
def delete_file_path_no_file_exists_test(self):
""""
Test the delete_file function when the file to remove does not exist
"""
# GIVEN: A mocked os which returns False when os.path.exists is called
with patch('openlp.core.utils.os', **{'path.exists.return_value': False}):
# WHEN: Calling delete_file with a file path
result = delete_file('path/file.ext')
# THEN: delete_file should return True
self.assertTrue(result, 'delete_file should return True when the file doesnt exist')
def delete_file_path_exception_test(self):
""""
Test the delete_file function when os.remove raises an exception
"""
# GIVEN: A mocked os which returns True when os.path.exists is called and raises an OSError when os.remove is
# called.
with patch('openlp.core.utils.os', **{'path.exists.return_value': True, 'path.exists.side_effect': OSError}), \
patch('openlp.core.utils.log') as mocked_log:
# WHEN: Calling delete_file with a file path
result = delete_file('path/file.ext')
# THEN: delete_file should log and exception and return False
self.assertEqual(mocked_log.exception.call_count, 1)
self.assertFalse(result, 'delete_file should return False when os.remove raises an OSError')
def get_locale_key_test(self):
"""
Test the get_locale_key(string) function

View File

@ -24,6 +24,7 @@ Package to test the openlp.core.__init__ package.
"""
from optparse import Values
import os
import sys
from unittest import TestCase
from unittest.mock import MagicMock, patch
@ -118,12 +119,27 @@ class TestInit(TestCase, TestMixin):
"""
Test that parse_options parses short options correctly
"""
# GIVEN: A list of vaild short options
# GIVEN: A list of valid short options
options = ['-e', '-l', 'debug', '-pd', '-s', 'style', 'extra', 'qt', 'args']
# WHEN: Calling parse_options
resluts = parse_options(options)
results = parse_options(options)
# THEN: A tuple should be returned with the parsed options and left over args
self.assertEqual(resluts, (Values({'no_error_form': True, 'dev_version': True, 'portable': True,
self.assertEqual(results, (Values({'no_error_form': True, 'dev_version': True, 'portable': True,
'style': 'style', 'loglevel': 'debug'}), ['extra', 'qt', 'args']))
def parse_options_valid_argv_short_options_test(self):
"""
Test that parse_options parses valid short options correctly when passed through sys.argv
"""
# GIVEN: A list of valid options
options = ['openlp.py', '-e', '-l', 'debug', '-pd', '-s', 'style', 'extra', 'qt', 'args']
# WHEN: Passing in the options through sys.argv and calling parse_args with None
with patch.object(sys, 'argv', options):
results = parse_options(None)
# THEN: parse_args should return a tuple of valid options and of left over options that OpenLP does not use
self.assertEqual(results, (Values({'no_error_form': True, 'dev_version': True, 'portable': True,
'style': 'style', 'loglevel': 'debug'}), ['extra', 'qt', 'args']))

View File

@ -29,11 +29,18 @@ log = logging.getLogger(__name__)
log.debug('test_projectorsourceform loaded')
from unittest import TestCase
from PyQt4 import QtGui
from PyQt4.QtGui import QDialog
from tests.functional import patch
from tests.functional.openlp_core_lib.test_projectordb import tmpfile
from tests.helpers.testmixin import TestMixin
from openlp.core.lib.projector.constants import PJLINK_DEFAULT_CODES, PJLINK_DEFAULT_SOURCES
from tests.resources.projector.data import TEST_DB, TEST1_DATA
from openlp.core.ui.projector.sourceselectform import source_group
from openlp.core.common import Registry, Settings
from openlp.core.lib.projector.db import ProjectorDB
from openlp.core.lib.projector.constants import PJLINK_DEFAULT_CODES, PJLINK_DEFAULT_SOURCES
from openlp.core.ui.projector.sourceselectform import source_group, SourceSelectSingle
def build_source_dict():
@ -54,6 +61,37 @@ class ProjectorSourceFormTest(TestCase, TestMixin):
"""
Test class for the Projector Source Select form module
"""
@patch('openlp.core.lib.projector.db.init_url')
def setUp(self, mocked_init_url):
"""
Set up anything necessary for all tests
"""
mocked_init_url.start()
mocked_init_url.return_value = 'sqlite:///{}'.format(tmpfile)
self.build_settings()
self.setup_application()
Registry.create()
# Do not try to recreate if we've already been created from a previous test
if not hasattr(self, 'projectordb'):
self.projectordb = ProjectorDB()
# Retrieve/create a database record
self.projector = self.projectordb.get_projector_by_ip(TEST1_DATA.ip)
if not self.projector:
self.projectordb.add_projector(projector=TEST1_DATA)
self.projector = self.projectordb.get_projector_by_ip(TEST1_DATA.ip)
self.projector.dbid = self.projector.id
self.projector.db_item = self.projector
def tearDown(self):
"""
Close database session.
Delete all C++ objects at end so we don't segfault.
"""
self.projectordb.session.close()
del(self.projectordb)
del(self.projector)
self.destroy_settings()
def source_dict_test(self):
"""
Test that source list dict returned from sourceselectform module is a valid dict with proper entries
@ -70,3 +108,43 @@ class ProjectorSourceFormTest(TestCase, TestMixin):
# THEN: return dictionary should match test dictionary
self.assertEquals(check, build_source_dict(),
"Source group dictionary should match test dictionary")
@patch.object(QDialog, 'exec_')
def source_select_edit_button_test(self, mocked_qdialog):
"""
Test source select form edit has Ok, Cancel, Reset, and Revert buttons
"""
# GIVEN: Initial setup and mocks
self.projector.source_available = ['11', ]
self.projector.source = '11'
# WHEN we create a source select widget and set edit=True
select_form = SourceSelectSingle(parent=None, projectordb=self.projectordb)
select_form.edit = True
select_form.exec_(projector=self.projector)
projector = select_form.projector
# THEN: Verify all 4 buttons are available
self.assertEquals(len(select_form.button_box.buttons()), 4,
'SourceSelect dialog box should have "OK", "Cancel" '
'"Rest", and "Revert" buttons available')
@patch.object(QDialog, 'exec_')
def source_select_noedit_button_test(self, mocked_qdialog):
"""
Test source select form view has OK and Cancel buttons only
"""
# GIVEN: Initial setup and mocks
self.projector.source_available = ['11', ]
self.projector.source = '11'
# WHEN we create a source select widget and set edit=False
select_form = SourceSelectSingle(parent=None, projectordb=self.projectordb)
select_form.edit = False
select_form.exec_(projector=self.projector)
projector = select_form.projector
# THEN: Verify only 2 buttons are available
self.assertEquals(len(select_form.button_box.buttons()), 2,
'SourceSelect dialog box should only have "OK" '
'and "Cancel" buttons available')

View File

@ -23,9 +23,12 @@
The :mod:`tests.resources.projector.data file contains test data
"""
import os
from openlp.core.lib.projector.db import Projector
# Test data
TEST_DB = os.path.join('tmp', 'openlp-test-projectordb.sql')
TEST1_DATA = Projector(ip='111.111.111.111',
port='1111',
pin='1111',