This commit is contained in:
Tomas Groth 2016-01-08 22:51:40 +01:00
commit 5d6758ffaf
53 changed files with 355 additions and 227 deletions

View File

@ -43,3 +43,5 @@ __pycache__
.coverage
cover
*.kdev4
./.coveragerc
./coverage

View File

@ -55,7 +55,7 @@ def init_db(url, auto_flush=True, auto_commit=False, base=None):
metadata = MetaData(bind=engine)
else:
base.metadata.bind = engine
metadata = None
metadata = base.metadata
session = scoped_session(sessionmaker(autoflush=auto_flush, autocommit=auto_commit, bind=engine))
return session, metadata
@ -227,13 +227,12 @@ class Manager(object):
"""
self.is_dirty = False
self.session = None
# See if we're using declarative_base with a pre-existing session.
log.debug('Manager: Testing for pre-existing session')
if session is not None:
log.debug('Manager: Using existing session')
else:
log.debug('Manager: Creating new session')
self.db_url = None
if db_file_name:
log.debug('Manager: Creating new DB url')
self.db_url = init_url(plugin_name, db_file_name)
else:
self.db_url = init_url(plugin_name)
if upgrade_mod:
try:
db_ver, up_ver = upgrade_db(self.db_url, upgrade_mod)
@ -248,10 +247,13 @@ class Manager(object):
'not be loaded.\n\nDatabase: %s') % (db_ver, up_ver, self.db_url)
)
return
try:
self.session = init_schema(self.db_url)
except (SQLAlchemyError, DBAPIError):
handle_db_error(plugin_name, db_file_name)
if not session:
try:
self.session = init_schema(self.db_url)
except (SQLAlchemyError, DBAPIError):
handle_db_error(plugin_name, db_file_name)
else:
self.session = session
def save_object(self, object_instance, commit=True):
"""
@ -344,13 +346,13 @@ class Manager(object):
for try_count in range(3):
try:
return self.session.query(object_class).filter(filter_clause).first()
except OperationalError:
except OperationalError as oe:
# This exception clause is for users running MySQL which likes to terminate connections on its own
# without telling anyone. See bug #927473. However, other dbms can raise it, usually in a
# non-recoverable way. So we only retry 3 times.
log.exception('Probably a MySQL issue, "MySQL has gone away"')
if try_count >= 2:
if try_count >= 2 or 'MySQL has gone away' in str(oe):
raise
log.exception('Probably a MySQL issue, "MySQL has gone away"')
def get_all_objects(self, object_class, filter_clause=None, order_by_ref=None):
"""

View File

@ -20,18 +20,18 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
:mod:`openlp.core.lib.projector.db` module
:mod:`openlp.core.lib.projector.db` module
Provides the database functions for the Projector module.
Provides the database functions for the Projector module.
The Manufacturer, Model, Source tables keep track of the video source
strings used for display of input sources. The Source table maps
manufacturer-defined or user-defined strings from PJLink default strings
to end-user readable strings; ex: PJLink code 11 would map "RGB 1"
default string to "RGB PC (analog)" string.
(Future feature).
The Manufacturer, Model, Source tables keep track of the video source
strings used for display of input sources. The Source table maps
manufacturer-defined or user-defined strings from PJLink default strings
to end-user readable strings; ex: PJLink code 11 would map "RGB 1"
default string to "RGB PC (analog)" string.
(Future feature).
The Projector table keeps track of entries for controlled projectors.
The Projector table keeps track of entries for controlled projectors.
"""
import logging
@ -218,19 +218,19 @@ class ProjectorDB(Manager):
"""
def __init__(self, *args, **kwargs):
log.debug('ProjectorDB().__init__(args="%s", kwargs="%s")' % (args, kwargs))
super().__init__(plugin_name='projector',
init_schema=self.init_schema)
super().__init__(plugin_name='projector', init_schema=self.init_schema)
log.debug('ProjectorDB() Initialized using db url %s' % self.db_url)
log.debug('Session: %s', self.session)
def init_schema(*args, **kwargs):
def init_schema(self, *args, **kwargs):
"""
Setup the projector database and initialize the schema.
Declarative uses table classes to define schema.
"""
url = init_url('projector')
session, metadata = init_db(url, base=Base)
Base.metadata.create_all(checkfirst=True)
self.db_url = init_url('projector')
session, metadata = init_db(self.db_url, base=Base)
metadata.create_all(checkfirst=True)
return session
def get_projector_by_id(self, dbid):

View File

@ -24,7 +24,7 @@ The About dialog.
"""
import webbrowser
from PyQt5 import QtWidgets
from PyQt5 import QtCore, QtWidgets
from openlp.core.lib import translate
from openlp.core.utils import get_application_version
@ -40,7 +40,8 @@ class AboutForm(QtWidgets.QDialog, UiAboutDialog):
"""
Do some initialisation stuff
"""
super(AboutForm, self).__init__(parent)
super(AboutForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self._setup()
def _setup(self):

View File

@ -89,7 +89,8 @@ class ExceptionForm(QtWidgets.QDialog, Ui_ExceptionDialog, RegistryProperties):
"""
Constructor.
"""
super(ExceptionForm, self).__init__()
super(ExceptionForm, self).__init__(None, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.setupUi(self)
self.settings_section = 'crashreport'
self.report_text = '**OpenLP Bug Report**\n' \

View File

@ -23,7 +23,7 @@
The file rename dialog.
"""
from PyQt5 import QtWidgets
from PyQt5 import QtCore, QtWidgets
from .filerenamedialog import Ui_FileRenameDialog
@ -38,7 +38,8 @@ class FileRenameForm(QtWidgets.QDialog, Ui_FileRenameDialog, RegistryProperties)
"""
Constructor
"""
super(FileRenameForm, self).__init__(Registry().get('main_window'))
super(FileRenameForm, self).__init__(Registry().get('main_window'),
QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self._setup()
def _setup(self):

View File

@ -22,7 +22,7 @@
"""
The language selection dialog.
"""
from PyQt5 import QtWidgets
from PyQt5 import QtCore, QtWidgets
from openlp.core.lib.ui import create_action
from openlp.core.utils import LanguageManager
@ -37,7 +37,8 @@ class FirstTimeLanguageForm(QtWidgets.QDialog, Ui_FirstTimeLanguageDialog):
"""
Constructor
"""
super(FirstTimeLanguageForm, self).__init__(parent)
super(FirstTimeLanguageForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.setupUi(self)
self.qm_list = LanguageManager.get_qm_list()
self.language_combo_box.addItem('Autodetect')

View File

@ -25,7 +25,7 @@ Custom tags can be defined and saved. The Custom Tag arrays are saved in a json
Base Tags cannot be changed.
"""
from PyQt5 import QtWidgets
from PyQt5 import QtCore, QtWidgets
from openlp.core.common import translate
from openlp.core.lib import FormattingTags
@ -51,7 +51,8 @@ class FormattingTagForm(QtWidgets.QDialog, Ui_FormattingTagDialog, FormattingTag
"""
Constructor
"""
super(FormattingTagForm, self).__init__(parent)
super(FormattingTagForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.setupUi(self)
self._setup()

View File

@ -24,7 +24,7 @@ The actual plugin view form
"""
import logging
from PyQt5 import QtWidgets
from PyQt5 import QtCore, QtWidgets
from openlp.core.common import RegistryProperties, translate
from openlp.core.lib import PluginStatus
@ -41,7 +41,8 @@ class PluginForm(QtWidgets.QDialog, Ui_PluginViewDialog, RegistryProperties):
"""
Constructor
"""
super(PluginForm, self).__init__(parent)
super(PluginForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.active_plugin = None
self.programatic_change = False
self.setupUi(self)

View File

@ -112,7 +112,8 @@ class PrintServiceForm(QtWidgets.QDialog, Ui_PrintServiceDialog, RegistryPropert
"""
Constructor
"""
super(PrintServiceForm, self).__init__(Registry().get('main_window'))
super(PrintServiceForm, self).__init__(Registry().get('main_window'),
QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.printer = QtPrintSupport.QPrinter()
self.print_dialog = QtPrintSupport.QPrintDialog(self.printer, self)
self.document = QtGui.QTextDocument()

View File

@ -144,7 +144,8 @@ class ProjectorEditForm(QDialog, Ui_ProjectorEditForm):
editProjector = pyqtSignal(object)
def __init__(self, parent=None, projectordb=None):
super(ProjectorEditForm, self).__init__(parent=parent)
super(ProjectorEditForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.projectordb = projectordb
self.setupUi(self)
self.button_box.accepted.connect(self.accept_me)

View File

@ -236,7 +236,8 @@ class SourceSelectTabs(QDialog):
:param projectordb: ProjectorDB session to use
"""
log.debug('Initializing SourceSelectTabs()')
super(SourceSelectTabs, self).__init__(parent)
super(SourceSelectTabs, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.setMinimumWidth(350)
self.projectordb = projectordb
self.edit = edit
@ -385,7 +386,8 @@ class SourceSelectSingle(QDialog):
"""
log.debug('Initializing SourceSelectSingle()')
self.projectordb = projectordb
super(SourceSelectSingle, self).__init__(parent)
super(SourceSelectSingle, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.edit = edit
if self.edit:
title = translate('OpenLP.SourceSelectForm', 'Edit Projector Source Text')

View File

@ -22,7 +22,7 @@
"""
The service item edit dialog
"""
from PyQt5 import QtWidgets
from PyQt5 import QtCore, QtWidgets
from openlp.core.common import Registry, RegistryProperties
@ -37,7 +37,8 @@ class ServiceItemEditForm(QtWidgets.QDialog, Ui_ServiceItemEditDialog, RegistryP
"""
Constructor
"""
super(ServiceItemEditForm, self).__init__(Registry().get('main_window'))
super(ServiceItemEditForm, self).__init__(Registry().get('main_window'),
QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.setupUi(self)
self.item_list = []
self.list_widget.currentRowChanged.connect(self.on_current_row_changed)

View File

@ -22,7 +22,7 @@
"""
The :mod:`~openlp.core.ui.servicenoteform` module contains the `ServiceNoteForm` class.
"""
from PyQt5 import QtWidgets
from PyQt5 import QtCore, QtWidgets
from openlp.core.common import Registry, RegistryProperties, translate
from openlp.core.lib import SpellTextEdit
@ -37,7 +37,8 @@ class ServiceNoteForm(QtWidgets.QDialog, RegistryProperties):
"""
Constructor
"""
super(ServiceNoteForm, self).__init__(Registry().get('main_window'))
super(ServiceNoteForm, self).__init__(Registry().get('main_window'),
QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.setupUi()
self.retranslateUi()

View File

@ -46,7 +46,8 @@ class SettingsForm(QtWidgets.QDialog, Ui_SettingsDialog, RegistryProperties):
"""
Registry().register('settings_form', self)
Registry().register_function('bootstrap_post_set_up', self.bootstrap_post_set_up)
super(SettingsForm, self).__init__(parent)
super(SettingsForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.processes = []
self.setupUi(self)
self.setting_list_widget.currentRowChanged.connect(self.list_item_changed)

View File

@ -44,7 +44,8 @@ class ShortcutListForm(QtWidgets.QDialog, Ui_ShortcutListDialog, RegistryPropert
"""
Constructor
"""
super(ShortcutListForm, self).__init__(parent)
super(ShortcutListForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.setupUi(self)
self.changed_actions = {}
self.action_list = ActionList.get_instance()

View File

@ -22,7 +22,7 @@
"""
The actual start time form.
"""
from PyQt5 import QtWidgets
from PyQt5 import QtCore, QtWidgets
from .starttimedialog import Ui_StartTimeDialog
@ -38,7 +38,8 @@ class StartTimeForm(QtWidgets.QDialog, Ui_StartTimeDialog, RegistryProperties):
"""
Constructor
"""
super(StartTimeForm, self).__init__(Registry().get('main_window'))
super(StartTimeForm, self).__init__(Registry().get('main_window'),
QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.setupUi(self)
def exec(self):

View File

@ -36,10 +36,11 @@ class AlertForm(QtWidgets.QDialog, Ui_AlertDialog):
"""
Initialise the alert form
"""
super(AlertForm, self).__init__(Registry().get('main_window'),
QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
self.manager = plugin.manager
self.plugin = plugin
self.item_id = None
super(AlertForm, self).__init__(Registry().get('main_window'))
self.setupUi(self)
self.display_button.clicked.connect(self.on_display_clicked)
self.display_close_button.clicked.connect(self.on_display_close_clicked)

View File

@ -49,7 +49,8 @@ class BookNameForm(QDialog, Ui_BookNameDialog):
"""
Constructor
"""
super(BookNameForm, self).__init__(parent)
super(BookNameForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.setupUi(self)
self.custom_signals()
self.book_names = BibleStrings().BookNames

View File

@ -24,7 +24,7 @@ import logging
import os
import re
from PyQt5 import QtWidgets
from PyQt5 import QtCore, QtWidgets
from openlp.core.common import RegistryProperties, UiStrings, translate
from openlp.core.lib.ui import critical_error_message_box
@ -45,7 +45,8 @@ class EditBibleForm(QtWidgets.QDialog, Ui_EditBibleDialog, RegistryProperties):
"""
Constructor
"""
super(EditBibleForm, self).__init__(parent)
super(EditBibleForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.media_item = media_item
self.book_names = BibleStrings().BookNames
self.setupUi(self)

View File

@ -26,6 +26,7 @@ Module implementing LanguageForm.
import logging
from PyQt5.QtWidgets import QDialog
from PyQt5 import QtCore
from openlp.core.common import translate
from openlp.core.lib.ui import critical_error_message_box
@ -46,7 +47,8 @@ class LanguageForm(QDialog, Ui_LanguageDialog):
"""
Constructor
"""
super(LanguageForm, self).__init__(parent)
super(LanguageForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.setupUi(self)
def exec(self, bible_name):

View File

@ -254,6 +254,7 @@ class BibleMediaItem(MediaManagerItem):
def on_focus(self):
if self.quickTab.isVisible():
self.quick_search_edit.setFocus()
self.quick_search_edit.selectAll()
else:
self.advanced_book_combo_box.setFocus()

View File

@ -22,7 +22,7 @@
import logging
from PyQt5 import QtWidgets
from PyQt5 import QtCore, QtWidgets
from openlp.core.common import Registry, translate
from openlp.core.lib.ui import critical_error_message_box, find_and_set_in_combo_box
@ -44,7 +44,8 @@ class EditCustomForm(QtWidgets.QDialog, Ui_CustomEditDialog):
"""
Constructor
"""
super(EditCustomForm, self).__init__(parent)
super(EditCustomForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.manager = manager
self.media_item = media_item
self.setupUi(self)

View File

@ -22,7 +22,7 @@
import logging
from PyQt5 import QtWidgets
from PyQt5 import QtCore, QtWidgets
from .editcustomslidedialog import Ui_CustomSlideEditDialog
@ -39,7 +39,8 @@ class EditCustomSlideForm(QtWidgets.QDialog, Ui_CustomSlideEditDialog):
"""
Constructor
"""
super(EditCustomSlideForm, self).__init__(parent)
super(EditCustomSlideForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.setupUi(self)
# Connecting signals and slots
self.insert_button.clicked.connect(self.on_insert_button_clicked)

View File

@ -190,8 +190,7 @@ class CustomMediaItem(MediaManagerItem):
if QtWidgets.QMessageBox.question(
self, UiStrings().ConfirmDelete,
translate('CustomPlugin.MediaItem',
'Are you sure you want to delete the %n selected custom slide(s)?',
'', QtCore.QCoreApplication.CodecForTr, len(items)),
'Are you sure you want to delete the "%d" selected custom slide(s)?') %len(items),
QtWidgets.QMessageBox.StandardButtons(
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No),
QtWidgets.QMessageBox.Yes) == QtWidgets.QMessageBox.No:
@ -208,6 +207,7 @@ class CustomMediaItem(MediaManagerItem):
Set the focus
"""
self.search_text_edit.setFocus()
self.search_text_edit.selectAll()
def generate_slide_data(self, service_item, item=None, xml_version=False,
remote=False, context=ServiceItemContext.Service):

View File

@ -20,7 +20,7 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from PyQt5 import QtWidgets
from PyQt5 import QtCore, QtWidgets
from openlp.core.common import translate
from openlp.core.lib.ui import critical_error_message_box
@ -35,7 +35,8 @@ class AddGroupForm(QtWidgets.QDialog, Ui_AddGroupDialog):
"""
Constructor
"""
super(AddGroupForm, self).__init__(parent)
super(AddGroupForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.setupUi(self)
def exec(self, clear=True, show_top_level_group=False, selected_group=None):

View File

@ -20,7 +20,7 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from PyQt5 import QtWidgets
from PyQt5 import QtCore, QtWidgets
from openlp.plugins.images.forms.choosegroupdialog import Ui_ChooseGroupDialog
@ -33,7 +33,8 @@ class ChooseGroupForm(QtWidgets.QDialog, Ui_ChooseGroupDialog):
"""
Constructor
"""
super(ChooseGroupForm, self).__init__(parent)
super(ChooseGroupForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.setupUi(self)
def exec(self, selected_group=None):

View File

@ -52,7 +52,8 @@ class MediaClipSelectorForm(QtWidgets.QDialog, Ui_MediaClipSelector, RegistryPro
"""
Constructor
"""
super(MediaClipSelectorForm, self).__init__(parent)
super(MediaClipSelectorForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.vlc_instance = None
self.vlc_media_player = None
self.vlc_media = None

View File

@ -272,7 +272,7 @@ window.OpenLP = {
value[0] = OpenLP.escapeString(value[0])
}
var txt = "";
if (value[2].length > 0) {
if (value.length > 2) {
txt = value[1] + " ( " + value[2] + " )";
} else {
txt = value[1];

View File

@ -20,7 +20,7 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from PyQt5 import QtWidgets
from PyQt5 import QtCore, QtWidgets
from openlp.core.lib import translate
from openlp.core.lib.ui import critical_error_message_box
@ -35,7 +35,8 @@ class AuthorsForm(QtWidgets.QDialog, Ui_AuthorsDialog):
"""
Set up the screen and common data
"""
super(AuthorsForm, self).__init__(parent)
super(AuthorsForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.setupUi(self)
self.auto_display_name = False
self.first_name_edit.textEdited.connect(self.on_first_name_edited)

View File

@ -55,7 +55,8 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties):
"""
Constructor
"""
super(EditSongForm, self).__init__(parent)
super(EditSongForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.media_item = media_item
self.song = None
# can this be automated?
@ -76,7 +77,7 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties):
self.verse_edit_all_button.clicked.connect(self.on_verse_edit_all_button_clicked)
self.verse_delete_button.clicked.connect(self.on_verse_delete_button_clicked)
self.verse_list_widget.itemClicked.connect(self.on_verse_list_view_clicked)
self.verse_order_edit.textChanged.connect(self.on_verse_order_text_changed)
self.verse_order_edit.textEdited.connect(self.on_verse_order_text_changed)
self.theme_add_button.clicked.connect(self.theme_manager.on_add_theme)
self.maintenance_button.clicked.connect(self.on_maintenance_button_clicked)
self.from_file_button.clicked.connect(self.on_audio_add_from_file_button_clicked)
@ -803,6 +804,8 @@ class EditSongForm(QtWidgets.QDialog, Ui_EditSongDialog, RegistryProperties):
:param text: The text of the verse order edit (ignored).
"""
# First make sure that all letters entered in the verse order field are uppercase
self.verse_order_edit.setText(text.upper())
# Extract all verses which were used in the order.
verses_in_order = self._extract_verse_order(self.verse_order_edit.text())
# Find the verses which were not used in the order.

View File

@ -23,7 +23,7 @@
import re
import logging
from PyQt5 import QtGui, QtWidgets
from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.plugins.songs.lib import VerseType
from .editversedialog import Ui_EditVerseDialog
@ -41,7 +41,8 @@ class EditVerseForm(QtWidgets.QDialog, Ui_EditVerseDialog):
"""
Constructor
"""
super(EditVerseForm, self).__init__(parent)
super(EditVerseForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.setupUi(self)
self.has_single_verse = False
self.insert_button.clicked.connect(self.on_insert_button_clicked)

View File

@ -37,7 +37,8 @@ class MediaFilesForm(QtWidgets.QDialog, Ui_MediaFilesDialog):
log.info('%s MediaFilesForm loaded', __name__)
def __init__(self, parent):
super(MediaFilesForm, self).__init__()
super(MediaFilesForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.setupUi(self)
def populate_files(self, files):

View File

@ -23,7 +23,7 @@
This module contains the song book form
"""
from PyQt5 import QtWidgets
from PyQt5 import QtCore, QtWidgets
from openlp.core.lib import translate
from openlp.core.lib.ui import critical_error_message_box
@ -38,7 +38,8 @@ class SongBookForm(QtWidgets.QDialog, Ui_SongBookDialog):
"""
Constructor
"""
super(SongBookForm, self).__init__(parent)
super(SongBookForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.setupUi(self)
def exec(self, clear=True):

View File

@ -44,7 +44,8 @@ class SongMaintenanceForm(QtWidgets.QDialog, Ui_SongMaintenanceDialog, RegistryP
"""
Constructor
"""
super(SongMaintenanceForm, self).__init__(parent)
super(SongMaintenanceForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.setupUi(self)
self.manager = manager
self.author_form = AuthorsForm(self)

View File

@ -81,7 +81,8 @@ class SongSelectForm(QtWidgets.QDialog, Ui_SongSelectDialog):
"""
def __init__(self, parent=None, plugin=None, db_manager=None):
QtWidgets.QDialog.__init__(self, parent)
QtWidgets.QDialog.__init__(self, parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.plugin = plugin
self.db_manager = db_manager
self.setup_ui(self)

View File

@ -23,7 +23,7 @@
This module contains the topic edit form.
"""
from PyQt5 import QtWidgets
from PyQt5 import QtCore, QtWidgets
from openlp.core.lib import translate
from openlp.core.lib.ui import critical_error_message_box
@ -38,7 +38,8 @@ class TopicsForm(QtWidgets.QDialog, Ui_TopicsDialog):
"""
Constructor
"""
super(TopicsForm, self).__init__(parent)
super(TopicsForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.setupUi(self)
def exec(self, clear=True):

View File

@ -112,6 +112,7 @@ class SongMediaItem(MediaManagerItem):
def on_focus(self):
self.search_text_edit.setFocus()
self.search_text_edit.selectAll()
def config_update(self):
"""
@ -363,8 +364,8 @@ class SongMediaItem(MediaManagerItem):
items = self.list_view.selectedIndexes()
if QtWidgets.QMessageBox.question(
self, UiStrings().ConfirmDelete,
translate('SongsPlugin.MediaItem', 'Are you sure you want to delete the %n selected song(s)?', '',
QtCore.QCoreApplication.CodecForTr, len(items)),
translate('SongsPlugin.MediaItem',
'Are you sure you want to delete the "%d" selected song(s)?') % len(items),
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No),
QtWidgets.QMessageBox.Yes) == QtWidgets.QMessageBox.No:
return

View File

@ -20,7 +20,7 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from PyQt5 import QtWidgets
from PyQt5 import QtCore, QtWidgets
from openlp.core.common import RegistryProperties, translate
from openlp.plugins.songusage.lib.db import SongUsageItem
@ -36,7 +36,8 @@ class SongUsageDeleteForm(QtWidgets.QDialog, Ui_SongUsageDeleteDialog, RegistryP
Constructor
"""
self.manager = manager
super(SongUsageDeleteForm, self).__init__(parent)
super(SongUsageDeleteForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.setupUi(self)
self.button_box.clicked.connect(self.on_button_box_clicked)

View File

@ -23,7 +23,7 @@
import logging
import os
from PyQt5 import QtWidgets
from PyQt5 import QtCore, QtWidgets
from sqlalchemy.sql import and_
from openlp.core.common import RegistryProperties, Settings, check_directory_exists, translate
@ -44,7 +44,8 @@ class SongUsageDetailForm(QtWidgets.QDialog, Ui_SongUsageDetailDialog, RegistryP
"""
Initialise the form
"""
super(SongUsageDetailForm, self).__init__(parent)
super(SongUsageDetailForm, self).__init__(parent, QtCore.Qt.WindowSystemMenuHint
| QtCore.Qt.WindowTitleHint)
self.plugin = plugin
self.setupUi(self)

View File

@ -22,26 +22,3 @@
"""
Module-level functions for the functional test suite
"""
import os
from tests.functional import patch
from openlp.core.common import is_win
from .test_projectordb import tmpfile
def setUp():
if not is_win():
# Wine creates a sharing violation during tests. Ignore.
try:
os.remove(tmpfile)
except:
pass
def tearDown():
"""
Ensure test suite has been cleaned up after tests
"""
patch.stopall()

View File

@ -60,6 +60,22 @@ class TestMediaManagerItem(TestCase, TestMixin):
# THEN: on_preview_click() should have been called
mocked_on_preview_click.assert_called_with()
def required_icons_test(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
self.assertFalse(mmi.has_import_icon, 'There should be no import icon by default')
self.assertTrue(mmi.has_new_icon, 'By default a new icon should be present')
self.assertFalse(mmi.has_file_icon, 'There should be no file icon by default')
self.assertTrue(mmi.has_delete_icon, 'By default a delete icon should be present')
self.assertFalse(mmi.add_to_service_item, 'There should be no add_to_service icon by default')
@patch(u'openlp.core.lib.mediamanageritem.Settings')
@patch(u'openlp.core.lib.mediamanageritem.MediaManagerItem.on_live_click')
def on_double_clicked_go_live_test(self, mocked_on_live_click, MockedSettings):

View File

@ -25,15 +25,13 @@ record functions.
PREREQUISITE: add_record() and get_all() functions validated.
"""
import os
from unittest import TestCase
from tests.functional import MagicMock, patch
from openlp.core.lib.projector.db import Projector, ProjectorDB, ProjectorSource
from tests.resources.projector.data import TEST1_DATA, TEST2_DATA, TEST3_DATA
tmpfile = '/tmp/openlp-test-projectordb.sql'
from tests.functional import MagicMock, patch
from tests.resources.projector.data import TEST_DB, TEST1_DATA, TEST2_DATA, TEST3_DATA
def compare_data(one, two):
@ -60,15 +58,15 @@ def compare_source(one, two):
one.text == two.text
def add_records(self, test):
def add_records(projector_db, test):
"""
Add record if not in database
"""
record_list = self.projector.get_projector_all()
record_list = projector_db.get_projector_all()
if len(record_list) < 1:
added = False
for record in test:
added = self.projector.add_projector(record) or added
added = projector_db.add_projector(record) or added
return added
for new_record in test:
@ -76,7 +74,7 @@ def add_records(self, test):
for record in record_list:
if compare_data(record, new_record):
break
added = self.projector.add_projector(new_record)
added = projector_db.add_projector(new_record)
return added
@ -88,15 +86,17 @@ class TestProjectorDB(TestCase):
"""
Set up anything necessary for all tests
"""
if not hasattr(self, 'projector'):
with patch('openlp.core.lib.projector.db.init_url') as mocked_init_url:
mocked_init_url.return_value = 'sqlite:///%s' % tmpfile
self.projector = ProjectorDB()
with patch('openlp.core.lib.projector.db.init_url') as mocked_init_url:
if os.path.exists(TEST_DB):
os.unlink(TEST_DB)
mocked_init_url.return_value = 'sqlite:///%s' % TEST_DB
self.projector = ProjectorDB()
def tearDown(self):
"""
Clean up
"""
self.projector.session.close()
self.projector = None
def find_record_by_ip_test(self):
@ -104,13 +104,13 @@ class TestProjectorDB(TestCase):
Test find record by IP
"""
# GIVEN: Record entries in database
add_records(self, [TEST1_DATA, TEST2_DATA])
add_records(self.projector, [Projector(**TEST1_DATA), Projector(**TEST2_DATA)])
# WHEN: Search for record using IP
record = self.projector.get_projector_by_ip(TEST2_DATA.ip)
record = self.projector.get_projector_by_ip(TEST2_DATA['ip'])
# THEN: Verify proper record returned
self.assertTrue(compare_data(TEST2_DATA, record),
self.assertTrue(compare_data(Projector(**TEST2_DATA), record),
'Record found should have been test_2 data')
def find_record_by_name_test(self):
@ -118,13 +118,13 @@ class TestProjectorDB(TestCase):
Test find record by name
"""
# GIVEN: Record entries in database
add_records(self, [TEST1_DATA, TEST2_DATA])
add_records(self.projector, [Projector(**TEST1_DATA), Projector(**TEST2_DATA)])
# WHEN: Search for record using name
record = self.projector.get_projector_by_name(TEST2_DATA.name)
record = self.projector.get_projector_by_name(TEST2_DATA['name'])
# THEN: Verify proper record returned
self.assertTrue(compare_data(TEST2_DATA, record),
self.assertTrue(compare_data(Projector(**TEST2_DATA), record),
'Record found should have been test_2 data')
def record_delete_test(self):
@ -132,14 +132,14 @@ class TestProjectorDB(TestCase):
Test record can be deleted
"""
# GIVEN: Record in database
add_records(self, [TEST3_DATA, ])
record = self.projector.get_projector_by_ip(TEST3_DATA.ip)
add_records(self.projector, [Projector(**TEST3_DATA), ])
record = self.projector.get_projector_by_ip(TEST3_DATA['ip'])
# WHEN: Record deleted
self.projector.delete_projector(record)
# THEN: Verify record not retrievable
found = self.projector.get_projector_by_ip(TEST3_DATA.ip)
found = self.projector.get_projector_by_ip(TEST3_DATA['ip'])
self.assertFalse(found, 'test_3 record should have been deleted')
def record_edit_test(self):
@ -147,34 +147,35 @@ class TestProjectorDB(TestCase):
Test edited record returns the same record ID with different data
"""
# GIVEN: Record entries in database
add_records(self, [TEST1_DATA, TEST2_DATA])
add_records(self.projector, [Projector(**TEST1_DATA), Projector(**TEST2_DATA)])
# WHEN: We retrieve a specific record
record = self.projector.get_projector_by_ip(TEST1_DATA.ip)
record = self.projector.get_projector_by_ip(TEST1_DATA['ip'])
record_id = record.id
# WHEN: Data is changed
record.ip = TEST3_DATA.ip
record.port = TEST3_DATA.port
record.pin = TEST3_DATA.pin
record.name = TEST3_DATA.name
record.location = TEST3_DATA.location
record.notes = TEST3_DATA.notes
record.ip = TEST3_DATA['ip']
record.port = TEST3_DATA['port']
record.pin = TEST3_DATA['pin']
record.name = TEST3_DATA['name']
record.location = TEST3_DATA['location']
record.notes = TEST3_DATA['notes']
updated = self.projector.update_projector(record)
self.assertTrue(updated, 'Save updated record should have returned True')
record = self.projector.get_projector_by_ip(TEST3_DATA.ip)
record = self.projector.get_projector_by_ip(TEST3_DATA['ip'])
# THEN: Record ID should remain the same, but data should be changed
self.assertEqual(record_id, record.id, 'Edited record should have the same ID')
self.assertTrue(compare_data(TEST3_DATA, record), 'Edited record should have new data')
self.assertTrue(compare_data(Projector(**TEST3_DATA), record), 'Edited record should have new data')
def source_add_test(self):
"""
Test source entry for projector item
"""
# GIVEN: Record entries in database
self.projector.add_projector(TEST1_DATA)
item = self.projector.get_projector_by_id(TEST1_DATA.id)
projector1 = Projector(**TEST1_DATA)
self.projector.add_projector(projector1)
item = self.projector.get_projector_by_id(projector1.id)
item_id = item.id
# WHEN: A source entry is saved for item
@ -184,3 +185,4 @@ class TestProjectorDB(TestCase):
# THEN: Projector should have the same source entry
item = self.projector.get_projector_by_id(item_id)
self.assertTrue(compare_source(item.source_list[0], source))

View File

@ -22,7 +22,7 @@
"""
Package to test the openlp.core.ui.slidecontroller package.
"""
from unittest import TestCase
from unittest import TestCase, skipUnless
from PyQt5 import QtCore
@ -141,13 +141,14 @@ class TestMainDisplay(TestCase, TestMixin):
mocked_songs_plugin.refresh_css.assert_called_with(main_display.frame)
mocked_bibles_plugin.refresh_css.assert_called_with(main_display.frame)
@patch('openlp.core.ui.maindisplay.is_macosx')
@skipUnless(is_macosx(), 'Can only run test on Mac OS X due to pyobjc dependency.')
def macosx_display_window_flags_state_test(self, is_macosx):
"""
Test that on Mac OS X we set the proper window flags
"""
if not is_macosx():
self.skipTest('Can only run test on Mac OS X due to pyobjc dependency.')
# GIVEN: A new SlideController instance on Mac OS X.
is_macosx.return_value = True
self.screens.set_current_display(0)
display = MagicMock()
@ -159,12 +160,11 @@ class TestMainDisplay(TestCase, TestMixin):
main_display.windowFlags(),
'The window flags should be Qt.Window, and Qt.FramelessWindowHint.')
@skipUnless(is_macosx(), 'Can only run test on Mac OS X due to pyobjc dependency.')
def macosx_display_test(self):
"""
Test display on Mac OS X
"""
if not is_macosx():
self.skipTest('Can only run test on Mac OS X due to pyobjc dependency.')
# GIVEN: A new SlideController instance on Mac OS X.
self.screens.set_current_display(0)
display = MagicMock()

View File

@ -257,3 +257,22 @@ class TestMediaItem(TestCase, TestMixin):
# THEN: They should not match
self.assertFalse(result, "Authors should not match")
def build_remote_search_test(self):
"""
Test results for the remote search api
"""
# GIVEN: A Song and a search a JSON array should be returned.
mock_song = MagicMock()
mock_song.id = 123
mock_song.title = 'My Song'
mock_song.search_title = 'My Song'
mock_song.alternate_title = 'My alternative'
self.media_item.search_entire = MagicMock()
self.media_item.search_entire.return_value = [mock_song]
# WHEN: I process a search
search_results = self.media_item.search('My Song', False)
# THEN: The correct formatted results are returned
self.assertEqual(search_results, [[123, 'My Song', 'My alternative']])

View File

@ -0,0 +1,84 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2015 OpenLP Developers #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
This module contains tests for the SongFormat class
"""
from unittest import TestCase
from openlp.plugins.songs.lib.importer import SongFormat
class TestSongFormat(TestCase):
"""
Test the functions in the :class:`SongFormat` class.
"""
def test_get_format_list(self):
"""
Test that get_format_list() returns all available formats
"""
# GIVEN: The SongFormat class
# WHEN: Retrieving the format list
# THEN: All SongFormats should be returned
self.assertEquals(len(SongFormat.get_format_list()), len(SongFormat.__attributes__),
"The returned SongFormats don't match the stored ones")
def test_get_attributed_no_attributes(self):
"""
Test that SongFormat.get(song_format) returns all attributes associated with the given song_format
"""
# GIVEN: A SongFormat
# WHEN: Retrieving all attributes of a SongFormat
for song_format in SongFormat.get_format_list():
# THEN: All attributes associated with the SongFormat should be returned
self.assertEquals(SongFormat.get(song_format), SongFormat.__attributes__[song_format],
"The returned attributes don't match the stored ones")
def test_get_attributed_single_attribute(self):
"""
Test that SongFormat.get(song_format, attribute) returns only one -and the correct- attribute
"""
# GIVEN: A SongFormat
for song_format in SongFormat.get_format_list():
# WHEN: Retrieving an attribute that overrides the default values
for attribute in SongFormat.get(song_format).keys():
# THEN: Return the attribute
self.assertEquals(SongFormat.get(song_format, attribute), SongFormat.get(song_format)[attribute],
"The returned attribute doesn't match the stored one")
# WHEN: Retrieving an attribute that was not overridden
for attribute in SongFormat.__defaults__.keys():
if attribute not in SongFormat.get(song_format).keys():
# THEN: Return the default value
self.assertEquals(SongFormat.get(song_format, attribute), SongFormat.__defaults__[attribute],
"The returned attribute does not match the default values stored")
def test_get_attributed_multiple_attributes(self):
"""
Test that multiple attributes can be retrieved for a song_format
"""
# GIVEN: A SongFormat
# WHEN: Retrieving multiple attributes at the same time
for song_format in SongFormat.get_format_list():
# THEN: Return all attributes that were specified
self.assertEquals(len(SongFormat.get(song_format, 'canDisable', 'availability')), 2,
"Did not return the correct number of attributes when retrieving multiple attributes at once")

View File

@ -22,35 +22,3 @@
"""
Module-level functions for the functional test suite
"""
import os
from openlp.core.common import is_win
from tests.interfaces import patch
from .test_projectormanager import tmpfile
def setUp():
"""
Set up this module of tests
"""
if not is_win():
# Wine creates a sharing violation during tests. Ignore.
try:
os.remove(tmpfile)
except:
pass
def tearDown():
"""
Ensure test suite has been cleaned up after tests
"""
patch.stopall()
if not is_win():
try:
# In case of changed schema, remove old test file
os.remove(tmpfile)
except FileNotFoundError:
pass

View File

@ -23,7 +23,7 @@
Interface tests to test the openlp.core.ui.projector.editform.ProjectorEditForm()
class and methods.
"""
import os
from unittest import TestCase
from openlp.core.common import Registry, Settings
@ -32,7 +32,7 @@ from openlp.core.ui import ProjectorEditForm
from tests.functional import patch
from tests.helpers.testmixin import TestMixin
from tests.resources.projector.data import TEST1_DATA, TEST2_DATA
from tests.resources.projector.data import TEST_DB, TEST1_DATA, TEST2_DATA
class TestProjectorEditForm(TestCase, TestMixin):
@ -49,7 +49,9 @@ class TestProjectorEditForm(TestCase, TestMixin):
self.setup_application()
Registry.create()
with patch('openlp.core.lib.projector.db.init_url') as mocked_init_url:
mocked_init_url.return_value = 'sqlite://'
if os.path.exists(TEST_DB):
os.unlink(TEST_DB)
mocked_init_url.return_value = 'sqlite:///' + TEST_DB
self.projectordb = ProjectorDB()
self.projector_form = ProjectorEditForm(projectordb=self.projectordb)
@ -93,11 +95,13 @@ class TestProjectorEditForm(TestCase, TestMixin):
with patch('openlp.core.ui.projector.editform.QDialog.exec'):
# WHEN: Calling edit form with existing projector instance
self.projector_form.exec(projector=TEST1_DATA)
self.projector_form.exec(projector=Projector(**TEST1_DATA))
item = self.projector_form.projector
# THEN: Should be editing an existing entry
self.assertFalse(self.projector_form.new_projector,
'Projector edit form should be marked as existing entry')
self.assertTrue((item.ip is TEST1_DATA.ip and item.name is TEST1_DATA.name),
self.assertTrue((item.ip is TEST1_DATA['ip'] and item.name is TEST1_DATA['name']),
'Projector edit form should have TEST1_DATA() instance to edit')

View File

@ -22,7 +22,6 @@
"""
Interface tests to test the themeManager class and related methods.
"""
import os
from unittest import TestCase
@ -33,9 +32,7 @@ from tests.helpers.testmixin import TestMixin
from openlp.core.ui import ProjectorManager, ProjectorEditForm
from openlp.core.lib.projector.db import Projector, ProjectorDB
from tests.resources.projector.data import TEST1_DATA, TEST2_DATA, TEST3_DATA
tmpfile = '/tmp/openlp-test-projectormanager.sql'
from tests.resources.projector.data import TEST_DB, TEST1_DATA, TEST2_DATA, TEST3_DATA
class TestProjectorManager(TestCase, TestMixin):
@ -49,12 +46,13 @@ class TestProjectorManager(TestCase, TestMixin):
self.build_settings()
self.setup_application()
Registry.create()
if not hasattr(self, 'projector_manager'):
with patch('openlp.core.lib.projector.db.init_url') as mocked_init_url:
mocked_init_url.return_value = 'sqlite:///%s' % tmpfile
self.projectordb = ProjectorDB()
if not hasattr(self, 'projector_manager'):
self.projector_manager = ProjectorManager(projectordb=self.projectordb)
with patch('openlp.core.lib.projector.db.init_url') as mocked_init_url:
if os.path.exists(TEST_DB):
os.unlink(TEST_DB)
mocked_init_url.return_value = 'sqlite:///%s' % TEST_DB
self.projectordb = ProjectorDB()
if not hasattr(self, 'projector_manager'):
self.projector_manager = ProjectorManager(projectordb=self.projectordb)
def tearDown(self):
"""

View File

@ -20,24 +20,24 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
:mod: `tests.interfaces.openlp_core_ui.test_projectorsourceform` module
:mod: `tests.interfaces.openlp_core_ui.test_projectorsourceform` module
Tests for the Projector Source Select form.
Tests for the Projector Source Select form.
"""
import logging
log = logging.getLogger(__name__)
log.debug('test_projectorsourceform loaded')
import os
from unittest import TestCase
from PyQt5.QtWidgets import QDialog
from tests.functional import patch
from tests.functional.openlp_core_lib.test_projectordb import tmpfile
from tests.helpers.testmixin import TestMixin
from tests.resources.projector.data import TEST_DB, TEST1_DATA
from openlp.core.common import Registry, Settings
from openlp.core.lib.projector.db import ProjectorDB
from openlp.core.lib.projector.db import ProjectorDB, Projector
from openlp.core.lib.projector.constants import PJLINK_DEFAULT_CODES, PJLINK_DEFAULT_SOURCES
from openlp.core.ui.projector.sourceselectform import source_group, SourceSelectSingle
@ -65,7 +65,9 @@ class ProjectorSourceFormTest(TestCase, TestMixin):
"""
Set up anything necessary for all tests
"""
mocked_init_url.return_value = 'sqlite:///{}'.format(tmpfile)
if os.path.exists(TEST_DB):
os.unlink(TEST_DB)
mocked_init_url.return_value = 'sqlite:///{}'.format(TEST_DB)
self.build_settings()
self.setup_application()
Registry.create()
@ -73,10 +75,10 @@ class ProjectorSourceFormTest(TestCase, TestMixin):
if not hasattr(self, 'projectordb'):
self.projectordb = ProjectorDB()
# Retrieve/create a database record
self.projector = self.projectordb.get_projector_by_ip(TEST1_DATA.ip)
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.projectordb.add_projector(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

View File

@ -130,7 +130,7 @@ class TestBibleHTTP(TestCase):
# THEN: The list should not be None, and some known bibles should be there
self.assertIsNotNone(bibles)
self.assertIn(('New Int. Readers Version', 'NIRV', 'en'), bibles)
self.assertIn(('Българската Библия', 'BLG', 'bg'), bibles)
self.assertIn(('Священное Писание, Восточный перевод', 'CARS', 'ru'), bibles)
def biblegateway_get_bibles_test(self):
"""

View File

@ -142,3 +142,18 @@ class TestEditSongForm(TestCase, TestMixin):
'CCLI label should not be "{}"'.format(UiStrings().CCLINumberLabel))
self.assertEquals(form.ccli_label.text(), UiStrings().CCLISongNumberLabel,
'CCLI label text should be "{}"'.format(UiStrings().CCLISongNumberLabel))
def verse_order_lowercase_test(self):
"""
Test that entering a verse order in lowercase automatically converts to uppercase
"""
# GIVEN; Mocked methods
form = self.form
# WHEN: We enter a verse order in lowercase
form.verse_order_edit.setText('v1 v2 c1 v3 c1 v4 c1')
# Need to manually trigger this method as it is only triggered by manual input
form.on_verse_order_text_changed(form.verse_order_edit.text())
# THEN: The verse order should be converted to uppercase
self.assertEqual(form.verse_order_edit.text(), 'V1 V2 C1 V3 C1 V4 C1')

View File

@ -24,28 +24,28 @@ The :mod:`tests.resources.projector.data file contains test data
"""
import os
from openlp.core.lib.projector.db import Projector
from tempfile import gettempdir
# Test data
TEST_DB = os.path.join('tmp', 'openlp-test-projectordb.sql')
TEST_DB = os.path.join(gettempdir(), 'openlp-test-projectordb.sql')
TEST1_DATA = Projector(ip='111.111.111.111',
port='1111',
pin='1111',
name='___TEST_ONE___',
location='location one',
notes='notes one')
TEST1_DATA = dict(ip='111.111.111.111',
port='1111',
pin='1111',
name='___TEST_ONE___',
location='location one',
notes='notes one')
TEST2_DATA = Projector(ip='222.222.222.222',
port='2222',
pin='2222',
name='___TEST_TWO___',
location='location two',
notes='notes two')
TEST2_DATA = dict(ip='222.222.222.222',
port='2222',
pin='2222',
name='___TEST_TWO___',
location='location two',
notes='notes two')
TEST3_DATA = Projector(ip='333.333.333.333',
port='3333',
pin='3333',
name='___TEST_THREE___',
location='location three',
notes='notes three')
TEST3_DATA = dict(ip='333.333.333.333',
port='3333',
pin='3333',
name='___TEST_THREE___',
location='location three',
notes='notes three')