From: nouri <svn...@pl...> - 2006-03-30 11:15:23
|
Author: nouri Date: Thu Mar 30 11:15:07 2006 New Revision: 6206 Added: Relations/trunk/tests/testUtils.py (contents, props changed) Modified: Relations/trunk/ChangeLog Relations/trunk/field.py Relations/trunk/skins/relations/relations_adddelete_vocab.py Relations/trunk/tests/testComponents.py Relations/trunk/tests/testRuleset.py Relations/trunk/utils.py Log: * utils.py (adddeleteVocab): I put the ``adddelete_vocab`` script onto the filesystem while adding a check for ``ModifyPortalContent`` on context. The Python script still exists, but it's only an alias now. Also added tests, which the script didn't have. Modified: Relations/trunk/ChangeLog ============================================================================== --- Relations/trunk/ChangeLog (original) +++ Relations/trunk/ChangeLog Thu Mar 30 11:15:07 2006 @@ -1,3 +1,11 @@ +2006-03-30 Daniel Nouri <daniel (dot) nouri at gmail (dot) com> + + * utils.py (adddeleteVocab): I put the ``adddelete_vocab`` script + onto the filesystem while adding a check for + ``ModifyPortalContent`` on context. The Python script still + exists, but it's only an alias now. Also added tests, which the + script didn't have. + 2006-03-01 Jens Klein <je...@bl...> * field.py: i18n moved in Archetypes 1.4 to Modified: Relations/trunk/field.py ============================================================================== --- Relations/trunk/field.py (original) +++ Relations/trunk/field.py Thu Mar 30 11:15:07 2006 @@ -19,6 +19,7 @@ from config import RELATIONS_LIBRARY import processor +import utils class RelationField(ReferenceField): """ @@ -94,8 +95,8 @@ def _Vocabulary(self, content_instance): - rel_vocab=content_instance.relations_adddelete_vocab( - ruleset_ids=[self.relationship]) + rel_vocab=utils.addeleteVocab(content_instance, + ruleset_ids=[self.relationship]) if rel_vocab: tuples=rel_vocab[0]['tuples'] Modified: Relations/trunk/skins/relations/relations_adddelete_vocab.py ============================================================================== --- Relations/trunk/skins/relations/relations_adddelete_vocab.py (original) +++ Relations/trunk/skins/relations/relations_adddelete_vocab.py Thu Mar 30 11:15:07 2006 @@ -4,67 +4,10 @@ ##bind context=context ##bind container=container ## -from Products.Relations.brain import makeBrainAggregate -from Products.Relations.utils import isReferenceable -# What we return here is a list of dictionaries with the following keys: -# - id the ruleset's id, which is the relationship -# - title the ruleset's title -# - tuples a list of tuples, see below. -# -# Each 'tuples' item is a 2-tuple in the form (aggregated brain, selected), -# where selected is true if there's a reference -# (source=context, target=vocab item, relationship=ruleset.id). -# -# If test_only=1, I will return true if *any* vocabulary item exists. Otherwise -# I will return a false value. +# This script just become an alias for the utils.adddeleteVocab +# function. -value = [] +from Products.Relations.utils import adddeleteVocab -if not isReferenceable(context): - return [] - -library = context.relations_library -refctl = context.reference_catalog -mtool = context.portal_membership - -if not ruleset_ids: - rulesets = library.getRulesets() -else: - rulesets = [library.getRuleset(rid) for rid in ruleset_ids] - -for ruleset in rulesets: - if not mtool.checkPermission('View', ruleset): continue - relationship = ruleset.getId() - vocabulary = ruleset.makeVocabulary(context) - if vocabulary is None: vocabulary = [] - refs = refctl(sourceUID=context.UID(), relationship=relationship) - existing_targetUIDs = [r.targetUID for r in refs] - if not vocabulary and not existing_targetUIDs: - continue # we don't add an entry - elif test_only: - return True - - entry = {'id': relationship, - 'title': ruleset.Title(), - 'tuples': []} - value.append(entry) - - tuples = entry['tuples'] - - # first add all vocabulary items to 'tuples' in entry dict - for item in vocabulary: - selected = False - if item.UID in existing_targetUIDs: - selected = True - tuples.append((item, selected)) - - # now find existing refs that are not part of the vocab, which we add - vocab_uids = [item.UID for (item, selected) in tuples] - for uid in existing_targetUIDs: - if uid not in vocab_uids: - tuples.append((makeBrainAggregate(context, uid), True)) - -return value - - +return adddeleteVocab(context, test_only, ruleset_ids) Modified: Relations/trunk/tests/testComponents.py ============================================================================== --- Relations/trunk/tests/testComponents.py (original) +++ Relations/trunk/tests/testComponents.py Thu Mar 30 11:15:07 2006 @@ -310,6 +310,8 @@ self.assertEquals(self.objs[0].getRefs(), []) def testInverseWithSameTriple(self): + # This test requires the dpunktnpunkt-multipleref branch of + # Archetypes to work from Products.Relations import config config.ALLOW_MULTIPLE_REFS_PER_TRIPLE = True Modified: Relations/trunk/tests/testRuleset.py ============================================================================== --- Relations/trunk/tests/testRuleset.py (original) +++ Relations/trunk/tests/testRuleset.py Thu Mar 30 11:15:07 2006 @@ -436,6 +436,8 @@ self.assertEquals(len(brains), 1) def testDefaultPrimaryImplicatorMultipleRefsPerTriple(self): + # This test requires the dpunktnpunkt-multipleref branch of + # Archetypes to work from Products.Relations import config config.ALLOW_MULTIPLE_REFS_PER_TRIPLE = True Added: Relations/trunk/tests/testUtils.py ============================================================================== --- (empty file) +++ Relations/trunk/tests/testUtils.py Thu Mar 30 11:15:07 2006 @@ -0,0 +1,74 @@ +import os, sys +if __name__ == '__main__': + execfile(os.path.join(sys.path[0], 'framework.py')) + +from Products.CMFTestCase import CMFTestCase + +import common +common.installProducts() +CMFTestCase.setupCMFSite() + +import brain +import processor +import utils + +class TestAdddeleteVocab(CMFTestCase.CMFTestCase): + + TYPES = 'SimpleFolder', 'SimpleType', 'ComplexType' + + def afterSetUp(self): + common.installWithinPortal(self, self.portal) + + # create some objects + self.objs = common.createObjects(self, self.TYPES) + self.brains = [brain.makeBrainAggregate(self.portal, obj.UID()) + for obj in self.objs] + + # construct and register a ruleset + self.ruleset = common.createRuleset(self, 'ruleset') + + # Allow self.TYPES as target + self.ruleset.invokeFactory('Type Constraint', 'tc') + self.ruleset.tc.setAllowedTargetTypes(self.TYPES) + + def testNoPermissions(self): + vocab = utils.adddeleteVocab(self.objs[0]) + self.assertEquals(len(vocab), 1) + self.assertEquals(len(vocab[0]['tuples']), 3) + + self.logout() + vocab = utils.adddeleteVocab(self.objs[0]) + self.assertEquals(len(vocab), 0) + + def testTestOnly(self): + vocab = utils.adddeleteVocab(self.objs[0], test_only=1) + self.failUnless(vocab) + + self.ruleset.tc.setAllowedTargetTypes(['Gorilla']) + vocab = utils.adddeleteVocab(self.objs[0], test_only=1) + self.failIf(vocab) + + def testRuleSetIds(self): + # Add another ruleset and allow all self.TYPES as targets + self.ruleset2 = common.createRuleset(self, 'ruleset2') + self.ruleset2.invokeFactory('Type Constraint', 'tc') + self.ruleset2.tc.setAllowedTargetTypes(self.TYPES) + + vocab = utils.adddeleteVocab(self.objs[0]) + self.assertEquals(len(vocab), 2) + self.failUnless(vocab[0]['id'] in ('ruleset', 'ruleset2')) + self.failUnless(vocab[1]['id'] in ('ruleset', 'ruleset2')) + + vocab = utils.adddeleteVocab(self.objs[0], ruleset_ids=['ruleset']) + self.assertEquals(len(vocab), 1) + self.assertEquals(vocab[0]['id'], 'ruleset') + + +def test_suite(): + from unittest import TestSuite, makeSuite + suite = TestSuite() + suite.addTest(makeSuite(TestAdddeleteVocab)) + return suite + +if __name__ == '__main__': + framework() Modified: Relations/trunk/utils.py ============================================================================== --- Relations/trunk/utils.py (original) +++ Relations/trunk/utils.py Thu Mar 30 11:15:07 2006 @@ -4,6 +4,7 @@ from OFS.CopySupport import CopySource from Products.CMFCore.utils import getToolByName +from Products.CMFCore import permissions try: from Products.CMFCore.PortalFolder import PortalFolderBase @@ -11,11 +12,12 @@ from Products.CMFCore.PortalFolder import PortalFolder PortalFolderBase = PortalFolder - from Products.Archetypes.ArchetypeTool import listTypes +from Products.Relations.brain import makeBrainAggregate + + modulesec = ModuleSecurityInfo('Products.Relations.utils') -modulesec.declarePublic('isReferenceable') class AllowedTypesByIface: """An approach to restrict allowed content types in a container by @@ -119,10 +121,83 @@ return [t for t in pttool.listContentTypes() if t in attypes] +modulesec.declarePublic('isReferenceable') def isReferenceable(context): if getattr(aq_base(context), 'isReferenceable', None) is not None: return True else: return False +modulesec.declarePublic('isReferenceable') +def adddeleteVocab(context, test_only=0, ruleset_ids=None): + """Make Relations vocabularies by querying all rulesets. + + What we return here is a list of dictionaries with the following + keys: + + - id the ruleset's id, which is the relationship + - title the ruleset's title + - tuples a list of tuples, see below. + + Each 'tuples' item is a 2-tuple in the form (aggregated brain, + selected), where selected is true if there's a reference + (source=context, target=vocab item, relationship=ruleset.id). + + If test_only=1, I will return true if *any* vocabulary item + exists. Otherwise I will return a false value. + """ + + value = [] + + membership = getToolByName(context, 'portal_membership') + if not membership.checkPermission(permissions.ModifyPortalContent, + context): + return [] + + if not isReferenceable(context): + return [] + + library = context.relations_library + refctl = context.reference_catalog + mtool = context.portal_membership + + if not ruleset_ids: + rulesets = library.getRulesets() + else: + rulesets = [library.getRuleset(rid) for rid in ruleset_ids] + + for ruleset in rulesets: + if not mtool.checkPermission('View', ruleset): continue + relationship = ruleset.getId() + vocabulary = ruleset.makeVocabulary(context) + if vocabulary is None: vocabulary = [] + refs = refctl(sourceUID=context.UID(), relationship=relationship) + existing_targetUIDs = [r.targetUID for r in refs] + if not vocabulary and not existing_targetUIDs: + continue # we don't add an entry + elif test_only: + return True + + entry = {'id': relationship, + 'title': ruleset.Title(), + 'tuples': []} + value.append(entry) + + tuples = entry['tuples'] + + # first add all vocabulary items to 'tuples' in entry dict + for item in vocabulary: + selected = False + if item.UID in existing_targetUIDs: + selected = True + tuples.append((item, selected)) + + # now find existing refs that are not part of the vocab, which we add + vocab_uids = [item.UID for (item, selected) in tuples] + for uid in existing_targetUIDs: + if uid not in vocab_uids: + tuples.append((makeBrainAggregate(context, uid), True)) + + return value + |