openlp-core team mailing list archive
-
openlp-core team
-
Mailing list archive
-
Message #32082
[Merge] lp:~raoul-snyman/openlp/fix-version-check into lp:openlp
Raoul Snyman has proposed merging lp:~raoul-snyman/openlp/fix-version-check into lp:openlp.
Requested reviews:
OpenLP Core (openlp-core)
For more details, see:
https://code.launchpad.net/~raoul-snyman/openlp/fix-version-check/+merge/331081
WIP: this needs Phil's "pathlib5" merge proposal merged first.
--
Your team OpenLP Core is requested to review the proposed merge of lp:~raoul-snyman/openlp/fix-version-check into lp:openlp.
=== modified file 'openlp.py'
--- openlp.py 2016-12-31 11:01:36 +0000
+++ openlp.py 2017-09-20 17:03:28 +0000
@@ -20,13 +20,17 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
-
+"""
+The entrypoint for OpenLP
+"""
+import faulthandler
+import multiprocessing
import sys
-import multiprocessing
from openlp.core.common import is_win, is_macosx
from openlp.core import main
+faulthandler.enable()
if __name__ == '__main__':
"""
=== modified file 'openlp/core/__init__.py'
--- openlp/core/__init__.py 2017-09-03 10:18:14 +0000
+++ openlp/core/__init__.py 2017-09-20 17:03:28 +0000
@@ -26,7 +26,6 @@
All the core functions of the OpenLP application including the GUI, settings,
logging and a plugin framework are contained within the openlp.core module.
"""
-
import argparse
import logging
import os
@@ -41,7 +40,7 @@
from openlp.core.common import Registry, OpenLPMixin, AppLocation, LanguageManager, Settings, UiStrings, \
check_directory_exists, is_macosx, is_win, translate
from openlp.core.common.path import Path
-from openlp.core.common.versionchecker import VersionThread, get_application_version
+from openlp.core.version import check_for_update, get_version
from openlp.core.lib import ScreenList
from openlp.core.resources import qInitResources
from openlp.core.ui import SplashScreen
@@ -155,8 +154,8 @@
self.processEvents()
if not has_run_wizard:
self.main_window.first_time()
- version = VersionThread(self.main_window)
- version.start()
+ if Settings().value('core/update check'):
+ check_for_update(self.main_window)
self.main_window.is_display_blank()
self.main_window.app_startup()
return self.exec()
@@ -184,22 +183,18 @@
data_folder_path = str(AppLocation.get_data_path())
if not os.path.exists(data_folder_path):
log.critical('Database was not found in: ' + data_folder_path)
- status = QtWidgets.QMessageBox.critical(None, translate('OpenLP', 'Data Directory Error'),
- translate('OpenLP', 'OpenLP data folder was not found in:\n\n{path}'
- '\n\nThe location of the data folder was '
- 'previously changed from the OpenLP\'s '
- 'default location. If the data was stored on '
- 'removable device, that device needs to be '
- 'made available.\n\nYou may reset the data '
- 'location back to the default location, '
- 'or you can try to make the current location '
- 'available.\n\nDo you want to reset to the '
- 'default data location? If not, OpenLP will be '
- 'closed so you can try to fix the the problem.')
- .format(path=data_folder_path),
- QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes |
- QtWidgets.QMessageBox.No),
- QtWidgets.QMessageBox.No)
+ status = QtWidgets.QMessageBox.critical(
+ None, translate('OpenLP', 'Data Directory Error'),
+ translate('OpenLP', 'OpenLP data folder was not found in:\n\n{path}\n\nThe location of the data '
+ 'folder was previously changed from the OpenLP\'s default location. If the data was '
+ 'stored on removable device, that device needs to be made available.\n\nYou may reset '
+ 'the data location back to the default location, or you can try to make the current '
+ 'location available.\n\nDo you want to reset to the default data location? If not, '
+ 'OpenLP will be closed so you can try to fix the the problem.').format(
+ path=data_folder_path),
+ QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No),
+ QtWidgets.QMessageBox.No
+ )
if status == QtWidgets.QMessageBox.No:
# If answer was "No", return "True", it will shutdown OpenLP in def main
log.info('User requested termination')
@@ -240,7 +235,7 @@
:param can_show_splash: Should OpenLP show the splash screen
"""
data_version = Settings().value('core/application version')
- openlp_version = get_application_version()['version']
+ openlp_version = get_version()['version']
# New installation, no need to create backup
if not has_run_wizard:
Settings().setValue('core/application version', openlp_version)
@@ -415,7 +410,7 @@
Registry.create()
Registry().register('application', application)
Registry().set_flag('no_web_server', args.no_web_server)
- application.setApplicationVersion(get_application_version()['version'])
+ application.setApplicationVersion(get_version()['version'])
# Check if an instance of OpenLP is already running. Quit if there is a running instance and the user only wants one
if application.is_already_running():
sys.exit()
=== modified file 'openlp/core/api/poll.py'
--- openlp/core/api/poll.py 2017-06-17 08:51:01 +0000
+++ openlp/core/api/poll.py 2017-09-20 17:03:28 +0000
@@ -52,7 +52,7 @@
'isSecure': Settings().value('api/authentication enabled'),
'isAuthorised': False,
'chordNotation': Settings().value('songs/chord notation'),
- 'isStagedActive': self.is_stage_active(),
+ 'isStageActive': self.is_stage_active(),
'isLiveActive': self.is_live_active(),
'isChordsActive': self.is_chords_active()
}
=== modified file 'openlp/core/common/httputils.py'
--- openlp/core/common/httputils.py 2017-08-13 05:50:44 +0000
+++ openlp/core/common/httputils.py 2017-09-20 17:03:28 +0000
@@ -25,17 +25,12 @@
import hashlib
import logging
import os
-import platform
-import socket
import sys
-import subprocess
import time
-import urllib.error
-import urllib.parse
-import urllib.request
-from http.client import HTTPException
from random import randint
+import requests
+
from openlp.core.common import Registry, trace_error_handler
log = logging.getLogger(__name__ + '.__init__')
@@ -69,33 +64,6 @@
CONNECTION_RETRIES = 2
-class HTTPRedirectHandlerFixed(urllib.request.HTTPRedirectHandler):
- """
- Special HTTPRedirectHandler used to work around http://bugs.python.org/issue22248
- (Redirecting to urls with special chars)
- """
- def redirect_request(self, req, fp, code, msg, headers, new_url):
- #
- """
- Test if the new_url can be decoded to ascii
-
- :param req:
- :param fp:
- :param code:
- :param msg:
- :param headers:
- :param new_url:
- :return:
- """
- try:
- new_url.encode('latin1').decode('ascii')
- fixed_url = new_url
- except Exception:
- # The url could not be decoded to ascii, so we do some url encoding
- fixed_url = urllib.parse.quote(new_url.encode('latin1').decode('utf-8', 'replace'), safe='/:')
- return super(HTTPRedirectHandlerFixed, self).redirect_request(req, fp, code, msg, headers, fixed_url)
-
-
def get_user_agent():
"""
Return a user agent customised for the platform the user is on.
@@ -107,7 +75,7 @@
return browser_list[random_index]
-def get_web_page(url, header=None, update_openlp=False):
+def get_web_page(url, headers=None, update_openlp=False, proxies=None):
"""
Attempts to download the webpage at url and returns that page or None.
@@ -116,71 +84,37 @@
:param update_openlp: Tells OpenLP to update itself if the page is successfully downloaded.
Defaults to False.
"""
- # TODO: Add proxy usage. Get proxy info from OpenLP settings, add to a
- # proxy_handler, build into an opener and install the opener into urllib2.
- # http://docs.python.org/library/urllib2.html
if not url:
return None
- # This is needed to work around http://bugs.python.org/issue22248 and https://bugs.launchpad.net/openlp/+bug/1251437
- opener = urllib.request.build_opener(HTTPRedirectHandlerFixed())
- urllib.request.install_opener(opener)
- req = urllib.request.Request(url)
- if not header or header[0].lower() != 'user-agent':
- user_agent = get_user_agent()
- req.add_header('User-Agent', user_agent)
- if header:
- req.add_header(header[0], header[1])
+ if not headers:
+ headers = {}
+ if 'user-agent' not in [key.lower() for key in headers.keys()]:
+ headers['User-Agent'] = get_user_agent()
log.debug('Downloading URL = %s' % url)
retries = 0
- while retries <= CONNECTION_RETRIES:
- retries += 1
- time.sleep(0.1)
+ while retries < CONNECTION_RETRIES:
try:
- page = urllib.request.urlopen(req, timeout=CONNECTION_TIMEOUT)
- log.debug('Downloaded page {text}'.format(text=page.geturl()))
- break
- except urllib.error.URLError as err:
- log.exception('URLError on {text}'.format(text=url))
- log.exception('URLError: {text}'.format(text=err.reason))
- page = None
- if retries > CONNECTION_RETRIES:
- raise
- except socket.timeout:
- log.exception('Socket timeout: {text}'.format(text=url))
- page = None
- if retries > CONNECTION_RETRIES:
- raise
- except socket.gaierror:
- log.exception('Socket gaierror: {text}'.format(text=url))
- page = None
- if retries > CONNECTION_RETRIES:
- raise
- except ConnectionRefusedError:
- log.exception('ConnectionRefused: {text}'.format(text=url))
- page = None
- if retries > CONNECTION_RETRIES:
- raise
- break
- except ConnectionError:
- log.exception('Connection error: {text}'.format(text=url))
- page = None
- if retries > CONNECTION_RETRIES:
- raise
- except HTTPException:
- log.exception('HTTPException error: {text}'.format(text=url))
- page = None
- if retries > CONNECTION_RETRIES:
- raise
+ response = requests.get(url, headers=headers, proxies=proxies, timeout=float(CONNECTION_TIMEOUT))
+ log.debug('Downloaded page {url}'.format(url=response.url))
+ break
+ except IOError:
+ # For now, catch IOError. All requests errors inherit from IOError
+ log.exception('Unable to connect to {url}'.format(url=url))
+ response = None
+ if retries >= CONNECTION_RETRIES:
+ raise ConnectionError('Unable to connect to {url}, see log for details'.format(url=url))
+ retries += 1
except:
# Don't know what's happening, so reraise the original
+ log.exception('Unknown error when trying to connect to {url}'.format(url=url))
raise
if update_openlp:
Registry().get('application').process_events()
- if not page:
- log.exception('{text} could not be downloaded'.format(text=url))
+ if not response or not response.text:
+ log.error('{url} could not be downloaded'.format(url=url))
return None
- log.debug(page)
- return page
+ log.debug(response.text)
+ return response.text
def get_url_file_size(url):
@@ -192,19 +126,18 @@
retries = 0
while True:
try:
- site = urllib.request.urlopen(url, timeout=CONNECTION_TIMEOUT)
- meta = site.info()
- return int(meta.get("Content-Length"))
- except urllib.error.URLError:
+ response = requests.head(url, timeout=float(CONNECTION_TIMEOUT), allow_redirects=True)
+ return int(response.headers['Content-Length'])
+ except IOError:
if retries > CONNECTION_RETRIES:
- raise
+ raise ConnectionError('Unable to download {url}'.format(url=url))
else:
retries += 1
time.sleep(0.1)
continue
-def url_get_file(callback, url, f_path, sha256=None):
+def url_get_file(callback, url, file_path, sha256=None):
""""
Download a file given a URL. The file is retrieved in chunks, giving the ability to cancel the download at any
point. Returns False on download error.
@@ -217,56 +150,42 @@
block_count = 0
block_size = 4096
retries = 0
- log.debug("url_get_file: " + url)
- while True:
+ log.debug('url_get_file: %s', url)
+ while retries < CONNECTION_RETRIES:
try:
- filename = open(f_path, "wb")
- url_file = urllib.request.urlopen(url, timeout=CONNECTION_TIMEOUT)
- if sha256:
- hasher = hashlib.sha256()
- # Download until finished or canceled.
- while not callback.was_cancelled:
- data = url_file.read(block_size)
- if not data:
- break
- filename.write(data)
+ with open(file_path, 'wb') as saved_file:
+ response = requests.get(url, timeout=float(CONNECTION_TIMEOUT), stream=True)
if sha256:
- hasher.update(data)
- block_count += 1
- callback._download_progress(block_count, block_size)
- filename.close()
+ hasher = hashlib.sha256()
+ # Download until finished or canceled.
+ for chunk in response.iter_content(chunk_size=block_size):
+ if callback.was_cancelled:
+ break
+ saved_file.write(chunk)
+ if sha256:
+ hasher.update(chunk)
+ block_count += 1
+ callback._download_progress(block_count, block_size)
+ response.close()
if sha256 and hasher.hexdigest() != sha256:
- log.error('sha256 sums did not match for file: {file}'.format(file=f_path))
- os.remove(f_path)
+ log.error('sha256 sums did not match for file %s, got %s, expected %s', file_path, hasher.hexdigest(),
+ sha256)
+ os.remove(file_path)
return False
- except (urllib.error.URLError, socket.timeout) as err:
+ break
+ except IOError:
trace_error_handler(log)
- filename.close()
- os.remove(f_path)
+ os.remove(file_path)
if retries > CONNECTION_RETRIES:
return False
else:
retries += 1
time.sleep(0.1)
continue
- break
# Delete file if cancelled, it may be a partial file.
if callback.was_cancelled:
- os.remove(f_path)
+ os.remove(file_path)
return True
-def ping(host):
- """
- Returns True if host responds to a ping request
- """
- # Ping parameters as function of OS
- ping_str = "-n 1" if platform.system().lower() == "windows" else "-c 1"
- args = "ping " + " " + ping_str + " " + host
- need_sh = False if platform.system().lower() == "windows" else True
-
- # Ping
- return subprocess.call(args, shell=need_sh) == 0
-
-
__all__ = ['get_web_page']
=== modified file 'openlp/core/lib/plugin.py'
--- openlp/core/lib/plugin.py 2017-08-26 15:06:11 +0000
+++ openlp/core/lib/plugin.py 2017-09-20 17:03:28 +0000
@@ -27,7 +27,7 @@
from PyQt5 import QtCore
from openlp.core.common import Registry, RegistryProperties, Settings, UiStrings
-from openlp.core.common.versionchecker import get_application_version
+from openlp.core.version import get_version
log = logging.getLogger(__name__)
@@ -139,7 +139,7 @@
if version:
self.version = version
else:
- self.version = get_application_version()['version']
+ self.version = get_version()['version']
self.settings_section = self.name
self.icon = None
self.media_item_class = media_item_class
=== added file 'openlp/core/threading.py'
--- openlp/core/threading.py 1970-01-01 00:00:00 +0000
+++ openlp/core/threading.py 2017-09-20 17:03:28 +0000
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2017 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 #
+###############################################################################
+"""
+The :mod:`openlp.core.threading` module contains some common threading code
+"""
+from PyQt5 import QtCore
+
+
+def run_thread(parent, worker, prefix='', auto_start=True):
+ """
+ Create a thread and assign a worker to it. This removes a lot of boilerplate code from the codebase.
+
+ :param object parent: The parent object so that the thread and worker are not orphaned.
+ :param QObject worker: A QObject-based worker object which does the actual work.
+ :param str prefix: A prefix to be applied to the attribute names.
+ :param bool auto_start: Automatically start the thread. Defaults to True.
+ """
+ # Set up attribute names
+ thread_name = 'thread'
+ worker_name = 'worker'
+ if prefix:
+ thread_name = '_'.join([prefix, thread_name])
+ worker_name = '_'.join([prefix, worker_name])
+ # Create the thread and add the thread and the worker to the parent
+ thread = QtCore.QThread()
+ setattr(parent, thread_name, thread)
+ setattr(parent, worker_name, worker)
+ # Move the worker into the thread's context
+ worker.moveToThread(thread)
+ # Connect slots and signals
+ thread.started.connect(worker.start)
+ worker.quit.connect(thread.quit)
+ worker.quit.connect(worker.deleteLater)
+ thread.finished.connect(thread.deleteLater)
+ if auto_start:
+ thread.start()
=== modified file 'openlp/core/ui/aboutform.py'
--- openlp/core/ui/aboutform.py 2017-06-04 12:14:23 +0000
+++ openlp/core/ui/aboutform.py 2017-09-20 17:03:28 +0000
@@ -26,7 +26,7 @@
from PyQt5 import QtCore, QtWidgets
-from openlp.core.common.versionchecker import get_application_version
+from openlp.core.version import get_version
from openlp.core.lib import translate
from .aboutdialog import UiAboutDialog
@@ -49,7 +49,7 @@
Set up the dialog. This method is mocked out in tests.
"""
self.setup_ui(self)
- application_version = get_application_version()
+ application_version = get_version()
about_text = self.about_text_edit.toPlainText()
about_text = about_text.replace('<version>', application_version['version'])
if application_version['build']:
=== modified file 'openlp/core/ui/exceptionform.py'
--- openlp/core/ui/exceptionform.py 2017-08-26 15:06:11 +0000
+++ openlp/core/ui/exceptionform.py 2017-09-20 17:03:28 +0000
@@ -71,7 +71,7 @@
VLC_VERSION = '-'
from openlp.core.common import RegistryProperties, Settings, UiStrings, is_linux, translate
-from openlp.core.common.versionchecker import get_application_version
+from openlp.core.version import get_version
from openlp.core.ui.lib.filedialog import FileDialog
from .exceptiondialog import Ui_ExceptionDialog
@@ -110,7 +110,7 @@
"""
Create an exception report.
"""
- openlp_version = get_application_version()
+ openlp_version = get_version()
description = self.description_text_edit.toPlainText()
traceback = self.exception_text_edit.toPlainText()
system = translate('OpenLP.ExceptionForm', 'Platform: {platform}\n').format(platform=platform.platform())
=== modified file 'openlp/core/ui/firsttimeform.py'
--- openlp/core/ui/firsttimeform.py 2017-08-25 20:03:25 +0000
+++ openlp/core/ui/firsttimeform.py 2017-09-20 17:03:28 +0000
@@ -181,22 +181,16 @@
self.application.process_events()
try:
web_config = get_web_page('{host}{name}'.format(host=self.web, name='download.cfg'),
- header=('User-Agent', user_agent))
- except (urllib.error.URLError, ConnectionError) as err:
- msg = QtWidgets.QMessageBox()
- title = translate('OpenLP.FirstTimeWizard', 'Network Error')
- msg.setText('{title} {error}'.format(title=title,
- error=err.code if hasattr(err, 'code') else ''))
- msg.setInformativeText(translate('OpenLP.FirstTimeWizard',
- 'There was a network error attempting to '
- 'connect to retrieve initial configuration information'))
- msg.setStandardButtons(msg.Ok)
- ans = msg.exec()
+ headers={'User-Agent': user_agent})
+ except ConnectionError:
+ QtWidgets.QMessageBox.critical(self, translate('OpenLP.FirstTimeWizard', 'Network Error'),
+ translate('OpenLP.FirstTimeWizard', 'There was a network error attempting '
+ 'to connect to retrieve initial configuration information'),
+ QtWidgets.QMessageBox.Ok)
web_config = False
if web_config:
- files = web_config.read()
try:
- self.config.read_string(files.decode())
+ self.config.read_string(web_config)
self.web = self.config.get('general', 'base url')
self.songs_url = self.web + self.config.get('songs', 'directory') + '/'
self.bibles_url = self.web + self.config.get('bibles', 'directory') + '/'
=== modified file 'openlp/core/ui/generaltab.py'
--- openlp/core/ui/generaltab.py 2017-08-26 15:06:11 +0000
+++ openlp/core/ui/generaltab.py 2017-09-20 17:03:28 +0000
@@ -163,7 +163,6 @@
self.startup_layout.addWidget(self.show_splash_check_box)
self.check_for_updates_check_box = QtWidgets.QCheckBox(self.startup_group_box)
self.check_for_updates_check_box.setObjectName('check_for_updates_check_box')
- self.check_for_updates_check_box.setVisible(False)
self.startup_layout.addWidget(self.check_for_updates_check_box)
self.right_layout.addWidget(self.startup_group_box)
# Logo
=== modified file 'openlp/core/ui/mainwindow.py'
--- openlp/core/ui/mainwindow.py 2017-09-03 10:18:14 +0000
+++ openlp/core/ui/mainwindow.py 2017-09-20 17:03:28 +0000
@@ -40,7 +40,6 @@
check_directory_exists, translate, is_win, is_macosx, add_actions
from openlp.core.common.actions import ActionList, CategoryOrder
from openlp.core.common.path import Path, path_to_str, str_to_path
-from openlp.core.common.versionchecker import get_application_version
from openlp.core.lib import Renderer, PluginManager, ImageManager, PluginStatus, ScreenList, build_icon
from openlp.core.lib.ui import create_action
from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, ThemeManager, LiveController, PluginForm, \
@@ -52,6 +51,7 @@
from openlp.core.ui.lib.dockwidget import OpenLPDockWidget
from openlp.core.ui.lib.filedialog import FileDialog
from openlp.core.ui.lib.mediadockmanager import MediaDockManager
+from openlp.core.version import get_version
log = logging.getLogger(__name__)
@@ -488,7 +488,6 @@
"""
The main window.
"""
- openlp_version_check = QtCore.pyqtSignal(QtCore.QVariant)
log.info('MainWindow loaded')
def __init__(self):
@@ -497,6 +496,8 @@
"""
super(MainWindow, self).__init__()
Registry().register('main_window', self)
+ self.version_thread = None
+ self.version_worker = None
self.clipboard = self.application.clipboard()
self.arguments = ''.join(self.application.args)
# Set up settings sections for the main application (not for use by plugins).
@@ -562,7 +563,6 @@
self.application.set_busy_cursor()
# Simple message boxes
Registry().register_function('theme_update_global', self.default_theme_changed)
- self.openlp_version_check.connect(self.version_notice)
Registry().register_function('config_screen_changed', self.screen_changed)
Registry().register_function('bootstrap_post_set_up', self.bootstrap_post_set_up)
# Reset the cursor
@@ -607,7 +607,7 @@
if widget:
widget.on_focus()
- def version_notice(self, version):
+ def on_new_version(self, version):
"""
Notifies the user that a newer version of OpenLP is available.
Triggered by delay thread and cannot display popup.
@@ -617,7 +617,7 @@
log.debug('version_notice')
version_text = translate('OpenLP.MainWindow', 'Version {new} of OpenLP is now available for download (you are '
'currently running version {current}). \n\nYou can download the latest version from '
- 'http://openlp.org/.').format(new=version, current=get_application_version()[u'full'])
+ 'http://openlp.org/.').format(new=version, current=get_version()[u'full'])
QtWidgets.QMessageBox.question(self, translate('OpenLP.MainWindow', 'OpenLP Version Updated'), version_text)
def show(self):
@@ -1011,6 +1011,17 @@
if not self.application.is_event_loop_active:
event.ignore()
return
+ # Sometimes the version thread hasn't finished, let's wait for it
+ try:
+ if self.version_thread and self.version_thread.isRunning():
+ wait_dialog = QtWidgets.QProgressDialog('Waiting for some things to finish...', '', 0, 0, self)
+ wait_dialog.setWindowModality(QtCore.Qt.WindowModal)
+ wait_dialog.setAutoClose(False)
+ self.version_thread.wait()
+ wait_dialog.close()
+ except RuntimeError:
+ # Ignore the RuntimeError that is thrown when Qt has already deleted the C++ thread object
+ pass
# If we just did a settings import, close without saving changes.
if self.settings_imported:
self.clean_up(False)
=== renamed file 'openlp/core/common/versionchecker.py' => 'openlp/core/version.py'
--- openlp/core/common/versionchecker.py 2017-08-03 17:54:40 +0000
+++ openlp/core/version.py 2017-09-20 17:03:28 +0000
@@ -20,24 +20,22 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
-The :mod:`openlp.core.common` module downloads the version details for OpenLP.
+The :mod:`openlp.core.version` module downloads the version details for OpenLP.
"""
import logging
import os
import platform
import sys
import time
-import urllib.error
-import urllib.parse
-import urllib.request
-from datetime import datetime
+from datetime import date
from distutils.version import LooseVersion
from subprocess import Popen, PIPE
+import requests
from PyQt5 import QtCore
-from openlp.core.common import AppLocation, Registry, Settings
-from openlp.core.common.httputils import ping
+from openlp.core.common import AppLocation, Settings
+from openlp.core.threading import run_thread
log = logging.getLogger(__name__)
@@ -46,42 +44,93 @@
CONNECTION_RETRIES = 2
-class VersionThread(QtCore.QThread):
- """
- A special Qt thread class to fetch the version of OpenLP from the website.
- This is threaded so that it doesn't affect the loading time of OpenLP.
- """
- def __init__(self, main_window):
- """
- Constructor for the thread class.
-
- :param main_window: The main window Object.
- """
- log.debug("VersionThread - Initialise")
- super(VersionThread, self).__init__(None)
- self.main_window = main_window
-
- def run(self):
- """
- Run the thread.
- """
- self.sleep(1)
- log.debug('Version thread - run')
- found = ping("openlp.io")
- Registry().set_flag('internet_present', found)
- update_check = Settings().value('core/update check')
- if found:
- Registry().execute('get_website_version')
- if update_check:
- app_version = get_application_version()
- version = check_latest_version(app_version)
- log.debug("Versions {version1} and {version2} ".format(version1=LooseVersion(str(version)),
- version2=LooseVersion(str(app_version['full']))))
- if LooseVersion(str(version)) > LooseVersion(str(app_version['full'])):
- self.main_window.openlp_version_check.emit('{version}'.format(version=version))
-
-
-def get_application_version():
+class VersionWorker(QtCore.QObject):
+ """
+ A worker class to fetch the version of OpenLP from the website. This is run from within a thread so that it
+ doesn't affect the loading time of OpenLP.
+ """
+ new_version = QtCore.pyqtSignal(dict)
+ no_internet = QtCore.pyqtSignal()
+ quit = QtCore.pyqtSignal()
+
+ def __init__(self, last_check_date, current_version):
+ """
+ Constructor for the version check worker.
+
+ :param string last_check_date: The last day we checked for a new version of OpenLP
+ """
+ log.debug('VersionWorker - Initialise')
+ super(VersionWorker, self).__init__(None)
+ self.last_check_date = last_check_date
+ self.current_version = current_version
+
+ def start(self):
+ """
+ Check the latest version of OpenLP against the version file on the OpenLP site.
+
+ **Rules around versions and version files:**
+
+ * If a version number has a build (i.e. -bzr1234), then it is a nightly.
+ * If a version number's minor version is an odd number, it is a development release.
+ * If a version number's minor version is an even number, it is a stable release.
+ """
+ log.debug('VersionWorker - Start')
+ # I'm not entirely sure why this was here, I'm commenting it out until I hit the same scenario
+ time.sleep(1)
+ download_url = 'http://www.openlp.org/files/version.txt'
+ if self.current_version['build']:
+ download_url = 'http://www.openlp.org/files/nightly_version.txt'
+ elif int(self.current_version['version'].split('.')[1]) % 2 != 0:
+ download_url = 'http://www.openlp.org/files/dev_version.txt'
+ headers = {
+ 'User-Agent': 'OpenLP/{version} {system}/{release}; '.format(version=self.current_version['full'],
+ system=platform.system(),
+ release=platform.release())
+ }
+ remote_version = None
+ retries = 0
+ while retries < 3:
+ try:
+ response = requests.get(download_url, headers=headers)
+ remote_version = response.text
+ log.debug('New version found: %s', remote_version)
+ break
+ except IOError:
+ log.exception('Unable to connect to OpenLP server to download version file')
+ retries += 1
+ else:
+ self.no_internet.emit()
+ if remote_version and LooseVersion(remote_version) > LooseVersion(self.current_version['full']):
+ self.new_version.emit(remote_version)
+ self.quit.emit()
+
+
+def update_check_date():
+ """
+ Save when we last checked for an update
+ """
+ Settings().setValue('core/last version test', date.today().strftime('%Y-%m-%d'))
+
+
+def check_for_update(parent):
+ """
+ Run a thread to download and check the version of OpenLP
+
+ :param MainWindow parent: The parent object for the thread. Usually the OpenLP main window.
+ """
+ last_check_date = Settings().value('core/last version test')
+ if date.today().strftime('%Y-%m-%d') <= last_check_date:
+ log.debug('Version check skipped, last checked today')
+ return
+ worker = VersionWorker(last_check_date, get_version())
+ worker.new_version.connect(parent.on_new_version)
+ worker.quit.connect(update_check_date)
+ # TODO: Use this to figure out if there's an Internet connection?
+ # worker.no_internet.connect(parent.on_no_internet)
+ run_thread(parent, worker, 'version')
+
+
+def get_version():
"""
Returns the application version of the running instance of OpenLP::
@@ -150,55 +199,3 @@
else:
log.info('Openlp version {version}'.format(version=APPLICATION_VERSION['version']))
return APPLICATION_VERSION
-
-
-def check_latest_version(current_version):
- """
- Check the latest version of OpenLP against the version file on the OpenLP
- site.
-
- **Rules around versions and version files:**
-
- * If a version number has a build (i.e. -bzr1234), then it is a nightly.
- * If a version number's minor version is an odd number, it is a development release.
- * If a version number's minor version is an even number, it is a stable release.
-
- :param current_version: The current version of OpenLP.
- """
- version_string = current_version['full']
- # set to prod in the distribution config file.
- settings = Settings()
- settings.beginGroup('core')
- last_test = settings.value('last version test')
- this_test = str(datetime.now().date())
- settings.setValue('last version test', this_test)
- settings.endGroup()
- if last_test != this_test:
- if current_version['build']:
- req = urllib.request.Request('http://www.openlp.org/files/nightly_version.txt')
- else:
- version_parts = current_version['version'].split('.')
- if int(version_parts[1]) % 2 != 0:
- req = urllib.request.Request('http://www.openlp.org/files/dev_version.txt')
- else:
- req = urllib.request.Request('http://www.openlp.org/files/version.txt')
- req.add_header('User-Agent', 'OpenLP/{version} {system}/{release}; '.format(version=current_version['full'],
- system=platform.system(),
- release=platform.release()))
- remote_version = None
- retries = 0
- while True:
- try:
- remote_version = str(urllib.request.urlopen(req, None,
- timeout=CONNECTION_TIMEOUT).read().decode()).strip()
- except (urllib.error.URLError, ConnectionError):
- if retries > CONNECTION_RETRIES:
- log.exception('Failed to download the latest OpenLP version file')
- else:
- retries += 1
- time.sleep(0.1)
- continue
- break
- if remote_version:
- version_string = remote_version
- return version_string
=== modified file 'openlp/plugins/bibles/lib/importers/http.py'
--- openlp/plugins/bibles/lib/importers/http.py 2017-08-04 17:40:57 +0000
+++ openlp/plugins/bibles/lib/importers/http.py 2017-09-20 17:03:28 +0000
@@ -93,7 +93,7 @@
NAME = 'BibleGateway'
def __init__(self, proxy_url=None):
- log.debug('BGExtract.init("{url}")'.format(url=proxy_url))
+ log.debug('BGExtract.init(proxy_url="{url}")'.format(url=proxy_url))
self.proxy_url = proxy_url
socket.setdefaulttimeout(30)
@@ -285,15 +285,10 @@
log.debug('BGExtract.get_books_from_http("{version}")'.format(version=version))
url_params = urllib.parse.urlencode({'action': 'getVersionInfo', 'vid': '{version}'.format(version=version)})
reference_url = 'http://www.biblegateway.com/versions/?{url}#books'.format(url=url_params)
- page = get_web_page(reference_url)
- if not page:
+ page_source = get_web_page(reference_url)
+ if not page_source:
send_error_message('download')
return None
- page_source = page.read()
- try:
- page_source = str(page_source, 'utf8')
- except UnicodeDecodeError:
- page_source = str(page_source, 'cp1251')
try:
soup = BeautifulSoup(page_source, 'lxml')
except Exception:
@@ -759,7 +754,7 @@
return BiblesResourcesDB.get_verse_count(book_id, chapter)
-def get_soup_for_bible_ref(reference_url, header=None, pre_parse_regex=None, pre_parse_substitute=None):
+def get_soup_for_bible_ref(reference_url, headers=None, pre_parse_regex=None, pre_parse_substitute=None):
"""
Gets a webpage and returns a parsed and optionally cleaned soup or None.
@@ -772,15 +767,15 @@
if not reference_url:
return None
try:
- page = get_web_page(reference_url, header, True)
+ page_source = get_web_page(reference_url, headers, update_openlp=True)
except Exception as e:
- page = None
- if not page:
+ log.exception('Unable to download Bible %s, unknown exception occurred', reference_url)
+ page_source = None
+ if not page_source:
send_error_message('download')
return None
- page_source = page.read()
if pre_parse_regex and pre_parse_substitute is not None:
- page_source = re.sub(pre_parse_regex, pre_parse_substitute, page_source.decode())
+ page_source = re.sub(pre_parse_regex, pre_parse_substitute, page_source)
soup = None
try:
soup = BeautifulSoup(page_source, 'lxml')
=== modified file 'openlp/plugins/remotes/deploy.py'
--- openlp/plugins/remotes/deploy.py 2017-08-12 20:58:16 +0000
+++ openlp/plugins/remotes/deploy.py 2017-09-20 17:03:28 +0000
@@ -19,10 +19,11 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
-
+"""
+Download and "install" the remote web client
+"""
import os
-import zipfile
-import urllib.error
+from zipfile import ZipFile
from openlp.core.common import AppLocation, Registry
from openlp.core.common.httputils import url_get_file, get_web_page, get_url_file_size
@@ -38,7 +39,7 @@
:return: None
"""
zip_file = os.path.join(app_root, zip_name)
- web_zip = zipfile.ZipFile(zip_file)
+ web_zip = ZipFile(zip_file)
web_zip.extractall(app_root)
@@ -48,11 +49,10 @@
"""
user_agent = 'OpenLP/' + Registry().get('application').applicationVersion()
try:
- web_config = get_web_page('{host}{name}'.format(host='https://get.openlp.org/webclient/', name='download.cfg'),
- header=('User-Agent', user_agent))
- except (urllib.error.URLError, ConnectionError) as err:
+ web_config = get_web_page('https://get.openlp.org/webclient/download.cfg', headers={'User-Agent': user_agent})
+ except ConnectionError:
return False
- file_bits = web_config.read().decode('utf-8').split()
+ file_bits = web_config.split()
return file_bits[0], file_bits[2]
=== modified file 'openlp/plugins/songs/lib/openlyricsxml.py'
--- openlp/plugins/songs/lib/openlyricsxml.py 2017-06-09 15:56:40 +0000
+++ openlp/plugins/songs/lib/openlyricsxml.py 2017-09-20 17:03:28 +0000
@@ -62,7 +62,7 @@
from lxml import etree, objectify
from openlp.core.common import translate, Settings
-from openlp.core.common.versionchecker import get_application_version
+from openlp.core.version import get_version
from openlp.core.lib import FormattingTags
from openlp.plugins.songs.lib import VerseType, clean_song
from openlp.plugins.songs.lib.db import Author, AuthorType, Book, Song, Topic
@@ -234,7 +234,7 @@
# Append the necessary meta data to the song.
song_xml.set('xmlns', NAMESPACE)
song_xml.set('version', OpenLyrics.IMPLEMENTED_VERSION)
- application_name = 'OpenLP ' + get_application_version()['version']
+ application_name = 'OpenLP ' + get_version()['version']
song_xml.set('createdIn', application_name)
song_xml.set('modifiedIn', application_name)
# "Convert" 2012-08-27 11:49:15 to 2012-08-27T11:49:15.
=== modified file 'scripts/check_dependencies.py'
--- scripts/check_dependencies.py 2017-06-06 20:58:12 +0000
+++ scripts/check_dependencies.py 2017-09-20 17:03:28 +0000
@@ -26,7 +26,7 @@
of required python modules and their version. To verify availability of Python
modules, simply run this script::
- @:~$ ./check_dependencies.py
+ $ ./check_dependencies.py
"""
import os
@@ -45,7 +45,7 @@
VERS = {
- 'Python': '3.0',
+ 'Python': '3.4',
'PyQt5': '5.0',
'Qt5': '5.0',
'sqlalchemy': '0.5',
@@ -97,7 +97,8 @@
'asyncio',
'waitress',
'six',
- 'webob'
+ 'webob',
+ 'requests'
]
=== added file 'tests/functional/openlp_core/test_version.py'
--- tests/functional/openlp_core/test_version.py 1970-01-01 00:00:00 +0000
+++ tests/functional/openlp_core/test_version.py 2017-09-20 17:03:28 +0000
@@ -0,0 +1,204 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2017 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 #
+###############################################################################
+"""
+Package to test the openlp.core.version package.
+"""
+import sys
+from datetime import date
+from unittest.mock import MagicMock, patch
+
+from requests.exceptions import ConnectionError
+
+from openlp.core.version import VersionWorker, check_for_update, get_version, update_check_date
+
+
+def test_worker_init():
+ """Test the VersionWorker constructor"""
+ # GIVEN: A last check date and a current version
+ last_check_date = '1970-01-01'
+ current_version = '2.0'
+
+ # WHEN: A worker is created
+ worker = VersionWorker(last_check_date, current_version)
+
+ # THEN: The correct attributes should have been set
+ assert worker.last_check_date == last_check_date
+ assert worker.current_version == current_version
+
+
+@patch('openlp.core.version.platform')
+@patch('openlp.core.version.requests')
+def test_worker_start(mock_requests, mock_platform):
+ """Test the VersionWorkder.start() method"""
+ # GIVEN: A last check date, current version, and an instance of worker
+ last_check_date = '1970-01-01'
+ current_version = {'full': '2.0', 'version': '2.0', 'build': None}
+ mock_platform.system.return_value = 'Linux'
+ mock_platform.release.return_value = '4.12.0-1-amd64'
+ mock_requests.get.return_value = MagicMock(text='2.4.6')
+ worker = VersionWorker(last_check_date, current_version)
+
+ # WHEN: The worker is run
+ with patch.object(worker, 'new_version') as mock_new_version, \
+ patch.object(worker, 'quit') as mock_quit:
+ worker.start()
+
+ # THEN: The check completes and the signal is emitted
+ expected_download_url = 'http://www.openlp.org/files/version.txt'
+ expected_headers = {'User-Agent': 'OpenLP/2.0 Linux/4.12.0-1-amd64; '}
+ mock_requests.get.assert_called_once_with(expected_download_url, headers=expected_headers)
+ mock_new_version.emit.assert_called_once_with('2.4.6')
+ mock_quit.emit.assert_called_once_with()
+
+
+@patch('openlp.core.version.platform')
+@patch('openlp.core.version.requests')
+def test_worker_start_dev_version(mock_requests, mock_platform):
+ """Test the VersionWorkder.start() method for dev versions"""
+ # GIVEN: A last check date, current version, and an instance of worker
+ last_check_date = '1970-01-01'
+ current_version = {'full': '2.1.3', 'version': '2.1.3', 'build': None}
+ mock_platform.system.return_value = 'Linux'
+ mock_platform.release.return_value = '4.12.0-1-amd64'
+ mock_requests.get.return_value = MagicMock(text='2.4.6')
+ worker = VersionWorker(last_check_date, current_version)
+
+ # WHEN: The worker is run
+ with patch.object(worker, 'new_version') as mock_new_version, \
+ patch.object(worker, 'quit') as mock_quit:
+ worker.start()
+
+ # THEN: The check completes and the signal is emitted
+ expected_download_url = 'http://www.openlp.org/files/dev_version.txt'
+ expected_headers = {'User-Agent': 'OpenLP/2.1.3 Linux/4.12.0-1-amd64; '}
+ mock_requests.get.assert_called_once_with(expected_download_url, headers=expected_headers)
+ mock_new_version.emit.assert_called_once_with('2.4.6')
+ mock_quit.emit.assert_called_once_with()
+
+
+@patch('openlp.core.version.platform')
+@patch('openlp.core.version.requests')
+def test_worker_start_nightly_version(mock_requests, mock_platform):
+ """Test the VersionWorkder.start() method for nightlies"""
+ # GIVEN: A last check date, current version, and an instance of worker
+ last_check_date = '1970-01-01'
+ current_version = {'full': '2.1-bzr2345', 'version': '2.1', 'build': '2345'}
+ mock_platform.system.return_value = 'Linux'
+ mock_platform.release.return_value = '4.12.0-1-amd64'
+ mock_requests.get.return_value = MagicMock(text='2.4.6')
+ worker = VersionWorker(last_check_date, current_version)
+
+ # WHEN: The worker is run
+ with patch.object(worker, 'new_version') as mock_new_version, \
+ patch.object(worker, 'quit') as mock_quit:
+ worker.start()
+
+ # THEN: The check completes and the signal is emitted
+ expected_download_url = 'http://www.openlp.org/files/nightly_version.txt'
+ expected_headers = {'User-Agent': 'OpenLP/2.1-bzr2345 Linux/4.12.0-1-amd64; '}
+ mock_requests.get.assert_called_once_with(expected_download_url, headers=expected_headers)
+ mock_new_version.emit.assert_called_once_with('2.4.6')
+ mock_quit.emit.assert_called_once_with()
+
+
+@patch('openlp.core.version.platform')
+@patch('openlp.core.version.requests')
+def test_worker_start_connection_error(mock_requests, mock_platform):
+ """Test the VersionWorkder.start() method when a ConnectionError happens"""
+ # GIVEN: A last check date, current version, and an instance of worker
+ last_check_date = '1970-01-01'
+ current_version = {'full': '2.0', 'version': '2.0', 'build': None}
+ mock_platform.system.return_value = 'Linux'
+ mock_platform.release.return_value = '4.12.0-1-amd64'
+ mock_requests.get.side_effect = ConnectionError('Could not connect')
+ worker = VersionWorker(last_check_date, current_version)
+
+ # WHEN: The worker is run
+ with patch.object(worker, 'no_internet') as mocked_no_internet, \
+ patch.object(worker, 'quit') as mocked_quit:
+ worker.start()
+
+ # THEN: The check completes and the signal is emitted
+ expected_download_url = 'http://www.openlp.org/files/version.txt'
+ expected_headers = {'User-Agent': 'OpenLP/2.0 Linux/4.12.0-1-amd64; '}
+ mock_requests.get.assert_called_with(expected_download_url, headers=expected_headers)
+ assert mock_requests.get.call_count == 3
+ mocked_no_internet.emit.assert_called_once_with()
+ mocked_quit.emit.assert_called_once_with()
+
+
+@patch('openlp.core.version.Settings')
+def test_update_check_date(MockSettings):
+ """Test that the update_check_date() function writes the correct date"""
+ # GIVEN: A mocked Settings object
+ mocked_settings = MagicMock()
+ MockSettings.return_value = mocked_settings
+
+ # WHEN: update_check_date() is called
+ update_check_date()
+
+ # THEN: The correct date should have been saved
+ mocked_settings.setValue.assert_called_once_with('core/last version test', date.today().strftime('%Y-%m-%d'))
+
+
+@patch('openlp.core.version.Settings')
+@patch('openlp.core.version.run_thread')
+def test_check_for_update(mocked_run_thread, MockSettings):
+ """Test the check_for_update() function"""
+ # GIVEN: A mocked settings object
+ mocked_settings = MagicMock()
+ mocked_settings.value.return_value = '1970-01-01'
+ MockSettings.return_value = mocked_settings
+
+ # WHEN: check_for_update() is called
+ check_for_update(MagicMock())
+
+ # THEN: The right things should have been called and a thread set in motion
+ assert mocked_run_thread.call_count == 1
+
+
+@patch('openlp.core.version.Settings')
+@patch('openlp.core.version.run_thread')
+def test_check_for_update_skipped(mocked_run_thread, MockSettings):
+ """Test that the check_for_update() function skips running if it already ran today"""
+ # GIVEN: A mocked settings object
+ mocked_settings = MagicMock()
+ mocked_settings.value.return_value = date.today().strftime('%Y-%m-%d')
+ MockSettings.return_value = mocked_settings
+
+ # WHEN: check_for_update() is called
+ check_for_update(MagicMock())
+
+ # THEN: The right things should have been called and a thread set in motion
+ assert mocked_run_thread.call_count == 0
+
+
+def test_get_version_dev_version():
+ """Test the get_version() function"""
+ # GIVEN: We're in dev mode
+ with patch.object(sys, 'argv', ['--dev-version']), \
+ patch('openlp.core.version.APPLICATION_VERSION', None):
+ # WHEN: get_version() is run
+ version = get_version()
+
+ # THEN: version is something
+ assert version
=== modified file 'tests/functional/openlp_core_api/test_websockets.py'
--- tests/functional/openlp_core_api/test_websockets.py 2017-08-12 19:34:56 +0000
+++ tests/functional/openlp_core_api/test_websockets.py 2017-09-20 17:03:28 +0000
@@ -70,7 +70,7 @@
"""
# GIVEN: A new httpserver
# WHEN: I start the server
- server = WebSocketServer()
+ WebSocketServer()
# THEN: the api environment should have been created
self.assertEquals(1, mock_qthread.call_count, 'The qthread should have been called once')
@@ -93,7 +93,7 @@
"""
Test the poll function returns the correct JSON
"""
- # WHEN: the system is configured with a set of data
+ # GIVEN: the system is configured with a set of data
mocked_service_manager = MagicMock()
mocked_service_manager.service_id = 21
mocked_live_controller = MagicMock()
@@ -105,8 +105,15 @@
mocked_live_controller.desktop_screen.isChecked.return_value = False
Registry().register('live_controller', mocked_live_controller)
Registry().register('service_manager', mocked_service_manager)
+ # WHEN: The poller polls
+ with patch.object(self.poll, 'is_stage_active') as mocked_is_stage_active, \
+ patch.object(self.poll, 'is_live_active') as mocked_is_live_active, \
+ patch.object(self.poll, 'is_chords_active') as mocked_is_chords_active:
+ mocked_is_stage_active.return_value = True
+ mocked_is_live_active.return_value = True
+ mocked_is_chords_active.return_value = True
+ poll_json = self.poll.poll()
# THEN: the live json should be generated and match expected results
- poll_json = self.poll.poll()
self.assertTrue(poll_json['results']['blank'], 'The blank return value should be True')
self.assertFalse(poll_json['results']['theme'], 'The theme return value should be False')
self.assertFalse(poll_json['results']['display'], 'The display return value should be False')
=== modified file 'tests/functional/openlp_core_common/test_httputils.py'
--- tests/functional/openlp_core_common/test_httputils.py 2017-06-09 20:53:13 +0000
+++ tests/functional/openlp_core_common/test_httputils.py 2017-09-20 17:03:28 +0000
@@ -24,11 +24,10 @@
"""
import os
import tempfile
-import socket
from unittest import TestCase
from unittest.mock import MagicMock, patch
-from openlp.core.common.httputils import get_user_agent, get_web_page, get_url_file_size, url_get_file, ping
+from openlp.core.common.httputils import get_user_agent, get_web_page, get_url_file_size, url_get_file
from tests.helpers.testmixin import TestMixin
@@ -67,7 +66,7 @@
"""
with patch('openlp.core.common.httputils.sys') as mocked_sys:
- # GIVEN: The system is Linux
+ # GIVEN: The system is Windows
mocked_sys.platform = 'win32'
# WHEN: We call get_user_agent()
@@ -82,7 +81,7 @@
"""
with patch('openlp.core.common.httputils.sys') as mocked_sys:
- # GIVEN: The system is Linux
+ # GIVEN: The system is macOS
mocked_sys.platform = 'darwin'
# WHEN: We call get_user_agent()
@@ -97,7 +96,7 @@
"""
with patch('openlp.core.common.httputils.sys') as mocked_sys:
- # GIVEN: The system is Linux
+ # GIVEN: The system is something else
mocked_sys.platform = 'freebsd'
# WHEN: We call get_user_agent()
@@ -119,182 +118,127 @@
# THEN: None should be returned
self.assertIsNone(result, 'The return value of get_web_page should be None')
- def test_get_web_page(self):
+ @patch('openlp.core.common.httputils.requests')
+ @patch('openlp.core.common.httputils.get_user_agent')
+ @patch('openlp.core.common.httputils.Registry')
+ def test_get_web_page(self, MockRegistry, mocked_get_user_agent, mocked_requests):
"""
Test that the get_web_page method works correctly
"""
- with patch('openlp.core.common.httputils.urllib.request.Request') as MockRequest, \
- patch('openlp.core.common.httputils.urllib.request.urlopen') as mock_urlopen, \
- patch('openlp.core.common.httputils.get_user_agent') as mock_get_user_agent, \
- patch('openlp.core.common.Registry') as MockRegistry:
- # GIVEN: Mocked out objects and a fake URL
- mocked_request_object = MagicMock()
- MockRequest.return_value = mocked_request_object
- mocked_page_object = MagicMock()
- mock_urlopen.return_value = mocked_page_object
- mock_get_user_agent.return_value = 'user_agent'
- fake_url = 'this://is.a.fake/url'
-
- # WHEN: The get_web_page() method is called
- returned_page = get_web_page(fake_url)
-
- # THEN: The correct methods are called with the correct arguments and a web page is returned
- MockRequest.assert_called_with(fake_url)
- mocked_request_object.add_header.assert_called_with('User-Agent', 'user_agent')
- self.assertEqual(1, mocked_request_object.add_header.call_count,
- 'There should only be 1 call to add_header')
- mock_get_user_agent.assert_called_with()
- mock_urlopen.assert_called_with(mocked_request_object, timeout=30)
- mocked_page_object.geturl.assert_called_with()
- self.assertEqual(0, MockRegistry.call_count, 'The Registry() object should have never been called')
- self.assertEqual(mocked_page_object, returned_page, 'The returned page should be the mock object')
-
- def test_get_web_page_with_header(self):
+ # GIVEN: Mocked out objects and a fake URL
+ mocked_requests.get.return_value = MagicMock(text='text')
+ mocked_get_user_agent.return_value = 'user_agent'
+ fake_url = 'this://is.a.fake/url'
+
+ # WHEN: The get_web_page() method is called
+ returned_page = get_web_page(fake_url)
+
+ # THEN: The correct methods are called with the correct arguments and a web page is returned
+ mocked_requests.get.assert_called_once_with(fake_url, headers={'User-Agent': 'user_agent'},
+ proxies=None, timeout=30.0)
+ mocked_get_user_agent.assert_called_once_with()
+ assert MockRegistry.call_count == 0, 'The Registry() object should have never been called'
+ assert returned_page == 'text', 'The returned page should be the mock object'
+
+ @patch('openlp.core.common.httputils.requests')
+ @patch('openlp.core.common.httputils.get_user_agent')
+ def test_get_web_page_with_header(self, mocked_get_user_agent, mocked_requests):
"""
Test that adding a header to the call to get_web_page() adds the header to the request
"""
- with patch('openlp.core.common.httputils.urllib.request.Request') as MockRequest, \
- patch('openlp.core.common.httputils.urllib.request.urlopen') as mock_urlopen, \
- patch('openlp.core.common.httputils.get_user_agent') as mock_get_user_agent:
- # GIVEN: Mocked out objects, a fake URL and a fake header
- mocked_request_object = MagicMock()
- MockRequest.return_value = mocked_request_object
- mocked_page_object = MagicMock()
- mock_urlopen.return_value = mocked_page_object
- mock_get_user_agent.return_value = 'user_agent'
- fake_url = 'this://is.a.fake/url'
- fake_header = ('Fake-Header', 'fake value')
-
- # WHEN: The get_web_page() method is called
- returned_page = get_web_page(fake_url, header=fake_header)
-
- # THEN: The correct methods are called with the correct arguments and a web page is returned
- MockRequest.assert_called_with(fake_url)
- mocked_request_object.add_header.assert_called_with(fake_header[0], fake_header[1])
- self.assertEqual(2, mocked_request_object.add_header.call_count,
- 'There should only be 2 calls to add_header')
- mock_get_user_agent.assert_called_with()
- mock_urlopen.assert_called_with(mocked_request_object, timeout=30)
- mocked_page_object.geturl.assert_called_with()
- self.assertEqual(mocked_page_object, returned_page, 'The returned page should be the mock object')
-
- def test_get_web_page_with_user_agent_in_headers(self):
+ # GIVEN: Mocked out objects, a fake URL and a fake header
+ mocked_requests.get.return_value = MagicMock(text='text')
+ mocked_get_user_agent.return_value = 'user_agent'
+ fake_url = 'this://is.a.fake/url'
+ fake_headers = {'Fake-Header': 'fake value'}
+
+ # WHEN: The get_web_page() method is called
+ returned_page = get_web_page(fake_url, headers=fake_headers)
+
+ # THEN: The correct methods are called with the correct arguments and a web page is returned
+ expected_headers = dict(fake_headers)
+ expected_headers.update({'User-Agent': 'user_agent'})
+ mocked_requests.get.assert_called_once_with(fake_url, headers=expected_headers,
+ proxies=None, timeout=30.0)
+ mocked_get_user_agent.assert_called_with()
+ assert returned_page == 'text', 'The returned page should be the mock object'
+
+ @patch('openlp.core.common.httputils.requests')
+ @patch('openlp.core.common.httputils.get_user_agent')
+ def test_get_web_page_with_user_agent_in_headers(self, mocked_get_user_agent, mocked_requests):
"""
Test that adding a user agent in the header when calling get_web_page() adds that user agent to the request
"""
- with patch('openlp.core.common.httputils.urllib.request.Request') as MockRequest, \
- patch('openlp.core.common.httputils.urllib.request.urlopen') as mock_urlopen, \
- patch('openlp.core.common.httputils.get_user_agent') as mock_get_user_agent:
- # GIVEN: Mocked out objects, a fake URL and a fake header
- mocked_request_object = MagicMock()
- MockRequest.return_value = mocked_request_object
- mocked_page_object = MagicMock()
- mock_urlopen.return_value = mocked_page_object
- fake_url = 'this://is.a.fake/url'
- user_agent_header = ('User-Agent', 'OpenLP/2.2.0')
-
- # WHEN: The get_web_page() method is called
- returned_page = get_web_page(fake_url, header=user_agent_header)
-
- # THEN: The correct methods are called with the correct arguments and a web page is returned
- MockRequest.assert_called_with(fake_url)
- mocked_request_object.add_header.assert_called_with(user_agent_header[0], user_agent_header[1])
- self.assertEqual(1, mocked_request_object.add_header.call_count,
- 'There should only be 1 call to add_header')
- self.assertEqual(0, mock_get_user_agent.call_count, 'get_user_agent should not have been called')
- mock_urlopen.assert_called_with(mocked_request_object, timeout=30)
- mocked_page_object.geturl.assert_called_with()
- self.assertEqual(mocked_page_object, returned_page, 'The returned page should be the mock object')
-
- def test_get_web_page_update_openlp(self):
- """
- Test that passing "update_openlp" as true to get_web_page calls Registry().get('app').process_events()
- """
- with patch('openlp.core.common.httputils.urllib.request.Request') as MockRequest, \
- patch('openlp.core.common.httputils.urllib.request.urlopen') as mock_urlopen, \
- patch('openlp.core.common.httputils.get_user_agent') as mock_get_user_agent, \
- patch('openlp.core.common.httputils.Registry') as MockRegistry:
- # GIVEN: Mocked out objects, a fake URL
- mocked_request_object = MagicMock()
- MockRequest.return_value = mocked_request_object
- mocked_page_object = MagicMock()
- mock_urlopen.return_value = mocked_page_object
- mock_get_user_agent.return_value = 'user_agent'
- mocked_registry_object = MagicMock()
- mocked_application_object = MagicMock()
- mocked_registry_object.get.return_value = mocked_application_object
- MockRegistry.return_value = mocked_registry_object
- fake_url = 'this://is.a.fake/url'
-
- # WHEN: The get_web_page() method is called
- returned_page = get_web_page(fake_url, update_openlp=True)
-
- # THEN: The correct methods are called with the correct arguments and a web page is returned
- MockRequest.assert_called_with(fake_url)
- mocked_request_object.add_header.assert_called_with('User-Agent', 'user_agent')
- self.assertEqual(1, mocked_request_object.add_header.call_count,
- 'There should only be 1 call to add_header')
- mock_urlopen.assert_called_with(mocked_request_object, timeout=30)
- mocked_page_object.geturl.assert_called_with()
- mocked_registry_object.get.assert_called_with('application')
- mocked_application_object.process_events.assert_called_with()
- self.assertEqual(mocked_page_object, returned_page, 'The returned page should be the mock object')
-
- def test_get_url_file_size(self):
- """
- Test that passing "update_openlp" as true to get_web_page calls Registry().get('app').process_events()
- """
- with patch('openlp.core.common.httputils.urllib.request.urlopen') as mock_urlopen, \
- patch('openlp.core.common.httputils.get_user_agent') as mock_get_user_agent:
- # GIVEN: Mocked out objects, a fake URL
- mocked_page_object = MagicMock()
- mock_urlopen.return_value = mocked_page_object
- mock_get_user_agent.return_value = 'user_agent'
- fake_url = 'this://is.a.fake/url'
-
- # WHEN: The get_url_file_size() method is called
- size = get_url_file_size(fake_url)
-
- # THEN: The correct methods are called with the correct arguments and a web page is returned
- mock_urlopen.assert_called_with(fake_url, timeout=30)
-
- @patch('openlp.core.ui.firsttimeform.urllib.request.urlopen')
- def test_socket_timeout(self, mocked_urlopen):
+ # GIVEN: Mocked out objects, a fake URL and a fake header
+ mocked_requests.get.return_value = MagicMock(text='text')
+ fake_url = 'this://is.a.fake/url'
+ user_agent_headers = {'User-Agent': 'OpenLP/2.2.0'}
+
+ # WHEN: The get_web_page() method is called
+ returned_page = get_web_page(fake_url, headers=user_agent_headers)
+
+ # THEN: The correct methods are called with the correct arguments and a web page is returned
+ mocked_requests.get.assert_called_once_with(fake_url, headers=user_agent_headers,
+ proxies=None, timeout=30.0)
+ assert mocked_get_user_agent.call_count == 0, 'get_user_agent() should not have been called'
+ assert returned_page == 'text', 'The returned page should be "test"'
+
+ @patch('openlp.core.common.httputils.requests')
+ @patch('openlp.core.common.httputils.get_user_agent')
+ @patch('openlp.core.common.httputils.Registry')
+ def test_get_web_page_update_openlp(self, MockRegistry, mocked_get_user_agent, mocked_requests):
+ """
+ Test that passing "update_openlp" as true to get_web_page calls Registry().get('app').process_events()
+ """
+ # GIVEN: Mocked out objects, a fake URL
+ mocked_requests.get.return_value = MagicMock(text='text')
+ mocked_get_user_agent.return_value = 'user_agent'
+ mocked_registry_object = MagicMock()
+ mocked_application_object = MagicMock()
+ mocked_registry_object.get.return_value = mocked_application_object
+ MockRegistry.return_value = mocked_registry_object
+ fake_url = 'this://is.a.fake/url'
+
+ # WHEN: The get_web_page() method is called
+ returned_page = get_web_page(fake_url, update_openlp=True)
+
+ # THEN: The correct methods are called with the correct arguments and a web page is returned
+ mocked_requests.get.assert_called_once_with(fake_url, headers={'User-Agent': 'user_agent'},
+ proxies=None, timeout=30.0)
+ mocked_get_user_agent.assert_called_once_with()
+ mocked_registry_object.get.assert_called_with('application')
+ mocked_application_object.process_events.assert_called_with()
+ assert returned_page == 'text', 'The returned page should be the mock object'
+
+ @patch('openlp.core.common.httputils.requests')
+ def test_get_url_file_size(self, mocked_requests):
+ """
+ Test that calling "get_url_file_size" works correctly
+ """
+ # GIVEN: Mocked out objects, a fake URL
+ mocked_requests.head.return_value = MagicMock(headers={'Content-Length': 100})
+ fake_url = 'this://is.a.fake/url'
+
+ # WHEN: The get_url_file_size() method is called
+ file_size = get_url_file_size(fake_url)
+
+ # THEN: The correct methods are called with the correct arguments and a web page is returned
+ mocked_requests.head.assert_called_once_with(fake_url, allow_redirects=True, timeout=30.0)
+ assert file_size == 100
+
+ @patch('openlp.core.common.httputils.requests')
+ @patch('openlp.core.common.httputils.os.remove')
+ def test_socket_timeout(self, mocked_remove, mocked_requests):
"""
Test socket timeout gets caught
"""
# GIVEN: Mocked urlopen to fake a network disconnect in the middle of a download
- mocked_urlopen.side_effect = socket.timeout()
+ mocked_requests.get.side_effect = IOError
# WHEN: Attempt to retrieve a file
- url_get_file(MagicMock(), url='http://localhost/test', f_path=self.tempfile)
+ url_get_file(MagicMock(), url='http://localhost/test', file_path=self.tempfile)
# THEN: socket.timeout should have been caught
# NOTE: Test is if $tmpdir/tempfile is still there, then test fails since ftw deletes bad downloaded files
- self.assertFalse(os.path.exists(self.tempfile), 'FTW url_get_file should have caught socket.timeout')
-
- def test_ping_valid(self):
- """
- Test ping for OpenLP
- """
- # GIVEN: a valid url to test
- url = "openlp.io"
-
- # WHEN: Attempt to check the url exists
- url_found = ping(url)
-
- # THEN: It should be found
- self.assertTrue(url_found, 'OpenLP.io is not found')
-
- def test_ping_invalid(self):
- """
- Test ping for OpenLP
- """
- # GIVEN: a valid url to test
- url = "trb143.io"
-
- # WHEN: Attempt to check the url exists
- url_found = ping(url)
-
- # THEN: It should be found
- self.assertFalse(url_found, 'TRB143.io is found')
+ mocked_remove.assert_called_with(self.tempfile)
+ assert mocked_remove.call_count == 3, 'os.remove() should have been called 3 times'
=== removed file 'tests/functional/openlp_core_common/test_versionchecker.py'
--- tests/functional/openlp_core_common/test_versionchecker.py 2017-04-24 05:17:55 +0000
+++ tests/functional/openlp_core_common/test_versionchecker.py 1970-01-01 00:00:00 +0000
@@ -1,64 +0,0 @@
-# -*- coding: utf-8 -*-
-# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
-
-###############################################################################
-# OpenLP - Open Source Lyrics Projection #
-# --------------------------------------------------------------------------- #
-# Copyright (c) 2008-2017 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 #
-###############################################################################
-"""
-Package to test the openlp.core.common.versionchecker package.
-"""
-from unittest import TestCase
-from unittest.mock import MagicMock, patch
-
-from openlp.core.common.settings import Settings
-from openlp.core.common.versionchecker import VersionThread
-
-from tests.helpers.testmixin import TestMixin
-
-
-class TestVersionchecker(TestMixin, TestCase):
-
- def setUp(self):
- """
- Create an instance and a few example actions.
- """
- self.build_settings()
-
- def tearDown(self):
- """
- Clean up
- """
- self.destroy_settings()
-
- def test_version_thread_triggered(self):
- """
- Test the version thread call does not trigger UI
- :return:
- """
- # GIVEN: a equal version setup and the data is not today.
- mocked_main_window = MagicMock()
- Settings().setValue('core/last version test', '1950-04-01')
- # WHEN: We check to see if the version is different .
- with patch('PyQt5.QtCore.QThread'),\
- patch('openlp.core.common.versionchecker.get_application_version') as mocked_get_application_version:
- mocked_get_application_version.return_value = {'version': '1.0.0', 'build': '', 'full': '2.0.4'}
- version_thread = VersionThread(mocked_main_window)
- version_thread.run()
- # THEN: If the version has changed the main window is notified
- self.assertTrue(mocked_main_window.openlp_version_check.emit.called,
- 'The main windows should have been notified')
=== modified file 'tests/functional/openlp_core_ui/test_aboutform.py'
--- tests/functional/openlp_core_ui/test_aboutform.py 2017-04-24 05:17:55 +0000
+++ tests/functional/openlp_core_ui/test_aboutform.py 2017-09-20 17:03:28 +0000
@@ -47,13 +47,13 @@
# THEN: A web browser is opened
mocked_webbrowser.open_new.assert_called_with('http://openlp.org/en/contribute')
- @patch('openlp.core.ui.aboutform.get_application_version')
- def test_about_form_build_number(self, mocked_get_application_version):
+ @patch('openlp.core.ui.aboutform.get_version')
+ def test_about_form_build_number(self, mocked_get_version):
"""
Test that the build number is added to the about form
"""
- # GIVEN: A mocked out get_application_version function
- mocked_get_application_version.return_value = {'version': '3.1.5', 'build': '3000'}
+ # GIVEN: A mocked out get_version function
+ mocked_get_version.return_value = {'version': '3.1.5', 'build': '3000'}
# WHEN: The about form is created
about_form = AboutForm(None)
=== modified file 'tests/functional/openlp_core_ui/test_exceptionform.py'
--- tests/functional/openlp_core_ui/test_exceptionform.py 2017-08-26 15:06:11 +0000
+++ tests/functional/openlp_core_ui/test_exceptionform.py 2017-09-20 17:03:28 +0000
@@ -53,7 +53,7 @@
@patch("openlp.core.ui.exceptionform.Qt.qVersion")
@patch("openlp.core.ui.exceptionform.QtGui.QDesktopServices.openUrl")
-@patch("openlp.core.ui.exceptionform.get_application_version")
+@patch("openlp.core.ui.exceptionform.get_version")
@patch("openlp.core.ui.exceptionform.sqlalchemy")
@patch("openlp.core.ui.exceptionform.bs4")
@patch("openlp.core.ui.exceptionform.etree")
@@ -64,18 +64,10 @@
"""
Test functionality of exception form functions
"""
- def __method_template_for_class_patches(self,
- __PLACEHOLDER_FOR_LOCAL_METHOD_PATCH_DECORATORS_GO_HERE__,
- mocked_python_version,
- mocked_platform,
- mocked_is_linux,
- mocked_etree,
- mocked_bs4,
- mocked_sqlalchemy,
- mocked_application_version,
- mocked_openlurl,
- mocked_qversion,
- ):
+ def __method_template_for_class_patches(self, __PLACEHOLDER_FOR_LOCAL_METHOD_PATCH_DECORATORS_GO_HERE__,
+ mocked_python_version, mocked_platform, mocked_is_linux,
+ mocked_etree, mocked_bs4, mocked_sqlalchemy, mocked_get_version,
+ mocked_openlurl, mocked_qversion):
"""
Template so you don't have to remember the layout of class mock options for methods
"""
@@ -86,7 +78,7 @@
mocked_platform.return_value = 'Nose Test'
mocked_qversion.return_value = 'Qt5 test'
mocked_is_linux.return_value = False
- mocked_application_version.return_value = 'Trunk Test'
+ mocked_get_version.return_value = 'Trunk Test'
def setUp(self):
self.setup_application()
@@ -107,22 +99,10 @@
@patch("openlp.core.ui.exceptionform.QtCore.QUrl")
@patch("openlp.core.ui.exceptionform.QtCore.QUrlQuery.addQueryItem")
@patch("openlp.core.ui.exceptionform.Qt")
- def test_on_send_report_button_clicked(self,
- mocked_qt,
- mocked_add_query_item,
- mocked_qurl,
- mocked_file_dialog,
- mocked_ui_exception_dialog,
- mocked_python_version,
- mocked_platform,
- mocked_is_linux,
- mocked_etree,
- mocked_bs4,
- mocked_sqlalchemy,
- mocked_application_version,
- mocked_openlurl,
- mocked_qversion,
- ):
+ def test_on_send_report_button_clicked(self, mocked_qt, mocked_add_query_item, mocked_qurl, mocked_file_dialog,
+ mocked_ui_exception_dialog, mocked_python_version, mocked_platform,
+ mocked_is_linux, mocked_etree, mocked_bs4, mocked_sqlalchemy,
+ mocked_get_version, mocked_openlurl, mocked_qversion):
"""
Test send report creates the proper system information text
"""
@@ -134,10 +114,10 @@
mocked_platform.return_value = 'Nose Test'
mocked_qversion.return_value = 'Qt5 test'
mocked_is_linux.return_value = False
- mocked_application_version.return_value = 'Trunk Test'
+ mocked_get_version.return_value = 'Trunk Test'
mocked_qt.PYQT_VERSION_STR = 'PyQt5 Test'
mocked_is_linux.return_value = False
- mocked_application_version.return_value = 'Trunk Test'
+ mocked_get_version.return_value = 'Trunk Test'
test_form = exceptionform.ExceptionForm()
test_form.file_attachment = None
@@ -157,19 +137,10 @@
@patch("openlp.core.ui.exceptionform.FileDialog.getSaveFileName")
@patch("openlp.core.ui.exceptionform.Qt")
- def test_on_save_report_button_clicked(self,
- mocked_qt,
- mocked_save_filename,
- mocked_python_version,
- mocked_platform,
- mocked_is_linux,
- mocked_etree,
- mocked_bs4,
- mocked_sqlalchemy,
- mocked_application_version,
- mocked_openlurl,
- mocked_qversion,
- ):
+ def test_on_save_report_button_clicked(self, mocked_qt, mocked_save_filename, mocked_python_version,
+ mocked_platform, mocked_is_linux, mocked_etree, mocked_bs4,
+ mocked_sqlalchemy, mocked_get_version, mocked_openlurl,
+ mocked_qversion):
"""
Test save report saves the correct information to a file
"""
@@ -181,7 +152,7 @@
mocked_qversion.return_value = 'Qt5 test'
mocked_qt.PYQT_VERSION_STR = 'PyQt5 Test'
mocked_is_linux.return_value = False
- mocked_application_version.return_value = 'Trunk Test'
+ mocked_get_version.return_value = 'Trunk Test'
mocked_save_filename.return_value = (Path('testfile.txt'), 'filter')
test_form = exceptionform.ExceptionForm()
=== modified file 'tests/functional/openlp_core_ui/test_first_time.py'
--- tests/functional/openlp_core_ui/test_first_time.py 2017-04-24 05:17:55 +0000
+++ tests/functional/openlp_core_ui/test_first_time.py 2017-09-20 17:03:28 +0000
@@ -22,9 +22,6 @@
"""
Package to test the openlp.core.utils.__init__ package.
"""
-import urllib.request
-import urllib.error
-import urllib.parse
from unittest import TestCase
from unittest.mock import patch
@@ -37,20 +34,21 @@
"""
Test First Time Wizard import functions
"""
- def test_webpage_connection_retry(self):
+ @patch('openlp.core.common.httputils.requests')
+ def test_webpage_connection_retry(self, mocked_requests):
"""
Test get_web_page will attempt CONNECTION_RETRIES+1 connections - bug 1409031
"""
# GIVEN: Initial settings and mocks
- with patch.object(urllib.request, 'urlopen') as mocked_urlopen:
- mocked_urlopen.side_effect = ConnectionError
-
- # WHEN: A webpage is requested
- try:
- get_web_page(url='http://localhost')
- except:
- pass
-
- # THEN: urlopen should have been called CONNECTION_RETRIES + 1 count
- self.assertEquals(mocked_urlopen.call_count, CONNECTION_RETRIES + 1,
- 'get_web_page() should have tried {} times'.format(CONNECTION_RETRIES))
+ mocked_requests.get.side_effect = IOError('Unable to connect')
+
+ # WHEN: A webpage is requested
+ try:
+ get_web_page('http://localhost')
+ except Exception as e:
+ assert isinstance(e, ConnectionError)
+
+ # THEN: urlopen should have been called CONNECTION_RETRIES + 1 count
+ assert mocked_requests.get.call_count == CONNECTION_RETRIES, \
+ 'get should have been called {} times, but was only called {} times'.format(
+ CONNECTION_RETRIES, mocked_requests.get.call_count)
=== modified file 'tests/functional/openlp_core_ui/test_firsttimeform.py'
--- tests/functional/openlp_core_ui/test_firsttimeform.py 2017-08-25 20:03:25 +0000
+++ tests/functional/openlp_core_ui/test_firsttimeform.py 2017-09-20 17:03:28 +0000
@@ -34,7 +34,7 @@
from tests.helpers.testmixin import TestMixin
-FAKE_CONFIG = b"""
+FAKE_CONFIG = """
[general]
base url = http://example.com/frw/
[songs]
@@ -45,7 +45,7 @@
directory = themes
"""
-FAKE_BROKEN_CONFIG = b"""
+FAKE_BROKEN_CONFIG = """
[general]
base url = http://example.com/frw/
[songs]
@@ -54,7 +54,7 @@
directory = bibles
"""
-FAKE_INVALID_CONFIG = b"""
+FAKE_INVALID_CONFIG = """
<html>
<head><title>This is not a config file</title></head>
<body>Some text</body>
@@ -112,7 +112,7 @@
patch('openlp.core.ui.firsttimeform.Settings') as MockedSettings, \
patch('openlp.core.ui.firsttimeform.gettempdir') as mocked_gettempdir, \
patch('openlp.core.ui.firsttimeform.check_directory_exists') as mocked_check_directory_exists, \
- patch.object(frw.application, 'set_normal_cursor') as mocked_set_normal_cursor:
+ patch.object(frw.application, 'set_normal_cursor'):
mocked_settings = MagicMock()
mocked_settings.value.return_value = True
MockedSettings.return_value = mocked_settings
@@ -192,7 +192,7 @@
with patch('openlp.core.ui.firsttimeform.get_web_page') as mocked_get_web_page:
first_time_form = FirstTimeForm(None)
first_time_form.initialize(MagicMock())
- mocked_get_web_page.return_value.read.return_value = FAKE_BROKEN_CONFIG
+ mocked_get_web_page.return_value = FAKE_BROKEN_CONFIG
# WHEN: The First Time Wizard is downloads the config file
first_time_form._download_index()
@@ -208,7 +208,7 @@
with patch('openlp.core.ui.firsttimeform.get_web_page') as mocked_get_web_page:
first_time_form = FirstTimeForm(None)
first_time_form.initialize(MagicMock())
- mocked_get_web_page.return_value.read.return_value = FAKE_INVALID_CONFIG
+ mocked_get_web_page.return_value = FAKE_INVALID_CONFIG
# WHEN: The First Time Wizard is downloads the config file
first_time_form._download_index()
@@ -225,14 +225,13 @@
# GIVEN: Initial setup and mocks
first_time_form = FirstTimeForm(None)
first_time_form.initialize(MagicMock())
- mocked_get_web_page.side_effect = urllib.error.HTTPError(url='http//localhost',
- code=407,
- msg='Network proxy error',
- hdrs=None,
- fp=None)
+ mocked_get_web_page.side_effect = ConnectionError('')
+ mocked_message_box.Ok = 'OK'
+
# WHEN: the First Time Wizard calls to get the initial configuration
first_time_form._download_index()
# THEN: the critical_error_message_box should have been called
- self.assertEquals(mocked_message_box.mock_calls[1][1][0], 'Network Error 407',
- 'first_time_form should have caught Network Error')
+ mocked_message_box.critical.assert_called_once_with(
+ first_time_form, 'Network Error', 'There was a network error attempting to connect to retrieve '
+ 'initial configuration information', 'OK')
=== modified file 'tests/functional/test_init.py'
--- tests/functional/test_init.py 2017-04-24 05:17:55 +0000
+++ tests/functional/test_init.py 2017-09-20 17:03:28 +0000
@@ -24,11 +24,11 @@
"""
import os
from unittest import TestCase
-from unittest.mock import MagicMock, patch, call
+from unittest.mock import MagicMock, patch
from PyQt5 import QtCore, QtWidgets
-from openlp.core import OpenLP, parse_options
+from openlp.core import OpenLP
from openlp.core.common import Settings
from tests.helpers.testmixin import TestMixin
@@ -96,9 +96,9 @@
'build': 'bzr000'
}
Settings().setValue('core/application version', '2.2.0')
- with patch('openlp.core.get_application_version') as mocked_get_application_version,\
+ with patch('openlp.core.get_version') as mocked_get_version,\
patch('openlp.core.QtWidgets.QMessageBox.question') as mocked_question:
- mocked_get_application_version.return_value = MOCKED_VERSION
+ mocked_get_version.return_value = MOCKED_VERSION
mocked_question.return_value = QtWidgets.QMessageBox.No
# WHEN: We check if a backup should be created
@@ -122,9 +122,9 @@
Settings().setValue('core/application version', '2.0.5')
self.openlp.splash = MagicMock()
self.openlp.splash.isVisible.return_value = True
- with patch('openlp.core.get_application_version') as mocked_get_application_version,\
+ with patch('openlp.core.get_version') as mocked_get_version, \
patch('openlp.core.QtWidgets.QMessageBox.question') as mocked_question:
- mocked_get_application_version.return_value = MOCKED_VERSION
+ mocked_get_version.return_value = MOCKED_VERSION
mocked_question.return_value = QtWidgets.QMessageBox.No
# WHEN: We check if a backup should be created
Follow ups