From cfdddc4469144e3fffd04ab68577a71aad44921a Mon Sep 17 00:00:00 2001 From: bendikro Date: Wed, 19 Oct 2016 10:07:18 +0200 Subject: [PATCH] [Web][Tests] Refactor web tests --- deluge/tests/common.py | 13 +++++ deluge/tests/common_web.py | 96 ++++++++++++++++++++++++++++++++++ deluge/tests/test_json_api.py | 20 +++---- deluge/tests/test_ui_common.py | 9 +++- deluge/tests/test_web_api.py | 38 +------------- 5 files changed, 125 insertions(+), 51 deletions(-) create mode 100644 deluge/tests/common_web.py diff --git a/deluge/tests/common.py b/deluge/tests/common.py index 61567212d..0254125b1 100644 --- a/deluge/tests/common.py +++ b/deluge/tests/common.py @@ -1,3 +1,12 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2016 bendikro +# +# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with +# the additional special exception to link portions of this program with the OpenSSL library. +# See LICENSE for more details. +# + import os import sys import tempfile @@ -32,6 +41,10 @@ def setup_test_logger(level="info", prefix="deluge"): deluge.log.setup_logger(level, filename="%s.log" % prefix, twisted_observer=False) +def get_test_data_file(filename): + return os.path.join(os.path.join(os.path.dirname(__file__), "data"), filename) + + def todo_test(caller): # If we are using the delugereporter we can set todo mark on the test # Without the delugereporter the todo would print a stack trace, so in diff --git a/deluge/tests/common_web.py b/deluge/tests/common_web.py new file mode 100644 index 000000000..1c6b19c37 --- /dev/null +++ b/deluge/tests/common_web.py @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2016 bendikro +# +# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with +# the additional special exception to link portions of this program with the OpenSSL library. +# See LICENSE for more details. +# + +from twisted.internet import reactor + +import deluge.common +import deluge.component as component +import deluge.ui.web.auth +import deluge.ui.web.server +from deluge import configmanager +from deluge.ui.web.server import DelugeWeb + +from .basetest import BaseTestCase +from .daemon_base import DaemonBase + + +class ReactorOverride(object): + """ + Class used to to mock the reactor + + During unit tests, the reactor must not be touched, so for code that + explicitly calls the reactor, we use a mock. + + """ + def __getattr__(self, attr): + if attr == "run": + return self._run + if attr == "stop": + return self._stop + return getattr(reactor, attr) + + def _run(self): + pass + + def _stop(self): + pass + + +class WebServerTestBase(BaseTestCase, DaemonBase): + """ + Base class for tests that need a running webapi + + """ + def set_up(self): + self.host_id = None + deluge.ui.web.server.reactor = ReactorOverride() + d = self.common_set_up() + d.addCallback(self.start_core) + d.addCallback(self.start_webapi) + return d + + def start_webapi(self, arg): + self.webserver_listen_port = 8999 + + config_defaults = deluge.ui.web.server.CONFIG_DEFAULTS.copy() + config_defaults["port"] = self.webserver_listen_port + self.config = configmanager.ConfigManager("web.conf", config_defaults) + + self.deluge_web = DelugeWeb(daemon=False) + + host = list(self.deluge_web.web_api.host_list["hosts"][0]) + host[2] = self.listen_port + self.deluge_web.web_api.host_list["hosts"][0] = tuple(host) + self.host_id = host[0] + self.deluge_web.start() + + def tear_down(self): + d = component.shutdown() + d.addCallback(self.terminate_core) + return d + + +class WebServerMockBase(object): + """ + Class with utility functions for mocking with tests using the webserver + + """ + def mock_authentication_ignore(self, auth): + + def check_request(request, method=None, level=None): + pass + + self.patch(auth, "check_request", check_request) + + def mock_compress_body(self): + + def compress(contents, request): + return contents + # Patch compress to avoid having to decompress output with zlib + self.patch(deluge.ui.web.json_api, "compress", compress) diff --git a/deluge/tests/test_json_api.py b/deluge/tests/test_json_api.py index ba03c056f..87c6f89e7 100644 --- a/deluge/tests/test_json_api.py +++ b/deluge/tests/test_json_api.py @@ -25,6 +25,7 @@ from deluge.ui.web.json_api import JSON, JSONException from . import common from .basetest import BaseTestCase +from .common_web import WebServerMockBase from .daemon_base import DaemonBase common.disable_new_release_check() @@ -186,7 +187,7 @@ class RPCRaiseDelugeErrorJSONTestCase(JSONBase): yield result -class JSONRequestFailedTestCase(JSONBase): +class JSONRequestFailedTestCase(JSONBase, WebServerMockBase): def set_up(self): d = self.common_set_up() @@ -225,25 +226,16 @@ class JSONRequestFailedTestCase(JSONBase): def test_render_on_rpc_request_failed(self): json = JSON() - def get_session_id(s_id): - return s_id - self.patch(deluge.ui.web.auth, "get_session_id", get_session_id) - auth_conf = {"session_timeout": 10, "sessions": []} - auth = Auth(auth_conf) - request = Request(MagicMock(), False) - request.base = "" - auth._create_session(request) methods = yield json.get_remote_methods() # Verify the function has been registered self.assertTrue("testclass.test" in methods) request = MagicMock() - request.getCookie = MagicMock(return_value=auth.config["sessions"].keys()[0]) - def compress(contents, request): - return contents - # Patch compress to avoid having to decompress output - self.patch(deluge.ui.web.json_api, "compress", compress) + # Circumvent authentication + auth = Auth({}) + self.mock_authentication_ignore(auth) + self.mock_compress_body() def write(response_str): request.write_was_called = True diff --git a/deluge/tests/test_ui_common.py b/deluge/tests/test_ui_common.py index 09f2c940c..55541e82b 100644 --- a/deluge/tests/test_ui_common.py +++ b/deluge/tests/test_ui_common.py @@ -1,5 +1,11 @@ # -*- coding: utf-8 -*- - +# +# Copyright (C) 2016 bendikro +# +# This file is part of Deluge and is licensed under GNU General Public License 3.0, or later, with +# the additional special exception to link portions of this program with the OpenSSL library. +# See LICENSE for more details. +# from twisted.trial import unittest from deluge.ui.common import TorrentInfo @@ -8,6 +14,7 @@ from . import common class UICommonTestCase(unittest.TestCase): + def setUp(self): # NOQA pass diff --git a/deluge/tests/test_web_api.py b/deluge/tests/test_web_api.py index 18c03193e..a2cc54bd0 100644 --- a/deluge/tests/test_web_api.py +++ b/deluge/tests/test_web_api.py @@ -15,50 +15,16 @@ from twisted.web.client import Agent, FileBodyProducer from twisted.web.http_headers import Headers from twisted.web.static import File -import deluge.common import deluge.component as component -import deluge.ui.web.auth -import deluge.ui.web.server -from deluge import configmanager from deluge.ui.client import client -from deluge.ui.web.server import DelugeWeb from . import common -from .basetest import BaseTestCase -from .daemon_base import DaemonBase +from .common_web import WebServerTestBase common.disable_new_release_check() -class WebAPITestCase(BaseTestCase, DaemonBase): - - def set_up(self): - self.host_id = None - deluge.ui.web.server.reactor = common.ReactorOverride() - d = self.common_set_up() - d.addCallback(self.start_core) - d.addCallback(self.start_webapi) - return d - - def start_webapi(self, arg): - self.webserver_listen_port = 8999 - - config_defaults = deluge.ui.web.server.CONFIG_DEFAULTS.copy() - config_defaults["port"] = self.webserver_listen_port - self.config = configmanager.ConfigManager("web.conf", config_defaults) - - self.deluge_web = DelugeWeb(daemon=False) - - host = list(self.deluge_web.web_api.host_list["hosts"][0]) - host[2] = self.listen_port - self.deluge_web.web_api.host_list["hosts"][0] = tuple(host) - self.host_id = host[0] - self.deluge_web.start() - - def tear_down(self): - d = component.shutdown() - d.addCallback(self.terminate_core) - return d +class WebAPITestCase(WebServerTestBase): def test_connect_invalid_host(self): d = self.deluge_web.web_api.connect("id")