def setUp(self): super(TestBaseBehavior, self).setUp() fti = DexterityFTI('OpenGeverBaseFTI') fti.schema = 'opengever.base.tests.emptyschema.IEmptySchema' fti.behaviors = ('opengever.base.behaviors.base.IOpenGeverBase', ) self.portal.portal_types._setObject('OpenGeverBaseFTI', fti) fti.lookupSchema() transaction.commit()
def setUp(self): self.portal = self.layer['portal'] setRoles(self.portal, TEST_USER_ID, ['Reviewer', 'Manager']) self.request = self.portal.REQUEST # fti self.fti_note = DexterityFTI('note') self.fti_note.schema = dottedname(INoteSchemaPrimary) self.portal.portal_types._setObject('note', self.fti_note) self.fti_invi = DexterityFTI('invitation') self.fti_invi.schema = dottedname(IInvitationSchemaNonPrimary) self.portal.portal_types._setObject('invitation', self.fti_invi) # register register(self.fti_note) register(self.fti_invi)
def setUp(self): self.portal = self.layer['portal'] # XXX below code is only needed if theres no Folder FTI already setup. typetool = getToolByName(self.portal, "portal_types") if "Folder" not in typetool.objectIds(): # XXX Check if this is needed for Plone 5.0! In 4.3 the FTI is # already setup fti = DexterityFTI('Folder') typetool._setObject('Folder', fti)
def add_folder_type(portal): fti = DexterityFTI('folder') portal.portal_types._setObject('folder', fti) fti.klass = 'plone.dexterity.content.Container' fti.filter_content_types = False fti.behaviors = ( 'plone.app.dexterity.behaviors.metadata.IBasic', 'brasil.gov.vcge.dx.behaviors.IVCGE') return fti
def afterSetUp(self): import Products.CMFDiffTool import plone.app.dexterity self.loadZCML('configure.zcml', package=Products.CMFDiffTool) self.loadZCML('configure.zcml', package=plone.app.dexterity) portal = self.portal types_tool = getToolByName(portal, 'portal_types') sm = getSiteManager(portal) sm.registerUtility( component=vocabulary_factory, provided=IVocabularyFactory, name=u'Products.CMFDiffTool.testing.VOCABULARY' ) fti = DexterityFTI( TEST_CONTENT_TYPE_ID, factory=TEST_CONTENT_TYPE_ID, global_allow=True, behaviors=( 'plone.app.versioningbehavior.behaviors.IVersionable', 'plone.app.dexterity.behaviors.metadata.IBasic', 'plone.app.dexterity.behaviors.metadata.IRelatedItems', ), model_source=''' <model xmlns="http://namespaces.plone.org/supermodel/schema"> <schema> <field name="text" type="zope.schema.Text"> <title>Text</title> <required>False</required> </field> <field name="file" type="plone.namedfile.field.NamedFile"> <title>File</title> <required>False</required> </field> <field name="date" type="zope.schema.Date"> <title>Date</title> <required>False</required> </field> <field name="files" type="zope.schema.List"> <title>Date</title> <required>False</required> <value_type type="plone.namedfile.field.NamedFile"> <title>Val</title> </value_type> </field> <field name="choice" type="zope.schema.Choice"> <title>Choice</title> <required>False</required> <vocabulary>Products.CMFDiffTool.testing.VOCABULARY</vocabulary> </field> </schema> </model> ''' ) types_tool._setObject(TEST_CONTENT_TYPE_ID, fti)
def test_addview_sets_form_portal_type(self): context = Container(u"container") request = TestRequest() fti = DexterityFTI(u"testtype") addview = DefaultAddView(context, request, fti) self.assertEqual(u"testtype", addview.form_instance.portal_type)
def test_lookupModel_with_schema_only(self): fti = DexterityFTI(u"testtype") fti.schema = u"plone.dexterity.tests.schemata.ITestSchema" fti.model_source = None fti.model_file = None model = fti.lookupModel() self.assertEqual(1, len(model.schemata)) self.assertEqual(ITestSchema, model.schema)
def add_folder_type(portal): fti = DexterityFTI('folder') portal.portal_types._setObject('folder', fti) fti.klass = 'plone.dexterity.content.Container' fti.filter_content_types = False fti.behaviors = ('Products.CMFPlone.interfaces.constrains.' 'ISelectableConstrainTypes', 'plone.app.dexterity.behaviors.metadata.IBasic') return fti
def test_schema_lookup_add(self): # Context and request context_mock = self.create_dummy(portal_type=u'testtype') request_mock = TestRequest() # FTI fti_mock = DexterityFTI(u"testtype") fti_mock.lookupSchema = Mock(return_value=ISchema) fti_mock.behaviors = (IBehaviorOne.__identifier__, IBehaviorTwo.__identifier__, IBehaviorThree.__identifier__) self.mock_utility(fti_mock, IDexterityFTI, name=u"testtype") from plone.behavior.interfaces import IBehavior from plone.behavior.registration import BehaviorRegistration registration = BehaviorRegistration( title=u"Test Behavior 1", description=u"Provides test behavior", interface=IBehaviorOne, marker=None, factory=None) self.mock_utility(registration, IBehavior, IBehaviorOne.__identifier__) registration = BehaviorRegistration( title=u"Test Behavior 2", description=u"Provides test behavior", interface=IBehaviorTwo, marker=None, factory=None) self.mock_utility(registration, IBehavior, IBehaviorTwo.__identifier__) registration = BehaviorRegistration( title=u"Test Behavior 3", description=u"Provides test behavior", interface=IBehaviorThree, marker=None, factory=None) self.mock_utility(registration, IBehavior, IBehaviorThree.__identifier__) # Form view = DefaultAddForm(context_mock, request_mock) view.portal_type = u"testtype" self.assertEqual(ISchema, view.schema) # we expect here only formfieldprovider! self.assertEqual((IBehaviorOne, IBehaviorTwo), tuple(view.additionalSchemata)) # When we register our own IBehaviorAssignable we can # influence what goes into the additionalSchemata. But in an Addform # this never grips, since its an adapter on context, and contextless # there is always the FTI the only valid source self.mock_adapter(NoBehaviorAssignable, IBehaviorAssignable, [Interface]) self.assertEqual((IBehaviorOne, IBehaviorTwo), tuple(view.additionalSchemata))
def setUp(self): self.portal = self.layer["portal"] self.request = self.layer["request"] login(self.portal, TEST_USER_NAME) setRoles(self.portal, TEST_USER_ID, ["Manager"]) fti = DexterityFTI("blocksfolder") self.portal.portal_types._setObject("blocksfolder", fti) fti.klass = "plone.dexterity.content.Container" fti.behaviors = ("volto.blocks", )
def setUp(self): super(TestCreatorBehavior, self).setUp() self.grant('Contributor') fti = DexterityFTI('ReferenceFTI') fti.behaviors = ('opengever.base.behaviors.creator.ICreator', ) self.portal.portal_types._setObject('ReferenceFTI', fti) fti.lookupSchema() transaction.commit()
def test_deleted_factory_not_unregistered_if_not_unique(self): portal_type = 'testtype' fti = DexterityFTI(portal_type, factory='common-factory') portal_type2 = 'testtype2' fti2 = DexterityFTI(portal_type2, factory='common-factory') container_dummy = self.create_dummy() # Mock the lookup of the site and the site manager at the site root dummy_site = self.create_dummy() self.mock_utility(dummy_site, Interface) site_manager_mock = self.mocker.proxy( PersistentComponents(bases=(getGlobalSiteManager(), ))) getSiteManager_mock = self.mocker.replace( 'zope.component.hooks.getSiteManager') self.expect( getSiteManager_mock(dummy_site)).result(site_manager_mock).count( 1, None) # Pretend two FTIs are registered, both using common-factory # NB: Assuming that 'testtype' was already removed when this gets # called self.expect(site_manager_mock.registeredUtilities()).result([ self.create_dummy(provided=IFactory, name='common-factory', info='plone.dexterity.dynamic'), self.create_dummy(component=fti2, provided=IDexterityFTI, name='testtype2', info='plone.dexterity.dynamic'), ]) # We shouldn't remove this since fti2 still uses it self.expect( site_manager_mock.unregisterUtility( provided=IFactory, name='common-factory')).count(0) # The type itself should be removed though self.expect( site_manager_mock.unregisterUtility(provided=IDexterityFTI, name='testtype')).count(1) self.replay() ftiRemoved(fti, ObjectRemovedEvent(fti, container_dummy, fti.getId()))
def test_renamed_factory_not_unregistered_if_not_unique(self): portal_type = u"testtype" fti = DexterityFTI(portal_type, factory='common-factory') portal_type2 = u"testtype2" fti2 = DexterityFTI(portal_type2, factory='common-factory') # Mock the lookup of the site and the site manager at the site root dummy_site = self.create_dummy() self.mock_utility(dummy_site, ISiteRoot) site_manager_mock = Mock(wraps=PersistentComponents( bases=(getGlobalSiteManager(), ))) from zope.component.hooks import getSiteManager self.patch_global(getSiteManager, return_value=site_manager_mock) # Pretend two FTIs are registered, both using common-factory site_manager_mock.registeredUtilities = Mock(return_value=[ self.create_dummy(provided=IFactory, name='common-factory', info='plone.dexterity.dynamic'), self.create_dummy(component=fti, provided=IDexterityFTI, name='testtype', info='plone.dexterity.dynamic'), self.create_dummy(component=fti2, provided=IDexterityFTI, name='testtype2', info='plone.dexterity.dynamic'), ]) fti.factory = 'new-factory' ftiModified( fti, ObjectModifiedEvent( fti, DexterityFTIModificationDescription('factory', 'common-factory'))) # We shouldn't remove this since fti2 still uses it self.assertFalse(site_manager_mock.unregisterUtility.called) # A new one may still be created, however self.assertEqual(site_manager_mock.registerUtility.call_args[0][2], 'new-factory')
def test_provided_by_subclass(self): # Make sure the __providedBy__ descriptor lives in sub-classes # Dummy type class MyItem(Item): pass class FauxDataManager(object): def setstate(self, obj): pass def oldstate(self, obj, tid): pass def register(self, obj): pass # Dummy instance item = MyItem(id=u'id') item.portal_type = 'testtype' item._p_jar = FauxDataManager() # Dummy schema class ISchema(Interface): foo = zope.schema.TextLine(title=u"foo", default=u"foo_default") bar = zope.schema.TextLine(title=u"bar") class IMarker(Interface): pass # FTI mock fti_mock = self.mocker.proxy(DexterityFTI(u"testtype")) self.expect(fti_mock.lookupSchema()).result(ISchema).count(1) self.mock_utility(fti_mock, IDexterityFTI, name=u"testtype") self.replay() self.assertFalse(ISchema.implementedBy(MyItem)) # Schema as looked up in FTI is now provided by item ... self.assertTrue(ISchema.providedBy(item)) # If the _v_ attribute cache does not work, then we'd expect to have # to look up the schema more than once (since we invalidated) # the cache. This is not the case, as evidenced by .count(1) above. self.assertTrue(ISchema.providedBy(item)) # We also need to ensure that the _v_ attribute doesn't hide any # interface set directly on the instance with alsoProvides() or # directlyProvides(). This is done by clearing the cache when these # are invoked. alsoProvides(item, IMarker) self.assertTrue(IMarker.providedBy(item)) self.assertTrue(ISchema.providedBy(item))
def test_components_reregistered_on_rename(self): portal_type = u"testtype" fti = DexterityFTI(portal_type) container_dummy = self.create_dummy() # Mock the lookup of the site and the site manager at the site root dummy_site = self.create_dummy() self.mock_utility(dummy_site, ISiteRoot) site_manager_mock = self.mocker.proxy( PersistentComponents(bases=(getGlobalSiteManager(), ))) getSiteManager_mock = self.mocker.replace( 'zope.component.hooks.getSiteManager') self.expect( getSiteManager_mock(dummy_site)).result(site_manager_mock).count( 1, None) # First look for unregistration of all local components self.expect( site_manager_mock.unregisterUtility( provided=IDexterityFTI, name=portal_type)).passthrough() # Then look for re-registration of global components self.expect( site_manager_mock.registerUtility( fti, IDexterityFTI, portal_type, info='plone.dexterity.dynamic')).passthrough() self.expect( site_manager_mock.registerUtility( mocker.MATCH(lambda x: isinstance(x, DexterityFactory) and x. portal_type == portal_type), IFactory, portal_type, info='plone.dexterity.dynamic')).passthrough() self.assertEqual('string:${folder_url}/++add++testtype', fti.add_view_expr) self.replay() ftiRenamed( fti, ObjectMovedEvent(fti, container_dummy, fti.getId(), container_dummy, u"newtype")) site_dummy = self.create_dummy( getSiteManager=lambda: site_manager_mock) setSite(site_dummy) setHooks() self.assertNotEquals(None, queryUtility(IDexterityFTI, name=portal_type)) self.assertNotEquals(None, queryUtility(IFactory, name=portal_type))
def test_meta_type_change_class(self): fti = DexterityFTI( u"testtype", klass="plone.dexterity.tests.test_fti.TestClass" ) fti._updateProperty( 'klass', "plone.dexterity.tests.test_fti.TestClass2" ) self.assertEqual(TestClass2.meta_type, fti.Metatype())
def test_add(self): # Container, new object, and request container = Mock() obj = Mock() request = TestRequest() container._setObject = Mock(return_value=u'newid') container._getOb = Mock(return_value=obj) container.absolute_url = Mock( return_value="http://nohost/plone/container") obj.id = u"newid" obj.portal_type = 'testtype' # New object's FTI fti_mock = DexterityFTI(u"testtype") fti_mock.isConstructionAllowed = Mock(return_value=True) self.mock_utility(fti_mock, IDexterityFTI, name=u"testtype") # Container FTI container_fti_mock = DexterityFTI(u"containertype") container_fti_mock.allowType = Mock(return_value=True) self.mock_utility(container_fti_mock, IDexterityFTI, name=u"containertype") container.getTypeInfo = Mock(return_value=container_fti_mock) # Name chooser @implementer(INameChooser) class NameChooser(object): def __init__(self, context): pass def chooseName(self, name, object): return u"newid" self.mock_adapter(NameChooser, INameChooser, (Interface, )) form = DefaultAddForm(container, request) form.portal_type = u"testtype" form.add(obj)
def setUp(self): portal_types = api.portal.get_tool('portal_types') # Define new portal type without behavior fti = DexterityFTI(str('without_behavior'), title='Without Behavior') fti.behaviors = ('plone.app.dexterity.behaviors.metadata.IBasic', ) fti.model_source = u"""\ <model xmlns="http://namespaces.plone.org/supermodel/schema"> <schema> <field name="custom" type="zope.schema.TextLine"> <description /> <required>False</required> <title>Custom field</title> </field> </schema> </model>""" portal_types._setObject(str('without_behavior'), fti) # Define new portal type with behavior fti = DexterityFTI(str('with_behavior'), title='With Behavior') fti.behaviors = ( 'plone.app.dexterity.behaviors.metadata.IBasic', 'collective.dexteritytextindexer.behavior.IDexterityTextIndexer') fti.model_source = u"""\ <model xmlns="http://namespaces.plone.org/supermodel/schema"> <schema> <field name="custom" type="zope.schema.TextLine"> <description /> <required>False</required> <title>Custom field</title> </field> </schema> </model>""" portal_types._setObject(str('with_behavior'), fti) setRoles(self.layer['portal'], TEST_USER_ID, ['Manager']) transaction.commit() self.browser = Browser(self.layer['app']) self.browser.addHeader( 'Authorization', 'Basic {0}:{1}'.format(TEST_USER_NAME, TEST_USER_PASSWORD)) self.portal_url = self.layer['portal'].absolute_url()
def setUp(self): super(DexterityContentTestCase, self).setUp() self.portal.portal_types._setObject("test_type", DexterityFTI("test_type")) test_type = self.portal.portal_types.test_type test_type.klass = "plone.dexterity.content.Item" test_type.behaviors = ("plone.app.dexterity.behaviors.metadata.IDublinCore",) self.portal.invokeFactory("test_type", "test_content") self.content = self.portal["test_content"] self.content.setSubject(u"Keyword1 Keyword2 Keyword3".split()) self.content.reindexObject()
def add_folder_type(portal): from plone.dexterity.fti import DexterityFTI fti = DexterityFTI(DEXTERITY_FTI_FOLDER) portal.portal_types._setObject(DEXTERITY_FTI_FOLDER, fti) fti.klass = 'plone.dexterity.content.Container' fti.filter_content_types = False fti.behaviors = ('plone.app.dexterity.behaviors.metadata.IBasic', 'brasil.gov.vcge.dx.behaviors.IVCGE') return fti
def testRelations(self): rel_fti = DexterityFTI( 'RelationsType', schema= 'plone.app.versioningbehavior.tests.test_modifiers.IRelationsType') self.portal.portal_types._setObject('RelationsType', rel_fti) # Setup IIntIds utility which is required for relations to work from five.intid import site from zope.app.intid.interfaces import IIntIds site.add_intids(self.portal) intids = getUtility(IIntIds) source = createContentInContainer(self.portal, 'RelationsType') target = createContentInContainer(self.portal, 'RelationsType') # Test modifier when no relations are set modifier = SkipRelations('modifier', 'Modifier') pers_id, pers_load, empty1, empty2 = modifier.getOnCloneModifiers( source) self.assertTrue(pers_id(None) is None) self.assertTrue(pers_id(None) is None) self.assertTrue(pers_load(None) is None) self.assertTrue(pers_load(None) is None) self.assertTrue(empty1 == []) self.assertTrue(empty2 == []) repo_clone = createContent('RelationsType') modifier.afterRetrieveModifier(source, repo_clone) self.assertTrue(repo_clone.single is source.single) self.assertTrue(repo_clone.multiple is source.multiple) # Add some relations source.single = RelationValue(intids.getId(target)) source.multiple = [RelationValue(intids.getId(target))] # Update relations from zope.lifecycleevent import ObjectModifiedEvent from zope.event import notify notify(ObjectModifiedEvent(source)) modifier = SkipRelations('modifier', 'Modifier') pers_id, pers_load, empty1, empty2 = modifier.getOnCloneModifiers( source) self.assertTrue(pers_id(source.single)) self.assertTrue(pers_id(source.multiple)) self.assertTrue(pers_load(source.single) is None) self.assertTrue(pers_load(source.multiple) is None) self.assertTrue(empty1 == []) self.assertTrue(empty2 == []) repo_clone = createContent('RelationsType') modifier.afterRetrieveModifier(source, repo_clone) self.assertTrue(repo_clone.single is source.single) self.assertTrue(repo_clone.multiple is source.multiple)
def test_addview_and_factory_not_overridden_on_creation(self): fti = DexterityFTI( u"testtype", add_view_expr="string:${folder_url}/@@my-addview", factory="my.factory" ) self.assertEqual( 'string:${folder_url}/@@my-addview', fti.add_view_expr ) self.assertEqual('my.factory', fti.factory)
def create(self, data): type_id = data.pop('id') props = dict(self.context.fti.propertyItems()) # make sure we don't share the factory if props['factory'] == self.context.fti.getId(): del props['factory'] props['title'] = data['title'] props['add_view_expr'] = props['add_view_expr'].replace(self.context.fti.getId(), type_id) fti = DexterityFTI(type_id, **props) return fti
def test_title_i18n(self): fti = DexterityFTI(u'testtype', title=b't\xc3\xa9st') # with no i18n domain, we get the UTF8-encoded title self.assertEqual(b't\xc3\xa9st'.decode('utf8'), fti.Title()) # with an i18n domain, we get a Message fti.i18n_domain = 'test' msgid = fti.Title() self.assertEqual(u't\xe9st', msgid) self.assertEqual('test', msgid.domain)
def test_invalidate_cache(self): portal_type = u"testtype" fti = DexterityFTI(portal_type) SCHEMA_CACHE.get(portal_type) SCHEMA_CACHE.behavior_schema_interfaces(fti) self.assertIn('_v_schema_behavior_schema_interfaces', fti.__dict__.keys()) invalidate_cache(fti) self.assertNotIn('_v_schema_behavior_schema_interfaces', fti.__dict__.keys())
def test_description_i18n(self): fti = DexterityFTI('testtype', description='t\xc3\xa9st') # with no i18n domain, we get the UTF8-encoded title self.assertEqual('t\xc3\xa9st', fti.Description()) # with an i18n domain, we get a Message fti.i18n_domain = 'test' msgid = fti.Description() self.assertEqual('t\xe9st', msgid) self.assertEqual('test', msgid.domain)
def setUp(self): super(TestDocumentNumbering, self).setUp() fti = DexterityFTI('SimpleDocument') fti.klass = 'plone.dexterity.content.Container' fti.behaviors = ('opengever.document.behaviors.IBaseDocument', ) fti.schema = 'opengever.document.document.IDocumentSchema' typestool = getToolByName(self.portal, 'portal_types') typestool._setObject('SimpleDocument', fti) register(fti)
def setUpPloneSite(self, portal): self.applyProfile(portal, 'plone.app.dexterity:default') self.applyProfile(portal, 'plone.app.drafts:default') if 'Folder' not in portal.portal_types.objectIds(): fti = DexterityFTI('Folder') fti.behaviors = ( 'plone.app.dexterity.behaviors.metadata.IDublinCore', ) fti.klass = 'plone.dexterity.content.Container' fti.filter_content_types = False fti.global_allow = True portal.portal_types._setObject('Folder', fti) fti = DexterityFTI('MyDocument') fti.behaviors = ( 'plone.app.dexterity.behaviors.metadata.IDublinCore', 'plone.app.drafts.interfaces.IDraftable', ) fti.global_allow = True portal.portal_types._setObject('MyDocument', fti)
def setUp(self): self.portal = self.layer["portal"] self.request = self.layer["request"] login(self.portal, TEST_USER_NAME) setRoles(self.portal, TEST_USER_ID, ["Manager"]) fti = DexterityFTI("tiledfolder") self.portal.portal_types._setObject("tiledfolder", fti) fti.klass = "plone.dexterity.content.Container" fti.behaviors = ("plone.tiles", ) self.fti = fti alsoProvides(self.request, ITiles)
def setUp(self): super(TestSequenceBehavior, self).setUp() self.grant('Manager') fti = DexterityFTI( 'type1', klass="plone.dexterity.content.Container", global_allow=True, allowed_content_types=['type1'], behaviors=[ "opengever.base.behaviors.sequence.ISequenceNumberBehavior" ]) self.portal.portal_types._setObject('type1', fti) fti = DexterityFTI('type2', klass="plone.dexterity.content.Container", global_allow=True, allowed_content_types=['type2']) self.portal.portal_types._setObject('type2', fti) self.portal.invokeFactory('type1', 'n1') self.portal.invokeFactory('type1', 'n2') self.portal.invokeFactory('type2', 'f1')