[Zope3-checkins] SVN: Zope3/trunk/src/zope/app/ Make functional test harnesses cookie aware. Multiple requests in a test

Stuart Bishop stuart at stuartbishop.net
Wed Jul 14 23:13:15 EDT 2004


Log message for revision 26546:
  Make functional test harnesses cookie aware. Multiple requests in a test
  handle cookies similar to a browser, implicitly resending them on each
  request. Cookies can either be set manually in the tests or from the 
  server responses.
  


Changed:
  A   Zope3/trunk/src/zope/app/ftests/test_functional.py
  U   Zope3/trunk/src/zope/app/tests/functional.py


-=-
Added: Zope3/trunk/src/zope/app/ftests/test_functional.py
===================================================================
--- Zope3/trunk/src/zope/app/ftests/test_functional.py	2004-07-15 03:08:12 UTC (rev 26545)
+++ Zope3/trunk/src/zope/app/ftests/test_functional.py	2004-07-15 03:13:15 UTC (rev 26546)
@@ -0,0 +1,126 @@
+##############################################################################
+#
+# Copyright (c) 2004 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.
+#
+##############################################################################
+"""Functional tests for the functional test framework
+
+$Id: functional.py 26214 2004-07-08 19:00:07Z srichter $
+"""
+
+import unittest
+from zope.app.tests.functional import SampleFunctionalTest, BrowserTestCase
+
+class CookieFunctionalTest(BrowserTestCase):
+
+    """Functional tests should handle cookies like a web browser
+    
+    Multiple requests in the same test should acumulate cookies.
+    We also ensure that cookies with path values are only sent for
+    the correct URL's so we can test cookies don't 'leak'. Expiry,
+    secure and other cookie attributes are not being worried about
+    at the moment
+
+    """
+
+    def setUp(self):
+        super(CookieFunctionalTest, self).setUp()
+        self.assertEqual(
+                len(self.cookies.keys()), 0,
+                'cookies store should be empty'
+                )
+
+        root = self.getRootFolder()
+
+        from zope.app.zptpage.zptpage import ZPTPage
+
+        page = ZPTPage()
+        page.evaluateInlineCode = True
+        page.source = u'''<script type="text/server-python">
+            cookies = ['%s=%s'%(k,v) for k,v in request.getCookies().items()]
+            cookies.sort()
+            print ';'.join(cookies)
+            </script>'''
+        root['getcookies'] = page
+
+        page = ZPTPage()
+        page.evaluateInlineCode = True
+        page.source = u'''<script type="text/server-python">
+            request.response.setCookie('bid','bval')
+            </script>'''
+        root['setcookie'] = page
+
+
+    def tearDown(self):
+        root = self.getRootFolder()
+        del root['getcookies']
+        del root['setcookie']
+        super(CookieFunctionalTest, self).tearDown()
+
+    def testDefaultCookies(self):
+        # By default no cookies are set
+        response = self.publish('/')
+        self.assertEquals(response.getStatus(), 200)
+        self.assert_(not response._request._cookies)
+
+    def testSimpleCookies(self):
+        self.cookies['aid'] = 'aval'
+        response = self.publish('/')
+        self.assertEquals(response.getStatus(), 200)
+        self.assertEquals(response._request._cookies['aid'], 'aval')
+
+    def testCookiePaths(self):
+        # We only send cookies if the path is correct
+        self.cookies['aid'] = 'aval'
+        self.cookies['aid']['Path'] = '/sub/folder'
+        self.cookies['bid'] = 'bval'
+        response = self.publish('/')
+
+        self.assertEquals(response.getStatus(), 200)
+        self.assert_(not response._request._cookies.has_key('aid'))
+        self.assertEquals(response._request._cookies['bid'], 'bval')
+
+    def testHttpCookieHeader(self):
+        # Passing an HTTP_COOKIE header to publish adds cookies
+        response = self.publish('/', env={
+            'HTTP_COOKIE': '$Version=1, aid=aval; $Path=/sub/folder, bid=bval'
+            })
+        self.assertEquals(response.getStatus(), 200)
+        self.failIf(response._request._cookies.has_key('aid'))
+        self.assertEquals(response._request._cookies['bid'], 'bval')
+
+    def testStickyCookies(self):
+        # Cookies should acumulate during the test
+        response = self.publish('/', env={'HTTP_COOKIE': 'aid=aval;'})
+        self.assertEquals(response.getStatus(), 200)
+
+        # Cookies are implicity passed to further requests in this test
+        response = self.publish('/getcookies')
+        self.assertEquals(response.getStatus(), 200)
+        self.assertEquals(response.getBody().strip(), 'aid=aval')
+
+        # And cookies set in responses also acumulate
+        response = self.publish('/setcookie')
+        self.assertEquals(response.getStatus(), 200)
+        response = self.publish('/getcookies')
+        self.assertEquals(response.getStatus(), 200)
+        self.assertEquals(response.getBody().strip(), 'aid=aval;bid=bval')
+
+
+def test_suite():
+    suite = unittest.TestSuite()
+    suite.addTest(unittest.makeSuite(SampleFunctionalTest))
+    suite.addTest(unittest.makeSuite(CookieFunctionalTest))
+    return suite
+
+
+if __name__ == '__main__':
+    unittest.main()


Property changes on: Zope3/trunk/src/zope/app/ftests/test_functional.py
___________________________________________________________________
Name: svn:keywords "LastChangedDate Author Id LastChangedRevision LastChangedBy HeadURL"
   + 
Name: svn:eol-style
   + native

Modified: Zope3/trunk/src/zope/app/tests/functional.py
===================================================================
--- Zope3/trunk/src/zope/app/tests/functional.py	2004-07-15 03:08:12 UTC (rev 26545)
+++ Zope3/trunk/src/zope/app/tests/functional.py	2004-07-15 03:13:15 UTC (rev 26546)
@@ -23,6 +23,7 @@
 import unittest
 
 from StringIO import StringIO
+from Cookie import SimpleCookie
 
 from transaction import get_transaction
 from ZODB.DB import DB
@@ -161,7 +162,13 @@
 class BrowserTestCase(FunctionalTestCase):
     """Functional test case for Browser requests."""
 
+    def setUp(self):
+        super(BrowserTestCase, self).setUp()
+        # Somewhere to store cookies between consecutive requests
+        self.cookies = SimpleCookie()
+
     def tearDown(self):
+        del self.cookies
         self.setSite(None)
         super(BrowserTestCase, self).tearDown()
 
@@ -191,7 +198,8 @@
         if outstream is None:
             outstream = HTTPTaskStub()
         environment = {"HTTP_HOST": 'localhost',
-                       "HTTP_REFERER": 'localhost'}
+                       "HTTP_REFERER": 'localhost',
+                       "HTTP_COOKIE": self.__http_cookie(path)}
         environment.update(env)
         app = FunctionalTestSetup().getApplication()
         request = app._request(path, '', outstream,
@@ -200,6 +208,12 @@
                                request=BrowserRequest)
         return request
 
+    def __http_cookie(self, path):
+        '''Return self.cookies as an HTTP_COOKIE environment format string'''
+        l = [m.OutputString() for m in self.cookies.values()
+                if path.startswith(m['path'])]
+        return '; '.join(l)
+
     def publish(self, path, basic=None, form=None, env={},
                 handle_errors=False):
         """Renders an object at a given location.
@@ -217,10 +231,27 @@
         outstream = HTTPTaskStub()
         old_site = self.getSite()
         self.setSite(None)
+        # A cookie header has been sent - ensure that future requests
+        # in this test also send the cookie, as this is what browsers do.
+        # We pull it apart and reassemble the header to block cookies
+        # with invalid paths going through, which may or may not be correct
+        if env.has_key('HTTP_COOKIE'):
+            self.cookies.load(env['HTTP_COOKIE'])
+            del env['HTTP_COOKIE'] # Added again in makeRequest
+
         request = self.makeRequest(path, basic=basic, form=form, env=env,
                                    outstream=outstream)
         response = ResponseWrapper(request.response, outstream, path)
+        if env.has_key('HTTP_COOKIE'):
+            self.cookies.load(env['HTTP_COOKIE'])
         publish(request, handle_errors=handle_errors)
+        # Urgh - need to play with the response's privates to extract
+        # cookies that have been set
+        for k,v in response._cookies.items():
+            k = k.encode('utf8')
+            self.cookies[k] = v['value'].encode('utf8')
+            if self.cookies[k].has_key('Path'):
+                self.cookies[k]['Path'] = v['Path']
         self.setSite(old_site)
         return response
 



More information about the Zope3-Checkins mailing list