[Checkins] SVN: zope.app.wsgi/trunk/src/zope/app/wsgi/testlayer.py Improve testing story to be compatible with zope.app.testing.functional
Sylvain Viollon
sylvain at infrae.com
Wed Apr 14 08:21:48 EDT 2010
Log message for revision 110857:
Improve testing story to be compatible with zope.app.testing.functional
Changed:
U zope.app.wsgi/trunk/src/zope/app/wsgi/testlayer.py
-=-
Modified: zope.app.wsgi/trunk/src/zope/app/wsgi/testlayer.py
===================================================================
--- zope.app.wsgi/trunk/src/zope/app/wsgi/testlayer.py 2010-04-14 12:20:36 UTC (rev 110856)
+++ zope.app.wsgi/trunk/src/zope/app/wsgi/testlayer.py 2010-04-14 12:21:48 UTC (rev 110857)
@@ -12,15 +12,21 @@
#
##############################################################################
from StringIO import StringIO
+import re
+import base64
-import wsgi_intercept
+from transaction import commit
+from wsgi_intercept.mechanize_intercept import Browser as BaseInterceptBrowser
from zope.app.appsetup.testlayer import ZODBLayer
-
+from zope.app.publication.httpfactory import HTTPPublicationRequestFactory
from zope.app.wsgi import WSGIPublisherApplication
-from zope.app.publication.httpfactory import HTTPPublicationRequestFactory
-from wsgi_intercept.mechanize_intercept import Browser as BaseInterceptBrowser
from zope.testbrowser.browser import Browser as ZopeTestbrowser
+import wsgi_intercept
+# List of hostname where the test browser/http function replies to
+TEST_HOSTS = ['localhost', '127.0.0.1']
+
+
class InterceptBrowser(BaseInterceptBrowser):
default_schemes = ['http']
@@ -40,6 +46,53 @@
ZopeTestbrowser.__init__(self, *args, **kwargs)
+basicre = re.compile('Basic (.+)?:(.+)?$')
+def auth_header(header):
+ """This function takes an authorization HTTP header and encode the
+ couple user, password into base 64 like the HTTP protocol wants
+ it.
+ """
+ match = basicre.match(header)
+ if match:
+ u, p = match.group(1, 2)
+ if u is None:
+ u = ''
+ if p is None:
+ p = ''
+ auth = base64.encodestring('%s:%s' % (u, p))
+ return 'Basic %s' % auth[:-1]
+ return header
+
+
+class TestBrowserMiddleware(object):
+ """This middleware makes the WSGI application compatible with the
+ HTTPCaller behavior defined in zope.app.testing.functional:
+ - It commits and synchronises the current transaction before and
+ after the test.
+ - It honors the X-zope-handle-errors header in order to support
+ zope.testbrowser Browser handleErrors flag.
+ - It modifies the HTTP Authorization header to encode user and
+ password into base 64 if it is Basic authentication.
+ """
+
+ def __init__(self, app, root):
+ self.root = root
+ self.app = app
+
+ def __call__(self, environ, start_response):
+ handle_errors = environ.get('HTTP_X_ZOPE_HANDLE_ERRORS', 'True')
+ self.app.handleErrors = handle_errors == 'True'
+
+ auth_key = 'HTTP_AUTHORIZATION'
+ if environ.has_key(auth_key):
+ environ[auth_key] = auth_header(environ[auth_key])
+
+ commit()
+ for entry in self.app(environ, start_response):
+ yield entry
+ self.root._p_jar.sync()
+
+
class BrowserLayer(ZODBLayer):
"""This create a test layer with a test database and register a wsgi
application to use that test database.
@@ -49,22 +102,21 @@
application.
"""
- handleErrors = True
-
def testSetUp(self):
super(BrowserLayer, self).testSetUp()
wsgi_app = WSGIPublisherApplication(
- self.db, HTTPPublicationRequestFactory, self.handleErrors)
+ self.db, HTTPPublicationRequestFactory, True)
def factory():
- return wsgi_app
+ return TestBrowserMiddleware(wsgi_app, self.getRootFolder())
- wsgi_intercept.add_wsgi_intercept('localhost', 80, factory)
+ for host in TEST_HOSTS:
+ wsgi_intercept.add_wsgi_intercept(host, 80, factory)
-
def testTearDown(self):
+ for host in TEST_HOSTS:
+ wsgi_intercept.remove_wsgi_intercept(host, 80)
super(BrowserLayer, self).testTearDown()
- wsgi_intercept.remove_wsgi_intercept('localhost', 80)
class NotInBrowserLayer(Exception):
More information about the checkins
mailing list