forked from openlp/openlp
Fix the Http router return values
bzr-revno: 2313
This commit is contained in:
commit
e9848a2653
@ -128,6 +128,15 @@ from openlp.core.common import AppLocation, Settings, translate
|
|||||||
from openlp.core.lib import Registry, PluginStatus, StringContent, image_to_byte
|
from openlp.core.lib import Registry, PluginStatus, StringContent, image_to_byte
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
FILE_TYPES = {
|
||||||
|
'.html': 'text/html',
|
||||||
|
'.css': 'text/css',
|
||||||
|
'.js': 'application/javascript',
|
||||||
|
'.jpg': 'image/jpeg',
|
||||||
|
'.gif': 'image/gif',
|
||||||
|
'.ico': 'image/x-icon',
|
||||||
|
'.png': 'image/png'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class HttpRouter(object):
|
class HttpRouter(object):
|
||||||
@ -346,30 +355,13 @@ class HttpRouter(object):
|
|||||||
path = os.path.normpath(os.path.join(self.html_dir, file_name))
|
path = os.path.normpath(os.path.join(self.html_dir, file_name))
|
||||||
if not path.startswith(self.html_dir):
|
if not path.startswith(self.html_dir):
|
||||||
return self.do_not_found()
|
return self.do_not_found()
|
||||||
ext = os.path.splitext(file_name)[1]
|
content = None
|
||||||
html = None
|
ext, content_type = self.get_content_type(path)
|
||||||
if ext == '.html':
|
|
||||||
self.send_header('Content-type', 'text/html')
|
|
||||||
variables = self.template_vars
|
|
||||||
html = Template(filename=path, input_encoding='utf-8', output_encoding='utf-8').render(**variables)
|
|
||||||
elif ext == '.css':
|
|
||||||
self.send_header('Content-type', 'text/css')
|
|
||||||
elif ext == '.js':
|
|
||||||
self.send_header('Content-type', 'application/javascript')
|
|
||||||
elif ext == '.jpg':
|
|
||||||
self.send_header('Content-type', 'image/jpeg')
|
|
||||||
elif ext == '.gif':
|
|
||||||
self.send_header('Content-type', 'image/gif')
|
|
||||||
elif ext == '.ico':
|
|
||||||
self.send_header('Content-type', 'image/x-icon')
|
|
||||||
elif ext == '.png':
|
|
||||||
self.send_header('Content-type', 'image/png')
|
|
||||||
else:
|
|
||||||
self.send_header('Content-type', 'text/plain')
|
|
||||||
file_handle = None
|
file_handle = None
|
||||||
try:
|
try:
|
||||||
if html:
|
if ext == '.html':
|
||||||
content = html
|
variables = self.template_vars
|
||||||
|
content = Template(filename=path, input_encoding='utf-8', output_encoding='utf-8').render(**variables)
|
||||||
else:
|
else:
|
||||||
file_handle = open(path, 'rb')
|
file_handle = open(path, 'rb')
|
||||||
log.debug('Opened %s' % path)
|
log.debug('Opened %s' % path)
|
||||||
@ -380,8 +372,22 @@ class HttpRouter(object):
|
|||||||
finally:
|
finally:
|
||||||
if file_handle:
|
if file_handle:
|
||||||
file_handle.close()
|
file_handle.close()
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header('Content-type', content_type)
|
||||||
|
self.end_headers()
|
||||||
return content
|
return content
|
||||||
|
|
||||||
|
def get_content_type(self, file_name):
|
||||||
|
"""
|
||||||
|
Examines the extension of the file and determines
|
||||||
|
what the content_type should be, defaults to text/plain
|
||||||
|
Returns the extension and the content_type
|
||||||
|
"""
|
||||||
|
content_type = 'text/plain'
|
||||||
|
ext = os.path.splitext(file_name)[1]
|
||||||
|
content_type = FILE_TYPES.get(ext, 'text/plain')
|
||||||
|
return ext, content_type
|
||||||
|
|
||||||
def poll(self):
|
def poll(self):
|
||||||
"""
|
"""
|
||||||
Poll OpenLP to determine the current slide number and item name.
|
Poll OpenLP to determine the current slide number and item name.
|
||||||
|
@ -62,7 +62,7 @@ class TestRemoteTab(TestCase):
|
|||||||
"""
|
"""
|
||||||
Create the UI
|
Create the UI
|
||||||
"""
|
"""
|
||||||
fd, self.ini_file = mkstemp('.ini')
|
self.fd, self.ini_file = mkstemp('.ini')
|
||||||
Settings().set_filename(self.ini_file)
|
Settings().set_filename(self.ini_file)
|
||||||
self.application = QtGui.QApplication.instance()
|
self.application = QtGui.QApplication.instance()
|
||||||
Settings().extend_default_settings(__default_settings__)
|
Settings().extend_default_settings(__default_settings__)
|
||||||
@ -76,6 +76,7 @@ class TestRemoteTab(TestCase):
|
|||||||
del self.application
|
del self.application
|
||||||
del self.parent
|
del self.parent
|
||||||
del self.form
|
del self.form
|
||||||
|
os.close(self.fd)
|
||||||
os.unlink(self.ini_file)
|
os.unlink(self.ini_file)
|
||||||
|
|
||||||
def get_ip_address_default_test(self):
|
def get_ip_address_default_test(self):
|
||||||
|
@ -37,7 +37,8 @@ from PyQt4 import QtGui
|
|||||||
|
|
||||||
from openlp.core.common import Settings
|
from openlp.core.common import Settings
|
||||||
from openlp.plugins.remotes.lib.httpserver import HttpRouter
|
from openlp.plugins.remotes.lib.httpserver import HttpRouter
|
||||||
from tests.functional import MagicMock
|
from tests.functional import MagicMock, patch
|
||||||
|
from mock import mock_open
|
||||||
|
|
||||||
__default_settings__ = {
|
__default_settings__ = {
|
||||||
'remotes/twelve hour': True,
|
'remotes/twelve hour': True,
|
||||||
@ -50,6 +51,7 @@ __default_settings__ = {
|
|||||||
'remotes/ip address': '0.0.0.0'
|
'remotes/ip address': '0.0.0.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_PATH = os.path.abspath(os.path.dirname(__file__))
|
||||||
|
|
||||||
class TestRouter(TestCase):
|
class TestRouter(TestCase):
|
||||||
"""
|
"""
|
||||||
@ -59,7 +61,7 @@ class TestRouter(TestCase):
|
|||||||
"""
|
"""
|
||||||
Create the UI
|
Create the UI
|
||||||
"""
|
"""
|
||||||
fd, self.ini_file = mkstemp('.ini')
|
self.fd, self.ini_file = mkstemp('.ini')
|
||||||
Settings().set_filename(self.ini_file)
|
Settings().set_filename(self.ini_file)
|
||||||
self.application = QtGui.QApplication.instance()
|
self.application = QtGui.QApplication.instance()
|
||||||
Settings().extend_default_settings(__default_settings__)
|
Settings().extend_default_settings(__default_settings__)
|
||||||
@ -70,6 +72,7 @@ class TestRouter(TestCase):
|
|||||||
Delete all the C++ objects at the end so that we don't have a segfault
|
Delete all the C++ objects at the end so that we don't have a segfault
|
||||||
"""
|
"""
|
||||||
del self.application
|
del self.application
|
||||||
|
os.close(self.fd)
|
||||||
os.unlink(self.ini_file)
|
os.unlink(self.ini_file)
|
||||||
|
|
||||||
def password_encrypter_test(self):
|
def password_encrypter_test(self):
|
||||||
@ -110,3 +113,62 @@ class TestRouter(TestCase):
|
|||||||
'The mocked function should match defined value.'
|
'The mocked function should match defined value.'
|
||||||
assert function['secure'] == False, \
|
assert function['secure'] == False, \
|
||||||
'The mocked function should not require any security.'
|
'The mocked function should not require any security.'
|
||||||
|
|
||||||
|
def get_content_type_test(self):
|
||||||
|
"""
|
||||||
|
Test the get_content_type logic
|
||||||
|
"""
|
||||||
|
# GIVEN: a set of files and their corresponding types
|
||||||
|
headers = [ ['test.html', 'text/html'], ['test.css', 'text/css'],
|
||||||
|
['test.js', 'application/javascript'], ['test.jpg', 'image/jpeg'],
|
||||||
|
['test.gif', 'image/gif'], ['test.ico', 'image/x-icon'],
|
||||||
|
['test.png', 'image/png'], ['test.whatever', 'text/plain'],
|
||||||
|
['test', 'text/plain'], ['', 'text/plain'],
|
||||||
|
[os.path.join(TEST_PATH,'test.html'), 'text/html']]
|
||||||
|
# WHEN: calling each file type
|
||||||
|
for header in headers:
|
||||||
|
ext, content_type = self.router.get_content_type(header[0])
|
||||||
|
# THEN: all types should match
|
||||||
|
self.assertEqual(content_type, header[1], 'Mismatch of content type')
|
||||||
|
|
||||||
|
def serve_file_without_params_test(self):
|
||||||
|
"""
|
||||||
|
Test the serve_file method without params
|
||||||
|
"""
|
||||||
|
# GIVEN: mocked environment
|
||||||
|
self.router.send_response = MagicMock()
|
||||||
|
self.router.send_header = MagicMock()
|
||||||
|
self.router.end_headers = MagicMock()
|
||||||
|
self.router.wfile = MagicMock()
|
||||||
|
self.router.html_dir = os.path.normpath('test/dir')
|
||||||
|
self.router.template_vars = MagicMock()
|
||||||
|
# WHEN: call serve_file with no file_name
|
||||||
|
self.router.serve_file()
|
||||||
|
# THEN: it should return a 404
|
||||||
|
self.router.send_response.assert_called_once_with(404)
|
||||||
|
self.router.send_header.assert_called_once_with('Content-type','text/html')
|
||||||
|
self.assertEqual(self.router.end_headers.call_count, 1,
|
||||||
|
'end_headers called once')
|
||||||
|
|
||||||
|
def serve_file_with_valid_params_test(self):
|
||||||
|
"""
|
||||||
|
Test the serve_file method with an existing file
|
||||||
|
"""
|
||||||
|
# GIVEN: mocked environment
|
||||||
|
self.router.send_response = MagicMock()
|
||||||
|
self.router.send_header = MagicMock()
|
||||||
|
self.router.end_headers = MagicMock()
|
||||||
|
self.router.wfile = MagicMock()
|
||||||
|
self.router.html_dir = os.path.normpath('test/dir')
|
||||||
|
self.router.template_vars = MagicMock()
|
||||||
|
with patch('openlp.core.lib.os.path.exists') as mocked_exists, \
|
||||||
|
patch('builtins.open', mock_open(read_data='123')):
|
||||||
|
mocked_exists.return_value = True
|
||||||
|
# WHEN: call serve_file with an existing html file
|
||||||
|
self.router.serve_file(os.path.normpath('test/dir/test.html'))
|
||||||
|
# THEN: it should return a 200 and the file
|
||||||
|
self.router.send_response.assert_called_once_with(200)
|
||||||
|
self.router.send_header.assert_called_once_with(
|
||||||
|
'Content-type','text/html')
|
||||||
|
self.assertEqual(self.router.end_headers.call_count, 1,
|
||||||
|
'end_headers called once')
|
||||||
|
Loading…
Reference in New Issue
Block a user