diff --git a/openlp/plugins/bibles/lib/http.py b/openlp/plugins/bibles/lib/http.py index b01377a05..736727e20 100644 --- a/openlp/plugins/bibles/lib/http.py +++ b/openlp/plugins/bibles/lib/http.py @@ -55,6 +55,7 @@ UGLY_CHARS = { log = logging.getLogger(__name__) + class BGExtract(object): """ Extract verses from BibleGateway @@ -671,6 +672,7 @@ class HTTPBible(BibleDB): application = property(_get_application) + def get_soup_for_bible_ref(reference_url, header=None, pre_parse_regex=None, pre_parse_substitute=None, cleaner=None): """ @@ -715,6 +717,7 @@ def get_soup_for_bible_ref(reference_url, header=None, pre_parse_regex=None, Registry().get(u'application').process_events() return soup + def send_error_message(error_type): """ Send a standard error message informing the user of an issue. diff --git a/openlp/plugins/remotes/lib/httpserver.py b/openlp/plugins/remotes/lib/httpserver.py index 51490bb38..0489428ac 100644 --- a/openlp/plugins/remotes/lib/httpserver.py +++ b/openlp/plugins/remotes/lib/httpserver.py @@ -158,12 +158,12 @@ class HttpServer(object): 'tools.auth.on': True } - def __init__(self, plugin): + def __init__(self): """ Initialise the http server, and start the server. """ log.debug(u'Initialise httpserver') - self.plugin = plugin + self.settings_section = u'remotes' self.router = HttpRouter() def start_server(self): @@ -187,17 +187,17 @@ class HttpServer(object): """ Define the configuration of the server. """ - if Settings().value(self.plugin.settings_section + u'/https enabled'): - port = Settings().value(self.plugin.settings_section + u'/https port') - address = Settings().value(self.plugin.settings_section + u'/ip address') + if Settings().value(self.settings_section + u'/https enabled'): + port = Settings().value(self.settings_section + u'/https port') + address = Settings().value(self.settings_section + u'/ip address') local_data = AppLocation.get_directory(AppLocation.DataDir) cherrypy.config.update({u'server.socket_host': str(address), u'server.socket_port': port, u'server.ssl_certificate': os.path.join(local_data, u'remotes', u'openlp.crt'), u'server.ssl_private_key': os.path.join(local_data, u'remotes', u'openlp.key')}) else: - port = Settings().value(self.plugin.settings_section + u'/port') - address = Settings().value(self.plugin.settings_section + u'/ip address') + port = Settings().value(self.settings_section + u'/port') + address = Settings().value(self.settings_section + u'/ip address') cherrypy.config.update({u'server.socket_host': str(address)}) cherrypy.config.update({u'server.socket_port': port}) cherrypy.config.update({u'environment': u'embedded'}) diff --git a/openlp/plugins/remotes/remoteplugin.py b/openlp/plugins/remotes/remoteplugin.py index fd2906feb..f443fbda4 100644 --- a/openlp/plugins/remotes/remoteplugin.py +++ b/openlp/plugins/remotes/remoteplugin.py @@ -67,7 +67,7 @@ class RemotesPlugin(Plugin): """ log.debug(u'initialise') Plugin.initialise(self) - self.server = HttpServer(self) + self.server = HttpServer() self.server.start_server() def finalise(self): diff --git a/tests/functional/openlp_core_lib/test_uistrings.py b/tests/functional/openlp_core_lib/test_uistrings.py index 3351657d1..0070533db 100644 --- a/tests/functional/openlp_core_lib/test_uistrings.py +++ b/tests/functional/openlp_core_lib/test_uistrings.py @@ -6,6 +6,7 @@ from unittest import TestCase from openlp.core.lib import UiStrings + class TestUiStrings(TestCase): def check_same_instance_test(self): diff --git a/tests/interfaces/openlp_plugins/__init__.pyc b/tests/interfaces/openlp_plugins/__init__.pyc deleted file mode 100644 index 0d24c9eff..000000000 Binary files a/tests/interfaces/openlp_plugins/__init__.pyc and /dev/null differ diff --git a/tests/interfaces/openlp_plugins/remotes/test_server.py b/tests/interfaces/openlp_plugins/remotes/test_server.py new file mode 100644 index 000000000..d7ce88010 --- /dev/null +++ b/tests/interfaces/openlp_plugins/remotes/test_server.py @@ -0,0 +1,120 @@ +""" +This module contains tests for the lib submodule of the Remotes plugin. +""" +import os + +from unittest import TestCase +from tempfile import mkstemp +from mock import MagicMock +import urllib2 +import cherrypy + +from BeautifulSoup import BeautifulSoup, NavigableString, Tag + +from openlp.core.lib import Settings +from openlp.plugins.remotes.lib.httpserver import HttpServer, fetch_password, sha_password_encrypter +from PyQt4 import QtGui + +__default_settings__ = { + u'remotes/twelve hour': True, + u'remotes/port': 4316, + u'remotes/https port': 4317, + u'remotes/https enabled': False, + u'remotes/user id': u'openlp', + u'remotes/password': u'password', + u'remotes/authentication enabled': False, + u'remotes/ip address': u'0.0.0.0' +} + + +class TestRouter(TestCase): + """ + Test the functions in the :mod:`lib` module. + """ + def setUp(self): + """ + Create the UI + """ + fd, self.ini_file = mkstemp(u'.ini') + Settings().set_filename(self.ini_file) + self.application = QtGui.QApplication.instance() + Settings().extend_default_settings(__default_settings__) + self.server = HttpServer() + + def tearDown(self): + """ + Delete all the C++ objects at the end so that we don't have a segfault + """ + del self.application + os.unlink(self.ini_file) + self.server.close() + + def start_server(self): + """ + Common function to start server then mock out the router. CherryPy crashes if you mock before you start + """ + self.server.start_server() + self.server.router = MagicMock() + self.server.router.process_http_request = process_http_request + + def start_default_server_test(self): + """ + Test the default server serves the correct initial page + """ + # GIVEN: A default configuration + Settings().setValue(u'remotes/authentication enabled', False) + self.start_server() + + # WHEN: called the route location + code, page = call_remote_server(u'http://localhost:4316') + + # THEN: default title will be returned + self.assertEqual(BeautifulSoup(page).title.text, u'OpenLP 2.1 Remote', + u'The default menu should be returned') + + def start_authenticating_server_test(self): + """ + Test the default server serves the correctly with authentication + """ + # GIVEN: A default authorised configuration + Settings().setValue(u'remotes/authentication enabled', True) + self.start_server() + + # WHEN: called the route location with no user details + code, page = call_remote_server(u'http://localhost:4316') + + # THEN: then server will ask for details + self.assertEqual(code, 401, u'The basic authorisation request should be returned') + + # WHEN: called the route location with user details + code, page = call_remote_server(u'http://localhost:4316', u'openlp', u'password') + + # THEN: default title will be returned + self.assertEqual(BeautifulSoup(page).title.text, u'OpenLP 2.1 Remote', + u'The default menu should be returned') + + # WHEN: called the route location with incorrect user details + code, page = call_remote_server(u'http://localhost:4316', u'itwinkle', u'password') + + # THEN: then server will ask for details + self.assertEqual(code, 401, u'The basic authorisation request should be returned') + + +def call_remote_server(url, username=None, password=None): + if username: + passman = urllib2.HTTPPasswordMgrWithDefaultRealm() + passman.add_password(None, url, username, password) + authhandler = urllib2.HTTPBasicAuthHandler(passman) + opener = urllib2.build_opener(authhandler) + urllib2.install_opener(opener) + try: + page = urllib2.urlopen(url) + return 0, page.read() + except urllib2.HTTPError, e: + return e.code, u'' + + +def process_http_request(url_path, *args): + cherrypy.response.status = 200 + return None +