################################################################################ # # Copyright (c) 2002-2005, Benjamin Saller <bcsaller@ideasuite.com>, and # the respective authors. All rights reserved. # For a list of Archetypes contributors see docs/CREDITS.txt. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # * Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # * Neither the name of the author nor the names of its contributors may be used # to endorse or promote products derived from this software without specific # prior written permission. # # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # FOR A PARTICULAR PURPOSE. # ################################################################################ """ """ import unittest from unittest import TestSuite, makeSuite from DateTime import DateTime from AccessControl import ClassSecurityInfo from AccessControl.SecurityInfo import ACCESS_PUBLIC, ACCESS_PRIVATE from Products.Archetypes.tests.atsitetestcase import ATSiteTestCase from Products.Archetypes.tests.utils import mkDummyInContext from Products.Archetypes.tests.utils import gen_class from Products.Archetypes import atapi from Products.Archetypes.interfaces.base import IBaseUnit from Products.Archetypes.ClassGen import generateMethods from Products.MimetypesRegistry.MimeTypesTool import MimeTypesTool from Products.PortalTransforms.TransformTool import TransformTool default_text = """ Title ===== Subtitle -------- """ schema = atapi.BaseSchema + atapi.Schema(( atapi.TextField('atextfield', default_content_type='text/x-rst', default=default_text, widget=atapi.RichWidget(description="Just a text field for the testing", label="A Text Field", )), atapi.FileField('afilefield', primary=1, widget=atapi.RichWidget(description="Just a file field for the testing", label="A File Field", )), atapi.FileField('anotherfilefield', widget=atapi.FileWidget), atapi.LinesField('alinesfield', widget=atapi.LinesWidget), atapi.DateTimeField('adatefield', widget=atapi.CalendarWidget(description="A date field", label="A Date Field")), atapi.ObjectField('anobjectfield', widget=atapi.StringWidget(description="An object field", label="An Object Field"), validators=('isURL',), ), atapi.FixedPointField('afixedpointfield', widget=atapi.DecimalWidget(description="A fixed point field", label="A Fixed Point Field"), ), atapi.StringField('awriteonlyfield', mode="w"), atapi.StringField('areadonlyfield', mode="r"), )) class DummyDiscussionTool: def isDiscussionAllowedFor(self, content): return False def overrideDiscussionFor(self, content, allowDiscussion): pass class SiteProperties: default_charset = 'UTF-8' def getProperty(self, name, default=None): return getattr(self, name, default) def hasProperty(self, name): return hasattr(self, name) class PortalProperties: site_properties = SiteProperties() class Dummy(atapi.BaseContent): portal_properties = PortalProperties() portal_discussion = DummyDiscussionTool() mimetypes_registry = MimeTypesTool() def __init__(self, oid='test', init_transforms=0, **kwargs): atapi.BaseContent.__init__(self, oid, **kwargs) self.portal_transforms = TransformTool() if init_transforms: from Products.PortalTransforms import transforms transforms.initialize(self.portal_transforms) atapi.BaseUnit.portal_properties = PortalProperties() def gen_dummy(): gen_class(Dummy, schema) class ClassGenTest(ATSiteTestCase): def afterSetUp(self): ATSiteTestCase.afterSetUp(self) self._dummy = mkDummyInContext(Dummy, oid='dummy', context=self.portal, schema=schema) def test_methods(self): obj = self._dummy #setters self.assertTrue(hasattr(obj, 'setAtextfield')) self.assertTrue(hasattr(obj, 'setAfilefield')) self.assertTrue(hasattr(obj, 'setAlinesfield')) self.assertTrue(hasattr(obj, 'setAdatefield')) self.assertTrue(hasattr(obj, 'setAnobjectfield')) self.assertTrue(hasattr(obj, 'setAfixedpointfield')) self.assertTrue(hasattr(obj, 'setAwriteonlyfield')) self.assertTrue(not hasattr(obj, 'setAreadonlyfield')) #getters self.assertTrue(hasattr(obj, 'getAtextfield')) self.assertTrue(hasattr(obj, 'getAfilefield')) self.assertTrue(hasattr(obj, 'getAlinesfield')) self.assertTrue(hasattr(obj, 'getAdatefield')) self.assertTrue(hasattr(obj, 'getAnobjectfield')) self.assertTrue(hasattr(obj, 'getAfixedpointfield')) self.assertTrue(not hasattr(obj, 'getAwriteonlyfield')) self.assertTrue(hasattr(obj, 'getAreadonlyfield')) #raw getters self.assertTrue(hasattr(obj, 'getRawAtextfield')) self.assertTrue(hasattr(obj, 'getRawAfilefield')) self.assertTrue(hasattr(obj, 'getRawAlinesfield')) self.assertTrue(hasattr(obj, 'getRawAdatefield')) self.assertTrue(hasattr(obj, 'getRawAnobjectfield')) self.assertTrue(hasattr(obj, 'getRawAfixedpointfield')) self.assertTrue(hasattr(obj, 'getRawAwriteonlyfield')) self.assertTrue(not hasattr(obj, 'getRawAreadonlyfield')) def test_textfield(self): obj = self._dummy obj.setAtextfield('Bla', mimetype="text/plain") self.assertEqual(str(obj.getAtextfield()), 'Bla') def test_filefield(self): obj = self._dummy obj.setAfilefield('Bla') self.assertEqual(str(obj.getAfilefield()), 'Bla') def test_linesfield(self): obj = self._dummy obj.setAlinesfield(['Bla', 'Ble', 'Bli']) self.assertEqual(obj.getAlinesfield(), ('Bla', 'Ble', 'Bli')) def test_datefield(self): obj = self._dummy obj.setAdatefield('2002/01/01') self.assertEqual(obj.getAdatefield(), DateTime('2002/01/01')) def test_objectfield(self): obj = self._dummy obj.setAnobjectfield('bla') self.assertEqual(obj.getAnobjectfield(), 'bla') def test_fixedpointfield(self): obj = self._dummy obj.setAfixedpointfield('26.05') self.assertEqual(obj.getAfixedpointfield(), '26.05') def test_writeonlyfield(self): obj = self._dummy obj.setAwriteonlyfield('bla') self.assertEqual(obj.getRawAwriteonlyfield(), 'bla') def test1_getbaseunit(self): obj = self._dummy for field in obj.Schema().fields(): if not hasattr(field, 'getBaseUnit'): continue bu = field.getBaseUnit(obj) self.assertTrue(IBaseUnit.providedBy(bu), ('Return value of %s.getBaseUnit() does not ' 'implement BaseUnit: %s' % (field.__class__, type(bu)))) class SecDummy1: schema = {} sec = ClassSecurityInfo() sec.declareProtected('View', 'makeFoo') def makeFoo(self): return 'foo' class SecDummy2: schema = {} def makeFoo(self): return 'foo' class SecDummy3: schema = {} class SecDummy4: schema = {} sec = ClassSecurityInfo() sec.declarePublic('makeFoo') def makeFoo(self): return 'foo' class SecDummy5: schema = {} sec = ClassSecurityInfo() sec.declarePrivate('makeFoo') def makeFoo(self): return 'foo' foo_field = atapi.StringField('foo', accessor='makeFoo', read_permission='Modify portal content', write_permission='Modify portal content') class ClassGenSecurityTest(unittest.TestCase): def test_security_dont_stomp_existing_decl_perm(self): self.assertFalse(hasattr(SecDummy1, '__ac_permissions__')) self.assertTrue(hasattr(SecDummy1, 'makeFoo')) existing_method = getattr(SecDummy1, 'makeFoo') generateMethods(SecDummy1, (foo_field,)) self.assertTrue(hasattr(SecDummy1, '__ac_permissions__')) self.assertTrue(SecDummy1.makeFoo == existing_method) got = SecDummy1.__ac_permissions__ expected = (('Modify portal content', ('setFoo', 'getRawFoo')), ('View', ('makeFoo',)),) self.assertEqual(got, expected) def test_security_dont_stomp_existing_decl_public(self): self.assertFalse(hasattr(SecDummy4, '__ac_permissions__')) self.assertFalse(hasattr(SecDummy4, 'makeFoo__roles__')) self.assertTrue(hasattr(SecDummy4, 'makeFoo')) existing_method = getattr(SecDummy4, 'makeFoo') generateMethods(SecDummy4, (foo_field,)) self.assertTrue(hasattr(SecDummy4, '__ac_permissions__')) self.assertTrue(SecDummy4.makeFoo == existing_method) got = SecDummy4.__ac_permissions__ expected = (('Modify portal content', ('setFoo', 'getRawFoo')),) self.assertEqual(got, expected) self.assertTrue(hasattr(SecDummy4, 'makeFoo__roles__')) self.assertTrue(SecDummy4.makeFoo__roles__ == ACCESS_PUBLIC) def test_security_dont_stomp_existing_decl_private(self): self.assertFalse(hasattr(SecDummy5, '__ac_permissions__')) self.assertFalse(hasattr(SecDummy5, 'makeFoo__roles__')) self.assertTrue(hasattr(SecDummy5, 'makeFoo')) existing_method = getattr(SecDummy5, 'makeFoo') generateMethods(SecDummy5, (foo_field,)) self.assertTrue(hasattr(SecDummy5, '__ac_permissions__')) self.assertTrue(SecDummy5.makeFoo == existing_method) got = SecDummy5.__ac_permissions__ expected = (('Modify portal content', ('setFoo', 'getRawFoo')),) self.assertEqual(got, expected) self.assertTrue(hasattr(SecDummy5, 'makeFoo__roles__')) self.assertTrue(SecDummy5.makeFoo__roles__ == ACCESS_PRIVATE) def test_security_protect_manual_method(self): self.assertFalse(hasattr(SecDummy2, '__ac_permissions__')) self.assertTrue(hasattr(SecDummy2, 'makeFoo')) existing_method = getattr(SecDummy2, 'makeFoo') generateMethods(SecDummy2, (foo_field,)) self.assertTrue(hasattr(SecDummy2, '__ac_permissions__')) self.assertTrue(SecDummy2.makeFoo == existing_method) got = SecDummy2.__ac_permissions__ expected = (('Modify portal content', ('makeFoo', 'setFoo', 'getRawFoo')),) self.assertEqual(got, expected) def test_security_protect_generate_method(self): self.assertFalse(hasattr(SecDummy3, '__ac_permissions__')) self.assertFalse(hasattr(SecDummy3, 'makeFoo')) generateMethods(SecDummy3, (foo_field,)) self.assertTrue(hasattr(SecDummy3, '__ac_permissions__')) self.assertTrue(hasattr(SecDummy3, 'makeFoo')) got = SecDummy3.__ac_permissions__ expected = (('Modify portal content', ('makeFoo', 'setFoo', 'getRawFoo')),) self.assertEqual(got, expected) def test_suite(): suite = TestSuite() tests = ( ClassGenSecurityTest, ClassGenTest ) for t in tests: suite.addTest(makeSuite(t)) return suite