[Zope-Checkins] SVN: Zope/trunk/src/Products/Sessions/ Use more canonical interface names; get real test coveage.

Tres Seaver tseaver at palladion.com
Mon May 11 13:29:34 EDT 2009


Log message for revision 99852:
  Use more canonical interface names; get real test coveage.

Changed:
  U   Zope/trunk/src/Products/Sessions/BrowserIdManager.py
  U   Zope/trunk/src/Products/Sessions/tests/testBrowserIdManager.py

-=-
Modified: Zope/trunk/src/Products/Sessions/BrowserIdManager.py
===================================================================
--- Zope/trunk/src/Products/Sessions/BrowserIdManager.py	2009-05-11 17:27:38 UTC (rev 99851)
+++ Zope/trunk/src/Products/Sessions/BrowserIdManager.py	2009-05-11 17:29:33 UTC (rev 99852)
@@ -43,7 +43,7 @@
 from ZPublisher.BeforeTraverse import queryBeforeTraverse
 from zope.interface import implements
 
-from Products.Sessions.SessionInterfaces import BrowserIdManagerInterface
+from Products.Sessions.SessionInterfaces import IBrowserIdManager
 from Products.Sessions.SessionPermissions import ACCESS_CONTENTS_PERM
 from Products.Sessions.SessionPermissions import CHANGE_IDMGR_PERM
 from Products.Sessions.SessionPermissions import MGMT_SCREEN_PERM
@@ -82,25 +82,15 @@
     if REQUEST is not None:
         return self.manage_main(self, REQUEST, update_menu=1)
     
-class BrowserIdManagerErr(Exception): pass
+class BrowserIdManagerErr(ValueError): # BBB
+    pass
     
 class BrowserIdManager(Item, Persistent, Implicit, RoleManager, Owned, Tabs):
-    """ browser id management class """
-
+    """ browser id management class
+    """
+    implements(IBrowserIdManager)
     meta_type = 'Browser Id Manager'
 
-    manage_options=(
-        {'label': 'Settings',
-         'action':'manage_browseridmgr',
-         },
-        {'label': 'Security', 'action':'manage_access'},
-        {'label': 'Ownership', 'action':'manage_owner'}
-        )
-
-    implements(BrowserIdManagerInterface)
-
-    icon = 'misc_/Sessions/idmgr.gif'
-
     security = ClassSecurityInfo()
     security.declareObjectPublic()
     ok = {'meta_type':1, 'id':1, 'title': 1, 'icon':1,
@@ -110,7 +100,7 @@
     security.setPermissionDefault(ACCESS_CONTENTS_PERM,['Manager','Anonymous'])
     security.setPermissionDefault(CHANGE_IDMGR_PERM, ['Manager'])
 
-    # backwards-compatibility for pre-2.6 instances
+    # BBB
     auto_url_encoding = 0
 
     def __init__(self, id, title='', idname='_ZopeId',
@@ -128,31 +118,20 @@
         self.setCookieHTTPOnly(cookiehttponly)
         self.setAutoUrlEncoding(auto_url_encoding)
 
-    def manage_afterAdd(self, item, container):
-        """ Maybe add our traversal hook """
-        self.updateTraversalData()
-
-    def manage_beforeDelete(self, item, container):
-        """ Remove our traversal hook if it exists """
-        self.unregisterTraversalHook()
-
+    # IBrowserIdManager
     security.declareProtected(ACCESS_CONTENTS_PERM, 'hasBrowserId')
     def hasBrowserId(self):
-        """ Returns true if there is a current browser id, but does
-        not create a browser id for the current request if one doesn't
-        already exist """
-        if self.getBrowserId(create=0): return 1
+        """ See IBrowserIdManager.
+        """
+        try:
+            return self.getBrowserId(create=0) is not None
+        except BrowserIdManagerErr:
+            return False
                 
     security.declareProtected(ACCESS_CONTENTS_PERM, 'getBrowserId')
     def getBrowserId(self, create=1):
+        """ See IBrowserIdManager.
         """
-        Examines the request and hands back browser id value or
-        None if no id exists.  If there is no browser id
-        and if 'create' is true, create one.  If cookies are are
-        an allowable id namespace and create is true, set one.  Stuff
-        the id and the namespace it was found in into the REQUEST object
-        for further reference during this request.
-        """
         REQUEST = self.REQUEST
         # let's see if bid has already been attached to request
         bid = getattr(REQUEST, 'browser_id_', None)
@@ -162,10 +141,9 @@
             if not isAWellFormedBrowserId(bid):
                 # somebody screwed with the REQUEST instance during
                 # this request.
-                raise BrowserIdManagerErr, (
-                    'Ill-formed browserid in REQUEST.browser_id_:  %s' % 
-                    escape(bid)
-                    )
+                raise BrowserIdManagerErr(
+                                'Ill-formed browserid in '
+                                'REQUEST.browser_id_:  %s' % escape(bid))
             return bid
         # fall through & ck form/cookie namespaces if bid is not in request.
         tk = self.browserid_name
@@ -196,71 +174,84 @@
         # implies a return of None if:
         # (not create=1) and (invalid or ((not in req) and (not in ns)))
 
-    security.declareProtected(ACCESS_CONTENTS_PERM, 'flushBrowserIdCookie')
-    def flushBrowserIdCookie(self):
-        """ removes the bid cookie from the client browser """
-        if 'cookies' not in self.browserid_namespaces:
-            raise BrowserIdManagerErr,('Cookies are not now being used as a '
-                                       'browser id namespace, thus the '
-                                       'browserid cookie cannot be flushed.')
-        self._setCookie('deleted', self.REQUEST, remove=1)
+    security.declareProtected(ACCESS_CONTENTS_PERM, 'getBrowserIdName')
+    def getBrowserIdName(self):
+        """ See IBrowserIdManager.
+        """
+        return self.browserid_name
 
-    security.declareProtected(ACCESS_CONTENTS_PERM,'setBrowserIdCookieByForce')
-    def setBrowserIdCookieByForce(self, bid):
-        """ """
-        if 'cookies' not in self.browserid_namespaces:
-            raise BrowserIdManagerErr,('Cookies are not now being used as a '
-                                       'browser id namespace, thus the '
-                                       'browserid cookie cannot be forced.')
-        self._setCookie(bid, self.REQUEST)
+    security.declareProtected(ACCESS_CONTENTS_PERM, 'isBrowserIdNew')
+    def isBrowserIdNew(self):
+        """ See IBrowserIdManager.
+        """
+        if not self.getBrowserId(create=False):
+            raise BrowserIdManagerErr('There is no current browser id.')
+        # ns will be None if new
+        return getattr(self.REQUEST, 'browser_id_ns_', None) is None
 
     security.declareProtected(ACCESS_CONTENTS_PERM, 'isBrowserIdFromCookie')
     def isBrowserIdFromCookie(self):
-        """ returns true if browser id is from REQUEST.cookies """
-        if not self.getBrowserId(): # make sure the bid is stuck on REQUEST
-            raise BrowserIdManagerErr, 'There is no current browser id.'
+        """ See IBrowserIdManager.
+        """
+        if not self.getBrowserId(create=False):
+            raise BrowserIdManagerErr('There is no current browser id.')
         if getattr(self.REQUEST, 'browser_id_ns_') == 'cookies':
             return 1
 
     security.declareProtected(ACCESS_CONTENTS_PERM, 'isBrowserIdFromForm')
     def isBrowserIdFromForm(self):
-        """ returns true if browser id is from REQUEST.form """
-        if not self.getBrowserId(): # make sure the bid is stuck on REQUEST
-            raise BrowserIdManagerErr, 'There is no current browser id.'
+        """ See IBrowserIdManager.
+        """
+        if not self.getBrowserId(create=False):
+            raise BrowserIdManagerErr('There is no current browser id.')
         if getattr(self.REQUEST, 'browser_id_ns_') == 'form':
             return 1
 
     security.declareProtected(ACCESS_CONTENTS_PERM, 'isBrowserIdFromUrl')
     def isBrowserIdFromUrl(self):
-        """ returns true if browser id is from first element of the
-        URL """
-        if not self.getBrowserId(): # make sure the bid is stuck on REQUEST
-            raise BrowserIdManagerErr, 'There is no current browser id.'
+        """ See IBrowserIdManager.
+        """
+        if not self.getBrowserId(create=False):
+            raise BrowserIdManagerErr('There is no current browser id.')
         if getattr(self.REQUEST, 'browser_id_ns_') == 'url':
             return 1
 
-    security.declareProtected(ACCESS_CONTENTS_PERM, 'isBrowserIdNew')
-    def isBrowserIdNew(self):
+    security.declareProtected(ACCESS_CONTENTS_PERM, 'flushBrowserIdCookie')
+    def flushBrowserIdCookie(self):
+        """ See IBrowserIdManager.
         """
-        returns true if browser id is 'new', meaning the id exists
-        but it has not yet been acknowledged by the client (the client
-        hasn't sent it back to us in a cookie or in a formvar).
+        if 'cookies' not in self.browserid_namespaces:
+            raise BrowserIdManagerErr(
+                            'Cookies are not now being used as a '
+                            'browser id namespace, thus the '
+                            'browserid cookie cannot be flushed.')
+        self._setCookie('deleted', self.REQUEST, remove=1)
+
+    security.declareProtected(ACCESS_CONTENTS_PERM,'setBrowserIdCookieByForce')
+    def setBrowserIdCookieByForce(self, bid):
+        """ See IBrowserIdManager.
         """
-        if not self.getBrowserId(): # make sure the id is stuck on REQUEST
-            raise BrowserIdManagerErr, 'There is no current browser id.'
-        # ns will be None if new, negating None below returns 1, which
-        # would indicate that it's new on this request
-        return getattr(self.REQUEST, 'browser_id_ns_', None) == None
+        if 'cookies' not in self.browserid_namespaces:
+            raise BrowserIdManagerErr(
+                            'Cookies are not now being used as a '
+                            'browser id namespace, thus the '
+                            'browserid cookie cannot be forced.')
+        self._setCookie(bid, self.REQUEST)
+
+    security.declareProtected(ACCESS_CONTENTS_PERM, 'getHiddenFormField')
+    def getHiddenFormField(self):
+        """ See IBrowserIdManager.
+        """
+        s = '<input type="hidden" name="%s" value="%s" />'
+        return s % (self.getBrowserIdName(), self.getBrowserId())
     
     security.declareProtected(ACCESS_CONTENTS_PERM, 'encodeUrl')
     def encodeUrl(self, url, style='querystring', create=1):
+        """ See IBrowserIdManager.
         """
-        encode a URL with the browser id as a postfixed query string
-        element or inlined into the url depending on the 'style' parameter
-        """
         bid = self.getBrowserId(create)
         if bid is None:
-            raise BrowserIdManagerErr, 'There is no current browser id.'
+            raise BrowserIdManagerErr('There is no current browser id.')
         name = self.getBrowserIdName()
         if style == 'querystring': # encode bid in querystring
             if '?' in url:
@@ -272,43 +263,18 @@
             path = '/%s/%s%s' % (name, bid, path)
             return urlunparse((proto, host, path, params, query, frag))
 
-    security.declareProtected(MGMT_SCREEN_PERM, 'manage_browseridmgr')
-    manage_browseridmgr = DTMLFile('dtml/manageIdManager', globals())
-
-    security.declareProtected(CHANGE_IDMGR_PERM,
-                              'manage_changeBrowserIdManager')
-    def manage_changeBrowserIdManager(
-        self, title='', idname='_ZopeId', location=('cookies', 'form'),
-        cookiepath='/', cookiedomain='', cookielifedays=0, cookiesecure=0,
-        cookiehttponly=0, auto_url_encoding=0,  REQUEST=None
-        ):
-        """ """
-        self.title = str(title)
-        self.setBrowserIdName(idname)
-        self.setCookiePath(cookiepath)
-        self.setCookieDomain(cookiedomain)
-        self.setCookieLifeDays(cookielifedays)
-        self.setCookieSecure(cookiesecure)
-        self.setCookieHTTPOnly(cookiehttponly)
-        self.setBrowserIdNamespaces(location)
-        self.setAutoUrlEncoding(auto_url_encoding)
-        self.updateTraversalData()
-        if REQUEST is not None:
-            msg = '/manage_browseridmgr?manage_tabs_message=Changes saved'
-            REQUEST.RESPONSE.redirect(self.absolute_url()+msg)
-
+    # Non-IBrowserIdManager accessors / mutators.
     security.declareProtected(CHANGE_IDMGR_PERM, 'setBrowserIdName')
     def setBrowserIdName(self, k):
-        """ sets browser id name string """
+        """ Set browser id name string
+
+        o Enforce "valid" values.
+        """
         if not (type(k) is type('') and k and not badidnamecharsin(k)):
-            raise BrowserIdManagerErr,'Bad id name string %s' % escape(repr(k))
+            raise BrowserIdManagerErr(
+                            'Bad id name string %s' % escape(repr(k)))
         self.browserid_name = k
 
-    security.declareProtected(ACCESS_CONTENTS_PERM, 'getBrowserIdName')
-    def getBrowserIdName(self):
-        """ """
-        return self.browserid_name
-
     security.declareProtected(CHANGE_IDMGR_PERM, 'setBrowserIdNamespaces')
     def setBrowserIdNamespaces(self, ns):
         """
@@ -316,9 +282,8 @@
         """
         for name in ns:
             if name not in ALLOWED_BID_NAMESPACES:
-                raise BrowserIdManagerErr, (
-                    'Bad browser id namespace %s' % repr(name)
-                    )
+                raise BrowserIdManagerErr(
+                            'Bad browser id namespace %s' % repr(name))
         self.browserid_namespaces = tuple(ns)
 
     security.declareProtected(ACCESS_CONTENTS_PERM, 'getBrowserIdNamespaces')
@@ -330,7 +295,8 @@
     def setCookiePath(self, path=''):
         """ sets cookie 'path' element for id cookie """
         if not (type(path) is type('') and not badcookiecharsin(path)):
-            raise BrowserIdManagerErr,'Bad cookie path %s' % escape(repr(path))
+            raise BrowserIdManagerErr(
+                            'Bad cookie path %s' % escape(repr(path)))
         self.cookie_path = path
 
     security.declareProtected(ACCESS_CONTENTS_PERM, 'getCookiePath')
@@ -342,10 +308,9 @@
     def setCookieLifeDays(self, days):
         """ offset for id cookie 'expires' element """
         if type(days) not in (type(1), type(1.0)):
-            raise BrowserIdManagerErr,(
-                'Bad cookie lifetime in days %s (requires integer value)'
-                % escape(repr(days))
-                )
+            raise BrowserIdManagerErr(
+                            'Bad cookie lifetime in days %s '
+                            '(requires integer value)' % escape(repr(days)))
         self.cookie_life_days = int(days)
 
     security.declareProtected(ACCESS_CONTENTS_PERM, 'getCookieLifeDays')
@@ -357,22 +322,21 @@
     def setCookieDomain(self, domain):
         """ sets cookie 'domain' element for id cookie """
         if type(domain) is not type(''):
-            raise BrowserIdManagerErr, (
-                'Cookie domain must be string: %s' % escape(repr(domain))
-                )
+            raise BrowserIdManagerErr(
+                            'Cookie domain must be string: %s'
+                                % escape(repr(domain)))
         if not domain:
             self.cookie_domain = ''
             return
         if not twodotsin(domain):
-            raise BrowserIdManagerErr, (
-                'Cookie domain must contain at least two dots (e.g. '
-                '".zope.org" or "www.zope.org") or it must be left blank. : '
-                '%s' % escape(`domain`)
-                )
+            raise BrowserIdManagerErr(
+                            'Cookie domain must contain at least two dots '
+                            '(e.g. ".zope.org" or "www.zope.org") or it must '
+                            'be left blank. : ' '%s' % escape(`domain`))
         if badcookiecharsin(domain):
-            raise BrowserIdManagerErr, (
-                'Bad characters in cookie domain %s' % escape(`domain`)
-                )
+            raise BrowserIdManagerErr(
+                            'Bad characters in cookie domain %s'
+                                % escape(`domain`))
         self.cookie_domain = domain
 
     security.declareProtected(ACCESS_CONTENTS_PERM, 'getCookieDomain')
@@ -416,15 +380,6 @@
         for this browser id """
         return 'url' in self.browserid_namespaces
 
-    security.declareProtected(ACCESS_CONTENTS_PERM, 'getHiddenFormField')
-    def getHiddenFormField(self):
-        """
-        Convenience method which returns a hidden form element
-        representing the current browser id name and browser id
-        """
-        s = '<input type="hidden" name="%s" value="%s">'
-        return s % (self.getBrowserIdName(), self.getBrowserId())
-
     def _setCookie(
         self, bid, REQUEST, remove=0, now=time.time, strftime=time.strftime,
         gmtime=time.gmtime
@@ -459,13 +414,15 @@
 
     def _setId(self, id):
         if id != self.id:
-            raise MessageDialog(
-                title='Cannot rename',
-                message='You cannot rename a browser id manager, sorry!',
-                action ='./manage_main',)
+            raise ValueError('Cannot rename a browser id manager')
 
+    # Jukes for handling URI-munged browser IDS
+    def hasTraversalHook(self, parent):
+        name = TRAVERSAL_APPHANDLE
+        return not not queryBeforeTraverse(parent, name)
+
     def updateTraversalData(self):
-        if self.isUrlInBidNamespaces():
+        if 'url' in self.browserid_namespaces:
             self.registerTraversalHook()
         else:
             self.unregisterTraversalHook()
@@ -484,10 +441,48 @@
             priority = 40 # "higher" priority than session data traverser
             registerBeforeTraverse(parent, hook, name, priority)
 
-    def hasTraversalHook(self, parent):
-        name = TRAVERSAL_APPHANDLE
-        return not not queryBeforeTraverse(parent, name)
+    # ZMI
+    icon = 'misc_/Sessions/idmgr.gif'
+    manage_options=({'label': 'Settings', 'action':'manage_browseridmgr'},
+                    {'label': 'Security', 'action':'manage_access'},
+                    {'label': 'Ownership', 'action':'manage_owner'},
+                   )
 
+    def manage_afterAdd(self, item, container):
+        """ Maybe add our traversal hook """
+        self.updateTraversalData()
+
+    def manage_beforeDelete(self, item, container):
+        """ Remove our traversal hook if it exists """
+        self.unregisterTraversalHook()
+
+    security.declareProtected(MGMT_SCREEN_PERM, 'manage_browseridmgr')
+    manage_browseridmgr = DTMLFile('dtml/manageIdManager', globals())
+
+    security.declareProtected(CHANGE_IDMGR_PERM,
+                              'manage_changeBrowserIdManager')
+    def manage_changeBrowserIdManager(
+        self, title='', idname='_ZopeId', location=('cookies', 'form'),
+        cookiepath='/', cookiedomain='', cookielifedays=0, cookiesecure=0,
+        cookiehttponly=0, auto_url_encoding=0,  REQUEST=None
+        ):
+        """ """
+        self.title = str(title)
+        self.setBrowserIdName(idname)
+        self.setCookiePath(cookiepath)
+        self.setCookieDomain(cookiedomain)
+        self.setCookieLifeDays(cookielifedays)
+        self.setCookieSecure(cookiesecure)
+        self.setCookieHTTPOnly(cookiehttponly)
+        self.setBrowserIdNamespaces(location)
+        self.setAutoUrlEncoding(auto_url_encoding)
+        self.updateTraversalData()
+        if REQUEST is not None:
+            msg = '/manage_browseridmgr?manage_tabs_message=Changes saved'
+            REQUEST.RESPONSE.redirect(self.absolute_url()+msg)
+
+InitializeClass(BrowserIdManager)
+
 class BrowserIdManagerTraverser(Persistent):
     def __call__(self, container, request, browser_id=None,
                  browser_id_ns=None,
@@ -583,5 +578,3 @@
     """
     return '%08i%s' % (randint(0, maxint-1), getB64TStamp())
 
-
-InitializeClass(BrowserIdManager)

Modified: Zope/trunk/src/Products/Sessions/tests/testBrowserIdManager.py
===================================================================
--- Zope/trunk/src/Products/Sessions/tests/testBrowserIdManager.py	2009-05-11 17:27:38 UTC (rev 99851)
+++ Zope/trunk/src/Products/Sessions/tests/testBrowserIdManager.py	2009-05-11 17:29:33 UTC (rev 99852)
@@ -12,289 +12,648 @@
 ##############################################################################
 """
 Test suite for session id manager.
-
-$Id$
 """
-__version__ = "$Revision: 1.13 $"[11:-2]
+import unittest
 
-import sys
-import ZODB
-from Products.Sessions.BrowserIdManager import BrowserIdManager, \
-     BrowserIdManagerErr, BrowserIdManagerTraverser, \
-     isAWellFormedBrowserId
-from unittest import TestCase, TestSuite, TextTestRunner, makeSuite
-from ZPublisher.HTTPRequest import HTTPRequest
-from ZPublisher.HTTPResponse import HTTPResponse
-from ZPublisher.BeforeTraverse import queryBeforeTraverse
-from sys import stdin
-from OFS.Application import Application
+class TestBrowserIdManager(unittest.TestCase):
 
-class TestBrowserIdManager(TestCase):
-    def setUp(self):
-        self.app = Application()
-        self.app.id = 'App'
-        mgr = BrowserIdManager('browser_id_manager')
-        self.app._setObject('browser_id_manager', mgr)
-        self.m = self.app.browser_id_manager
-        resp = HTTPResponse()
-        environ = {}
-        environ['SERVER_NAME']='fred'
-        environ['SERVER_PORT']='80'
-        self.req = HTTPRequest(stdin, environ, resp)
-        self.req['TraversalRequestNameStack'] = ['foo', 'bar']
-        self.app.REQUEST = self.req
+    def _getTargetClass(self):
+        from Products.Sessions.BrowserIdManager import BrowserIdManager
+        return BrowserIdManager
 
-    def tearDown(self):
-        del self.m
-        self.app.REQUEST = None
-        del self.app
+    def _makeOne(self, request=None, name='browser_id_manager'):
+        bid = self._getTargetClass()(name)
+        if request is not None:
+            bid.REQUEST = request
+        return bid
 
-    def testSetBrowserIdName(self):
-        self.m.setBrowserIdName('foo')
-        self.failUnless(self.m.getBrowserIdName()== 'foo')
+    def test_hasBrowserId_already_set_on_request_invalid(self):
+        request = DummyRequest(browser_id_='xxx')
+        mgr = self._makeOne(request)
+        self.failIf(mgr.hasBrowserId())
 
-    def testSetBadBrowserIdName(self):
-        self.assertRaises(BrowserIdManagerErr,
-                          lambda self=self: self.m.setBrowserIdName(''))
-        self.assertRaises(BrowserIdManagerErr,
-                          lambda self=self: self.m.setBrowserIdName(1))
+    def test_hasBrowserId_already_set_on_request(self):
+        from Products.Sessions.BrowserIdManager import getNewBrowserId
+        request = DummyRequest(browser_id_=getNewBrowserId())
+        mgr = self._makeOne(request)
+        self.failUnless(mgr.hasBrowserId())
 
-    def testSetBadNamespaces(self):
-        d = ('gummy', 'froopy')
-        self.assertRaises(BrowserIdManagerErr,
-                          lambda self=self,d=d:
-                          self.m.setBrowserIdNamespaces(d))
+    def test_hasBrowserId_namespace_hit(self):
+        from Products.Sessions.BrowserIdManager import getNewBrowserId
+        request = DummyRequest(cookies={'bid': getNewBrowserId()})
+        mgr = self._makeOne(request)
+        mgr.setBrowserIdName('bid')
+        self.failUnless(mgr.hasBrowserId())
 
-    def testSetGoodNamespaces(self):
-        d = ('cookies', 'url', 'form')
-        self.m.setBrowserIdNamespaces(d)
-        self.failUnless(self.m.getBrowserIdNamespaces() == d)
+    def test_hasBrowserId_namespace_miss(self):
+        request = DummyRequest()
+        mgr = self._makeOne(request)
+        self.failIf(mgr.hasBrowserId())
+        self.assertRaises(AttributeError, getattr, request, 'browser_id_')
+        self.assertRaises(AttributeError, getattr, request, 'browser_id_ns_')
 
-    def testSetBadCookiePath(self):
-        path = '/;'
-        self.assertRaises(BrowserIdManagerErr,
-                        lambda self=self, path=path:self.m.setCookiePath(path))
+    def test_getBrowserId_already_set_on_request_invalid_raises(self):
+        request = DummyRequest(browser_id_='xxx')
+        mgr = self._makeOne(request)
+        self.assertRaises(ValueError, mgr.getBrowserId)
 
-    def testSetGoodCookiePath(self):
-        self.m.setCookiePath('/foo')
-        self.failUnless(self.m.getCookiePath() == '/foo')
+    def test_getBrowserId_already_set_on_request(self):
+        from Products.Sessions.BrowserIdManager import getNewBrowserId
+        bid = getNewBrowserId()
+        request = DummyRequest(browser_id_=bid)
+        mgr = self._makeOne(request)
+        self.assertEqual(mgr.getBrowserId(), bid)
 
-    def testSetBadCookieLifeDays(self):
-        self.assertRaises(BrowserIdManagerErr,
-                          lambda self=self: self.m.setCookieLifeDays(''))
+    def test_getBrowserId_namespace_hit(self):
+        from Products.Sessions.BrowserIdManager import getNewBrowserId
+        bid = getNewBrowserId()
+        request = DummyRequest(cookies={'bid': bid})
+        mgr = self._makeOne(request)
+        mgr.setBrowserIdName('bid')
+        self.failUnless(mgr.hasBrowserId())
+        self.assertEqual(request.browser_id_, bid)
+        self.assertEqual(request.browser_id_ns_, 'cookies')
 
-    def testSetGoodCookieLifeDays(self):
-        self.m.setCookieLifeDays(1)
-        self.failUnless(self.m.getCookieLifeDays() == 1)
+    def test_getBrowserId_namespace_miss_no_create(self):
+        request = DummyRequest()
+        mgr = self._makeOne(request)
+        mgr.setBrowserIdName('bid')
+        self.assertEqual(mgr.getBrowserId(create=False), None)
+        self.assertRaises(AttributeError, getattr, request, 'browser_id_')
+        self.assertRaises(AttributeError, getattr, request, 'browser_id_ns_')
 
-    def testSetBadCookieDomain(self):
-        self.assertRaises(BrowserIdManagerErr,
-                          lambda self=self: self.m.setCookieDomain('gubble'))
+    def test_getBrowserId_namespace_miss_w_create_no_cookies(self):
+        from Products.Sessions.BrowserIdManager import isAWellFormedBrowserId
+        request = DummyRequest()
+        mgr = self._makeOne(request)
+        mgr.setBrowserIdName('bid')
+        mgr.setBrowserIdNamespaces(())
+        bid = mgr.getBrowserId()
+        self.failUnless(isAWellFormedBrowserId(bid))
+        self.assertEqual(request.browser_id_, bid)
+        self.assertEqual(request.browser_id_ns_, None)
 
-    def testSetGoodCookieLifeDays(self):
-        self.m.setCookieLifeDays(1)
-        self.failUnless(self.m.getCookieLifeDays() == 1)
+    def test_getBrowserId_namespace_miss_w_create_w_cookies(self):
+        from Products.Sessions.BrowserIdManager import isAWellFormedBrowserId
+        response = DummyResponse(cookies={})
+        request = DummyRequest(RESPONSE=response)
+        mgr = self._makeOne(request)
+        mgr.setBrowserIdName('bid')
+        mgr.setBrowserIdNamespaces(('cookies',))
+        bid = mgr.getBrowserId()
+        self.failUnless(isAWellFormedBrowserId(bid))
+        self.assertEqual(request.browser_id_, bid)
+        self.assertEqual(request.browser_id_ns_, None)
+        self.assertEqual(response.cookies['bid'], {'path': '/', 'value': bid})
 
-    def testSetNoCookieDomain(self):
-        domain = ''
-        self.m.setCookieDomain(domain)
-        setdomain = self.m.getCookieDomain()
-        self.failUnless(setdomain == domain)
+    def test_isBrowserIdNew_nonesuch_raises(self):
+        request = DummyRequest()
+        mgr = self._makeOne(request)
+        self.assertRaises(ValueError, mgr.isBrowserIdNew)
 
-    def testSetBadCookieDomain(self):
-        # not enough dots, must be stringtype, semicolon follows respectively
-        for domain in ('zope.org', {1:1}, '.zope.org;'):
-            self.assertRaises(BrowserIdManagerErr,
-               lambda self=self, domain=domain: self.m.setCookieDomain(domain))
+    def test_isBrowserIdNew_no_ns(self):
+        from Products.Sessions.BrowserIdManager import getNewBrowserId
+        bid = getNewBrowserId()
+        request = DummyRequest(browser_id_=bid, browser_id_ns_=None)
+        mgr = self._makeOne(request)
+        self.failUnless(mgr.isBrowserIdNew())
 
-    def testSetGoodCookieDomain(self):
-        self.m.setCookieDomain('.zope.org')
-        setdomain = self.m.getCookieDomain()
-        self.failUnless( setdomain == '.zope.org', "%s" % setdomain )
+    def test_isBrowserIdNew_w_ns(self):
+        from Products.Sessions.BrowserIdManager import getNewBrowserId
+        bid = getNewBrowserId()
+        request = DummyRequest(browser_id_=bid, browser_id_ns_='url')
+        mgr = self._makeOne(request)
+        self.failIf(mgr.isBrowserIdNew())
 
-    def testSetCookieSecure(self):
-        self.m.setCookieSecure(1)
-        self.failUnless( self.m.getCookieSecure() == 1 )
+    def test_isBrowserIdFromCookie_nonesuch_raises(self):
+        request = DummyRequest()
+        mgr = self._makeOne(request)
+        self.assertRaises(ValueError, mgr.isBrowserIdFromCookie)
 
-    def testSetCookieHTTPOnly(self):
-        self.m.setCookieHTTPOnly(True)
-        self.assertEqual( self.m.getCookieHTTPOnly(), True )
+    def test_isBrowserIdFromCookie_wrong_ns(self):
+        from Products.Sessions.BrowserIdManager import getNewBrowserId
+        bid = getNewBrowserId()
+        request = DummyRequest(browser_id_=bid, browser_id_ns_='url')
+        mgr = self._makeOne(request)
+        self.failIf(mgr.isBrowserIdFromCookie())
 
-    def testGetBrowserIdCookie(self):
-        token = self.m.getBrowserId()
-        self.m.REQUEST.browser_id_ = token
-        self.m.REQUEST.browser_id_ns_ = 'cookies'
-        tokenkey = self.m.getBrowserIdName()
-        self.m.REQUEST.cookies[tokenkey] = token
-        a = self.m.getBrowserId()
-        self.failUnless( a == token, repr(a) )
-        self.failUnless( self.m.isBrowserIdFromCookie() )
+    def test_isBrowserIdFromCookie_right_ns(self):
+        from Products.Sessions.BrowserIdManager import getNewBrowserId
+        bid = getNewBrowserId()
+        request = DummyRequest(browser_id_=bid, browser_id_ns_='cookies')
+        mgr = self._makeOne(request)
+        self.failUnless(mgr.isBrowserIdFromCookie())
 
-    def testSetBrowserIdDontCreate(self):
-        a = self.m.getBrowserId(0)
-        self.failUnless( a == None )
+    def test_isBrowserIdFromForm_nonesuch_raises(self):
+        request = DummyRequest()
+        mgr = self._makeOne(request)
+        self.assertRaises(ValueError, mgr.isBrowserIdFromForm)
 
-    def testSetBrowserIdCreate(self):
-        a = self.m.getBrowserId(1)
-        tokenkey = self.m.getBrowserIdName()
-        b = self.m.REQUEST.RESPONSE.cookies[tokenkey]
-        self.failUnless( a == b['value'] )
+    def test_isBrowserIdFromForm_wrong_ns(self):
+        from Products.Sessions.BrowserIdManager import getNewBrowserId
+        bid = getNewBrowserId()
+        request = DummyRequest(browser_id_=bid, browser_id_ns_='url')
+        mgr = self._makeOne(request)
+        self.failIf(mgr.isBrowserIdFromForm())
 
-    def testHasBrowserId(self):
-        self.failUnless( not self.m.hasBrowserId() )
-        a = self.m.getBrowserId()
-        self.failUnless( self.m.hasBrowserId() )
+    def test_isBrowserIdFromForm_right_ns(self):
+        from Products.Sessions.BrowserIdManager import getNewBrowserId
+        bid = getNewBrowserId()
+        request = DummyRequest(browser_id_=bid, browser_id_ns_='form')
+        mgr = self._makeOne(request)
+        self.failUnless(mgr.isBrowserIdFromForm())
 
-    def testBrowserIdIsNew(self):
-        a = self.m.getBrowserId()
-        self.failUnless( self.m.isBrowserIdNew() )
+    def test_isBrowserIdFromUrl_nonesuch_raises(self):
+        request = DummyRequest()
+        mgr = self._makeOne(request)
+        self.assertRaises(ValueError, mgr.isBrowserIdFromUrl)
 
-    def testIsBrowserIdFromCookieOnly(self):
-        token = self.m.getBrowserId()
-        self.m.REQUEST.browser_id_ = token
-        self.m.REQUEST.browser_id_ns_ = 'cookies'
-        tokenkey = self.m.getBrowserIdName()
-        self.m.REQUEST.form[tokenkey] = token
-        self.m.setBrowserIdNamespaces(('cookies',))
-        a = self.m.getBrowserId()
-        self.failUnless( self.m.isBrowserIdFromCookie() )
-        self.failUnless( not self.m.isBrowserIdFromForm() )
+    def test_isBrowserIdFromUrl_wrong_ns(self):
+        from Products.Sessions.BrowserIdManager import getNewBrowserId
+        bid = getNewBrowserId()
+        request = DummyRequest(browser_id_=bid, browser_id_ns_='form')
+        mgr = self._makeOne(request)
+        self.failIf(mgr.isBrowserIdFromUrl())
 
-    def testIsBrowserIdFromFormOnly(self):
-        token = self.m.getBrowserId()
-        self.m.REQUEST.browser_id_ = token
-        self.m.REQUEST.browser_id_ns_ = 'form'
-        tokenkey = self.m.getBrowserIdName()
-        self.m.REQUEST.form[tokenkey] = token
-        self.m.setBrowserIdNamespaces(('form',))
-        a = self.m.getBrowserId()
-        self.failUnless( not self.m.isBrowserIdFromCookie() )
-        self.failUnless( self.m.isBrowserIdFromForm() )
+    def test_isBrowserIdFromUrl_right_ns(self):
+        from Products.Sessions.BrowserIdManager import getNewBrowserId
+        bid = getNewBrowserId()
+        request = DummyRequest(browser_id_=bid, browser_id_ns_='url')
+        mgr = self._makeOne(request)
+        self.failUnless(mgr.isBrowserIdFromUrl())
 
-    def testIsBrowserIdFromUrlOnly(self):
-        token = self.m.getBrowserId()
-        self.m.REQUEST.browser_id_ = token
-        self.m.REQUEST.browser_id_ns_ = 'url'
-        self.m.setBrowserIdNamespaces(('url',))
-        a = self.m.getBrowserId()
-        self.failUnless( not self.m.isBrowserIdFromCookie() )
-        self.failUnless( self.m.isBrowserIdFromUrl() )
+    def test_flushBrowserIdCookie_wrong_ns_raises(self):
+        mgr = self._makeOne()
+        mgr.setBrowserIdNamespaces(('url', 'form'))
+        self.assertRaises(ValueError, mgr.flushBrowserIdCookie)
 
-    def testFlushBrowserIdCookie(self):
-        token = self.m.getBrowserId()
-        self.m.REQUEST.browser_id_ = token
-        self.m.REQUEST.browser_id_ns_ = 'cookies'
-        tokenkey = self.m.getBrowserIdName()
-        self.m.REQUEST.cookies[tokenkey] = token
-        a = self.m.getBrowserId()
-        self.failUnless( a == token, repr(a) )
-        self.failUnless( self.m.isBrowserIdFromCookie() )
-        self.m.flushBrowserIdCookie()
-        c = self.m.REQUEST.RESPONSE.cookies[tokenkey]
-        self.failUnless( c['value'] == 'deleted' )
+    def test_flushBrowserIdCookie_ok(self):
+        response = DummyResponse(cookies={})
+        request = DummyRequest(RESPONSE=response)
+        mgr = self._makeOne(request)
+        mgr.setBrowserIdName('bid')
+        mgr.setBrowserIdNamespaces(('cookies',))
+        mgr.flushBrowserIdCookie()
+        self.assertEqual(response.cookies['bid'],
+                         {'path': '/',
+                          'expires': 'Sun, 10-May-1971 11:59:00 GMT',
+                          'value': 'deleted'})
 
-    def testSetBrowserIdCookieByForce(self):
-        token = self.m.getBrowserId()
-        self.m.REQUEST.browser_id_ = token
-        self.m.REQUEST.browser_id_ns_ = 'cookies'
-        tokenkey = self.m.getBrowserIdName()
-        self.m.REQUEST.cookies[tokenkey] = token
-        a = self.m.getBrowserId()
-        self.failUnless( a == token )
-        self.failUnless( self.m.isBrowserIdFromCookie() )
-        token = 'abcdefghijk'
-        self.m.setBrowserIdCookieByForce(token)
-        c = self.m.REQUEST.RESPONSE.cookies[tokenkey]
-        self.failUnless( c['value'] == token )
+    def test_setBrowserIdCookieByForce_wrong_ns_raises(self):
+        from Products.Sessions.BrowserIdManager import getNewBrowserId
+        bid = getNewBrowserId()
+        mgr = self._makeOne()
+        mgr.setBrowserIdNamespaces(('url', 'form'))
+        self.assertRaises(ValueError, mgr.setBrowserIdCookieByForce, bid)
 
-    def testEncodeUrl(self):
-        keystring = self.m.getBrowserIdName()
-        key = self.m.getBrowserId()
-        u = '/home/chrism/foo'
-        r = self.m.encodeUrl(u)
-        self.failUnless( r == '%s?%s=%s' % (u, keystring, key) )
-        u = 'http://www.zope.org/Members/mcdonc?foo=bar&spam=eggs'
-        r = self.m.encodeUrl(u)
-        self.failUnless( r == '%s&amp;%s=%s' % (u, keystring, key) )
-        r = self.m.encodeUrl(u, style='inline')
-        self.failUnless( r == 'http://www.zope.org/%s/%s/Members/mcdonc?foo=bar&spam=eggs' % (keystring, key))
+    def test_setBrowserIdCookieByForce_ok(self):
+        from Products.Sessions.BrowserIdManager import getNewBrowserId
+        bid = getNewBrowserId()
+        response = DummyResponse(cookies={})
+        request = DummyRequest(RESPONSE=response)
+        mgr = self._makeOne(request)
+        mgr.setBrowserIdName('bid')
+        mgr.setBrowserIdNamespaces(('cookies',))
+        mgr.setBrowserIdCookieByForce(bid)
+        self.assertEqual(response.cookies['bid'], {'path': '/', 'value': bid})
 
-    def testGetHiddenFormField(self):
-        keystring = self.m.getBrowserIdName()
-        key = self.m.getBrowserId()
-        html = self.m.getHiddenFormField()
-        expected = ('<input type="hidden" name="%s" value="%s">' %
-                    (keystring, key))
-        self.failUnless( html == expected )
+    def test_getHiddenFormField(self):
+        from Products.Sessions.BrowserIdManager import getNewBrowserId
+        bid = getNewBrowserId()
+        request = DummyRequest(browser_id_=bid)
+        mgr = self._makeOne(request)
+        mgr.setBrowserIdName('bid')
+        self.assertEqual(mgr.getHiddenFormField(),
+                         '<input type="hidden" name="bid" value="%s" />' % bid)
 
-    def testHTTPOnlyCookieAttribute(self):
-        self.m.setCookieHTTPOnly(True)
-        self.failUnless(self.m.getBrowserId())
-        resp_cookies = self.req.RESPONSE.cookies
-        session_cookie = resp_cookies[self.m.browserid_name]
-        self.assertEqual(session_cookie['http_only'], True)
+    def test_encodeUrl_no_create_no_bid_raises(self):
+        URL = 'http://example.com/'
+        request = DummyRequest()
+        mgr = self._makeOne(request)
+        self.assertRaises(ValueError, mgr.encodeUrl, URL, create=False)
 
-    def testSecureCookieAttribute_correct_url(self):
-        self.m.setCookieSecure(1)
-        self.req['URL1'] = 'https://www.test.org'
-        self.failUnless(self.m.getBrowserId())
-        resp_cookies = self.req.RESPONSE.cookies
-        session_cookie = resp_cookies[self.m.browserid_name]
-        self.assertEqual(session_cookie['secure'], True)
+    def test_encodeUrl_no_create_w_bid_querystring_style(self):
+        from Products.Sessions.BrowserIdManager import getNewBrowserId
+        URL = 'http://example.com/'
+        bid = getNewBrowserId()
+        request = DummyRequest(browser_id_=bid)
+        mgr = self._makeOne(request)
+        mgr.setBrowserIdName('bid')
+        munged = mgr.encodeUrl(URL, create=False)
+        self.assertEqual(munged, '%s?bid=%s' % (URL, bid))
 
-    # This test document the 'feature':
-    # return a browser ID but dont set the cookie 
-    def testSecureCookieAttribute_wrong_url(self):
-        self.m.setCookieSecure(1)
-        self.req['URL1'] = 'http://www.test.org'
-        self.failUnless(self.m.getBrowserId())
-        self.assertEqual( self.req.RESPONSE.cookies, {} )
+    def test_encodeUrl_no_create_w_bid_querystring_style_existing_qs(self):
+        from Products.Sessions.BrowserIdManager import getNewBrowserId
+        URL = 'http://example.com/'
+        QS = 'foo=bar'
+        bid = getNewBrowserId()
+        request = DummyRequest(browser_id_=bid)
+        mgr = self._makeOne(request)
+        mgr.setBrowserIdName('bid')
+        munged = mgr.encodeUrl('%s?%s' % (URL, QS), create=False)
+        self.assertEqual(munged, '%s?%s&amp;bid=%s' % (URL, QS, bid))
+
+    def test_encodeUrl_no_create_w_bid_inline_style(self):
+        from Products.Sessions.BrowserIdManager import getNewBrowserId
+        NETHOST = 'http://example.com'
+        PATH_INFO = 'path/to/page'
+        URL = '%s/%s' % (NETHOST, PATH_INFO)
+        bid = getNewBrowserId()
+        request = DummyRequest(browser_id_=bid)
+        mgr = self._makeOne(request)
+        mgr.setBrowserIdName('bid')
+        munged = mgr.encodeUrl(URL, style='inline', create=False)
+        self.assertEqual(munged, '%s/bid/%s/%s' % (NETHOST, bid, PATH_INFO))
+
+    def test_setBrowserIdName_empty_string_raises(self):
+        mgr = self._makeOne()
+        self.assertRaises(ValueError, mgr.setBrowserIdName, '')
+
+    def test_setBrowserIdName_non_string_raises(self):
+        mgr = self._makeOne()
+        self.assertRaises(ValueError, mgr.setBrowserIdName, 1)
+
+    def test_setBrowserIdName_normal(self):
+        mgr = self._makeOne()
+        mgr.setBrowserIdName('foo')
+        self.assertEqual(mgr.getBrowserIdName(), 'foo')
+
+    def test_setBrowserIdNamespaces_invalid_raises(self):
+        mgr = self._makeOne()
+        self.assertRaises(ValueError,
+                          mgr.setBrowserIdNamespaces, ('gummy', 'froopy'))
+
+    def test_setBrowserIdNamespaces_normal(self):
+        NAMESPACES = ('cookies', 'url', 'form')
+        mgr = self._makeOne()
+        mgr.setBrowserIdNamespaces(NAMESPACES)
+        self.assertEqual(mgr.getBrowserIdNamespaces(), NAMESPACES)
+
+    def test_setCookiePath_invalid_raises(self):
+        mgr = self._makeOne()
+        self.assertRaises(ValueError, mgr.setCookiePath, '/;')
+
+    def test_setCookiePath_normal(self):
+        mgr = self._makeOne()
+        mgr.setCookiePath('/foo')
+        self.assertEqual(mgr.getCookiePath(), '/foo')
+
+    def test_setCookieLifeDays_invalid_raises(self):
+        mgr = self._makeOne()
+        self.assertRaises(ValueError, mgr.setCookieLifeDays, '')
+
+    def test_setCookieLifeDays_normal(self):
+        mgr = self._makeOne()
+        mgr.setCookieLifeDays(1)
+        self.assertEqual(mgr.getCookieLifeDays(), 1)
+
+    def test_setCookieDomain_non_string_raises(self):
+        mgr = self._makeOne()
+        self.assertRaises(ValueError, mgr.setCookieDomain, {1:1})
+
+    def test_setCookieDomain_no_dots_raises(self):
+        mgr = self._makeOne()
+        self.assertRaises(ValueError, mgr.setCookieDomain, 'gubble')
+
+    def test_setCookieDomain_one_dot_raises(self):
+        mgr = self._makeOne()
+        self.assertRaises(ValueError, mgr.setCookieDomain, 'zope.org')
+
+    def test_setCookieDomain_trailing_semicolon_raises(self):
+        mgr = self._makeOne()
+        self.assertRaises(ValueError, mgr.setCookieDomain, '.zope.org;')
+
+    def test_setCookieDomain_empty_OK(self):
+        mgr = self._makeOne()
+        mgr.setCookieDomain('')
+        self.assertEqual(mgr.getCookieDomain(), '')
+
+    def test_setCookieDomain_two_dots(self):
+        mgr = self._makeOne()
+        mgr.setCookieDomain('.zope.org')
+        self.assertEqual(mgr.getCookieDomain(), '.zope.org')
+
+    def test_setCookieDomain_three_dots(self):
+        mgr = self._makeOne()
+        mgr.setCookieDomain('.dev.zope.org')
+        self.assertEqual(mgr.getCookieDomain(), '.dev.zope.org')
+
+    def test_setCookieSecure_int(self):
+        mgr = self._makeOne()
+        mgr.setCookieSecure(1)
+        self.failUnless(mgr.getCookieSecure())
+        mgr.setCookieSecure(0)
+        self.failIf(mgr.getCookieSecure())
+
+    def test_setCookieSecure_bool(self):
+        mgr = self._makeOne()
+        mgr.setCookieSecure(True)
+        self.failUnless(mgr.getCookieSecure())
+        mgr.setCookieSecure(False)
+        self.failIf(mgr.getCookieSecure())
+
+    def test_setCookieHTTPOnly_bool(self):
+        mgr = self._makeOne()
+        mgr.setCookieHTTPOnly(True)
+        self.failUnless(mgr.getCookieHTTPOnly())
+        mgr.setCookieHTTPOnly(False)
+        self.failIf(mgr.getCookieHTTPOnly())
+
+    def test_setAutoUrlEncoding_bool(self):
+        mgr = self._makeOne()
+        mgr.setAutoUrlEncoding(True)
+        self.failUnless(mgr.getAutoUrlEncoding())
+        mgr.setAutoUrlEncoding(False)
+        self.failIf(mgr.getAutoUrlEncoding())
+
+    def test_isUrlInBidNamespaces(self):
+        mgr = self._makeOne()
+        mgr.setBrowserIdNamespaces(('cookies', 'url', 'form'))
+        self.failUnless(mgr.isUrlInBidNamespaces())
+        mgr.setBrowserIdNamespaces(('cookies', 'form'))
+        self.failIf(mgr.isUrlInBidNamespaces())
+
+    def test__setCookie_remove(self):
+        response = DummyResponse(cookies={})
+        request = DummyRequest(RESPONSE=response)
+        mgr = self._makeOne(request)
+        mgr.setBrowserIdName('bid')
+        mgr._setCookie('xxx', request, remove=True)
+        self.assertEqual(response.cookies['bid'],
+                         {'path': '/', 'value': 'xxx',
+                          'expires': 'Sun, 10-May-1971 11:59:00 GMT'})
+
+    def test__setCookie_cookie_life_days(self):
+        response = DummyResponse(cookies={})
+        request = DummyRequest(RESPONSE=response)
+        mgr = self._makeOne(request)
+        mgr.setBrowserIdName('bid')
+        mgr.setCookieLifeDays(1)
+        mgr._setCookie('xxx', request,
+                       now=lambda: 1,
+                       strftime=lambda x, y: 'Seconds: %d' % y,
+                       gmtime=lambda x: x)
+        self.assertEqual(response.cookies['bid'],
+                         {'path': '/', 'value': 'xxx',
+                          'expires': 'Seconds: 86401'})
+
+    def test__setCookie_cookie_secure_no_URL1_sets_no_cookie(self):
+        request = DummyRequest()
+        mgr = self._makeOne(request)
+        mgr.setBrowserIdName('bid')
+        mgr.setCookieSecure(True)
+        mgr._setCookie('xxx', request) # no response, doesn't blow up
+
+    def test__setCookie_cookie_secure_not_https_sets_no_cookie(self):
+        request = DummyRequest(URL1='http://example.com/')
+        mgr = self._makeOne(request)
+        mgr.setBrowserIdName('bid')
+        mgr.setCookieSecure(True)
+        mgr._setCookie('xxx', request) # no response, doesn't blow up
+
+    def test__setCookie_cookie_secure_is_https(self):
+        response = DummyResponse(cookies={})
+        request = DummyRequest(RESPONSE=response, URL1='https://example.com/')
+        mgr = self._makeOne(request)
+        mgr.setBrowserIdName('bid')
+        mgr.setCookieSecure(True)
+        mgr._setCookie('xxx', request)
+        self.assertEqual(response.cookies['bid'],
+                         {'path': '/', 'value': 'xxx', 'secure': True})
+
+    def test__setCookie_domain(self):
+        response = DummyResponse(cookies={})
+        request = DummyRequest(RESPONSE=response)
+        mgr = self._makeOne(request)
+        mgr.setBrowserIdName('bid')
+        mgr.setCookieDomain('.zope.org')
+        mgr._setCookie('xxx', request)
+        self.assertEqual(response.cookies['bid'],
+                         {'path': '/', 'value': 'xxx', 'domain': '.zope.org'})
+
+    def test__setCookie_path(self):
+        response = DummyResponse(cookies={})
+        request = DummyRequest(RESPONSE=response)
+        mgr = self._makeOne(request)
+        mgr.setBrowserIdName('bid')
+        mgr.setCookiePath('/path/')
+        mgr._setCookie('xxx', request)
+        self.assertEqual(response.cookies['bid'],
+                         {'path': '/path/', 'value': 'xxx'})
+
+    def test__setCookie_http_only(self):
+        response = DummyResponse(cookies={})
+        request = DummyRequest(RESPONSE=response, URL1='https://example.com/')
+        mgr = self._makeOne(request)
+        mgr.setBrowserIdName('bid')
+        mgr.setCookieHTTPOnly(True)
+        mgr._setCookie('xxx', request)
+        self.assertEqual(response.cookies['bid'],
+                         {'path': '/', 'value': 'xxx', 'http_only': True})
+
+    def test__setId_same_id_noop(self):
+        mgr = self._makeOne(name='foo')
+        mgr._setId('foo')
+
+    def test__setId_different_id_raises(self):
+        mgr = self._makeOne(name='foo')
+        self.assertRaises(ValueError, mgr._setId, 'bar')
+
+    def test_setCookieSecure_non_HTTPS_doesnt_set_cookie(self):
+        # Document the "feature" that 'setCookieSecure' allows returning
+        # a browser ID even where the URL is not HTTPS, and therefor no
+        # cookie is set.
+        response = DummyResponse(cookies={})
+        request = DummyRequest(RESPONSE=response, URL1='http://example.com/')
+        mgr = self._makeOne(request)
+        mgr.setCookieSecure(1)
+        bid = mgr.getBrowserId() # doesn't raise
+        self.assertEqual(len(response.cookies), 0)
+
+    def test_hasTraversalHook_missing(self):
+        mgr = self._makeOne()
+        parent = DummyObject()
+        self.failIf(mgr.hasTraversalHook(parent))
+
+    def test_hasTraversalHook_present(self):
+        mgr = self._makeOne()
+        parent = DummyObject()
+        parent.__before_traverse__ = {(0, 'BrowserIdManager'): object()}
+        self.failUnless(mgr.hasTraversalHook(parent))
+
+    def test_updateTraversalData_w_url_ns(self):
+        from Acquisition import Implicit
+        from ZPublisher.BeforeTraverse import queryBeforeTraverse
+        from Products.Sessions.BrowserIdManager import BrowserIdManagerTraverser
+        class Parent(Implicit):
+            pass
+        mgr = self._makeOne()
+        mgr.setBrowserIdNamespaces(('url',))
+        parent = Parent()
+        parent.browser_id_manager = mgr
+        parent.browser_id_manager.updateTraversalData() # needs wrapper
+        hooks = queryBeforeTraverse(parent, 'BrowserIdManager')
+        self.assertEqual(len(hooks), 1)
+        self.assertEqual(hooks[0][0], 40)
+        self.failUnless(isinstance(hooks[0][1], BrowserIdManagerTraverser))
+
+    def test_updateTraversalData_not_url_ns(self):
+        from Acquisition import Implicit
+        from ZPublisher.BeforeTraverse import queryBeforeTraverse
+        class Parent(Implicit):
+            pass
+        mgr = self._makeOne()
+        mgr.setBrowserIdNamespaces(('cookies', 'form'))
+        parent = Parent()
+        parent.__before_traverse__ = {(0, 'BrowserIdManager'): object()}
+        parent.browser_id_manager = mgr
+        parent.browser_id_manager.updateTraversalData() # needs wrapper
+        self.failIf(queryBeforeTraverse(mgr, 'BrowserIdManager'))
+
+    def test_registerTraversalHook_doesnt_replace_existing(self):
+        from Acquisition import Implicit
+        from ZPublisher.BeforeTraverse import queryBeforeTraverse
+        class Parent(Implicit):
+            pass
+        mgr = self._makeOne()
+        parent = Parent()
+        hook = object()
+        parent.__before_traverse__ = {(0, 'BrowserIdManager'): hook}
+        parent.browser_id_manager = mgr
+        parent.browser_id_manager.registerTraversalHook() # needs wrapper
+        hooks = queryBeforeTraverse(parent, 'BrowserIdManager')
+        self.assertEqual(len(hooks), 1)
+        self.assertEqual(hooks[0][0], 0)
+        self.failUnless(hooks[0][1] is hook)
+
+    def test_registerTraversalHook_normal(self):
+        from Acquisition import Implicit
+        from ZPublisher.BeforeTraverse import queryBeforeTraverse
+        from Products.Sessions.BrowserIdManager import BrowserIdManagerTraverser
+        class Parent(Implicit):
+            pass
+        mgr = self._makeOne()
+        parent = Parent()
+        parent.browser_id_manager = mgr
+        parent.browser_id_manager.registerTraversalHook() # needs wrapper
+        hooks = queryBeforeTraverse(parent, 'BrowserIdManager')
+        self.assertEqual(len(hooks), 1)
+        self.assertEqual(hooks[0][0], 40)
+        self.failUnless(isinstance(hooks[0][1], BrowserIdManagerTraverser))
+
+    def test_unregisterTraversalHook_nonesuch_doesnt_raise(self):
+        from Acquisition import Implicit
+        class Parent(Implicit):
+            pass
+        mgr = self._makeOne()
+        parent = Parent()
+        parent.browser_id_manager = mgr
+        parent.browser_id_manager.unregisterTraversalHook() # needs wrapper
+
+    def test_unregisterTraversalHook_normal(self):
+        from Acquisition import Implicit
+        from ZPublisher.BeforeTraverse import queryBeforeTraverse
+        class Parent(Implicit):
+            pass
+        mgr = self._makeOne()
+        parent = Parent()
+        parent.__before_traverse__ = {(0, 'BrowserIdManager'): object()}
+        parent.browser_id_manager = mgr
+        parent.browser_id_manager.unregisterTraversalHook() # needs wrapper
+        self.failIf(queryBeforeTraverse(mgr, 'BrowserIdManager'))
     
-    def testAutoUrlEncoding(self):
-        self.m.setAutoUrlEncoding(1)
-        self.m.setBrowserIdNamespaces(('url',))
-        self.m.updateTraversalData()
-        traverser = BrowserIdManagerTraverser()
-        traverser(self.app, self.req)
-        self.failUnless(isAWellFormedBrowserId(self.req.browser_id_))
-        self.failUnless(self.req.browser_id_ns_ == None)
-        self.failUnless(self.req._script[-1] == self.req.browser_id_)
-        self.failUnless(self.req._script[-2] == '_ZopeId')
 
-    def testUrlBrowserIdIsFound(self):
-        bid = '43295340A0bpcu4nkCI'
-        name = '_ZopeId'
-        resp = HTTPResponse()
-        environ = {}
-        environ['SERVER_NAME']='fred'
-        environ['SERVER_PORT']='80'
-        self.req = HTTPRequest(stdin, environ, resp)
-        self.req['TraversalRequestNameStack'] = ['foo', 'bar', bid, name]
-        self.app.REQUEST = self.req
-        self.m.setAutoUrlEncoding(1)
-        self.m.setBrowserIdNamespaces(('url',))
-        self.m.updateTraversalData()
-        traverser = BrowserIdManagerTraverser()
-        traverser(self.app, self.req)
-        self.failUnless(isAWellFormedBrowserId(self.req.browser_id_))
-        self.failUnless(self.req.browser_id_ns_ == 'url')
-        self.failUnless(self.req._script[-1] == self.req.browser_id_)
-        self.failUnless(self.req._script[-2] == '_ZopeId')
-        self.failUnless(self.req['TraversalRequestNameStack'] == ['foo','bar'])
+class TestBrowserIdManagerTraverser(unittest.TestCase):
 
-    def testUpdateTraversalData(self):
-        self.m.setBrowserIdNamespaces(('url',))
-        self.m.updateTraversalData()
-        self.failUnless(self.m.hasTraversalHook(self.app))
-        self.failUnless(queryBeforeTraverse(self.app, 'BrowserIdManager'))
-        self.m.setBrowserIdNamespaces(('cookies', 'form'))
-        self.m.updateTraversalData()
-        self.failUnless(not queryBeforeTraverse(self.app,'BrowserIdManager'))
+    def _getTargetClass(self):
+        from Products.Sessions.BrowserIdManager \
+            import BrowserIdManagerTraverser
+        return BrowserIdManagerTraverser
 
+    def _makeOne(self):
+        return self._getTargetClass()()
+
+    def test___call___no_mgr(self):
+        traverser = self._makeOne()
+        container = DummyObject()
+        request = DummyRequest()
+        traverser(container, request) # doesn't raise
+
+    def test___call___w_mgr_request_has_no_stack(self):
+        traverser = self._makeOne()
+        mgr = DummyBrowserIdManager()
+        container = DummyObject(browser_id_manager=mgr)
+        request = DummyRequest()
+        traverser(container, request) # doesn't raise
+
+    def test___call___w_mgr_request_has_stack_no_auto_encode(self):
+        from Products.Sessions.BrowserIdManager import getNewBrowserId
+        bid = getNewBrowserId()
+        traverser = self._makeOne()
+        mgr = DummyBrowserIdManager()
+        container = DummyObject(browser_id_manager=mgr)
+        request = DummyRequest(
+                    TraversalRequestNameStack=[bid, 'bid'])
+        traverser(container, request)
+        self.assertEqual(request.browser_id_, bid)
+        self.assertEqual(request.browser_id_ns_, 'url')
+        self.assertEqual(len(request.TraversalRequestNameStack), 0)
+
+    def test___call___w_mgr_request_has_stack_w_auto_encode(self):
+        from Products.Sessions.BrowserIdManager import getNewBrowserId
+        bid = getNewBrowserId()
+        traverser = self._makeOne()
+        mgr = DummyBrowserIdManager(True)
+        container = DummyObject(browser_id_manager=mgr)
+        request = DummyRequest(
+                    TraversalRequestNameStack=[bid, 'bid'], _script=[])
+        traverser(container, request)
+        self.assertEqual(request.browser_id_, bid)
+        self.assertEqual(request.browser_id_ns_, 'url')
+        self.assertEqual(len(request.TraversalRequestNameStack), 0)
+        self.assertEqual(len(request._script), 2)
+        self.assertEqual(request._script[0], 'bid')
+        self.assertEqual(request._script[1], bid)
+
+    def test___call___w_mgr_request_empty_stack_w_auto_encode(self):
+        from Products.Sessions.BrowserIdManager import isAWellFormedBrowserId
+        traverser = self._makeOne()
+        mgr = DummyBrowserIdManager(True)
+        container = DummyObject(browser_id_manager=mgr)
+        request = DummyRequest( TraversalRequestNameStack=[], _script=[])
+        traverser(container, request)
+        bid = request.browser_id_
+        self.failUnless(isAWellFormedBrowserId(bid))
+        self.assertEqual(request.browser_id_ns_, None)
+        self.assertEqual(len(request.TraversalRequestNameStack), 0)
+        self.assertEqual(len(request._script), 2)
+        self.assertEqual(request._script[0], 'bid')
+        self.assertEqual(request._script[1], bid)
+
+
+class DummyObject:
+    def __init__(self, **kw):
+        self.__dict__.update(kw)
+
+class DummyResponse(DummyObject):
+    pass
+
+class DummyRequest(DummyObject):
+    def __getitem__(self, key):
+        return getattr(self, key)
+    def get(self, key, default=None):
+        return getattr(self, key, default)
+
+class DummyBrowserIdManager:
+    def __init__(self, auto=False):
+        self._auto = auto
+    def getBrowserIdName(self):
+        return 'bid'
+    def getAutoUrlEncoding(self):
+        return self._auto
+
 def test_suite():
-    testsuite = makeSuite(TestBrowserIdManager, 'test')
-    return testsuite
-
-if __name__ == '__main__':
-    runner = TextTestRunner(verbosity=9)
-    runner.run(test_suite())
+    return unittest.TestSuite((
+        unittest.makeSuite(TestBrowserIdManager),
+        unittest.makeSuite(TestBrowserIdManagerTraverser),
+    ))



More information about the Zope-Checkins mailing list