From 6c6600c37b2a61d652aeebe3ae0f6cfcde26e44d Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sat, 21 Jun 2014 16:21:39 +0200 Subject: [PATCH 1/2] http: Group HTTP server tests --- tests/http/test_server.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/tests/http/test_server.py b/tests/http/test_server.py index 25373812..1e645025 100644 --- a/tests/http/test_server.py +++ b/tests/http/test_server.py @@ -33,7 +33,9 @@ class HttpServerTest(tornado.testing.AsyncHTTPTestCase): return tornado.web.Application(http_frontend._get_request_handlers()) - def test_root_should_return_index(self): + +class RootAppTest(HttpServerTest): + def test_should_return_index(self): response = self.fetch('/', method='GET') self.assertIn( @@ -43,7 +45,9 @@ class HttpServerTest(tornado.testing.AsyncHTTPTestCase): response.headers['X-Mopidy-Version'], mopidy.__version__) self.assertEqual(response.headers['Cache-Control'], 'no-cache') - def test_mopidy_should_return_index(self): + +class MopidyAppTest(HttpServerTest): + def test_should_return_index(self): response = self.fetch('/mopidy/', method='GET') self.assertIn( @@ -53,7 +57,7 @@ class HttpServerTest(tornado.testing.AsyncHTTPTestCase): response.headers['X-Mopidy-Version'], mopidy.__version__) self.assertEqual(response.headers['Cache-Control'], 'no-cache') - def test_mopidy_should_return_index_no_slash(self): + def test_without_slash_should_return_index(self): response = self.fetch('/mopidy', method='GET') self.assertIn( @@ -63,7 +67,7 @@ class HttpServerTest(tornado.testing.AsyncHTTPTestCase): response.headers['X-Mopidy-Version'], mopidy.__version__) self.assertEqual(response.headers['Cache-Control'], 'no-cache') - def test_should_return_js(self): + def test_should_return_static_files(self): response = self.fetch('/mopidy/mopidy.js', method='GET') self.assertIn( @@ -73,6 +77,8 @@ class HttpServerTest(tornado.testing.AsyncHTTPTestCase): response.headers['X-Mopidy-Version'], mopidy.__version__) self.assertEqual(response.headers['Cache-Control'], 'no-cache') + +class MopidyWebSocketHandlerTest(HttpServerTest): def test_should_return_ws(self): response = self.fetch('/mopidy/ws', method='GET') @@ -87,6 +93,8 @@ class HttpServerTest(tornado.testing.AsyncHTTPTestCase): 'Can "Upgrade" only to "WebSocket".', tornado.escape.to_unicode(response.body)) + +class MopidyRPCHandlerTest(HttpServerTest): def test_should_return_rpc_error(self): cmd = tornado.escape.json_encode({'action': 'get_version'}) From fbcc73004d5d7e613ef725c9366b2545c7263031 Mon Sep 17 00:00:00 2001 From: Stein Magnus Jodal Date: Sat, 21 Jun 2014 16:36:16 +0200 Subject: [PATCH 2/2] http: Redirect from /app to /app/ --- mopidy/http/actor.py | 10 +++++++++- mopidy/http/handlers.py | 9 ++++++++- tests/http/test_server.py | 34 +++++++++++++++++++++++++--------- 3 files changed, 42 insertions(+), 11 deletions(-) diff --git a/mopidy/http/actor.py b/mopidy/http/actor.py index eee09ffe..3ab0a480 100644 --- a/mopidy/http/actor.py +++ b/mopidy/http/actor.py @@ -84,6 +84,10 @@ class HttpFrontend(pykka.ThreadingActor, CoreListener): def _get_app_request_handlers(self): result = [] for app in self.apps: + result.append(( + r'/%s' % app['name'], + handlers.AddSlashHandler + )) request_handlers = app['factory'](self.config, self.core) for handler in request_handlers: handler = list(handler) @@ -96,7 +100,11 @@ class HttpFrontend(pykka.ThreadingActor, CoreListener): result = [] for static in self.statics: result.append(( - r'/%s/?(.*)' % static['name'], + r'/%s' % static['name'], + handlers.AddSlashHandler + )) + result.append(( + r'/%s/(.*)' % static['name'], handlers.StaticFileHandler, { 'path': static['path'], diff --git a/mopidy/http/handlers.py b/mopidy/http/handlers.py index 91cc69d9..5911fe09 100644 --- a/mopidy/http/handlers.py +++ b/mopidy/http/handlers.py @@ -23,7 +23,7 @@ def mopidy_app_factory(config, core): (r'/rpc', JsonRpcHandler, { 'core': core, }), - (r'/?(.*)', StaticFileHandler, { + (r'/(.*)', StaticFileHandler, { 'path': os.path.join(os.path.dirname(__file__), 'data'), 'default_filename': 'mopidy.html' }), @@ -143,3 +143,10 @@ class StaticFileHandler(tornado.web.StaticFileHandler): self.set_header('Cache-Control', 'no-cache') self.set_header( 'X-Mopidy-Version', mopidy.__version__.encode('utf-8')) + + +class AddSlashHandler(tornado.web.RequestHandler): + + @tornado.web.addslash + def prepare(self): + return super(AddSlashHandler, self).prepare() diff --git a/tests/http/test_server.py b/tests/http/test_server.py index 1e645025..5f3495a5 100644 --- a/tests/http/test_server.py +++ b/tests/http/test_server.py @@ -45,6 +45,14 @@ class RootAppTest(HttpServerTest): response.headers['X-Mopidy-Version'], mopidy.__version__) self.assertEqual(response.headers['Cache-Control'], 'no-cache') + def test_should_return_static_files(self): + response = self.fetch('/mopidy.css', method='GET') + + self.assertIn('html {', tornado.escape.to_unicode(response.body)) + self.assertEqual( + response.headers['X-Mopidy-Version'], mopidy.__version__) + self.assertEqual(response.headers['Cache-Control'], 'no-cache') + class MopidyAppTest(HttpServerTest): def test_should_return_index(self): @@ -57,15 +65,11 @@ class MopidyAppTest(HttpServerTest): response.headers['X-Mopidy-Version'], mopidy.__version__) self.assertEqual(response.headers['Cache-Control'], 'no-cache') - def test_without_slash_should_return_index(self): - response = self.fetch('/mopidy', method='GET') + def test_without_slash_should_redirect(self): + response = self.fetch('/mopidy', method='GET', follow_redirects=False) - self.assertIn( - 'Here you can see events arriving from Mopidy in real time:', - tornado.escape.to_unicode(response.body)) - self.assertEqual( - response.headers['X-Mopidy-Version'], mopidy.__version__) - self.assertEqual(response.headers['Cache-Control'], 'no-cache') + self.assertEqual(response.code, 301) + self.assertEqual(response.headers['Location'], '/mopidy/') def test_should_return_static_files(self): response = self.fetch('/mopidy/mopidy.js', method='GET') @@ -158,6 +162,12 @@ class HttpServerWithStaticFilesTest(tornado.testing.AsyncHTTPTestCase): return tornado.web.Application(http_frontend._get_request_handlers()) + def test_without_slash_should_redirect(self): + response = self.fetch('/static', method='GET', follow_redirects=False) + + self.assertEqual(response.code, 301) + self.assertEqual(response.headers['Location'], '/static/') + def test_can_serve_static_files(self): response = self.fetch('/static/test_server.py', method='GET') @@ -203,8 +213,14 @@ class HttpServerWithWsgiAppTest(tornado.testing.AsyncHTTPTestCase): return tornado.web.Application(http_frontend._get_request_handlers()) + def test_without_slash_should_redirect(self): + response = self.fetch('/wsgi', method='GET', follow_redirects=False) + + self.assertEqual(response.code, 301) + self.assertEqual(response.headers['Location'], '/wsgi/') + def test_can_wrap_wsgi_apps(self): - response = self.fetch('/wsgi', method='GET') + response = self.fetch('/wsgi/', method='GET') self.assertEqual(200, response.code) self.assertIn(