diff --git a/rhodecode/tests/__init__.py b/rhodecode/tests/__init__.py --- a/rhodecode/tests/__init__.py +++ b/rhodecode/tests/__init__.py @@ -38,7 +38,6 @@ from pylons.i18n.translation import _get from pylons.util import ContextObj from routes.util import URLGenerator -from webtest import TestApp from nose.plugins.skip import SkipTest import pytest diff --git a/rhodecode/tests/lib/middleware/test_csrf.py b/rhodecode/tests/lib/middleware/test_csrf.py --- a/rhodecode/tests/lib/middleware/test_csrf.py +++ b/rhodecode/tests/lib/middleware/test_csrf.py @@ -21,15 +21,15 @@ import wsgiref.simple_server import pytest -import webtest +from rhodecode.tests.utils import CustomTestApp from rhodecode.lib.middleware import csrf def test_origin_checker_no_origin(): app = csrf.OriginChecker( wsgiref.simple_server.demo_app, 'https://safe.org') - app = webtest.TestApp(app) + app = CustomTestApp(app) app.post('/foo') @@ -37,7 +37,7 @@ def test_origin_checker_no_origin(): def test_origin_checker_null_origin(): app = csrf.OriginChecker( wsgiref.simple_server.demo_app, 'https://safe.org') - app = webtest.TestApp(app) + app = CustomTestApp(app) app.post('/foo', headers={'Origin': 'null'}) @@ -50,7 +50,7 @@ def test_origin_checker_null_origin(): def test_origin_checker_valid_origin(origin): app = csrf.OriginChecker( wsgiref.simple_server.demo_app, 'http://safe.org') - app = webtest.TestApp(app) + app = CustomTestApp(app) app.post('/foo', headers={'Origin': origin}) @@ -63,7 +63,7 @@ def test_origin_checker_valid_origin(ori def test_origin_checker_valid_origin_https(origin): app = csrf.OriginChecker( wsgiref.simple_server.demo_app, 'https://safe.org') - app = webtest.TestApp(app) + app = CustomTestApp(app) app.post('/foo', headers={'Origin': origin}) @@ -76,7 +76,7 @@ def test_origin_checker_valid_origin_htt def test_origin_checker_invalid_origin(origin): app = csrf.OriginChecker( wsgiref.simple_server.demo_app, 'https://safe.org') - app = webtest.TestApp(app) + app = CustomTestApp(app) app.post('/foo', headers={'Origin': origin}, status=403) @@ -84,6 +84,6 @@ def test_origin_checker_invalid_origin(o def test_origin_checker_invalid_origin_skipped_url(): app = csrf.OriginChecker( wsgiref.simple_server.demo_app, 'https://safe.org', skip_urls=['/foo']) - app = webtest.TestApp(app) + app = CustomTestApp(app) app.post('/foo', headers={'Origin': 'http://www.evil.org'}) diff --git a/rhodecode/tests/lib/middleware/test_simplevcs.py b/rhodecode/tests/lib/middleware/test_simplevcs.py --- a/rhodecode/tests/lib/middleware/test_simplevcs.py +++ b/rhodecode/tests/lib/middleware/test_simplevcs.py @@ -22,7 +22,8 @@ import base64 import mock import pytest -import webtest.app + +from rhodecode.tests.utils import CustomTestApp from rhodecode.lib.caching_query import FromCache from rhodecode.lib.hooks_daemon import DummyHooksCallbackDaemon @@ -72,7 +73,7 @@ def vcscontroller(pylonsapp, config_stub set_anonymous_access(True) controller = StubVCSController(pylonsapp, pylonsapp.config, None) app = HttpsFixup(controller, pylonsapp.config) - app = webtest.app.TestApp(app) + app = CustomTestApp(app) _remove_default_user_from_query_cache() @@ -137,7 +138,7 @@ class StubFailVCSController(simplevcs.Si def fail_controller(pylonsapp): controller = StubFailVCSController(pylonsapp, pylonsapp.config, None) controller = HttpsFixup(controller, pylonsapp.config) - controller = webtest.app.TestApp(controller) + controller = CustomTestApp(controller) return controller diff --git a/rhodecode/tests/lib/middleware/utils/test_scm_app_http.py b/rhodecode/tests/lib/middleware/utils/test_scm_app_http.py --- a/rhodecode/tests/lib/middleware/utils/test_scm_app_http.py +++ b/rhodecode/tests/lib/middleware/utils/test_scm_app_http.py @@ -21,8 +21,8 @@ import mock import Pyro4 import pytest -import webtest +from rhodecode.tests.utils import CustomTestApp from rhodecode.lib.middleware.utils import scm_app_http, scm_app from rhodecode.lib.vcs.conf import settings @@ -34,7 +34,7 @@ def vcs_http_app(vcsserver_http_echo_app git_url = vcsserver_http_echo_app.http_url + 'stream/git/' vcs_http_proxy = scm_app_http.VcsHttpProxy( git_url, 'stub_path', 'stub_name', None) - app = webtest.TestApp(vcs_http_proxy) + app = CustomTestApp(vcs_http_proxy) return app @@ -112,7 +112,7 @@ def vcs_pyro4_app(vcsserver_pyro_echo_ap GIT_REMOTE_WSGI): pyro4_app = scm_app.create_git_wsgi_app( 'stub_path', 'stub_name', stub_config) - app = webtest.TestApp(pyro4_app) + app = CustomTestApp(pyro4_app) return app diff --git a/rhodecode/tests/lib/middleware/utils/test_wsgi_app_caller_client.py b/rhodecode/tests/lib/middleware/utils/test_wsgi_app_caller_client.py --- a/rhodecode/tests/lib/middleware/utils/test_wsgi_app_caller_client.py +++ b/rhodecode/tests/lib/middleware/utils/test_wsgi_app_caller_client.py @@ -18,8 +18,7 @@ # RhodeCode Enterprise Edition, including its added features, Support services, # and proprietary license terms, please see https://rhodecode.com/licenses/ -import webtest - +from rhodecode.tests.utils import CustomTestApp from rhodecode.lib.middleware.utils import wsgi_app_caller_client # pylint: disable=protected-access,too-many-public-methods @@ -88,7 +87,7 @@ def test_remote_app_caller(): wrapper_app = wsgi_app_caller_client.RemoteAppCaller( RemoteAppCallerMock(), 'a1', 'a2', arg3='a3', arg4='a4') - test_app = webtest.TestApp(wrapper_app) + test_app = CustomTestApp(wrapper_app) response = test_app.get('/path') diff --git a/rhodecode/tests/plugin.py b/rhodecode/tests/plugin.py --- a/rhodecode/tests/plugin.py +++ b/rhodecode/tests/plugin.py @@ -35,7 +35,6 @@ import pyramid.testing import pytest import colander import requests -from webtest.app import TestApp import rhodecode from rhodecode.lib.utils2 import AttributeDict @@ -62,6 +61,7 @@ from rhodecode.tests import ( login_user_session, get_new_dir, utils, TESTS_TMP_PATH, TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR2_LOGIN, TEST_USER_REGULAR_PASS) +from rhodecode.tests.utils import CustomTestApp from rhodecode.tests.fixture import Fixture @@ -211,7 +211,9 @@ def http_environ(http_host_stub): @pytest.fixture(scope='function') def app(request, pylonsapp, http_environ): - app = TestApp( + + + app = CustomTestApp( pylonsapp, extra_environ=http_environ) if request.cls: diff --git a/rhodecode/tests/utils.py b/rhodecode/tests/utils.py --- a/rhodecode/tests/utils.py +++ b/rhodecode/tests/utils.py @@ -23,14 +23,18 @@ import time import logging import os.path import subprocess32 +import tempfile import urllib2 from urlparse import urlparse, parse_qsl from urllib import unquote_plus +from webtest.app import ( + Request, TestResponse, TestApp, print_stderr, string_types) + import pytest import rc_testdata -from rhodecode.model.db import User +from rhodecode.model.db import User, Repository from rhodecode.model.meta import Session from rhodecode.model.scm import ScmModel from rhodecode.lib.vcs.backends.svn.repository import SubversionRepository @@ -39,6 +43,72 @@ from rhodecode.lib.vcs.backends.svn.repo log = logging.getLogger(__name__) +class CustomTestResponse(TestResponse): + def _save_output(self, out): + f = tempfile.NamedTemporaryFile( + delete=False, prefix='rc-test-', suffix='.html') + f.write(out) + return f.name + + def mustcontain(self, *strings, **kw): + """ + Assert that the response contains all of the strings passed + in as arguments. + + Equivalent to:: + + assert string in res + """ + if 'no' in kw: + no = kw['no'] + del kw['no'] + if isinstance(no, string_types): + no = [no] + else: + no = [] + if kw: + raise TypeError( + "The only keyword argument allowed is 'no'") + + f = self._save_output(str(self)) + + for s in strings: + if not s in self: + print_stderr("Actual response (no %r):" % s) + print_stderr(str(self)) + raise IndexError( + "Body does not contain string %r, output saved as %s" % ( + s, f)) + + for no_s in no: + if no_s in self: + print_stderr("Actual response (has %r)" % no_s) + print_stderr(str(self)) + raise IndexError( + "Body contains bad string %r, output saved as %s" % ( + no_s, f)) + + def assert_response(self): + return AssertResponse(self) + + +class TestRequest(Request): + + # for py.test + disabled = True + ResponseClass = CustomTestResponse + + +class CustomTestApp(TestApp): + """ + Custom app to make mustcontain more usefull + """ + RequestClass = TestRequest + + + + + def set_anonymous_access(enabled): """(Dis)allows anonymous access depending on parameter `enabled`""" user = User.get_default_user()