Back to index

plone3  3.1.7
test_referenceCatalog.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 Unittests for a reference Catalog
00027 
00028 $Id: test_referenceCatalog.py 7768 2007-03-18 23:38:08Z nouri $
00029 """
00030 
00031 from Products.Archetypes.tests.atsitetestcase import ATSiteTestCase
00032 from Products.Archetypes.tests.utils import makeContent
00033 
00034 from Products.Archetypes import config
00035 from Products.Archetypes.references import HoldingReference, CascadeReference
00036 from OFS.ObjectManager import BeforeDeleteException
00037 import transaction
00038 
00039 class ReferenceCatalogTests(ATSiteTestCase):
00040 
00041     def verifyBrains(self):
00042         uc = getattr(self.portal, config.UID_CATALOG)
00043         rc = getattr(self.portal, config.REFERENCE_CATALOG)
00044 
00045         #Verify all UIDs resolve
00046         brains = uc()
00047         objects = [b.getObject() for b in brains]
00048         self.failIf(None in objects, """bad uid resolution""")
00049         for b in brains:
00050             if b.getPath().startswith('/'):
00051                 print "Bad Brain", b, b.getObject()
00052 
00053         #Verify all references resolve
00054         brains = rc()
00055         objects = [b.getObject() for b in brains]
00056         self.failIf(None in objects, """bad ref catalog resolution""")
00057 
00058     def test_create(self):
00059         rc = getattr(self.portal, config.REFERENCE_CATALOG)
00060         uc = getattr(self.portal, config.UID_CATALOG)
00061 
00062         self.failUnless(rc is not None)
00063 
00064         id1 = "firstObject"
00065         obj = makeContent(self.folder, portal_type='Fact', id=id1)
00066         self.failUnless(obj.UID())
00067 
00068         brains = uc(UID=obj.UID())
00069         self.failUnless(len(brains) == 1)
00070 
00071         id2 = "secondObject"
00072         obj2 = makeContent(self.folder, portal_type='Fact', id=id2)
00073 
00074         self.verifyBrains()
00075         obj.addReference(obj2, 'testRelationship', foo="bar")
00076         self.verifyBrains()
00077         uid1 = obj.UID()
00078         uid2 = obj2.UID()
00079 
00080         brains = rc()
00081         ref = brains[0].getObject()
00082         self.failUnless(ref.sourceUID == uid1)
00083         self.failUnless(ref.targetUID == uid2)
00084 
00085         #Check the metadata
00086         self.failUnless(ref.foo == "bar")
00087 
00088         unqualified = obj.getRefs()
00089         byRel = obj.getRefs('testRelationship')
00090         assert unqualified[0] == byRel[0] == ref.getTargetObject()
00091 
00092         back = obj2.getBRefs()
00093         self.failUnless(back[0] == obj)
00094 
00095         self.failUnless(obj.reference_url().endswith(uid1))
00096 
00097         # Make sure all objects have _p_oids and _p_jars
00098         transaction.savepoint(optimistic=True)
00099 
00100         #Rename can't invalidate UID or references
00101         self.verifyBrains()
00102         obj.setId('new1')
00103         self.verifyBrains()
00104 
00105         self.failUnless(obj.getId() == 'new1')
00106         self.failUnless(obj.UID() == uid1)
00107 
00108         b = obj.getRefs()
00109         self.failUnless(b[0].UID() == uid2)
00110 
00111         obj2.setId('new2')
00112         self.failUnless(obj2.getId() == 'new2')
00113         self.failUnless(obj2.UID() == uid2)
00114 
00115         b = obj2.getBRefs()
00116 
00117         self.failUnless(b[0].UID() == uid1)
00118 
00119         #Add another reference with a different relationship (and the
00120         #other direction)
00121 
00122         obj2.addReference(obj, 'betaRelationship', this="that")
00123         b = obj2.getRefs('betaRelationship')
00124         self.failUnless(b[0].UID() == uid1)
00125         b = obj.getBRefs('betaRelationship')
00126         refs = rc.getBackReferences(obj, 'betaRelationship')
00127         # objs back ref should be obj2
00128         self.failUnless(refs[0].sourceUID == b[0].UID() == uid2)
00129         self.verifyBrains()
00130 
00131 
00132     def test_holdingref(self):
00133         rc = getattr(self.portal, config.REFERENCE_CATALOG)
00134         uc = getattr(self.portal, config.UID_CATALOG)
00135 
00136         obj1 = makeContent(self.folder, portal_type='Fact', id='obj1')
00137         obj2 = makeContent(self.folder, portal_type='Fact', id='obj2')
00138 
00139         obj1.addReference(obj2, relationship="uses", referenceClass=HoldingReference)
00140 
00141         self.failUnless(obj2 in obj1.getRefs('uses'))
00142 
00143         # a holding reference says obj2 can't be deleted cause its held
00144         try:
00145             self.folder._delObject(obj2.id)
00146         except BeforeDeleteException, E:
00147             pass
00148         else:
00149             raise AssertionError("holding reference didn't hold")
00150 
00151         #and just check to make sure its still there
00152         self.failUnless(hasattr(self.folder, obj2.id))
00153 
00154         obj3 = makeContent(self.folder, portal_type='Fact', id='obj3')
00155         obj4 = makeContent(self.folder, portal_type='Fact', id='obj4')
00156 
00157         obj3.addReference(obj4, relationship="uses", referenceClass=CascadeReference)
00158 
00159         self.folder.manage_delObjects(obj3.id)
00160         items = self.folder.contentIds()
00161         self.failIf(obj3.id in items)
00162         self.failIf(obj4.id in items)
00163 
00164     def test_cascaderef(self):
00165         my1stfolder = makeContent(self.folder, portal_type='SimpleFolder', id='my1stfolder')
00166         obj5 = makeContent(my1stfolder, portal_type='Fact', id='obj5')
00167         my2ndfolder = makeContent(self.folder, portal_type='SimpleFolder', id='my2ndfolder')
00168         obj6 = makeContent(my2ndfolder, portal_type='Fact', id='obj6')
00169         obj5.addReference(obj6, relationship="uses", referenceClass=CascadeReference)
00170         my1stfolder.manage_delObjects(['obj5'])
00171         items = my1stfolder.contentIds()
00172         self.failIf('obj5' in items)
00173         items = my2ndfolder.contentIds()
00174         self.failIf('obj6' in items)
00175 
00176     def test_delete(self):
00177         rc = getattr(self.portal, config.REFERENCE_CATALOG)
00178         uc = getattr(self.portal, config.UID_CATALOG)
00179 
00180         obj1 = makeContent(self.folder, portal_type='Fact', id='obj1')
00181         obj2 = makeContent(self.folder, portal_type='Fact', id='obj2')
00182 
00183         uid1 = obj1.UID()
00184         uid2 = obj2.UID()
00185 
00186 
00187         #Make a reference
00188         obj1.addReference(obj2, relationship="example")
00189 
00190         #and clean it up
00191         self.folder._delObject(obj1.id)
00192 
00193         # Assert that the reference is gone, that the UID is gone and
00194         # that the content is gone
00195         self.failUnless(obj2.getBRefs() == [])
00196         self.failIf(obj1.id in self.folder.contentIds())
00197 
00198         self.failIf(uid1 in uc.uniqueValuesFor('UID'))
00199         self.failUnless(uid2 in uc.uniqueValuesFor('UID'))
00200 
00201         sourceRefs = rc(sourceUID = uid1)
00202         targetRefs = rc(targetUID = uid1)
00203 
00204         assert len(sourceRefs) == 0
00205         assert len(targetRefs) == 0
00206 
00207         #also make sure there is nothing in the reference Catalog
00208         assert len(rc.getReferences(uid1)) == 0
00209         assert len(rc.getBackReferences(uid1)) == 0
00210         assert len(rc.getReferences(uid2)) == 0
00211         assert len(rc.getBackReferences(uid2)) == 0
00212 
00213     def test_custome_metadata(self):
00214         # create two objects
00215         # make ref from one object to the other
00216         # place a custom attribute on the reference
00217         # update schemas
00218         # test if attribute still exists on the reference object
00219         rc = self.portal.reference_catalog
00220 
00221         obj1 = makeContent(self.folder, portal_type='Refnode',
00222                            id='one')
00223         uid = obj1.UID()
00224         obj2 = makeContent(self.folder, portal_type='Refnode', id='two')
00225         uid2 = obj2.UID()
00226         # create reference
00227         obj1.update(link=[obj2.UID()])
00228         ref = rc.getReferences(obj1)[0]
00229         ref.attribute1 = "some_value"
00230         ruid = ref.UID()
00231         self.failUnless(ref.attribute1=='some_value')
00232 
00233 
00234         transaction.savepoint(optimistic=True)
00235         # update schema
00236         self.app.REQUEST.form['Archetypes.Refnode']=1
00237         self.app.REQUEST.form['update_all']=1
00238         self.portal.archetype_tool.manage_updateSchema(REQUEST=self.app.REQUEST)
00239         del obj1
00240 
00241         # get the reference for obj1
00242         obj1 = rc.lookupObject(uid)
00243         refs = rc.getReferences(obj1, relationship=obj1.Schema()['link'].relationship)
00244         ref = refs[0]
00245         ruid2 = ref.UID()
00246         assert ruid == ruid2, """ref uid got reassigned"""
00247         #check for the attribute
00248         self.failUnless(hasattr(ref, 'attribute1'), 'Custom attribute on reference object is lost during schema update')
00249         self.assertEqual(ref.attribute1, 'some_value')
00250 
00251 
00252 def test_suite():
00253     from unittest import TestSuite, makeSuite
00254     suite = TestSuite()
00255     suite.addTest(makeSuite(ReferenceCatalogTests))
00256     return suite