[CMF-checkins] CVS: CMF/CMFCore/tests/base - __init__.py:1.2.4.1 content.py:1.2.4.1 dummy.py:1.2.4.1 security.py:1.2.4.1 testcase.py:1.2.4.1 utils.py:1.2.4.1

Shane Hathaway shane@cvs.zope.org
Wed, 20 Feb 2002 15:14:53 -0500


Update of /cvs-repository/CMF/CMFCore/tests/base
In directory cvs.zope.org:/tmp/cvs-serv27999/CMFCore/tests/base

Added Files:
      Tag: cmf-pre-1_3-branch
	__init__.py content.py dummy.py security.py testcase.py 
	utils.py 
Log Message:
Merged changes from head, with a small change: the types tool does not need
to be extended in such a complex way.  I took out the type_type registry and
the __bobo_traverse__ hook and replaced it with the original code with only
minor mods that give you the same extensibility without all the hacking.
(If anyone actually wants to use the extensibility, which I suspect no one
is actually interested in doing, I will happily provide instructions and
will create a corrected unit test.)


=== Added File CMF/CMFCore/tests/base/__init__.py ===
"""
Generic stuff for unit testing the CMF.
"""


=== Added File CMF/CMFCore/tests/base/content.py ===
DOCTYPE = '''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">'''

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.
"""


=== Added File CMF/CMFCore/tests/base/dummy.py ===
from Acquisition import Implicit, aq_inner, aq_parent
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


=== Added File CMF/CMFCore/tests/base/security.py ===
from Acquisition import Implicit

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


=== Added File CMF/CMFCore/tests/base/testcase.py ===
import Zope
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)


=== Added File CMF/CMFCore/tests/base/utils.py ===
from unittest import TestSuite
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