summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorianb <devnull@localhost>2005-12-13 07:00:20 +0000
committerianb <devnull@localhost>2005-12-13 07:00:20 +0000
commit4e73bff9da87e35c7154ab1cc923bb4f9d40711d (patch)
treed2e4c92965398700457280d5829dfaa5cdf5b4fb /tests
parent55b404e53bc834daf3852069af6de9b1fca4c742 (diff)
downloadpaste-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.py41
-rw-r--r--tests/test_auth/test_auth_digest.py86
-rw-r--r--tests/test_exceptions/test_error_middleware.py30
-rw-r--r--tests/test_exceptions/test_formatter.py6
-rw-r--r--tests/test_exceptions/test_httpexceptions.py82
-rw-r--r--tests/test_request.py7
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('&nbsp;', ' ').replace('&lt;', '<').replace('&gt;', '>')
- 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('&nbsp;', ' ').replace('&lt;', '<').replace('&gt;', '>')
- 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 ;)