[CMF-checkins] CVS: CMF/CMFCore/tests/base - __init__.py:1.2 content.py:1.2 dummy.py:1.2 security.py:1.2 testcase.py:1.2 utils.py:1.2
Chris Withers
chrisw@nipltd.com
Fri, 15 Feb 2002 14:46:04 -0500
Update of /cvs-repository/CMF/CMFCore/tests/base
In directory cvs.zope.org:/tmp/cvs-serv10707/CMFCore/tests/base
Added Files:
__init__.py content.py dummy.py security.py testcase.py
utils.py
Log Message:
The unit tests hopefully smell better now. Please try and keep them this way. Look in CMFCore/tests/base for commonly used artifacts.
=== CMF/CMFCore/tests/base/__init__.py 1.1 => 1.2 ===
+Generic stuff for unit testing the CMF.
+"""
=== CMF/CMFCore/tests/base/content.py 1.1 => 1.2 ===
+
+HTML_TEMPLATE = '''\
+<html><head>
+ <title>%(title)s</title>
+</head>
+<body bgcolor="#efe843">%(body)s</body>
+</html>
+'''
+
+SIMPLE_HTML = '''\
+<html>
+ <head>
+ <title>Title in tag</title>
+ <meta name="description" content="Describe me">
+ <meta name="contributors" content="foo@bar.com; baz@bam.net;
+ Benotz, Larry J (larry@benotz.stuff)">
+ <meta name="title" content="Title in meta">
+ <meta name="subject" content="content management">
+ </head>
+ <body bgcolor="#ffffff">
+ <h1>Not a lot here</h1>
+ </body>
+</html>
+'''
+
+BASIC_HTML = '''\
+<html>
+ <head>
+ <title>Title in tag</title>
+ <meta name="description" content="Describe me">
+ <meta name="contributors" content="foo@bar.com; baz@bam.net;
+ Benotz, Larry J (larry@benotz.stuff)">
+ <meta name="title" content="Title in meta">
+ <meta name="subject" content="content management">
+ <meta name="keywords" content="unit tests, framework; ,zope ">
+ </head>
+ <body bgcolor="#ffffff">
+ <h1>Not a lot here</h1>
+ </body>
+</html>
+'''
+
+ENTITY_IN_TITLE = '''\
+<html>
+ <head>
+ <title>&Auuml;rger</title>
+ </head>
+ <bOdY>
+ <h2>Not a lot here either</h2>
+ </bodY>
+</html>
+'''
+
+SIMPLE_STRUCTUREDTEXT = '''\
+Title: My Document
+Description: A document by me
+Contributors: foo@bar.com; baz@bam.net; no@yes.maybe
+Subject: content management, zope
+
+This is the header
+
+ Body body body body body
+ body body body.
+
+ o A list item
+
+ o And another thing...
+'''
+
+BASIC_STRUCTUREDTEXT = '''\
+Title: My Document
+Description: A document by me
+Contributors: foo@bar.com; baz@bam.net; no@yes.maybe
+Subject: content management, zope
+Keywords: unit tests; , framework
+
+This is the header
+
+ Body body body body body
+ body body body.
+
+ o A list item
+
+ o And another thing...
+'''
+
+STX_WITH_HTML = """\
+Sometimes people do interesting things
+
+ Sometimes people do interesting things like have examples
+ of HTML inside their structured text document. We should
+ be detecting that this is indeed a structured text document
+ and **NOT** an HTML document::
+
+ <html>
+ <head><title>Hello World</title></head>
+ <body><p>Hello world, I am Bruce.</p></body>
+ </html>
+
+ All in favor say pi!
+"""
+
+
+STX_NO_HEADERS = """\
+Title Phrase
+
+ This is a "plain" STX file, with no headers. Saving with
+ it shouldn't overwrite any metadata.
+"""
+
+STX_NO_HEADERS_BUT_COLON = """\
+Plain STX: No magic!
+
+ This is a "plain" STX file, with no headers. Saving with
+ it shouldn't overwrite any metadata.
+"""
=== CMF/CMFCore/tests/base/dummy.py 1.1 => 1.2 ===
+from OFS.SimpleItem import Item
+from Products.CMFCore.PortalContent import PortalContent
+from Products.CMFCore.TypesTool import TypeInformation
+from Products.CMFCore.TypesTool import FactoryTypeInformation
+from Products.CMFCore.ActionProviderBase import ActionProviderBase
+
+class DummyObject(Implicit):
+ """
+ A dummy callable object.
+ Comes with getIcon and restrictedTraverse
+ methods.
+ """
+ def __init__(self, name='dummy',**kw):
+ self.name = name
+ self.__dict__.update( kw )
+
+ def __str__(self):
+ return self.name
+
+ def __call__(self):
+ return self.name
+
+ def restrictedTraverse( self, path ):
+ return path and getattr( self, path ) or self
+
+ def getIcon( self, relative=0 ):
+ return 'Site: %s' % relative
+
+class DummyContent( PortalContent, Item ):
+ """
+ A Dummy piece of PortalContent
+ """
+ meta_type = 'Dummy'
+ url = 'foo_url'
+ after_add_called = before_delete_called = 0
+
+ def __init__( self, id='dummy', *args, **kw ):
+ self.id = id
+ self._args = args
+ self._kw = {}
+ self._kw.update( kw )
+
+ self.reset()
+ self.catalog = kw.get('catalog',0)
+ self.url = kw.get('url',None)
+
+ def manage_afterAdd( self, item, container ):
+ self.after_add_called = 1
+ if self.catalog:
+ PortalContent.manage_afterAdd( self, item, container )
+
+ def manage_beforeDelete( self, item, container ):
+ self.before_delete_called = 1
+ if self.catalog:
+ PortalContent.manage_beforeDelete( self, item, container )
+
+ def absolute_url(self):
+ return self.url
+
+ def reset( self ):
+ self.after_add_called = self.before_delete_called = 0
+
+ # Make sure normal Database export/import stuff doesn't trip us up.
+ def _getCopy( self, container ):
+ return DummyContent( self.id, catalog=self.catalog )
+
+ def _safe_get(self,attr):
+ if self.catalog:
+ return getattr(self,attr,'')
+ else:
+ return getattr(self,attr)
+
+ def Title( self ):
+ return self.title
+
+ def Creator( self ):
+ return self._safe_get('creator')
+
+ def Subject( self ):
+ return self._safe_get('subject')
+
+ def Description( self ):
+ return self._safe_get('description')
+
+ def created( self ):
+ return self._safe_get('created_date')
+
+ def modified( self ):
+ return self._safe_get('modified_date')
+
+ def Type( self ):
+ return 'Dummy Content'
+
+def addDummy( self, id ):
+ """
+ Constructor method for DummyContent
+ """
+ self._setObject( id, DummyContent() )
+
+class DummyFactory:
+ """
+ Dummy Product Factory
+ """
+ def __init__( self, folder ):
+ self._folder = folder
+
+ def addFoo( self, id, *args, **kw ):
+ if self._folder._prefix:
+ id = '%s_%s' % ( self._folder._prefix, id )
+ foo = apply( DummyContent, ( id, ) + args, kw )
+ self._folder._setOb( id, foo )
+ if self._folder._prefix:
+ return id
+
+ __roles__ = ( 'FooAdder', )
+ __allow_access_to_unprotected_subobjects__ = { 'addFoo' : 1 }
+
+
+class DummyTypeInfo(TypeInformation):
+ """ Dummy class of type info object """
+ meta_type = "Dummy Test Type Info"
+
+DummyFTI = FactoryTypeInformation( 'Dummy',
+ meta_type=DummyContent.meta_type,
+ product='CMFDefault',
+ factory='addDocument',
+ actions= ( { 'name' : 'View',
+ 'action' : 'view',
+ 'permissions' : ('View', ) },
+ { 'name' : 'View2',
+ 'action' : 'view2',
+ 'permissions' : ('View', ) },
+ { 'name' : 'Edit',
+ 'action' : 'edit',
+ 'permissions' : ('forbidden permission',)
+ }
+ )
+ )
+
+class DummyFolder( Implicit ):
+ """
+ Dummy Container for testing
+ """
+ def __init__( self, fake_product=0, prefix='' ):
+ self._prefix = prefix
+
+ if fake_product:
+ self.manage_addProduct = { 'FooProduct' : DummyFactory( self ) }
+
+ self._objects = {}
+
+ def _setOb( self, id, obj ):
+ self._objects[id] = obj
+
+ def _getOb( self, id ):
+ return self._objects[id]
+
+ def _setObject(self,id,object):
+ setattr(self,id,object)
+
+class DummyTool(Implicit,ActionProviderBase):
+ """
+ This is a Dummy Tool that behaves as a
+ a MemberShipTool, a URLTool and an
+ Action Provider
+ """
+
+ _actions = [
+ DummyObject(),
+ DummyObject()
+ ]
+
+ root = 'DummyTool'
+
+ def __init__(self, anon=1):
+ self.anon = anon
+
+ def isAnonymousUser(self):
+ return self.anon
+
+ def getAuthenticatedMember(self):
+ return "member"
+
+ def __call__( self ):
+ return self.root
+
+ getPortalPath = __call__
+
+ def getPortalObject( self ):
+ return aq_parent( aq_inner( self ) )
+
+ def getIcon( self, relative=0 ):
+ return 'Tool: %s' % relative
=== CMF/CMFCore/tests/base/security.py 1.1 => 1.2 ===
+
+class PermissiveSecurityPolicy:
+ """
+ Very permissive security policy for unit testing purposes.
+ """
+ #
+ # Standard SecurityPolicy interface
+ #
+ def validate( self
+ , accessed=None
+ , container=None
+ , name=None
+ , value=None
+ , context=None
+ , roles=None
+ , *args
+ , **kw):
+ return 1
+
+ def checkPermission( self, permission, object, context) :
+ if permission == 'forbidden permission':
+ return 0
+ return 1
+
+class OmnipotentUser( Implicit ):
+ """
+ Omnipotent User for unit testing purposes.
+ """
+ def getId( self ):
+ return 'all_powerful_Oz'
+
+ getUserName = getId
+
+ def allowed( self, object, object_roles=None ):
+ return 1
+
+class UserWithRoles( Implicit ):
+ """
+ User with roles specified in constructor
+ for unit testing purposes.
+ """
+ def __init__( self, *roles ):
+ self._roles = roles
+
+ def getId( self ):
+ return 'high_roller'
+
+ getUserName = getId
+
+ def allowed( self, object, object_roles=None ):
+ if object_roles is None:
+ object_roles=()
+ for orole in object_roles:
+ if orole in self._roles:
+ return 1
+ return 0
+
+class AnonymousUser( Implicit ):
+ """
+ Anonymous USer for unit testing purposes.
+ """
+ def getId( self ):
+ return 'unit_tester'
+
+ getUserName = getId
+
+ def has_permission(self, permission, obj):
+ # For types tool tests dealing with filtered_meta_types
+ return 1
+
+ def allowed( self, object, object_roles=None ):
+ # for testing permissions on actions
+ if object.getId() == 'actions_dummy':
+ if 'Anonymous' in object_roles:
+ return 1
+ else:
+ return 0
+ return 1
=== CMF/CMFCore/tests/base/testcase.py 1.1 => 1.2 ===
+from unittest import TestCase
+from AccessControl.SecurityManagement import newSecurityManager
+from AccessControl.SecurityManagement import noSecurityManager
+from AccessControl.SecurityManager import setSecurityPolicy
+from Testing.makerequest import makerequest
+from security import PermissiveSecurityPolicy, AnonymousUser
+
+class TransactionalTest( TestCase ):
+
+ def setUp( self ):
+ get_transaction().begin()
+ self.connection = Zope.DB.open()
+ self.root = self.connection.root()[ 'Application' ]
+
+ def tearDown( self ):
+ get_transaction().abort()
+ self.connection.close()
+
+class RequestTest( TransactionalTest ):
+
+ def setUp(self):
+ TransactionalTest.setUp(self)
+ root = self.root
+ root = makerequest(root)
+ self.REQUEST = root.REQUEST
+ self.RESPONSE = root.REQUEST.RESPONSE
+
+class SecurityTest( TestCase ):
+
+ def setUp(self):
+ get_transaction().begin()
+ self._policy = PermissiveSecurityPolicy()
+ self._oldPolicy = setSecurityPolicy(self._policy)
+ self.connection = Zope.DB.open()
+ self.root = self.connection.root()[ 'Application' ]
+ newSecurityManager( None, AnonymousUser().__of__( self.root ) )
+
+ def tearDown( self ):
+ get_transaction().abort()
+ self.connection.close()
+ noSecurityManager()
+ setSecurityPolicy(self._oldPolicy)
+
+class SecurityRequestTest( SecurityTest ):
+
+ def setUp(self):
+ SecurityTest.setUp(self)
+ self.root = makerequest(self.root)
=== CMF/CMFCore/tests/base/utils.py 1.1 => 1.2 ===
+from sys import modules
+
+def build_test_suite(package_name,module_names,required=1):
+ """
+ Utlitity for building a test suite from a package name
+ and a list of modules.
+
+ If required is false, then ImportErrors will simply result
+ in that module's tests not being added to the returned
+ suite.
+ """
+
+ suite = TestSuite()
+ try:
+ for name in module_names:
+ the_name = package_name+'.'+name
+ __import__(the_name,globals(),locals())
+ suite.addTest(modules[the_name].test_suite())
+ except ImportError:
+ if required:
+ raise
+ return suite
+
+def has_path( catalog, path ):
+ """
+ Verify that catalog has an object at path.
+ """
+ if type( path ) is type( () ):
+ path = '/'.join(path)
+ rids = map( lambda x: x.data_record_id_, catalog.searchResults() )
+ for rid in rids:
+ if catalog.getpath( rid ) == path:
+ return 1
+ return 0
+