Commit 88ea141c authored by Hanno Schlichting's avatar Hanno Schlichting

Moved ``testbrowser`` module into the Testing package.

parent fec24881
...@@ -11,6 +11,8 @@ Trunk (unreleased) ...@@ -11,6 +11,8 @@ Trunk (unreleased)
Restructuring Restructuring
+++++++++++++ +++++++++++++
- Moved ``testbrowser`` module into the Testing package.
- Moved the code handling ZCML loading into the ``Zope2.App`` package. The - Moved the code handling ZCML loading into the ``Zope2.App`` package. The
component architecture is now setup before the application object is created component architecture is now setup before the application object is created
or any database connections are opened. So far the CA was setup somewhat or any database connections are opened. So far the CA was setup somewhat
......
...@@ -9,7 +9,7 @@ some: ...@@ -9,7 +9,7 @@ some:
>>> zcml.load_config("configure.zcml", Products.Five) >>> zcml.load_config("configure.zcml", Products.Five)
>>> zcml.load_config('aqlegacy.zcml', package=Products.Five.browser.tests) >>> zcml.load_config('aqlegacy.zcml', package=Products.Five.browser.tests)
>>> from Products.Five.testbrowser import Browser >>> from Testing.testbrowser import Browser
>>> browser = Browser() >>> browser = Browser()
>>> browser.handleErrors = False >>> browser.handleErrors = False
......
...@@ -37,7 +37,7 @@ def test_check_permission(): ...@@ -37,7 +37,7 @@ def test_check_permission():
zope.security.management.checkPermission(). We see it works as zope.security.management.checkPermission(). We see it works as
expected: expected:
>>> from Products.Five.testbrowser import Browser >>> from Testing.testbrowser import Browser
>>> browser = Browser() >>> browser = Browser()
>>> browser.open('http://localhost/test_folder_1_/testoid/@@zope3security.html?permission=zope2.View') >>> browser.open('http://localhost/test_folder_1_/testoid/@@zope3security.html?permission=zope2.View')
>>> print browser.contents >>> print browser.contents
......
...@@ -30,7 +30,7 @@ Making a site ...@@ -30,7 +30,7 @@ Making a site
Create the test browser we'll be using: Create the test browser we'll be using:
>>> from Products.Five.testbrowser import Browser >>> from Testing.testbrowser import Browser
>>> browser = Browser() >>> browser = Browser()
>>> browser.addHeader('Authorization', 'Basic manager:r00t') >>> browser.addHeader('Authorization', 'Basic manager:r00t')
......
############################################################################## # BBB
#
# Copyright (c) 2006 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Support for using zope.testbrowser from Zope2.
Mostly just copy and paste from zope.testbrowser.testing. from zope.deferredimport import deprecated
$Id$
"""
import sys
import socket
import urllib2
import mechanize
from zope.testbrowser import testing
from zope.testbrowser import browser
import zope.publisher.http
class PublisherConnection(testing.PublisherConnection):
def __init__(self, host, timeout=None):
from Testing.ZopeTestCase.zopedoctest.functional import http
self.caller = http
self.host = host
def getresponse(self):
"""Return a ``urllib2`` compatible response.
The goal of ths method is to convert the Zope Publisher's reseponse to
a ``urllib2`` compatible response, which is also understood by
mechanize.
"""
real_response = self.response._response
status = real_response.getStatus()
reason = zope.publisher.http.status_reasons[real_response.status]
headers = []
# Convert header keys to camel case. This is basically a copy
# paste from ZPublisher.HTTPResponse
for key, val in real_response.headers.items():
if key.lower() == key:
# only change non-literal header names
key = "%s%s" % (key[:1].upper(), key[1:])
start = 0
l = key.find('-',start)
while l >= start:
key = "%s-%s%s" % (key[:l],key[l+1:l+2].upper(),key[l+2:])
start = l + 1
l = key.find('-', start)
headers.append((key, val))
# get the cookies, breaking them into tuples for sorting
cookies = [(c[:10], c[12:]) for c in real_response._cookie_list()]
headers.extend(cookies)
headers.sort()
headers.insert(0, ('Status', "%s %s" % (status, reason)))
headers = '\r\n'.join('%s: %s' % h for h in headers)
content = real_response.body
return testing.PublisherResponse(content, headers, status, reason)
class PublisherHTTPHandler(urllib2.HTTPHandler):
"""Special HTTP handler to use the Zope Publisher."""
http_request = urllib2.AbstractHTTPHandler.do_request_
def http_open(self, req):
"""Open an HTTP connection having a ``urllib2`` request."""
# Here we connect to the publisher.
if sys.version_info > (2, 6) and not hasattr(req, 'timeout'):
# Workaround mechanize incompatibility with Python
# 2.6. See: LP #280334
req.timeout = socket._GLOBAL_DEFAULT_TIMEOUT
return self.do_open(PublisherConnection, req)
class PublisherMechanizeBrowser(mechanize.Browser):
"""Special ``mechanize`` browser using the Zope Publisher HTTP handler."""
default_schemes = ['http']
default_others = ['_http_error', '_http_request_upgrade',
'_http_default_error']
default_features = ['_redirect', '_cookies', '_referer', '_refresh',
'_equiv', '_basicauth', '_digestauth' ]
def __init__(self, *args, **kws):
inherited_handlers = ['_unknown', '_http_error',
'_http_request_upgrade', '_http_default_error', '_basicauth',
'_digestauth', '_redirect', '_cookies', '_referer',
'_refresh', '_equiv', '_gzip']
self.handler_classes = {"http": PublisherHTTPHandler}
for name in inherited_handlers:
self.handler_classes[name] = mechanize.Browser.handler_classes[name]
mechanize.Browser.__init__(self, *args, **kws)
class Browser(browser.Browser):
"""A Zope ``testbrowser` Browser that uses the Zope Publisher."""
def __init__(self, url=None):
mech_browser = PublisherMechanizeBrowser()
# override the http handler class
mech_browser.handler_classes["http"] = PublisherHTTPHandler
super(Browser, self).__init__(url=url, mech_browser=mech_browser)
deprecated("Please import from Testing.testbrowser",
PublisherConnection = 'Testing.testbrowser:PublisherConnection',
PublisherHTTPHandler = 'Testing.testbrowser:PublisherHTTPHandler',
PublisherMechanizeBrowser = 'Testing.testbrowser:PublisherMechanizeBrowser',
Browser = 'Testing.testbrowser:Browser',
)
...@@ -76,7 +76,6 @@ class TestPlacelessSetUp(ZopeTestCase.ZopeTestCase): ...@@ -76,7 +76,6 @@ class TestPlacelessSetUp(ZopeTestCase.ZopeTestCase):
tearDown() tearDown()
def testSimple(self): def testSimple(self):
# SetUp according to Five's adapter test
setUp() setUp()
setupZCML() setupZCML()
# Now we have a fixture that should work for adaptation # Now we have a fixture that should work for adaptation
......
##############################################################################
#
# Copyright (c) 2006 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Support for using zope.testbrowser from Zope2.
Mostly just copy and paste from zope.testbrowser.testing.
"""
import sys
import socket
import urllib2
import mechanize
from zope.testbrowser import testing
from zope.testbrowser import browser
import zope.publisher.http
class PublisherConnection(testing.PublisherConnection):
def __init__(self, host, timeout=None):
from Testing.ZopeTestCase.zopedoctest.functional import http
self.caller = http
self.host = host
def getresponse(self):
"""Return a ``urllib2`` compatible response.
The goal of ths method is to convert the Zope Publisher's reseponse to
a ``urllib2`` compatible response, which is also understood by
mechanize.
"""
real_response = self.response._response
status = real_response.getStatus()
reason = zope.publisher.http.status_reasons[real_response.status]
headers = []
# Convert header keys to camel case. This is basically a copy
# paste from ZPublisher.HTTPResponse
for key, val in real_response.headers.items():
if key.lower() == key:
# only change non-literal header names
key = "%s%s" % (key[:1].upper(), key[1:])
start = 0
l = key.find('-',start)
while l >= start:
key = "%s-%s%s" % (key[:l],key[l+1:l+2].upper(),key[l+2:])
start = l + 1
l = key.find('-', start)
headers.append((key, val))
# get the cookies, breaking them into tuples for sorting
cookies = [(c[:10], c[12:]) for c in real_response._cookie_list()]
headers.extend(cookies)
headers.sort()
headers.insert(0, ('Status', "%s %s" % (status, reason)))
headers = '\r\n'.join('%s: %s' % h for h in headers)
content = real_response.body
return testing.PublisherResponse(content, headers, status, reason)
class PublisherHTTPHandler(urllib2.HTTPHandler):
"""Special HTTP handler to use the Zope Publisher."""
http_request = urllib2.AbstractHTTPHandler.do_request_
def http_open(self, req):
"""Open an HTTP connection having a ``urllib2`` request."""
# Here we connect to the publisher.
if sys.version_info > (2, 6) and not hasattr(req, 'timeout'):
# Workaround mechanize incompatibility with Python
# 2.6. See: LP #280334
req.timeout = socket._GLOBAL_DEFAULT_TIMEOUT
return self.do_open(PublisherConnection, req)
class PublisherMechanizeBrowser(mechanize.Browser):
"""Special ``mechanize`` browser using the Zope Publisher HTTP handler."""
default_schemes = ['http']
default_others = ['_http_error', '_http_request_upgrade',
'_http_default_error']
default_features = ['_redirect', '_cookies', '_referer', '_refresh',
'_equiv', '_basicauth', '_digestauth' ]
def __init__(self, *args, **kws):
inherited_handlers = ['_unknown', '_http_error',
'_http_request_upgrade', '_http_default_error', '_basicauth',
'_digestauth', '_redirect', '_cookies', '_referer',
'_refresh', '_equiv', '_gzip']
self.handler_classes = {"http": PublisherHTTPHandler}
for name in inherited_handlers:
self.handler_classes[name] = mechanize.Browser.handler_classes[name]
mechanize.Browser.__init__(self, *args, **kws)
class Browser(browser.Browser):
"""A Zope ``testbrowser` Browser that uses the Zope Publisher."""
def __init__(self, url=None):
mech_browser = PublisherMechanizeBrowser()
# override the http handler class
mech_browser.handler_classes["http"] = PublisherHTTPHandler
super(Browser, self).__init__(url=url, mech_browser=mech_browser)
...@@ -32,7 +32,7 @@ def doctest_cookies(): ...@@ -32,7 +32,7 @@ def doctest_cookies():
We want to make sure that our testbrowser correctly understands We want to make sure that our testbrowser correctly understands
cookies. We'll add a stub to ``self.folder`` that sets a cookie. cookies. We'll add a stub to ``self.folder`` that sets a cookie.
>>> from Products.Five.tests.test_testbrowser import CookieStub >>> from Testing.tests.test_testbrowser import CookieStub
>>> self.folder._setObject('stub', CookieStub()) >>> self.folder._setObject('stub', CookieStub())
'stub' 'stub'
...@@ -47,7 +47,7 @@ def doctest_cookies(): ...@@ -47,7 +47,7 @@ def doctest_cookies():
Let's try to look at the same folder with testbrowser: Let's try to look at the same folder with testbrowser:
>>> from Products.Five.testbrowser import Browser >>> from Testing.testbrowser import Browser
>>> browser = Browser() >>> browser = Browser()
>>> browser.open('http://localhost/test_folder_1_/stub') >>> browser.open('http://localhost/test_folder_1_/stub')
>>> 'Set-Cookie: evil="cookie"' in str(browser.headers) >>> 'Set-Cookie: evil="cookie"' in str(browser.headers)
...@@ -59,15 +59,14 @@ def doctest_camel_case_headers(): ...@@ -59,15 +59,14 @@ def doctest_camel_case_headers():
Some setup: Some setup:
>>> from Products.Five.tests.test_testbrowser import CookieStub >>> from Testing.tests.test_testbrowser import CookieStub
>>> self.folder._setObject('stub', CookieStub()) >>> self.folder._setObject('stub', CookieStub())
'stub' 'stub'
The Zope2 response mungs headers so they come out in camel case we should The Zope2 response mungs headers so they come out in camel case we should
do the same. This is also more consistent with the Zope3 testbrowser tests. do the same. We will test a few:
We will test a few:
>>> from Products.Five.testbrowser import Browser >>> from Testing.testbrowser import Browser
>>> browser = Browser() >>> browser = Browser()
>>> browser.open('http://localhost/test_folder_1_/stub') >>> browser.open('http://localhost/test_folder_1_/stub')
>>> 'Content-Length: ' in str(browser.headers) >>> 'Content-Length: ' in str(browser.headers)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment