Fix up tests

This commit is contained in:
Tim Bentley 2013-03-29 09:32:46 +00:00
parent ced77e4ec3
commit 6cd384e028
3 changed files with 63 additions and 121 deletions

View File

@ -127,28 +127,32 @@ from PyQt4 import QtCore
from openlp.core.lib import Registry, Settings, PluginStatus, StringContent
from openlp.core.utils import AppLocation, translate
from cherrypy._cpcompat import md5, sha, ntob
from cherrypy._cpcompat import sha, ntob
log = logging.getLogger(__name__)
def sha_password_encrypter(password):
"""
Create an encrypted password for the given password.
"""
return sha(ntob(password)).hexdigest()
def fetch_password(username):
"""
Fetch the password for a provided user.
"""
if username != Settings().value(u'remotes/user id'):
return None
print "fetch password", username
return sha(ntob(Settings().value(u'remotes/password'))).hexdigest()
return sha_password_encrypter(Settings().value(u'remotes/password'))
class HttpServer(object):
"""
Ability to control OpenLP via a web browser.
This class controls the Cherrypy server and configuration.
"""
_cp_config = {
'tools.sessions.on': True,
'tools.auth.on': True
@ -167,7 +171,7 @@ class HttpServer(object):
Start the http server based on configuration.
"""
log.debug(u'Start CherryPy server')
# Define to security levels and add the router code
# Define to security levels and inject the router code
self.root = self.Public()
self.root.files = self.Files()
self.root.stage = self.Stage()
@ -180,6 +184,9 @@ class HttpServer(object):
cherrypy.engine.start()
def define_config(self):
"""
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')
@ -209,14 +216,12 @@ class HttpServer(object):
u'tools.basic_auth.on': False}}
return directory_config
def reload_config(self):
cherrypy.tree.mount(self.root, '/', config=self.define_config())
cherrypy.config.reset()
class Public:
"""
Main access class with may have security enabled on it.
"""
@cherrypy.expose
def default(self, *args, **kwargs):
print "public"
self.router.request_data = None
if isinstance(kwargs, dict):
self.router.request_data = kwargs.get(u'data', None)
@ -224,13 +229,18 @@ class HttpServer(object):
return self.router.process_http_request(url.path, *args)
class Files:
"""
Provides access to files and has no security available. These are read only accesses
"""
@cherrypy.expose
def default(self, *args, **kwargs):
print "files"
url = urlparse.urlparse(cherrypy.url())
return self.router.process_http_request(url.path, *args)
class Stage:
"""
Stageview is read only so security is not relevant and would reduce it's usability
"""
@cherrypy.expose
def default(self, *args, **kwargs):
url = urlparse.urlparse(cherrypy.url())
@ -246,12 +256,11 @@ class HttpServer(object):
class HttpRouter(object):
"""
A single connection, this handles communication between the server and the client.
This code is called by the HttpServer upon a request and it processes it based on the routing table.
"""
def __init__(self):
"""
Initialise the CherryPy Server
Initialise the router
"""
self.routes = [
(u'^/$', self.serve_file),
@ -275,7 +284,7 @@ class HttpRouter(object):
def process_http_request(self, url_path, *args):
"""
Common function to process HTTP requests where secure or insecure
Common function to process HTTP requests
"""
response = None
for route, func in self.routes:

View File

@ -8,7 +8,7 @@ from tempfile import mkstemp
from mock import patch, MagicMock
from openlp.core.lib import Settings
from openlp.plugins.remotes.lib.httpserver import HttpRouter
from openlp.plugins.remotes.lib.httpserver import HttpRouter, fetch_password, sha_password_encrypter
from PyQt4 import QtGui
__default_settings__ = {
@ -44,6 +44,43 @@ class TestRouter(TestCase):
del self.application
os.unlink(self.ini_file)
def fetch_password_unknown_test(self):
"""
Test the fetch password code with an unknown userid
"""
# GIVEN: A default configuration
# WHEN: called with the defined userid
password = fetch_password(u'itwinkle')
print password
# THEN: the function should return None
self.assertEqual(password, None, u'The result for fetch_password should be None')
def fetch_password_known_test(self):
"""
Test the fetch password code with the defined userid
"""
# GIVEN: A default configuration
# WHEN: called with the defined userid
password = fetch_password(u'openlp')
required_password = sha_password_encrypter(u'password')
# THEN: the function should return the correct password
self.assertEqual(password, required_password, u'The result for fetch_password should be the defined password')
def sha_password_encrypter_test(self):
"""
Test hash password function
"""
# GIVEN: A default configuration
# WHEN: called with the defined userid
required_password = sha_password_encrypter(u'password')
test_value = '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8'
# THEN: the function should return the correct password
self.assertEqual(required_password, test_value,
u'The result for sha_password_encrypter should return the correct encrypted password')
def process_http_request_test(self):
"""
Test the router control functionality
@ -61,22 +98,3 @@ class TestRouter(TestCase):
# THEN: the function should have been called only once
assert mocked_function.call_count == 1, \
u'The mocked function should have been matched and called once.'
#self.assertFalse()
# WHEN: We run the function with no input
#authenticated = check_credentials(u'', u'')
# THEN: The authentication will fail with an error message
#self.assertEqual(authenticated, u'Incorrect username or password.',
# u'The return should be a error message string')
# WHEN: We run the function with the correct input
#authenticated = check_credentials(u'twinkle', u'mongoose')
# THEN: The authentication will pass.
#self.assertEqual(authenticated, None, u'The return should be a None string')

View File

@ -1,85 +0,0 @@
"""
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 patch, MagicMock
import urllib
from BeautifulSoup import BeautifulSoup, NavigableString, Tag
from openlp.core.lib import Settings
from openlp.plugins.remotes.lib import HttpServer
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'
}
SESSION_KEY = '_cp_openlp'
class TestRemoteServer(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(self)
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)
os.unlink(Settings().fileName())
self.server.close()
def check_access_test(self):
"""
Test the Authentication check routine.
"""
# GIVEN: A user and password in settings
Settings().setValue(u'remotes/user id', u'twinkle')
Settings().setValue(u'remotes/password', u'mongoose')
# WHEN: We run the function with no input
authenticated = check_credentials(u'', u'')
# THEN: The authentication will fail with an error message
self.assertEqual(authenticated, u'Incorrect username or password.',
u'The return should be a error message string')
# WHEN: We run the function with the correct input
authenticated = check_credentials(u'twinkle', u'mongoose')
# THEN: The authentication will pass.
self.assertEqual(authenticated, None, u'The return should be a None string')
def check_auth_inactive_test(self):
"""
Test the Authentication check routine.
"""
# GIVEN: A access which is secure
Settings().setValue(u'remotes/authentication enabled', True)
# WHEN: We run the function with no input
f = urllib.urlopen("http://localhost:4316")
soup = BeautifulSoup(f.read())
print soup.title.string