Commit 65306d3c authored by Paul Winkler's avatar Paul Winkler

Merged makerequest fixes from trunk (collector 2057).

parents 363fb3f3 cf4287cf
......@@ -14,6 +14,14 @@ Zope Changes
to the rules for such a type laid out in the Python docs:
http://docs.python.org/api/supporting-cycle-detection.html
Zope 2.9.3 (UNRELEASED)
Bugs fixed
- Collector #2057: Allow Testing.makerequest to work with
any acquisition-supporting root object, not just Zope2.app.
Formerly, if you did that, getPhysicalPath() was broken.
Zope 2.9.2 (2006/03/27)
Bugs fixed
......
......@@ -127,25 +127,13 @@ def startZServer(number_of_threads=1, log=None):
def makerequest(app, stdout=sys.stdout):
'''Wraps the app into a fresh REQUEST.'''
from ZPublisher.BaseRequest import RequestContainer
from ZPublisher.Request import Request
from ZPublisher.Response import Response
response = Response(stdout=stdout)
from Testing.makerequest import makerequest as _makerequest
environ = {}
environ['SERVER_NAME'] = _Z2HOST or 'nohost'
environ['SERVER_PORT'] = '%d' % (_Z2PORT or 80)
environ['REQUEST_METHOD'] = 'GET'
request = Request(sys.stdin, environ, response)
request._steps = ['noobject'] # Fake a published object
request['ACTUAL_URL'] = request.get('URL') # Zope 2.7.4
# set Zope3-style default skin so that the request is usable for
# Zope3-style view look-ups
from zope.app.publication.browser import setDefaultSkin
setDefaultSkin(request)
return app.__of__(RequestContainer(REQUEST=request))
app = _makerequest(app, stdout=stdout, environ=environ)
return app
def appcall(function, *args, **kw):
'''Calls a function passing 'app' as first argument.'''
......
......@@ -19,27 +19,50 @@ Usage:
import makerequest
app = makerequest.makerequest(Zope2.app())
You can optionally pass stdout to be used by the response,
and an environ mapping to be used in the request.
Defaults are sys.stdout and os.environ.
If you don't want to start a zope app in your test, you can wrap other
objects, but they must support acquisition and you should only wrap
your root object.
$Id$
"""
import os
from os import environ
from sys import stdin, stdout
from ZPublisher.HTTPRequest import HTTPRequest
from ZPublisher.HTTPResponse import HTTPResponse
from ZPublisher.BaseRequest import RequestContainer
def makerequest(app, stdout=stdout):
def makerequest(app, stdout=stdout, environ=None):
resp = HTTPResponse(stdout=stdout)
environ['SERVER_NAME']='foo'
environ['SERVER_PORT']='80'
environ['REQUEST_METHOD'] = 'GET'
if environ is None:
environ = os.environ
environ.setdefault('SERVER_NAME', 'foo')
environ.setdefault('SERVER_PORT', '80')
environ.setdefault('REQUEST_METHOD', 'GET')
req = HTTPRequest(stdin, environ, resp)
req._steps = ['noobject'] # Fake a published object.
req['ACTUAL_URL'] = req.get('URL') # Zope 2.7.4
# set Zope3-style default skin so that the request is usable for
# Zope3-style view look-ups
# Zope3-style view look-ups.
from zope.app.publication.browser import setDefaultSkin
setDefaultSkin(req)
return app.__of__(RequestContainer(REQUEST = req))
requestcontainer = RequestContainer(REQUEST = req)
# Workaround for collector 2057: ensure that we don't break
# getPhysicalPath if app has that method.
# We could instead fix Traversable.getPhysicalPath() to check for
# existence of p.getPhysicalPath before calling it; but it's such
# a commonly called method that I don't want to impact performance
# for something that AFAICT only affects makerequest() in
# practice.
if getattr(app, 'getPhysicalPath', None) is not None:
requestcontainer.getPhysicalPath = lambda: ()
return app.__of__(requestcontainer)
##############################################################################
#
# 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.
#
##############################################################################
"""Unit tests of makequest.
$Id$
"""
import unittest
from Acquisition import Implicit
from Testing.makerequest import makerequest
from OFS.SimpleItem import SimpleItem
class MakerequestTests(unittest.TestCase):
def test_makerequest(self):
# The argument must support acquisition.
self.assertRaises(AttributeError, makerequest, object())
# After the call, it will have a REQUEST attribute.
item = Implicit()
self.failIf(hasattr(item, 'REQUEST'))
item = makerequest(item)
self.failUnless(hasattr(item, 'REQUEST'))
def test_dont_break_getPhysicalPath(self):
# see http://www.zope.org/Collectors/Zope/2057
item = SimpleItem()
self.assertEqual(item.getPhysicalPath(), ('',))
self.assertEqual(item.getPhysicalPath(),
makerequest(item).getPhysicalPath())
def test_stdout(self):
# You can pass a stdout arg and it's used by the response.
import cStringIO
out = cStringIO.StringIO()
item = makerequest(SimpleItem(), stdout=out)
item.REQUEST.RESPONSE.write('aaa')
out.seek(0)
written = out.read()
self.failUnless(written.startswith('Status: 200 OK\n'))
self.failUnless(written.endswith('\naaa'))
def test_environ(self):
# You can pass an environ argument to use in the request.
environ = {'foofoo': 'barbar'}
item = makerequest(SimpleItem(), environ=environ)
self.assertEqual(item.REQUEST.environ['foofoo'], 'barbar')
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(MakerequestTests))
return suite
if __name__=='__main__':
unittest.TextTestRunner().run(test_suite())
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