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 ...@@ -14,6 +14,14 @@ Zope Changes
to the rules for such a type laid out in the Python docs: to the rules for such a type laid out in the Python docs:
http://docs.python.org/api/supporting-cycle-detection.html 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) Zope 2.9.2 (2006/03/27)
Bugs fixed Bugs fixed
......
...@@ -127,25 +127,13 @@ def startZServer(number_of_threads=1, log=None): ...@@ -127,25 +127,13 @@ def startZServer(number_of_threads=1, log=None):
def makerequest(app, stdout=sys.stdout): def makerequest(app, stdout=sys.stdout):
'''Wraps the app into a fresh REQUEST.''' '''Wraps the app into a fresh REQUEST.'''
from ZPublisher.BaseRequest import RequestContainer from Testing.makerequest import makerequest as _makerequest
from ZPublisher.Request import Request
from ZPublisher.Response import Response
response = Response(stdout=stdout)
environ = {} environ = {}
environ['SERVER_NAME'] = _Z2HOST or 'nohost' environ['SERVER_NAME'] = _Z2HOST or 'nohost'
environ['SERVER_PORT'] = '%d' % (_Z2PORT or 80) environ['SERVER_PORT'] = '%d' % (_Z2PORT or 80)
environ['REQUEST_METHOD'] = 'GET' environ['REQUEST_METHOD'] = 'GET'
request = Request(sys.stdin, environ, response) app = _makerequest(app, stdout=stdout, environ=environ)
request._steps = ['noobject'] # Fake a published object return app
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))
def appcall(function, *args, **kw): def appcall(function, *args, **kw):
'''Calls a function passing 'app' as first argument.''' '''Calls a function passing 'app' as first argument.'''
......
...@@ -19,27 +19,50 @@ Usage: ...@@ -19,27 +19,50 @@ Usage:
import makerequest import makerequest
app = makerequest.makerequest(Zope2.app()) 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$ $Id$
""" """
import os import os
from os import environ
from sys import stdin, stdout from sys import stdin, stdout
from ZPublisher.HTTPRequest import HTTPRequest from ZPublisher.HTTPRequest import HTTPRequest
from ZPublisher.HTTPResponse import HTTPResponse from ZPublisher.HTTPResponse import HTTPResponse
from ZPublisher.BaseRequest import RequestContainer from ZPublisher.BaseRequest import RequestContainer
def makerequest(app, stdout=stdout): def makerequest(app, stdout=stdout, environ=None):
resp = HTTPResponse(stdout=stdout) resp = HTTPResponse(stdout=stdout)
environ['SERVER_NAME']='foo' if environ is None:
environ['SERVER_PORT']='80' environ = os.environ
environ['REQUEST_METHOD'] = 'GET' environ.setdefault('SERVER_NAME', 'foo')
environ.setdefault('SERVER_PORT', '80')
environ.setdefault('REQUEST_METHOD', 'GET')
req = HTTPRequest(stdin, environ, resp) 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 # 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 from zope.app.publication.browser import setDefaultSkin
setDefaultSkin(req) 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