2013-03-30 06:56:28 +00:00
|
|
|
"""
|
|
|
|
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
|
2013-08-31 18:17:38 +00:00
|
|
|
import urllib.request, urllib.error, urllib.parse
|
2013-03-30 06:56:28 +00:00
|
|
|
import cherrypy
|
|
|
|
|
2013-04-08 16:53:11 +00:00
|
|
|
from BeautifulSoup import BeautifulSoup
|
2013-03-30 06:56:28 +00:00
|
|
|
|
|
|
|
from openlp.core.lib import Settings
|
2013-04-08 16:53:11 +00:00
|
|
|
from openlp.plugins.remotes.lib.httpserver import HttpServer
|
2013-03-30 06:56:28 +00:00
|
|
|
from PyQt4 import QtGui
|
|
|
|
|
|
|
|
__default_settings__ = {
|
2013-08-31 18:17:38 +00:00
|
|
|
'remotes/twelve hour': True,
|
|
|
|
'remotes/port': 4316,
|
|
|
|
'remotes/https port': 4317,
|
|
|
|
'remotes/https enabled': False,
|
|
|
|
'remotes/user id': 'openlp',
|
|
|
|
'remotes/password': 'password',
|
|
|
|
'remotes/authentication enabled': False,
|
|
|
|
'remotes/ip address': '0.0.0.0'
|
2013-03-30 06:56:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class TestRouter(TestCase):
|
|
|
|
"""
|
|
|
|
Test the functions in the :mod:`lib` module.
|
|
|
|
"""
|
|
|
|
def setUp(self):
|
|
|
|
"""
|
|
|
|
Create the UI
|
|
|
|
"""
|
2013-08-31 18:17:38 +00:00
|
|
|
fd, self.ini_file = mkstemp('.ini')
|
2013-03-30 06:56:28 +00:00
|
|
|
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
|
2013-08-31 18:17:38 +00:00
|
|
|
Settings().setValue('remotes/authentication enabled', False)
|
2013-03-30 06:56:28 +00:00
|
|
|
self.start_server()
|
|
|
|
|
|
|
|
# WHEN: called the route location
|
2013-08-31 18:17:38 +00:00
|
|
|
code, page = call_remote_server('http://localhost:4316')
|
2013-03-30 06:56:28 +00:00
|
|
|
|
|
|
|
# THEN: default title will be returned
|
2013-08-31 18:17:38 +00:00
|
|
|
self.assertEqual(BeautifulSoup(page).title.text, 'OpenLP 2.1 Remote',
|
|
|
|
'The default menu should be returned')
|
2013-03-30 06:56:28 +00:00
|
|
|
|
|
|
|
def start_authenticating_server_test(self):
|
|
|
|
"""
|
|
|
|
Test the default server serves the correctly with authentication
|
|
|
|
"""
|
|
|
|
# GIVEN: A default authorised configuration
|
2013-08-31 18:17:38 +00:00
|
|
|
Settings().setValue('remotes/authentication enabled', True)
|
2013-03-30 06:56:28 +00:00
|
|
|
self.start_server()
|
|
|
|
|
|
|
|
# WHEN: called the route location with no user details
|
2013-08-31 18:17:38 +00:00
|
|
|
code, page = call_remote_server('http://localhost:4316')
|
2013-03-30 06:56:28 +00:00
|
|
|
|
|
|
|
# THEN: then server will ask for details
|
2013-08-31 18:17:38 +00:00
|
|
|
self.assertEqual(code, 401, 'The basic authorisation request should be returned')
|
2013-03-30 06:56:28 +00:00
|
|
|
|
|
|
|
# WHEN: called the route location with user details
|
2013-08-31 18:17:38 +00:00
|
|
|
code, page = call_remote_server('http://localhost:4316', 'openlp', 'password')
|
2013-03-30 06:56:28 +00:00
|
|
|
|
|
|
|
# THEN: default title will be returned
|
2013-08-31 18:17:38 +00:00
|
|
|
self.assertEqual(BeautifulSoup(page).title.text, 'OpenLP 2.1 Remote',
|
|
|
|
'The default menu should be returned')
|
2013-03-30 06:56:28 +00:00
|
|
|
|
|
|
|
# WHEN: called the route location with incorrect user details
|
2013-08-31 18:17:38 +00:00
|
|
|
code, page = call_remote_server('http://localhost:4316', 'itwinkle', 'password')
|
2013-03-30 06:56:28 +00:00
|
|
|
|
|
|
|
# THEN: then server will ask for details
|
2013-08-31 18:17:38 +00:00
|
|
|
self.assertEqual(code, 401, 'The basic authorisation request should be returned')
|
2013-03-30 06:56:28 +00:00
|
|
|
|
|
|
|
|
|
|
|
def call_remote_server(url, username=None, password=None):
|
2013-04-14 15:59:57 +00:00
|
|
|
"""
|
|
|
|
Helper function
|
|
|
|
|
|
|
|
``username``
|
|
|
|
The username.
|
|
|
|
|
|
|
|
``password``
|
|
|
|
The password.
|
|
|
|
"""
|
2013-03-30 06:56:28 +00:00
|
|
|
if username:
|
2013-08-31 18:17:38 +00:00
|
|
|
passman = urllib.request.HTTPPasswordMgrWithDefaultRealm()
|
2013-03-30 06:56:28 +00:00
|
|
|
passman.add_password(None, url, username, password)
|
2013-08-31 18:17:38 +00:00
|
|
|
authhandler = urllib.request.HTTPBasicAuthHandler(passman)
|
|
|
|
opener = urllib.request.build_opener(authhandler)
|
|
|
|
urllib.request.install_opener(opener)
|
2013-03-30 06:56:28 +00:00
|
|
|
try:
|
2013-08-31 18:17:38 +00:00
|
|
|
page = urllib.request.urlopen(url)
|
2013-03-30 06:56:28 +00:00
|
|
|
return 0, page.read()
|
2013-08-31 18:17:38 +00:00
|
|
|
except urllib.error.HTTPError as e:
|
|
|
|
return e.code, ''
|
2013-03-30 06:56:28 +00:00
|
|
|
|
|
|
|
|
|
|
|
def process_http_request(url_path, *args):
|
2013-04-14 15:59:57 +00:00
|
|
|
"""
|
|
|
|
Override function to make the Mock work but does nothing.
|
|
|
|
|
|
|
|
``Url_path``
|
|
|
|
The url_path.
|
|
|
|
|
|
|
|
``*args``
|
|
|
|
Some args.
|
|
|
|
"""
|
2013-03-30 06:56:28 +00:00
|
|
|
cherrypy.response.status = 200
|
|
|
|
return None
|
|
|
|
|