Back to index

plone3  3.1.7
test_referenceable.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 from Acquisition import aq_base
00027 import transaction
00028 
00029 from Products.Archetypes.tests.atsitetestcase import ATSiteTestCase
00030 from Products.Archetypes.tests.utils import makeContent
00031 
00032 from Products.Archetypes.examples import *
00033 from Products.Archetypes.config import *
00034 from Products.Archetypes.atapi import DisplayList
00035 
00036 class BaseReferenceableTests(ATSiteTestCase):
00037 
00038     FOLDER_TYPE = None
00039 
00040     def verifyBrains(self):
00041         uc = getattr(self.portal, UID_CATALOG)
00042         rc = getattr(self.portal, REFERENCE_CATALOG)
00043 
00044         #Verify all UIDs resolve
00045         brains = uc()
00046         uobjects = [b.getObject() for b in brains]
00047         self.failIf(None in uobjects, """bad uid resolution""")
00048 
00049         #Verify all references resolve
00050         brains = rc()
00051         robjects = [b.getObject() for b in brains]
00052         self.failIf(None in robjects, """bad ref catalog resolution""")
00053         return uobjects, robjects
00054 
00055     def test_hasUID( self ):
00056         doc = makeContent( self.folder
00057                            , portal_type='DDocument'
00058                            , title='Foo' )
00059 
00060         self.failUnless(hasattr(aq_base(doc), UUID_ATTR))
00061         self.failUnless(getattr(aq_base(doc), UUID_ATTR, None))
00062 
00063 
00064     def test_renamedontchangeUID( self ):
00065         catalog = self.portal.uid_catalog
00066 
00067         obj_id = 'demodoc'
00068         new_id = 'new_demodoc'
00069         doc = makeContent(self.folder
00070                           , portal_type='DDocument'
00071                           , title='Foo'
00072                           , id=obj_id)
00073 
00074 
00075         UID = doc.UID()
00076         # This test made an assumption about other UIDs in the system
00077         # that are wrong with things like ATCT
00078         self.failUnless(UID in catalog.uniqueValuesFor('UID'))
00079         # ensure object has a _p_jar
00080         transaction.savepoint(optimistic=True)
00081         self.folder.manage_renameObject(id=obj_id, new_id=new_id)
00082         doc = getattr(self.folder, new_id)
00083         self.failUnless(UID in catalog.uniqueValuesFor('UID'))
00084         self.assertEquals(doc.UID(), UID)
00085 
00086 
00087     def test_renameKeepsReferences(self):
00088         container = makeContent(self.folder,
00089                                 portal_type=self.FOLDER_TYPE,
00090                                 title='Spam',
00091                                 id='container')
00092 
00093         obj1 = makeContent(self.folder.container,
00094                            portal_type='SimpleType',
00095                            title='Eggs',
00096                            id='obj1')
00097         obj2 = makeContent(self.folder.container,
00098                            portal_type='SimpleType',
00099                            title='Foo',
00100                            id='obj2')
00101 
00102         obj1.addReference(obj2)
00103 
00104         self.verifyBrains()
00105         transaction.savepoint(optimistic=True)
00106         obj1.setId('foo')
00107         transaction.savepoint(optimistic=True)
00108 
00109         self.assertEquals(obj2.getBRefs(), [obj1])
00110         self.assertEquals(obj1.getRefs(), [obj2])
00111 
00112         self.verifyBrains()
00113         transaction.savepoint(optimistic=True)
00114         obj2.setId('bar')
00115         transaction.savepoint(optimistic=True)
00116 
00117         self.assertEquals(obj2.getBRefs(), [obj1])
00118         self.assertEquals(obj1.getRefs(), [obj2])
00119 
00120         self.verifyBrains()
00121 
00122     def test_renamecontainerKeepsReferences( self ):
00123         # test for #956677: renaming the container causes contained objects
00124         #                   to lose their refs
00125         container = makeContent(self.folder,
00126                                 portal_type=self.FOLDER_TYPE,
00127                                 title='Spam',
00128                                 id='container')
00129         obj1 = makeContent(self.folder.container,
00130                            portal_type='SimpleType',
00131                            title='Eggs',
00132                            id='obj1')
00133         obj2 = makeContent(self.folder,
00134                            portal_type='SimpleType',
00135                            title='Foo',
00136                            id='obj2')
00137 
00138         obj1.addReference(obj2)
00139 
00140         a,b = self.verifyBrains()
00141         transaction.savepoint(optimistic=True)
00142 
00143         self.assertEquals(obj2.getBRefs(), [obj1])
00144         self.assertEquals(obj1.getRefs(), [obj2])
00145 
00146         self.folder.manage_renameObject(id='container',
00147                                         new_id='cont4iner')
00148         c, d = self.verifyBrains()
00149 
00150         obj1 = self.folder.cont4iner.obj1
00151         obj2 = self.folder.cont4iner.obj2
00152 
00153         self.assertEquals(obj2.getBRefs(), [obj1])
00154         self.assertEquals(obj1.getRefs(), [obj2])
00155 
00156     def test_renamecontainerKeepsReferences2( self ):
00157         # test for [ 1013363 ] References break on folder rename
00158         folderA = makeContent(self.folder,
00159                                 portal_type=self.FOLDER_TYPE,
00160                                 title='Spam',
00161                                 id='folderA')
00162         objA = makeContent(self.folder.folderA,
00163                            portal_type='SimpleType',
00164                            title='Eggs',
00165                            id='objA')
00166 
00167         folderB = makeContent(self.folder,
00168                                 portal_type=self.FOLDER_TYPE,
00169                                 title='Spam',
00170                                 id='folderB')
00171         objB = makeContent(self.folder.folderB,
00172                            portal_type='SimpleType',
00173                            title='Eggs',
00174                            id='objB')
00175 
00176         objA.addReference(objB)
00177 
00178         a, b = self.verifyBrains()
00179         transaction.savepoint(optimistic=True)
00180 
00181         self.assertEquals(objB.getBRefs(), [objA])
00182         self.assertEquals(objA.getRefs(), [objB])
00183 
00184         # now rename folder B and see if objA still points to objB
00185         self.folder.manage_renameObject(id='folderB',
00186                                         new_id='folderC')
00187         c, d = self.verifyBrains()
00188 
00189         objB = self.folder.folderC.objB
00190 
00191         # check references
00192         self.assertEquals(objB.getBRefs(), [objA])
00193         self.assertEquals(objA.getRefs(), [objB])
00194 
00195     def test_UIDclash( self ):
00196         catalog = getattr(self.portal, UID_CATALOG)
00197 
00198         obj_id = 'demodoc'
00199         new_id = 'new_demodoc'
00200         doc = makeContent( self.folder
00201                            , portal_type='DDocument'
00202                            , title='Foo'
00203                            , id=obj_id)
00204 
00205         UID = doc.UID()
00206         # ensure object has a _p_jar
00207         transaction.savepoint(optimistic=True)
00208         self.folder.manage_renameObject(id=obj_id, new_id=new_id)
00209 
00210         #now, make a new one with the same ID and check it gets a different UID
00211         doc2 = makeContent( self.folder
00212                             , portal_type='DDocument'
00213                             , title='Foo'
00214                             , id=obj_id)
00215 
00216         UID2 = doc2.UID()
00217         self.failIf(UID == UID2)
00218         uniq = catalog.uniqueValuesFor('UID')
00219         self.failUnless(UID in uniq, (UID, uniq))
00220         self.failUnless(UID2 in uniq, (UID, uniq))
00221 
00222     def test_setUID_keeps_relationships(self):
00223         obj_id   = 'demodoc'
00224         known_id = 'known_doc'
00225         owned_id = 'owned_doc'
00226 
00227         a = makeContent(self.folder, portal_type='DDocument',
00228                         title='Foo', id=obj_id)
00229         b = makeContent(self.folder, portal_type='DDocument',
00230                         title='Foo', id=known_id)
00231         c = makeContent(self.folder, portal_type='DDocument',
00232                         title='Foo', id=owned_id)
00233 
00234         #Two made up kinda refs
00235         a.addReference(b, "KnowsAbout")
00236         b.addReference(a, "KnowsAbout")
00237         a.addReference(c, "Owns")
00238 
00239         refs = a.getRefs()
00240         self.failUnless(b in refs, (b, refs))
00241         self.failUnless(c in refs, (c, refs))
00242         self.assertEquals(a.getRefs('KnowsAbout'), [b])
00243         self.assertEquals(b.getRefs('KnowsAbout'), [a])
00244         self.assertEquals(a.getRefs('Owns'), [c])
00245         self.assertEquals(c.getBRefs('Owns'), [a])
00246 
00247         old_uid = a.UID()
00248 
00249         # Check existing forward refs
00250         fw_refs = a.getReferenceImpl()
00251         old_refs = []
00252         [old_refs.append(o.sourceUID) for o in fw_refs
00253          if not o.sourceUID in old_refs]
00254         self.assertEquals(len(old_refs), 1)
00255         self.assertEquals(old_refs[0], old_uid)
00256 
00257         # Check existing backward refs
00258         fw_refs = a.getBackReferenceImpl()
00259         old_refs = []
00260         [old_refs.append(o.targetUID) for o in fw_refs
00261          if not o.targetUID in old_refs]
00262         self.assertEquals(len(old_refs), 1)
00263         self.assertEquals(old_refs[0], old_uid)
00264 
00265         new_uid = '9x9x9x9x9x9x9x9x9x9x9x9x9x9x9x9x9'
00266         a._setUID(new_uid)
00267         self.assertEquals(a.UID(), new_uid)
00268 
00269         # Check existing forward refs got reassigned
00270         fw_refs = a.getReferenceImpl()
00271         new_refs = []
00272         [new_refs.append(o.sourceUID) for o in fw_refs
00273          if not o.sourceUID in new_refs]
00274         self.assertEquals(len(new_refs), 1)
00275         self.assertEquals(new_refs[0], new_uid)
00276 
00277         # Check existing backward refs got reassigned
00278         fw_refs = a.getBackReferenceImpl()
00279         new_refs = []
00280         [new_refs.append(o.targetUID) for o in fw_refs
00281          if not o.targetUID in new_refs]
00282         self.assertEquals(len(new_refs), 1)
00283         self.assertEquals(new_refs[0], new_uid)
00284 
00285         refs = a.getRefs()
00286         self.failUnless(b in refs, (b, refs))
00287         self.failUnless(c in refs, (c, refs))
00288         self.assertEquals(a.getRefs('KnowsAbout'), [b])
00289         self.assertEquals(b.getRefs('KnowsAbout'), [a])
00290         self.assertEquals(a.getRefs('Owns'), [c])
00291         self.assertEquals(c.getBRefs('Owns'), [a])
00292 
00293         self.verifyBrains()
00294 
00295     def test_relationships(self):
00296 
00297         obj_id   = 'demodoc'
00298         known_id = 'known_doc'
00299         owned_id = 'owned_doc'
00300         other_id = 'other_doc'
00301 
00302         a = makeContent( self.folder, portal_type='DDocument',
00303                          title='Foo', id=obj_id)
00304         b = makeContent( self.folder, portal_type='DDocument',
00305                          title='Foo', id=known_id)
00306         c = makeContent( self.folder, portal_type='DDocument',
00307                          title='Foo', id=owned_id)
00308 
00309         #Two made up kinda refs
00310         a.addReference(b, "KnowsAbout")
00311         a.addReference(c, "Owns")
00312 
00313         refs = a.getRefs()
00314         self.failUnless(b in refs, (b, refs))
00315         self.failUnless(c in refs, (c, refs))
00316         self.assertEquals(a.getRefs('Owns'), [c])
00317         self.assertEquals(c.getBRefs('Owns'), [a])
00318         rels = a.getRelationships()
00319         self.failUnless("KnowsAbout" in rels, ("KnowsAbout", rels))
00320         self.failUnless("Owns" in rels, ("Owns", rels))
00321 
00322         a.deleteReference(c, "Owns")
00323         self.assertEquals(a.getRefs(), [b])
00324         self.assertEquals(c.getBRefs(), [])
00325 
00326         #test querying references using the targetObject parameter
00327         d = makeContent( self.folder, portal_type='DDocument',
00328                          title='Foo', id=other_id)
00329 
00330         a.addReference(d,'Owns')
00331         a.addReference(d,'KnowsAbout')
00332 
00333         self.assertEqual(len(a.getReferenceImpl()),3)
00334         #get only refs to d
00335         self.assertEqual(len(a.getReferenceImpl(targetObject=d)),2)
00336 
00337     def test_back_relationships(self):
00338 
00339         account_id = 'caixa'
00340         invoice_id = 'fatura'
00341         payment_id = 'entrada'
00342         future_payment_id = 'cta_receber'
00343         payment2_id = 'quitacao'
00344 
00345         account = makeContent( self.folder, portal_type='DDocument',
00346                                title='Account', id=account_id)
00347         invoice = makeContent( self.folder, portal_type='DDocument',
00348                                title='Invoice', id=invoice_id)
00349         payment = makeContent( self.folder, portal_type='DDocument',
00350                                title='Payment', id=payment_id)
00351         future_payment = makeContent( self.folder, portal_type='DDocument',
00352                                       title='Future Payment',
00353                                       id=future_payment_id)
00354         payment2 = makeContent( self.folder, portal_type='DDocument',
00355                                 title='Payment 2', id=payment2_id)
00356 
00357         invoice.addReference(payment, "Owns")
00358         invoice.addReference(future_payment, "Owns")
00359         future_payment.addReference(payment2, "Owns")
00360         payment.addReference(account, "From")
00361         payment2.addReference(account, "From")
00362 
00363         brels = account.getBRelationships()
00364         self.assertEquals(brels, ['From'])
00365         brefs = account.getBRefs('From')
00366         self.assertEquals(brefs, [payment, payment2])
00367 
00368         brels = payment.getBRelationships()
00369         self.assertEquals(brels, ['Owns'])
00370         brefs = payment.getBRefs('Owns')
00371         self.assertEquals(brefs, [invoice])
00372 
00373         brels = payment2.getBRelationships()
00374         self.assertEquals(brels, ['Owns'])
00375         brefs = payment2.getBRefs('Owns')
00376         self.assertEquals(brefs, [future_payment])
00377 
00378         invoice.deleteReference(payment, "Owns")
00379 
00380         self.assertEquals(invoice.getRefs(), [future_payment])
00381         self.assertEquals(payment.getBRefs(), [])
00382 
00383     def test_singleReference(self):
00384         # If an object is referenced don't record its reference again
00385         a = makeContent( self.folder, portal_type='DDocument',title='Foo', id='a')
00386         b = makeContent( self.folder, portal_type='DDocument',title='Foo', id='b')
00387 
00388         #Add the same ref twice
00389         a.addReference(b, "KnowsAbout")
00390         a.addReference(b, "KnowsAbout")
00391 
00392         self.assertEquals(len(a.getRefs('KnowsAbout')),  1)
00393 
00394         #In this case its a different relationship
00395         a.addReference(b, 'Flogs')
00396         self.assertEquals(len(a.getRefs('KnowsAbout')), 1)
00397         self.assertEquals(len(a.getRefs()), 2)
00398 
00399     def test_multipleReferences(self):
00400         # If you provide updateReferences=False to addReference, it
00401         # will add, not replace the reference
00402         a = makeContent( self.folder, portal_type='DDocument',title='Foo', id='a')
00403         b = makeContent( self.folder, portal_type='DDocument',title='Foo', id='b')
00404 
00405         #Add the same ref twice
00406         a.addReference(b, "KnowsAbout", updateReferences=False)
00407         a.addReference(b, "KnowsAbout", updateReferences=False)
00408 
00409         self.assertEquals(len(a.getRefs('KnowsAbout')),  2)
00410 
00411         #In this case its a different relationship
00412         a.addReference(b, 'Flogs')
00413         self.assertEquals(len(a.getRefs('KnowsAbout')), 2)
00414         self.assertEquals(len(a.getRefs()), 3)
00415         
00416 
00417     def test_UIDunderContainment(self):
00418         # If an object is referenced don't record its reference again
00419         at = self.portal.archetype_tool
00420 
00421         folder = makeContent( self.folder, portal_type=self.FOLDER_TYPE,
00422                               title='Foo', id='folder')
00423         nonRef = makeContent( folder, portal_type='Document',
00424                               title='Foo', id='nonRef')
00425 
00426         fuid = folder.UID()
00427         nuid = nonRef.UID()
00428         # We expect this to break, an aq_explicit would fix it but
00429         # we can't change the calling convention
00430         # XXX: but proxy index could
00431         # XXX: assert fuid != nuid
00432 
00433     def test_hasRelationship(self):
00434         a = makeContent(self.folder, portal_type='DDocument',title='Foo', id='a')
00435         b = makeContent(self.folder, portal_type='DDocument',title='Foo', id='b')
00436         c = makeContent(self.folder, portal_type='DDocument',title='Foo', id='c')
00437 
00438         # Two made up kinda refs
00439         a.addReference(b, "KnowsAbout")
00440 
00441         self.assertEquals(a.hasRelationshipTo(b), 1)
00442         self.assertEquals(a.hasRelationshipTo(b, "KnowsAbout"), 1)
00443         self.assertEquals(a.hasRelationshipTo(b, "Foo"), 0)
00444         self.assertEquals(a.hasRelationshipTo(c), 0)
00445         self.assertEquals(a.hasRelationshipTo(c, "KnowsAbout"), 0)
00446 
00447         # XXX HasRelationshipFrom  || ( 1 for ref 2 for bref?)
00448 
00449     def test_graph(self):
00450         if not HAS_GRAPHVIZ:
00451             return
00452 
00453         # This just asserts that nothing went wrong
00454         a = makeContent(self.folder, portal_type='DDocument',title='Foo', id='a')
00455         b = makeContent( self.folder, portal_type='DDocument',title='Foo', id='b')
00456         c = makeContent( self.folder, portal_type='DDocument',title='Foo', id='c')
00457 
00458         # Two made up kinda refs
00459         a.addReference(b, "KnowsAbout")
00460         c.addReference(a, "Owns")
00461         refmap = a.getReferenceMap()
00462         self.failUnless(refmap, refmap)
00463         png = a.getReferencePng()
00464         self.failUnless(png, png)
00465 
00466 
00467     def test_folderishDeleteCleanup(self):
00468         self.folder.invokeFactory(type_name="Folder", id="reftest")
00469         folder = getattr(self.folder, "reftest")
00470 
00471         a = makeContent(folder, portal_type='DDocument',title='Foo', id='a')
00472         b = makeContent(folder, portal_type='DDocument',title='Bar', id='b')
00473         a.addReference(b, "KnowsAbout")
00474 
00475         # Again, lets assert the sanity of the UID and Ref Catalogs
00476         uc = self.portal.uid_catalog
00477         rc = self.portal.reference_catalog
00478 
00479         uids = uc.uniqueValuesFor('UID')
00480         self.failUnless(a.UID() in uids, (a.UID(), uids))
00481         self.failUnless(b.UID() in uids, (b.UID(), uids))
00482 
00483         refs = rc()
00484         self.assertEquals(len(refs), 1)
00485         ref = refs[0].getObject()
00486         self.assertEquals(ref.targetUID, b.UID())
00487         self.assertEquals(ref.sourceUID, a.UID())
00488 
00489         # Now Kill the folder and make sure it all went away
00490         self.folder._delObject("reftest")
00491         self.verifyBrains()
00492 
00493         uids = uc.uniqueValuesFor('UID')
00494         self.assertEquals(len(rc()), 0)
00495 
00496     def test_reindexUIDCatalog(self):
00497         catalog = self.portal.uid_catalog
00498 
00499         doc = makeContent(self.folder,
00500                           portal_type='DDocument',
00501                           id='demodoc')
00502         doc.update(title="sometitle")
00503         brain = catalog(UID=doc.UID())[0]
00504         self.assertEquals(brain.Title, doc.Title())
00505 
00506     def test_referenceReference(self):
00507         # Reference a reference object for fun (no, its like RDFs
00508         # metamodel)
00509         rc = self.portal.reference_catalog
00510 
00511         a = makeContent( self.folder, portal_type='DDocument',title='Foo', id='a')
00512         b = makeContent( self.folder, portal_type='DDocument',title='Foo', id='b')
00513         c = makeContent( self.folder, portal_type='DDocument',title='Foo', id='c')
00514         a.addReference(b)
00515 
00516         ref = a._getReferenceAnnotations().objectValues()[0]
00517         c.addReference(ref)
00518         ref.addReference(c)
00519         self.verifyBrains()
00520 
00521     def test_referenceFieldVocab(self):
00522         dummy = makeContent(self.folder, portal_type="Refnode", id="dummy")
00523         test123 = makeContent(self.folder, portal_type="Refnode",
00524                               id="Test123")
00525         test124 = makeContent(self.folder, portal_type="Refnode",
00526                               id="Test124")
00527         test125 = makeContent(self.folder, portal_type="Refnode",
00528                               id="Test125")
00529 
00530         field = dummy.Schema()['adds']
00531 
00532         expected = DisplayList([
00533             (test123.UID(), test123.getId()),
00534             (test124.UID(), test124.getId()),
00535             (test125.UID(), test125.getId()),
00536             (dummy.UID(), dummy.getId()),
00537             ])
00538 
00539         got = field.Vocabulary(dummy)
00540         self.assertEquals(got, expected)
00541 
00542         # We should have the option of nothing
00543         field = field.copy()
00544         field.required = 0
00545         field.multiValued = 0
00546 
00547         expected = DisplayList([
00548             (test123.UID(), test123.getId()),
00549             (test124.UID(), test124.getId()),
00550             (test125.UID(), test125.getId()),
00551             (dummy.UID(), dummy.getId()),
00552             ('', u'label_no_reference'),
00553             ])
00554         self.assertEquals(field.Vocabulary(dummy), expected)
00555 
00556         field = field.copy()
00557         field.vocabulary_display_path_bound = 1
00558         expected = DisplayList([
00559             (test123.UID(), test123.getId()),
00560             (test124.UID(), test124.getId()),
00561             (test125.UID(), test125.getId()),
00562             (dummy.UID(), dummy.getId()),
00563             ('', u'label_no_reference'),
00564             ])
00565         self.failIfEqual(field.Vocabulary(dummy), expected)
00566         field.vocabulary_display_path_bound = -1
00567         self.assertEquals(field.Vocabulary(dummy), expected)
00568 
00569     def test_noReferenceAfterDelete(self):
00570         # Deleting target should delete reference
00571         # added by GL
00572         a = makeContent(self.folder, portal_type='DDocument', id='a')
00573         b = makeContent(self.folder, portal_type='DDocument', id='b')
00574         a.addReference(b)
00575         self.folder._delObject('b')
00576 
00577         self.failUnlessEqual(a.getRefs(), [])
00578 
00579     def test_noBackReferenceAfterDelete(self):
00580         # Deleting source should delete back reference
00581         # added by GL
00582         a = makeContent(self.folder, portal_type='DDocument', id='a')
00583         b = makeContent(self.folder, portal_type='DDocument', id='b')
00584         a.addReference(b)
00585         self.folder._delObject('a')
00586 
00587         self.failUnlessEqual(b.getBRefs(), [])
00588 
00589     def test_copyKeepsReferences(self):
00590         # when copied a pasted object should NOT lose all references
00591         # if keepReferencesOnCopy is set
00592         # added by DaftDog (for plone tracker issue  #5180)
00593         org_folder = makeContent(self.folder,
00594                                  portal_type=self.FOLDER_TYPE,
00595                                  title='Origin folder',
00596                                  id='org_folder')
00597         dst_folder = makeContent(self.folder,
00598                                  portal_type=self.FOLDER_TYPE,
00599                                  title='Destination folder',
00600                                  id='dst_folder')
00601         a = makeContent(org_folder, portal_type='DDocument', id='a')
00602         b = makeContent(org_folder, portal_type='DDocument', id='b')
00603         related_field = a.getField('related')
00604         related_field.set(a, b.UID())
00605 
00606         self.failUnlessEqual(b.getBRefs(), [a])
00607         self.failUnlessEqual(a.getRefs(), [b])
00608 
00609         cb = org_folder.manage_copyObjects(ids=['a'])
00610         dst_folder.manage_pasteObjects(cb_copy_data=cb)
00611         copy_a = getattr(dst_folder, 'a')
00612 
00613         # The copy should get a new UID
00614         a_uid = a.UID()
00615         ca_uid = copy_a.UID()
00616         self.failIf(a_uid == ca_uid, (a_uid, ca_uid))
00617 
00618         # The copy should have the same references
00619         self.failUnlessEqual(a.getRefs(), copy_a.getRefs())
00620         self.failUnless(copy_a in b.getBRefs())
00621 
00622 
00623         # Original object should keep references
00624         self.failUnlessEqual(a.getRefs(), [b])
00625         # Original non-copied object should point to both the original and the copied object
00626         self.failUnlessEqual(b.getBRefs(), [a, copy_a])
00627 
00628     def test_copyPasteSupport(self):
00629         # copy/paste behaviour test
00630         # in another folder, pasted object should lose all references
00631         # added by GL (for bug #985393)
00632         org_folder = makeContent(self.folder,
00633                                  portal_type=self.FOLDER_TYPE,
00634                                  title='Origin folder',
00635                                  id='org_folder')
00636         dst_folder = makeContent(self.folder,
00637                                  portal_type=self.FOLDER_TYPE,
00638                                  title='Destination folder',
00639                                  id='dst_folder')
00640         a = makeContent(org_folder, portal_type='DDocument', id='a')
00641         b = makeContent(org_folder, portal_type='DDocument', id='b')
00642         a.addReference(b)
00643 
00644         self.failUnlessEqual(b.getBRefs(), [a])
00645         self.failUnlessEqual(a.getRefs(), [b])
00646 
00647         cb = org_folder.manage_copyObjects(ids=['a'])
00648         dst_folder.manage_pasteObjects(cb_copy_data=cb)
00649         copy_a = getattr(dst_folder, 'a')
00650 
00651         # The copy should get a new UID
00652         a_uid = a.UID()
00653         ca_uid = copy_a.UID()
00654         self.failIf(a_uid == ca_uid, (a_uid, ca_uid))
00655 
00656         # The copy shouldn't have references
00657         self.failUnlessEqual(copy_a.getRefs(), [])
00658         self.failIf(copy_a in b.getBRefs())
00659 
00660 
00661         # Original object should keep references
00662         self.failUnlessEqual(a.getRefs(), [b])
00663         self.failUnlessEqual(b.getBRefs(), [a])
00664 
00665     def test_cutPasteSupport(self):
00666         # cut/paste behaviour test
00667         # in another folder, pasted object should keep the references
00668         # added by GL (for bug #985393)
00669         org_folder = makeContent(self.folder,
00670                                  portal_type=self.FOLDER_TYPE,
00671                                  title='Origin folder',
00672                                  id='org_folder')
00673         dst_folder = makeContent(self.folder,
00674                                  portal_type=self.FOLDER_TYPE,
00675                                  title='Destination folder',
00676                                  id='dst_folder')
00677         a = makeContent(org_folder, portal_type='DDocument', id='a')
00678         b = makeContent(org_folder, portal_type='DDocument', id='b')
00679         a.addReference(b)
00680         transaction.savepoint(optimistic=True)
00681         cb = org_folder.manage_cutObjects(ids=['a'])
00682         dst_folder.manage_pasteObjects(cb_copy_data=cb)
00683         copy_a = getattr(dst_folder, 'a')
00684 
00685         self.failUnlessEqual(copy_a.getRefs(), [b])
00686         self.failUnlessEqual(b.getBRefs(), [copy_a])
00687 
00688     def test_folderCopyPasteSupport(self):
00689         # copy/paste behaviour test
00690         # sub-objects of copy/pasted folders should lose all references,
00691         # and duplicate refs should not be created on the original object.
00692         org_folder = makeContent(self.folder,
00693                                  portal_type=self.FOLDER_TYPE,
00694                                  title='Origin folder',
00695                                  id='org_folder')
00696         dst_folder = makeContent(self.folder,
00697                                  portal_type=self.FOLDER_TYPE,
00698                                  title='Destination folder',
00699                                  id='dst_folder')
00700         my_folder = makeContent(org_folder, portal_type=self.FOLDER_TYPE,
00701                                                              id='my_folder')
00702         a = makeContent(my_folder, portal_type='DDocument', id='a')
00703         b = makeContent(my_folder, portal_type='DDocument', id='b')
00704         a.addReference(b)
00705 
00706         self.failUnlessEqual(b.getBRefs(), [a])
00707         self.failUnlessEqual(a.getRefs(), [b])
00708 
00709         cb = org_folder.manage_copyObjects(ids=['my_folder'])
00710         dst_folder.manage_pasteObjects(cb_copy_data=cb)
00711         copy_folder = getattr(dst_folder, 'my_folder')
00712         copy_a = getattr(copy_folder, 'a')
00713 
00714         # The copy should get a new UID
00715         a_uid = a.UID()
00716         ca_uid = copy_a.UID()
00717         self.failIf(a_uid == ca_uid, (a_uid, ca_uid))
00718 
00719         # The copy shouldn't have references
00720         self.failUnlessEqual(copy_a.getRefs(), [])
00721         self.failIf(copy_a in b.getBRefs())
00722 
00723         #The copy's uid should have changed
00724         self.failIf(ca_uid == a_uid)
00725 
00726         # Original object should keep references
00727         self.failUnlessEqual(a.getRefs(), [b])
00728         self.failUnlessEqual(b.getBRefs(), [a])
00729 
00730     def test_folderCutPasteSupport(self):
00731         # copy/paste behaviour test
00732         # sub-objects of copy/pasted folders should lose all references,
00733         # and duplicate refs should not be created on the original object.
00734         org_folder = makeContent(self.folder,
00735                                  portal_type=self.FOLDER_TYPE,
00736                                  title='Origin folder',
00737                                  id='org_folder')
00738         dst_folder = makeContent(self.folder,
00739                                  portal_type=self.FOLDER_TYPE,
00740                                  title='Destination folder',
00741                                  id='dst_folder')
00742         my_folder = makeContent(org_folder, portal_type=self.FOLDER_TYPE,
00743                                                              id='my_folder')
00744         a = makeContent(my_folder, portal_type='DDocument', id='a')
00745         b = makeContent(my_folder, portal_type='DDocument', id='b')
00746         a.addReference(b)
00747 
00748         self.failUnlessEqual(b.getBRefs(), [a])
00749         self.failUnlessEqual(a.getRefs(), [b])
00750         a_uid = a.UID()
00751 
00752         transaction.savepoint(optimistic=True)
00753         cb = org_folder.manage_cutObjects(ids=['my_folder'])
00754         dst_folder.manage_pasteObjects(cb_copy_data=cb)
00755         copy_folder = getattr(dst_folder, 'my_folder')
00756         copy_a = getattr(copy_folder, 'a')
00757         copy_b = getattr(copy_folder, 'b')
00758         ca_uid = copy_a.UID()
00759 
00760         # The copy shouldn't have references
00761         self.failUnlessEqual(copy_a.getRefs(), [copy_b])
00762         self.failUnlessEqual(copy_b.getBRefs(), [copy_a])
00763 
00764         #The copy's uid should have changed
00765         self.failUnless(ca_uid == a_uid, (a_uid, ca_uid))
00766 
00767 
00768 class SimpleFolderReferenceableTests(BaseReferenceableTests):
00769     FOLDER_TYPE = 'SimpleFolder'
00770 
00771 class SimpleBTreeFolderReferenceableTests(BaseReferenceableTests):
00772     FOLDER_TYPE = 'SimpleBTreeFolder'
00773 
00774 def test_suite():
00775     from unittest import TestSuite, makeSuite
00776     suite = TestSuite()
00777     suite.addTest(makeSuite(SimpleFolderReferenceableTests))
00778     suite.addTest(makeSuite(SimpleBTreeFolderReferenceableTests))
00779     return suite