Back to index

plone3  3.1.7
test_classgen.py
Go to the documentation of this file.
00001 ################################################################################
00002 #
00003 # Copyright (c) 2002-2005, Benjamin Saller <bcsaller@ideasuite.com>, and
00004 #                              the respective authors. All rights reserved.
00005 # For a list of Archetypes contributors see docs/CREDITS.txt.
00006 #
00007 # Redistribution and use in source and binary forms, with or without
00008 # modification, are permitted provided that the following conditions are met:
00009 #
00010 # * Redistributions of source code must retain the above copyright notice, this
00011 #   list of conditions and the following disclaimer.
00012 # * Redistributions in binary form must reproduce the above copyright notice,
00013 #   this list of conditions and the following disclaimer in the documentation
00014 #   and/or other materials provided with the distribution.
00015 # * Neither the name of the author nor the names of its contributors may be used
00016 #   to endorse or promote products derived from this software without specific
00017 #   prior written permission.
00018 #
00019 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00020 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00021 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00022 # FOR A PARTICULAR PURPOSE.
00023 #
00024 ################################################################################
00025 """
00026 """
00027 
00028 import unittest
00029 
00030 from DateTime import DateTime
00031 from AccessControl import ClassSecurityInfo
00032 from AccessControl.SecurityInfo import ACCESS_PUBLIC, ACCESS_PRIVATE
00033 from Products.Archetypes.tests.atsitetestcase import ATSiteTestCase
00034 from Products.Archetypes.tests.utils import mkDummyInContext
00035 from Products.Archetypes.tests.utils import gen_class
00036 from Products.Archetypes.atapi import *
00037 from Products.Archetypes.interfaces.base import IBaseUnit
00038 from Products.Archetypes.ClassGen import generateMethods
00039 from Products.MimetypesRegistry.MimeTypesTool import MimeTypesTool
00040 from Products.PortalTransforms.TransformTool import TransformTool
00041 
00042 
00043 default_text = """
00044 Title
00045 =====
00046 
00047 Subtitle
00048 --------
00049 """
00050 
00051 schema = BaseSchema + Schema((
00052     TextField('atextfield',
00053               default_content_type='text/x-rst',
00054               default=default_text,
00055               widget=RichWidget(description="Just a text field for the testing",
00056                                   label="A Text Field",
00057                                   )),
00058 
00059     FileField('afilefield',
00060               primary=1,
00061               widget=RichWidget(description="Just a file field for the testing",
00062                                   label="A File Field",
00063                                   )),
00064 
00065     FileField('anotherfilefield', widget=FileWidget),
00066 
00067     LinesField('alinesfield', widget=LinesWidget),
00068 
00069     DateTimeField('adatefield',
00070                   widget=CalendarWidget(description="A date field",
00071                                         label="A Date Field")),
00072 
00073     ObjectField('anobjectfield',
00074                 widget=StringWidget(description="An object field",
00075                                     label="An Object Field"),
00076                 validators=('isURL',),
00077                 ),
00078 
00079     FixedPointField('afixedpointfield',
00080                     widget=DecimalWidget(description="A fixed point field",
00081                                          label="A Fixed Point Field"),
00082                     ),
00083     StringField('awriteonlyfield', mode="w"),
00084 
00085     StringField('areadonlyfield', mode="r"),
00086     ))
00087 
00088 class DummyDiscussionTool:
00089     def isDiscussionAllowedFor( self, content ):
00090         return False
00091     def overrideDiscussionFor(self, content, allowDiscussion):
00092         pass
00093 
00094 class SiteProperties:
00095     default_charset = 'UTF-8'
00096     def getProperty(self, name, default=None):
00097         return getattr(self, name, default)
00098 
00099     def hasProperty(self, name):
00100         return hasattr(self, name)
00101 
00102 class PortalProperties:
00103     site_properties = SiteProperties()
00104 
00105 class Dummy(BaseContent):
00106     portal_properties = PortalProperties()
00107     portal_discussion = DummyDiscussionTool()
00108     mimetypes_registry = MimeTypesTool()
00109     def __init__(self, oid='test', init_transforms=0, **kwargs):
00110         BaseContent.__init__(self, oid, **kwargs)
00111         self.portal_transforms = TransformTool()
00112         if init_transforms:
00113             from Products.PortalTransforms import transforms
00114             transforms.initialize(self.portal_transforms)
00115 
00116 BaseUnit.portal_properties = PortalProperties()
00117 
00118 def gen_dummy():
00119     gen_class(Dummy, schema)
00120 
00121 
00122 class ClassGenTest(ATSiteTestCase):
00123 
00124     def afterSetUp(self):
00125         ATSiteTestCase.afterSetUp(self)
00126         self._dummy = mkDummyInContext(Dummy, oid='dummy',
00127                                        context=self.portal,
00128                                        schema=schema)
00129 
00130     def test_methods(self):
00131         obj = self._dummy
00132         #setters
00133         self.failUnless(hasattr(obj, 'setAtextfield'))
00134         self.failUnless(hasattr(obj, 'setAfilefield'))
00135         self.failUnless(hasattr(obj, 'setAlinesfield'))
00136         self.failUnless(hasattr(obj, 'setAdatefield'))
00137         self.failUnless(hasattr(obj, 'setAnobjectfield'))
00138         self.failUnless(hasattr(obj, 'setAfixedpointfield'))
00139         self.failUnless(hasattr(obj, 'setAwriteonlyfield'))
00140         self.failUnless(not hasattr(obj, 'setAreadonlyfield'))
00141         #getters
00142         self.failUnless(hasattr(obj, 'getAtextfield'))
00143         self.failUnless(hasattr(obj, 'getAfilefield'))
00144         self.failUnless(hasattr(obj, 'getAlinesfield'))
00145         self.failUnless(hasattr(obj, 'getAdatefield'))
00146         self.failUnless(hasattr(obj, 'getAnobjectfield'))
00147         self.failUnless(hasattr(obj, 'getAfixedpointfield'))
00148         self.failUnless(not hasattr(obj, 'getAwriteonlyfield'))
00149         self.failUnless(hasattr(obj, 'getAreadonlyfield'))
00150         #raw getters
00151         self.failUnless(hasattr(obj, 'getRawAtextfield'))
00152         self.failUnless(hasattr(obj, 'getRawAfilefield'))
00153         self.failUnless(hasattr(obj, 'getRawAlinesfield'))
00154         self.failUnless(hasattr(obj, 'getRawAdatefield'))
00155         self.failUnless(hasattr(obj, 'getRawAnobjectfield'))
00156         self.failUnless(hasattr(obj, 'getRawAfixedpointfield'))
00157         self.failUnless(hasattr(obj, 'getRawAwriteonlyfield'))
00158         self.failUnless(not hasattr(obj, 'getRawAreadonlyfield'))
00159 
00160     def test_textfield(self):
00161         obj = self._dummy
00162         obj.setAtextfield('Bla', mimetype="text/plain")
00163         self.failUnlessEqual(str(obj.getAtextfield()), 'Bla')
00164 
00165     def test_filefield(self):
00166         obj = self._dummy
00167         obj.setAfilefield('Bla')
00168         self.failUnlessEqual(str(obj.getAfilefield()), 'Bla')
00169 
00170     def test_linesfield(self):
00171         obj = self._dummy
00172         obj.setAlinesfield(['Bla', 'Ble', 'Bli'])
00173         self.failUnlessEqual(obj.getAlinesfield(), ('Bla', 'Ble', 'Bli'))
00174 
00175     def test_datefield(self):
00176         obj = self._dummy
00177         obj.setAdatefield('2002/01/01')
00178         self.failUnlessEqual(obj.getAdatefield(), DateTime('2002/01/01'))
00179 
00180     def test_objectfield(self):
00181         obj = self._dummy
00182         obj.setAnobjectfield('bla')
00183         self.failUnlessEqual(obj.getAnobjectfield(), 'bla')
00184 
00185     def test_fixedpointfield(self):
00186         obj = self._dummy
00187         obj.setAfixedpointfield('26.05')
00188         self.failUnlessEqual(obj.getAfixedpointfield(), '26.05')
00189 
00190     def test_writeonlyfield(self):
00191         obj = self._dummy
00192         obj.setAwriteonlyfield('bla')
00193         self.failUnlessEqual(obj.getRawAwriteonlyfield(), 'bla')
00194 
00195     def test1_getbaseunit(self):
00196         obj = self._dummy
00197         for field in obj.Schema().fields():
00198             if not hasattr(field, 'getBaseUnit'):
00199                 continue
00200             bu = field.getBaseUnit(obj)
00201             self.failUnless(IBaseUnit.isImplementedBy(bu),
00202                             ('Return value of %s.getBaseUnit() does not '
00203                              'implement BaseUnit: %s' %
00204                              (field.__class__, type(bu))))
00205 
00206 class SecDummy1:
00207     type = {}
00208     sec = ClassSecurityInfo()
00209     sec.declareProtected('View', 'makeFoo')
00210     def makeFoo(self):
00211         return 'foo'
00212 
00213 class SecDummy2:
00214     type = {}
00215     def makeFoo(self):
00216         return 'foo'
00217 
00218 class SecDummy3:
00219     type = {}
00220 
00221 class SecDummy4:
00222     type = {}
00223     sec = ClassSecurityInfo()
00224     sec.declarePublic('makeFoo')
00225     def makeFoo(self):
00226         return 'foo'
00227 
00228 class SecDummy5:
00229     type = {}
00230     sec = ClassSecurityInfo()
00231     sec.declarePrivate('makeFoo')
00232     def makeFoo(self):
00233         return 'foo'
00234 
00235 foo_field = StringField('foo',
00236                         accessor='makeFoo',
00237                         read_permission='Modify portal content',
00238                         write_permission='Modify portal content')
00239 
00240 class ClassGenSecurityTest(unittest.TestCase):
00241 
00242     def test_security_dont_stomp_existing_decl_perm(self):
00243         self.failIf(hasattr(SecDummy1, '__ac_permissions__'))
00244         self.failUnless(hasattr(SecDummy1, 'makeFoo'))
00245         existing_method = getattr(SecDummy1, 'makeFoo')
00246         generateMethods(SecDummy1, (foo_field,))
00247         self.failUnless(hasattr(SecDummy1, '__ac_permissions__'))
00248         self.failUnless(SecDummy1.makeFoo == existing_method)
00249         got = SecDummy1.__ac_permissions__
00250         expected = (('Modify portal content',
00251                      ('setFoo', 'getRawFoo')),
00252                      ('View', ('makeFoo',)),)
00253         self.assertEquals(got, expected)
00254 
00255     def test_security_dont_stomp_existing_decl_public(self):
00256         self.failIf(hasattr(SecDummy4, '__ac_permissions__'))
00257         self.failIf(hasattr(SecDummy4, 'makeFoo__roles__'))
00258         self.failUnless(hasattr(SecDummy4, 'makeFoo'))
00259         existing_method = getattr(SecDummy4, 'makeFoo')
00260         generateMethods(SecDummy4, (foo_field,))
00261         self.failUnless(hasattr(SecDummy4, '__ac_permissions__'))
00262         self.failUnless(SecDummy4.makeFoo == existing_method)
00263         got = SecDummy4.__ac_permissions__
00264         expected = (('Modify portal content',
00265                      ('setFoo', 'getRawFoo')),)
00266         self.assertEquals(got, expected)
00267         self.failUnless(hasattr(SecDummy4, 'makeFoo__roles__'))
00268         self.failUnless(SecDummy4.makeFoo__roles__ == ACCESS_PUBLIC)
00269 
00270     def test_security_dont_stomp_existing_decl_private(self):
00271         self.failIf(hasattr(SecDummy5, '__ac_permissions__'))
00272         self.failIf(hasattr(SecDummy5, 'makeFoo__roles__'))
00273         self.failUnless(hasattr(SecDummy5, 'makeFoo'))
00274         existing_method = getattr(SecDummy5, 'makeFoo')
00275         generateMethods(SecDummy5, (foo_field,))
00276         self.failUnless(hasattr(SecDummy5, '__ac_permissions__'))
00277         self.failUnless(SecDummy5.makeFoo == existing_method)
00278         got = SecDummy5.__ac_permissions__
00279         expected = (('Modify portal content',
00280                      ('setFoo', 'getRawFoo')),)
00281         self.assertEquals(got, expected)
00282         self.failUnless(hasattr(SecDummy5, 'makeFoo__roles__'))
00283         self.failUnless(SecDummy5.makeFoo__roles__ == ACCESS_PRIVATE)
00284 
00285     def test_security_protect_manual_method(self):
00286         self.failIf(hasattr(SecDummy2, '__ac_permissions__'))
00287         self.failUnless(hasattr(SecDummy2, 'makeFoo'))
00288         existing_method = getattr(SecDummy2, 'makeFoo')
00289         generateMethods(SecDummy2, (foo_field,))
00290         self.failUnless(hasattr(SecDummy2, '__ac_permissions__'))
00291         self.failUnless(SecDummy2.makeFoo == existing_method)
00292         got = SecDummy2.__ac_permissions__
00293         expected = (('Modify portal content',
00294                      ('makeFoo', 'setFoo', 'getRawFoo')),)
00295         self.assertEquals(got, expected)
00296 
00297     def test_security_protect_generate_method(self):
00298         self.failIf(hasattr(SecDummy3, '__ac_permissions__'))
00299         self.failIf(hasattr(SecDummy3, 'makeFoo'))
00300         generateMethods(SecDummy3, (foo_field,))
00301         self.failUnless(hasattr(SecDummy3, '__ac_permissions__'))
00302         self.failUnless(hasattr(SecDummy3, 'makeFoo'))
00303         got = SecDummy3.__ac_permissions__
00304         expected = (('Modify portal content',
00305                      ('makeFoo', 'setFoo', 'getRawFoo')),)
00306         self.assertEquals(got, expected)
00307 
00308 def test_suite():
00309     from unittest import TestSuite, makeSuite
00310     suite = TestSuite()
00311     tests = (
00312         ClassGenSecurityTest,
00313         ClassGenTest
00314         )
00315     for t in tests:
00316         suite.addTest(makeSuite(t))
00317     return suite