diff options
| author | ianb <devnull@localhost> | 2005-12-13 07:00:20 +0000 |
|---|---|---|
| committer | ianb <devnull@localhost> | 2005-12-13 07:00:20 +0000 |
| commit | 4e73bff9da87e35c7154ab1cc923bb4f9d40711d (patch) | |
| tree | d2e4c92965398700457280d5829dfaa5cdf5b4fb /tests | |
| parent | 55b404e53bc834daf3852069af6de9b1fca4c742 (diff) | |
| download | paste-4e73bff9da87e35c7154ab1cc923bb4f9d40711d.tar.gz | |
Merged changes from cce branch (r3727:HEAD/4008); the branch is now in sync with trunk
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test_auth/test_auth_cookie.py | 41 | ||||
| -rw-r--r-- | tests/test_auth/test_auth_digest.py | 86 | ||||
| -rw-r--r-- | tests/test_exceptions/test_error_middleware.py | 30 | ||||
| -rw-r--r-- | tests/test_exceptions/test_formatter.py | 6 | ||||
| -rw-r--r-- | tests/test_exceptions/test_httpexceptions.py | 82 | ||||
| -rw-r--r-- | tests/test_request.py | 7 |
6 files changed, 235 insertions, 17 deletions
diff --git a/tests/test_auth/test_auth_cookie.py b/tests/test_auth/test_auth_cookie.py new file mode 100644 index 0000000..2bec414 --- /dev/null +++ b/tests/test_auth/test_auth_cookie.py @@ -0,0 +1,41 @@ +# (c) 2005 Clark C. Evans +# This module is part of the Python Paste Project and is released under +# the MIT License: http://www.opensource.org/licenses/mit-license.php + +from paste.auth import cookie +from paste.wsgilib import raw_interactive, header_value, dump_environ +from paste.httpexceptions import * +from Cookie import SimpleCookie +import urllib2, os + +def build(application,setenv, *args, **kwargs): + def setter(environ, start_response): + save = environ['paste.auth.cookie'].append + for (k,v) in setenv.items(): + save(k) + environ[k] = v + return application(environ, start_response) + return cookie.middleware(setter,*args,**kwargs) + +def test_noop(): + app = build(dump_environ,{}) + (status,headers,content,errors) = \ + raw_interactive(app) + assert not header_value(headers,'Set-Cookie') + +def test_basic(key='key', val='bingles'): + app = build(dump_environ,{key:val}) + (status,headers,content,errors) = \ + raw_interactive(app) + value = header_value(headers,'Set-Cookie') + assert "Path=/;" in value + assert "expires=" not in value + cookie = value.split(";")[0] + (status,headers,content,errors) = \ + raw_interactive(app,{'HTTP_COOKIE': cookie}) + assert ("%s: %s" % (key,val.replace("\n","\n "))) in content + +def test_roundtrip(): + roundtrip = str('').join(map(chr,xrange(256))) + test_basic(roundtrip,roundtrip) + diff --git a/tests/test_auth/test_auth_digest.py b/tests/test_auth/test_auth_digest.py new file mode 100644 index 0000000..1c0ced0 --- /dev/null +++ b/tests/test_auth/test_auth_digest.py @@ -0,0 +1,86 @@ +# (c) 2005 Clark C. Evans +# This module is part of the Python Paste Project and is released under +# the MIT License: http://www.opensource.org/licenses/mit-license.php + +from paste.auth import digest +from paste.wsgilib import raw_interactive, header_value +from paste.httpexceptions import * +import os + +def application(environ, start_response): + content = environ.get('REMOTE_USER','') + start_response("200 OK",(('Content-Type', 'text/plain'), + ('Content-Length', len(content)))) + return content + +realm = "tag:clarkevans.com,2005:testing" + +def backwords(realm,username): + """ dummy password hash, where user password is just reverse """ + password = list(username) + password.reverse() + password = "".join(password) + return digest.digest_password(username,realm,password) + +application = digest.middleware(application,realm,backwords) +application = HTTPExceptionHandler(application) + +def check(username, password, path="/"): + """ perform two-stage authentication to verify login """ + (status,headers,content,errors) = \ + raw_interactive(application,path, accept='text/html') + assert status.startswith("401") + challenge = header_value(headers,'WWW-Authenticate') + response = digest.response(challenge, realm, path, username, password) + assert "Digest" in response + (status,headers,content,errors) = \ + raw_interactive(application,path, + HTTP_AUTHORIZATION=response) + if status.startswith("200"): + return content + if status.startswith("401"): + return None + assert False, "Unexpected Status: %s" % status + +def test_digest(): + assert 'bing' == check("bing","gnib") + assert check("bing","bad") is None + +# +# The following code uses sockets to test the functionality, +# to enable use: +# +# $ TEST_SOCKET py.test +# + +if os.environ.get("TEST_SOCKET",""): + import urllib2 + from paste.debug.testserver import serve + server = serve(application) + + def authfetch(username,password,path="/",realm=realm): + server.accept(2) + import socket + socket.setdefaulttimeout(5) + uri = ("http://%s:%s" % server.server_address) + path + auth = urllib2.HTTPDigestAuthHandler() + auth.add_password(realm,uri,username,password) + opener = urllib2.build_opener(auth) + result = opener.open(uri) + return result.read() + + def test_success(): + assert "bing" == authfetch('bing','gnib') + + def test_failure(): + # urllib tries 5 more times before it gives up + server.accept(5) + try: + authfetch('bing','wrong') + assert False, "this should raise an exception" + except urllib2.HTTPError, e: + assert e.code == 401 + + def test_shutdown(): + server.stop() + diff --git a/tests/test_exceptions/test_error_middleware.py b/tests/test_exceptions/test_error_middleware.py index 5b1df26..658d887 100644 --- a/tests/test_exceptions/test_error_middleware.py +++ b/tests/test_exceptions/test_error_middleware.py @@ -1,11 +1,11 @@ from paste.fixture import * from paste.exceptions.errormiddleware import ErrorMiddleware from paste import lint - -def strip_html(s): - s = re.sub('<.*?>', '', s) - s = s.replace(' ', ' ').replace('<', '<').replace('>', '>') - return s +from paste.util.quoting import strip_html +# +# For some strange reason, these 4 lines cannot be removed or the regression +# test breaks; is it counting the number of lines in the file somehow? +# def do_request(app, expect_status=500): app = lint.middleware(app) @@ -19,10 +19,16 @@ def do_request(app, expect_status=500): def clear_middleware(app): """ The fixture sets paste.throw_errors, which suppresses exactly what - we want to test in this case. + we want to test in this case. This wrapper also strips exc_info + on the *first* call to start_response (but not the second, or + subsequent calls. """ def clear_throw_errors(environ, start_response): + headers_sent = [] def replacement(status, headers, exc_info=None): + if headers_sent: + return start_response(status, headers, exc_info) + headers_sent.append(True) return start_response(status, headers) if 'paste.throw_errors' in environ: del environ['paste.throw_errors'] @@ -64,7 +70,7 @@ def test_makes_exception(): res = do_request(bad_app) assert '<html' in res res = strip_html(str(res)) - print res + #print res assert 'bad_app() takes no arguments (2 given' in res assert 'iterator = application(environ, start_response_wrapper)' in res assert 'paste.lint' in res @@ -73,21 +79,21 @@ def test_makes_exception(): def test_start_res(): res = do_request(start_response_app) res = strip_html(str(res)) - print res + #print res assert 'ValueError: hi' in res assert 'test_error_middleware' in res - assert ':43 in start_response_app' in res + assert ':49 in start_response_app' in res def test_after_start(): res = do_request(after_start_response_app, 200) res = strip_html(str(res)) - print res + #print res assert 'ValueError: error2' in res - assert ':47' in res + assert ':53' in res def test_iter_app(): res = do_request(iter_app, 200) - print res + #print res assert 'None raises error' in res assert 'yielder' in res diff --git a/tests/test_exceptions/test_formatter.py b/tests/test_exceptions/test_formatter.py index dad8ed7..8e31fff 100644 --- a/tests/test_exceptions/test_formatter.py +++ b/tests/test_exceptions/test_formatter.py @@ -1,5 +1,6 @@ from paste.exceptions import formatter from paste.exceptions import collector +from paste.util.quoting import strip_html import sys import os import difflib @@ -28,11 +29,6 @@ class BadSupplement(Supplement): def getInfo(self): raise ValueError("This supplemental info is buggy") -def strip_html(s): - s = re.sub('<.*?>', '', s) - s = s.replace(' ', ' ').replace('<', '<').replace('>', '>') - return s - def call_error(sup): 1 + 2 __traceback_supplement__ = (sup, ()) diff --git a/tests/test_exceptions/test_httpexceptions.py b/tests/test_exceptions/test_httpexceptions.py new file mode 100644 index 0000000..5b0101b --- /dev/null +++ b/tests/test_exceptions/test_httpexceptions.py @@ -0,0 +1,82 @@ +# (c) 2005 Ian Bicking, Clark C. Evans and contributors +# This module is part of the Python Paste Project and is released under +# the MIT License: http://www.opensource.org/licenses/mit-license.php +""" +WSGI Exception Middleware + +Regression Test Suite +""" +from paste.httpexceptions import * +from paste.wsgilib import header_value +import py + +def test_HTTPMove(): + """ make sure that location is a mandatory attribute of Redirects """ + py.test.raises(AssertionError,HTTPFound) + py.test.raises(AssertionError,HTTPTemporaryRedirect, + headers=[('l0cation','/bing')]) + assert isinstance(HTTPMovedPermanently("This is a message", + headers=[('Location','/bing')]) + ,HTTPRedirection) + assert isinstance(HTTPUseProxy(headers=[('LOCATION','/bing')]) + ,HTTPRedirection) + assert isinstance(HTTPFound('/foobar'),HTTPRedirection) + +def test_badapp(): + """ verify that the middleware handles previously-started responses """ + def badapp(environ, start_response): + start_response("200 OK",[]) + raise HTTPBadRequest("Do not do this at home.") + newapp = HTTPExceptionHandler(badapp) + assert 'Bad Request' in ''.join(newapp({'HTTP_ACCEPT': 'text/html'}, + (lambda a, b, c=None: None))) + +def test_template(): + """ verify that html() and plain() output methods work """ + e = HTTPInternalServerError() + e.template = 'A %(ping)s and <b>%(pong)s</b> message.' + assert str(e).startswith("500 Internal Server Error") + assert e.plain({'ping': 'fun', 'pong': 'happy'}) == ( + '500 Internal Server Error\n' + 'A fun and happy message.\n') + assert '<p>A fun and <b>happy</b> message.</p>' in \ + e.html({'ping': 'fun', 'pong': 'happy'}) + +def test_redapp(): + """ check that redirect returns the correct, expected results """ + saved = [] + def saveit(status, headers, exc_info = None): + saved.append((status,headers)) + def redapp(environ, start_response): + raise HTTPFound("/bing/foo") + app = HTTPExceptionHandler(redapp) + result = list(app({'HTTP_ACCEPT': 'text/html'},saveit)) + assert '<a href="/bing/foo">' in result[0] + assert "302 Found" == saved[0][0] + assert "text/html" == header_value(saved[0][1], 'content-type') + assert "/bing/foo" == header_value(saved[0][1],'location') + result = list(app({'HTTP_ACCEPT': 'text/plain'},saveit)) + print result[0] == ( + '302 Found\n' + 'This resource was found at /bing/foo;\n' + 'you should be redirected automatically.\n') + assert "text/plain" == header_value(saved[1][1],'content-type') + assert "/bing/foo" == header_value(saved[1][1],'location') + +def test_misc(): + assert get_exception(301) == HTTPMovedPermanently + redirect = HTTPFound("/some/path") + assert isinstance(redirect,HTTPException) + assert isinstance(redirect,HTTPRedirection) + assert not isinstance(redirect,HTTPError) + notfound = HTTPNotFound() + assert isinstance(notfound,HTTPException) + assert isinstance(notfound,HTTPError) + assert isinstance(notfound,HTTPClientError) + assert not isinstance(notfound,HTTPServerError) + notimpl = HTTPNotImplemented() + assert isinstance(notimpl,HTTPException) + assert isinstance(notimpl,HTTPError) + assert isinstance(notimpl,HTTPServerError) + assert not isinstance(notimpl,HTTPClientError) + diff --git a/tests/test_request.py b/tests/test_request.py new file mode 100644 index 0000000..12a4ee9 --- /dev/null +++ b/tests/test_request.py @@ -0,0 +1,7 @@ +# (c) 2005 Ian Bicking, Clark C. Evans and contributors +# This module is part of the Python Paste Project and is released under +# the MIT License: http://www.opensource.org/licenses/mit-license.php +from paste.request import * +from py.test import raises + +#@@: regressions needed ;) |
