Back to index

plone3  3.1.7
testNavigationView.py
Go to the documentation of this file.
00001 #
00002 # Test methods used to make ...
00003 #
00004 
00005 from zope.publisher.browser import setDefaultSkin
00006 from zope.interface import directlyProvides
00007 
00008 from Products.CMFPlone.tests import PloneTestCase
00009 from Products.CMFPlone.tests import dummy
00010 
00011 from Products.CMFPlone.browser.navigation import CatalogNavigationTree
00012 from Products.CMFPlone.browser.navigation import CatalogSiteMap
00013 from Products.CMFPlone.browser.navigation import CatalogNavigationTabs
00014 from Products.CMFPlone.browser.navigation import CatalogNavigationBreadcrumbs
00015 from Products.CMFPlone.browser.navigation import PhysicalNavigationBreadcrumbs
00016 from Products.CMFPlone.interfaces import IHideFromBreadcrumbs
00017 
00018 portal_name = PloneTestCase.portal_name
00019 
00020 
00021 class TestBaseNavTree(PloneTestCase.PloneTestCase):
00022     """Tests for the navigation tree . This base test is a little geared toward 
00023        a catalog based implementation for now.
00024     """
00025 
00026     view_class = None
00027 
00028     def afterSetUp(self):
00029         self.request = self.app.REQUEST
00030         # Apply a default layer for view lookups to work in Zope 2.9+
00031         setDefaultSkin(self.request)
00032         self.populateSite()
00033         self.setupAuthenticator()
00034         
00035     def populateSite(self):
00036         self.setRoles(['Manager'])
00037         self.portal.invokeFactory('Document', 'doc1')
00038         self.portal.invokeFactory('Document', 'doc2')
00039         self.portal.invokeFactory('Document', 'doc3')
00040         self.portal.invokeFactory('Folder', 'folder1')
00041         self.portal.invokeFactory('Link', 'link1')
00042         self.portal.link1.setRemoteUrl('http://plone.org')
00043         self.portal.link1.reindexObject()
00044         folder1 = getattr(self.portal, 'folder1')
00045         folder1.invokeFactory('Document', 'doc11')
00046         folder1.invokeFactory('Document', 'doc12')
00047         folder1.invokeFactory('Document', 'doc13')
00048         self.portal.invokeFactory('Folder', 'folder2')
00049         folder2 = getattr(self.portal, 'folder2')
00050         folder2.invokeFactory('Document', 'doc21')
00051         folder2.invokeFactory('Document', 'doc22')
00052         folder2.invokeFactory('Document', 'doc23')
00053         folder2.invokeFactory('File', 'file21')
00054         self.setRoles(['Member'])
00055 
00056     def testCreateNavTree(self):
00057         # See if we can create one at all
00058         view = self.view_class(self.portal, self.request)
00059         tree = view.navigationTree()
00060         self.failUnless(tree)
00061         self.failUnless(tree.has_key('children'))
00062 
00063     def testCreateNavTreeCurrentItem(self):
00064         # With the context set to folder2 it should return a dict with
00065         # currentItem set to True
00066         view = self.view_class(self.portal.folder2, self.request)
00067         tree = view.navigationTree()
00068         self.failUnless(tree)
00069         self.assertEqual(tree['children'][-1]['currentItem'], True)
00070 
00071     def testNavTreeExcludesItemsWithExcludeProperty(self):
00072         # Make sure that items witht he exclude_from_nav property set get
00073         # no_display set to True
00074         self.portal.folder2.setExcludeFromNav(True)
00075         self.portal.folder2.reindexObject()
00076         view = self.view_class(self.portal.folder1.doc11, self.request)
00077         tree = view.navigationTree()
00078         self.failUnless(tree)
00079         for c in tree['children']:
00080             if c['item'].getPath() == '/plone/folder2':
00081                 self.fail()
00082 
00083     def testShowAllParentsOverridesNavTreeExcludesItemsWithExcludeProperty(self):
00084         # Make sure that items whose ids are in the idsNotToList navTree
00085         # property are not included
00086         self.portal.folder2.setExcludeFromNav(True)
00087         self.portal.folder2.reindexObject()
00088         ntp=self.portal.portal_properties.navtree_properties
00089         ntp.manage_changeProperties(showAllParents=True)
00090         view = self.view_class(self.portal.folder2.doc21, self.request)
00091         tree = view.navigationTree()
00092         self.failUnless(tree)
00093         found = False
00094         for c in tree['children']:
00095             if c['item'].getPath() == '/plone/folder2':
00096                 found = True
00097                 break
00098         self.failUnless(found)
00099 
00100     def testNavTreeExcludesItemsInIdsNotToList(self):
00101         # Make sure that items whose ids are in the idsNotToList navTree
00102         # property are not included
00103         ntp=self.portal.portal_properties.navtree_properties
00104         ntp.manage_changeProperties(idsNotToList=['folder2'])
00105         view = self.view_class(self.portal.folder1.doc11, self.request)
00106         tree = view.navigationTree()
00107         self.failUnless(tree)
00108         for c in tree['children']:
00109             if c['item'].getPath() == '/plone/folder2':
00110                 self.fail()
00111 
00112     def testShowAllParentsOverridesNavTreeExcludesItemsInIdsNotToList(self):
00113         # Make sure that items whose ids are in the idsNotToList navTree
00114         # property are not included
00115         ntp=self.portal.portal_properties.navtree_properties
00116         ntp.manage_changeProperties(idsNotToList=['folder2'], showAllParents=True)
00117         view = self.view_class(self.portal.folder2.doc21, self.request)
00118         tree = view.navigationTree()
00119         self.failUnless(tree)
00120         found = False
00121         for c in tree['children']:
00122             if c['item'].getPath() == '/plone/folder2':
00123                 found = True
00124                 break
00125         self.failUnless(found)
00126 
00127     def testNavTreeExcludesDefaultPage(self):
00128         # Make sure that items which are the default page are excluded
00129         self.portal.folder2.setDefaultPage('doc21')
00130         view = self.view_class(self.portal.folder1.doc11, self.request)
00131         tree = view.navigationTree()
00132         self.failUnless(tree)
00133         # Ensure that our 'doc21' default page is not in the tree.
00134         self.assertEqual([c for c in tree['children'][-1]['children']
00135                                             if c['item'].getPath()[-5:]=='doc21'],[])
00136 
00137     def testNavTreeMarksParentMetaTypesNotToQuery(self):
00138         # Make sure that items whose ids are in the idsNotToList navTree
00139         # property get no_display set to True
00140         view = self.view_class(self.portal.folder2.file21, self.request)
00141         tree = view.navigationTree()
00142         self.assertEqual(tree['children'][-1]['show_children'],True)
00143         ntp=self.portal.portal_properties.navtree_properties
00144         ntp.manage_changeProperties(parentMetaTypesNotToQuery=['Folder'])
00145         view = self.view_class(self.portal.folder2.file21, self.request)
00146         tree = view.navigationTree()
00147         self.assertEqual(tree['children'][-1]['show_children'],False)
00148 
00149     def testCreateNavTreeWithLink(self):
00150         view = self.view_class(self.portal, self.request)
00151         tree = view.navigationTree()
00152         for child in tree['children']:
00153             if child['portal_type'] != 'Link':
00154                 self.failIf(child['item'].getRemoteUrl)
00155             if child['Title'] == 'link1':
00156                 self.failUnlessEqual(child['item'].getRemoteUrl, 'http://plone.org')
00157 
00158     def testNonStructuralFolderHidesChildren(self):
00159         # Make sure NonStructuralFolders act as if parentMetaTypesNotToQuery
00160         # is set.
00161         f = dummy.NonStructuralFolder('ns_folder')
00162         self.folder._setObject('ns_folder', f)
00163         self.portal.portal_catalog.reindexObject(self.folder.ns_folder)
00164         self.portal.portal_catalog.reindexObject(self.folder)
00165         view = self.view_class(self.folder.ns_folder, self.request)
00166         tree = view.navigationTree()
00167         self.assertEqual(tree['children'][0]['children'][0]['children'][0]['item'].getPath(),
00168                                 '/plone/Members/test_user_1_/ns_folder')
00169         self.assertEqual(len(tree['children'][0]['children'][0]['children'][0]['children']), 0)
00170 
00171     def testTopLevel(self):
00172         ntp=self.portal.portal_properties.navtree_properties
00173         ntp.manage_changeProperties(topLevel=1)
00174         view = self.view_class(self.portal.folder2.file21, self.request)
00175         tree = view.navigationTree()
00176         self.failUnless(tree)
00177         self.assertEqual(tree['children'][-1]['item'].getPath(), '/plone/folder2/file21')
00178 
00179     def testTopLevelWithContextAboveLevel(self):
00180         ntp=self.portal.portal_properties.navtree_properties
00181         ntp.manage_changeProperties(topLevel=1)
00182         view = self.view_class(self.portal, self.request)
00183         tree = view.navigationTree()
00184         self.failUnless(tree)
00185         self.assertEqual(len(tree['children']), 0)
00186 
00187     def testTopLevelTooDeep(self):
00188         ntp=self.portal.portal_properties.navtree_properties
00189         ntp.manage_changeProperties(topLevel=5)
00190         view = self.view_class(self.portal, self.request)
00191         tree = view.navigationTree()
00192         self.failUnless(tree)
00193         self.assertEqual(len(tree['children']), 0)
00194 
00195     def testTopLevelWithNavigationRoot(self):
00196         self.portal.folder2.invokeFactory('Folder', 'folder21')
00197         self.portal.folder2.folder21.invokeFactory('Document', 'doc211')
00198         ntp=self.portal.portal_properties.navtree_properties
00199         ntp.manage_changeProperties(topLevel=1, root='/folder2')
00200         view = self.view_class(self.portal.folder2.folder21, self.request)
00201         tree = view.navigationTree()
00202         self.failUnless(tree)
00203         self.assertEqual(len(tree['children']), 1)
00204         self.assertEqual(tree['children'][0]['item'].getPath(), '/plone/folder2/folder21/doc211')
00205 
00206     def testTopLevelWithPortalFactory(self):
00207         ntp=self.portal.portal_properties.navtree_properties
00208         ntp.manage_changeProperties(topLevel=1)
00209         id=self.portal.generateUniqueId('Document')
00210         typeName='Document'
00211         newObject=self.portal.folder1.restrictedTraverse('portal_factory/' + typeName + '/' + id)
00212         # Will raise a KeyError unless bug is fixed
00213         view = self.view_class(newObject, self.request)
00214         tree = view.navigationTree()
00215     
00216     def testShowAllParentsOverridesBottomLevel(self):
00217         ntp=self.portal.portal_properties.navtree_properties
00218         ntp.manage_changeProperties(bottomLevel=1)
00219         view = self.view_class(self.portal.folder2.file21, self.request)
00220         tree = view.navigationTree()
00221         self.failUnless(tree)
00222         # Note: showAllParents makes sure we actually return items on the,
00223         # path to the context, but the portlet will not display anything
00224         # below bottomLevel. 
00225         self.assertEqual(tree['children'][-1]['item'].getPath(), '/plone/folder2')
00226         self.assertEqual(len(tree['children'][-1]['children']), 1)
00227         self.assertEqual(tree['children'][-1]['children'][0]['item'].getPath(), '/plone/folder2/file21')
00228         
00229     def testBottomLevelStopsAtFolder(self):
00230         ntp=self.portal.portal_properties.navtree_properties
00231         ntp.manage_changeProperties(bottomLevel=1)
00232         view = self.view_class(self.portal.folder2, self.request)
00233         tree = view.navigationTree()
00234         self.failUnless(tree)
00235         self.assertEqual(tree['children'][-1]['item'].getPath(), '/plone/folder2')
00236         self.assertEqual(len(tree['children'][-1]['children']), 0)
00237         
00238     def testNoRootSet(self):
00239         ntp=self.portal.portal_properties.navtree_properties
00240         ntp.manage_changeProperties(root='')
00241         view = self.view_class(self.portal.folder2.file21, self.request)
00242         tree = view.navigationTree()
00243         self.failUnless(tree)
00244         self.assertEqual(tree['children'][-1]['item'].getPath(), '/plone/folder2')
00245         
00246     def testRootIsPortal(self):
00247         ntp=self.portal.portal_properties.navtree_properties
00248         ntp.manage_changeProperties(root='/')
00249         view = self.view_class(self.portal.folder2.file21, self.request)
00250         tree = view.navigationTree()
00251         self.failUnless(tree)
00252         self.assertEqual(tree['children'][-1]['item'].getPath(), '/plone/folder2')
00253         
00254     def testRootIsNotPortal(self):
00255         ntp=self.portal.portal_properties.navtree_properties
00256         ntp.manage_changeProperties(root='/folder2')
00257         view = self.view_class(self.portal.folder2.file21, self.request)
00258         tree = view.navigationTree()
00259         self.failUnless(tree)
00260         self.assertEqual(tree['children'][0]['item'].getPath(), '/plone/folder2/doc21')
00261 
00262     def testRootDoesNotExist(self):
00263         ntp=self.portal.portal_properties.navtree_properties
00264         ntp.manage_changeProperties(root='/dodo')
00265         view = self.view_class(self.portal.folder2.file21, self.request)
00266         tree = view.navigationTree()
00267         self.failUnless(tree)
00268         self.assertEqual(tree.get('item', None), None)
00269         self.assertEqual(len(tree['children']), 0)
00270 
00271     def testAboveRoot(self):
00272         ntp=self.portal.portal_properties.navtree_properties
00273         ntp.manage_changeProperties(root='/folder2')
00274         view = self.view_class(self.portal, self.request)
00275         tree = view.navigationTree()
00276         self.failUnless(tree)
00277         self.assertEqual(tree['children'][0]['item'].getPath(), '/plone/folder2/doc21')
00278 
00279     def testOutsideRoot(self):
00280         ntp=self.portal.portal_properties.navtree_properties
00281         ntp.manage_changeProperties(root='/folder2')
00282         view = self.view_class(self.portal.folder1, self.request)
00283         tree = view.navigationTree()
00284         self.failUnless(tree)
00285         self.assertEqual(tree['children'][0]['item'].getPath(), '/plone/folder2/doc21')
00286 
00287     def testRootIsCurrent(self):
00288         ntp=self.portal.portal_properties.navtree_properties
00289         ntp.manage_changeProperties(currentFolderOnlyInNavtree=True)
00290         view = self.view_class(self.portal.folder2, self.request)
00291         tree = view.navigationTree()
00292         self.failUnless(tree)
00293         self.assertEqual(tree['children'][0]['item'].getPath(), '/plone/folder2/doc21')
00294 
00295     def testCustomQuery(self):
00296         # Try a custom query script for the navtree that returns only published
00297         # objects
00298         self.portal._delObject('Members')
00299         self.portal._delObject('news')
00300         self.portal._delObject('events')
00301         workflow = self.portal.portal_workflow
00302         factory = self.portal.manage_addProduct['PythonScripts']
00303         factory.manage_addPythonScript('getCustomNavQuery')
00304         script = self.portal.getCustomNavQuery
00305         script.ZPythonScript_edit('','return {"review_state":"published"}')
00306         self.assertEqual(self.portal.getCustomNavQuery(),{"review_state":"published"})
00307         view = self.view_class(self.portal.folder2, self.request)
00308         tree = view.navigationTree()
00309         self.failUnless(tree)
00310         self.failUnless(tree.has_key('children'))
00311         #Should only contain current object
00312         self.assertEqual(len(tree['children']), 1)
00313         #change workflow for folder1
00314         workflow.doActionFor(self.portal.folder1, 'publish')
00315         self.portal.folder1.reindexObject()
00316         view = self.view_class(self.portal.folder2, self.request)
00317         tree = view.navigationTree()
00318         #Should only contain current object and published folder
00319         self.assertEqual(len(tree['children']), 2)
00320 
00321     def testStateFiltering(self):
00322         # Test Navtree workflow state filtering
00323         self.portal._delObject('Members')
00324         self.portal._delObject('news')
00325         self.portal._delObject('events')
00326         workflow = self.portal.portal_workflow
00327         ntp=self.portal.portal_properties.navtree_properties
00328         ntp.manage_changeProperties(wf_states_to_show=['published'])
00329         ntp.manage_changeProperties(enable_wf_state_filtering=True)
00330         view = self.view_class(self.portal.folder2, self.request)
00331         tree = view.navigationTree()
00332         self.failUnless(tree)
00333         self.failUnless(tree.has_key('children'))
00334         #Should only contain current object
00335         self.assertEqual(len(tree['children']), 1)
00336         #change workflow for folder1
00337         workflow.doActionFor(self.portal.folder1, 'publish')
00338         self.portal.folder1.reindexObject()
00339         view = self.view_class(self.portal.folder2, self.request)
00340         tree = view.navigationTree()
00341         #Should only contain current object and published folder
00342         self.assertEqual(len(tree['children']), 2)
00343 
00344     
00345 
00346 class TestCatalogNavTree(TestBaseNavTree):
00347         view_class = CatalogNavigationTree
00348 
00349 class TestBaseSiteMap(PloneTestCase.PloneTestCase):
00350     """Tests for the sitemap view implementations. This base test is a little 
00351         geared toward a catalog based implementation for now.
00352     """
00353 
00354     view_class = None
00355 
00356     def afterSetUp(self):
00357         self.request = self.app.REQUEST
00358         # Apply a default layer for view lookups to work in Zope 2.9+
00359         setDefaultSkin(self.request)
00360         self.populateSite()
00361         
00362     def populateSite(self):
00363         self.setRoles(['Manager'])
00364         self.portal.invokeFactory('Document', 'doc1')
00365         self.portal.invokeFactory('Document', 'doc2')
00366         self.portal.invokeFactory('Document', 'doc3')
00367         self.portal.invokeFactory('Folder', 'folder1')
00368         self.portal.invokeFactory('Link', 'link1')
00369         self.portal.link1.setRemoteUrl('http://plone.org')
00370         self.portal.link1.reindexObject()
00371         folder1 = getattr(self.portal, 'folder1')
00372         folder1.invokeFactory('Document', 'doc11')
00373         folder1.invokeFactory('Document', 'doc12')
00374         folder1.invokeFactory('Document', 'doc13')
00375         self.portal.invokeFactory('Folder', 'folder2')
00376         folder2 = getattr(self.portal, 'folder2')
00377         folder2.invokeFactory('Document', 'doc21')
00378         folder2.invokeFactory('Document', 'doc22')
00379         folder2.invokeFactory('Document', 'doc23')
00380         folder2.invokeFactory('File', 'file21')
00381         self.setRoles(['Member'])
00382 
00383     def testCreateSitemap(self):
00384         view = self.view_class(self.portal, self.request)
00385         tree = view.siteMap()
00386         self.failUnless(tree)
00387 
00388     def testComplexSitemap(self):
00389         # create and test a reasonabley complex sitemap
00390         path = lambda x: '/'.join(x.getPhysicalPath())
00391         # We do this in a strange order in order to maximally demonstrate the bug
00392         folder1 = self.portal.folder1
00393         folder1.invokeFactory('Folder','subfolder1')
00394         subfolder1 = folder1.subfolder1
00395         folder1.invokeFactory('Folder','subfolder2')
00396         subfolder2 = folder1.subfolder2
00397         subfolder1.invokeFactory('Folder','subfolder11')
00398         subfolder11 = subfolder1.subfolder11
00399         subfolder1.invokeFactory('Folder','subfolder12')
00400         subfolder12 = subfolder1.subfolder12
00401         subfolder2.invokeFactory('Folder','subfolder21')
00402         subfolder21 = subfolder2.subfolder21
00403         folder1.invokeFactory('Folder','subfolder3')
00404         subfolder3 = folder1.subfolder3
00405         subfolder2.invokeFactory('Folder','subfolder22')
00406         subfolder22 = subfolder2.subfolder22
00407         subfolder22.invokeFactory('Folder','subfolder221')
00408         subfolder221 = subfolder22.subfolder221
00409 
00410         # Increase depth
00411         ntp=self.portal.portal_properties.navtree_properties
00412         ntp.manage_changeProperties(sitemapDepth=5)
00413 
00414         view = self.view_class(self.portal, self.request)
00415         sitemap = view.siteMap()
00416 
00417         folder1map = sitemap['children'][6]
00418         self.assertEqual(len(folder1map['children']), 6)
00419         self.assertEqual(folder1map['item'].getPath(), path(folder1))
00420 
00421         subfolder1map = folder1map['children'][3]
00422         self.assertEqual(subfolder1map['item'].getPath(), path(subfolder1))
00423         self.assertEqual(len(subfolder1map['children']), 2)
00424 
00425         subfolder2map = folder1map['children'][4]
00426         self.assertEqual(subfolder2map['item'].getPath(), path(subfolder2))
00427         self.assertEqual(len(subfolder2map['children']), 2)
00428 
00429         subfolder3map = folder1map['children'][5]
00430         self.assertEqual(subfolder3map['item'].getPath(), path(subfolder3))
00431         self.assertEqual(len(subfolder3map['children']), 0)
00432 
00433         subfolder11map = subfolder1map['children'][0]
00434         self.assertEqual(subfolder11map['item'].getPath(), path(subfolder11))
00435         self.assertEqual(len(subfolder11map['children']), 0)
00436 
00437         subfolder21map = subfolder2map['children'][0]
00438         self.assertEqual(subfolder21map['item'].getPath(), path(subfolder21))
00439         self.assertEqual(len(subfolder21map['children']), 0)
00440 
00441         subfolder22map = subfolder2map['children'][1]
00442         self.assertEqual(subfolder22map['item'].getPath(), path(subfolder22))
00443         self.assertEqual(len(subfolder22map['children']), 1)
00444 
00445         # Why isn't this showing up in the sitemap
00446         subfolder221map = subfolder22map['children'][0]
00447         self.assertEqual(subfolder221map['item'].getPath(), path(subfolder221))
00448         self.assertEqual(len(subfolder221map['children']), 0)
00449 
00450     def testSitemapWithTopLevel(self):
00451         ntp = self.portal.portal_properties.navtree_properties
00452         ntp.manage_changeProperties(topLevel=1)
00453         view = self.view_class(self.portal, self.request)
00454         sitemap = view.siteMap()
00455         self.assertEqual(sitemap['children'][-1]['item'].getPath(), '/plone/folder2')
00456         
00457     def testSitemapWithBottomLevel(self):
00458         ntp = self.portal.portal_properties.navtree_properties
00459         ntp.manage_changeProperties(bottomLevel=1)
00460         view = self.view_class(self.portal, self.request)
00461         sitemap = view.siteMap()
00462         self.assertEqual(sitemap['children'][-1]['item'].getPath(), '/plone/folder2')
00463         self.failUnless(len(sitemap['children'][-1]['children']) > 0)
00464         
00465     def testSitemapWithNavigationRoot(self):
00466         ntp = self.portal.portal_properties.navtree_properties
00467         ntp.manage_changeProperties(root = '/folder2')
00468         view = self.view_class(self.portal, self.request)
00469         sitemap = view.siteMap()
00470         self.assertEqual(sitemap['children'][-1]['item'].getPath(), '/plone/folder2/file21')
00471 
00472 class TestSiteMap(TestBaseSiteMap):
00473         view_class = CatalogSiteMap
00474 
00475 class TestBasePortalTabs(PloneTestCase.PloneTestCase):
00476     """Tests for the portal tabs view implementations
00477        This base test is a little geared toward a catalog based implementation
00478        for now.
00479     """
00480 
00481     view_class = None
00482 
00483     def afterSetUp(self):
00484         self.request = self.app.REQUEST
00485         setDefaultSkin(self.request)
00486         self.populateSite()
00487 
00488     def populateSite(self):
00489         self.setRoles(['Manager'])
00490         self.portal.invokeFactory('Document', 'doc1')
00491         self.portal.invokeFactory('Document', 'doc2')
00492         self.portal.invokeFactory('Document', 'doc3')
00493         self.portal.invokeFactory('Folder', 'folder1')
00494         self.portal.invokeFactory('Folder', 'folder2')
00495         self.setRoles(['Member'])
00496 
00497     def testCreateTopLevelTabs(self):
00498         # See if we can create one at all
00499         view = self.view_class(self.portal, self.request)
00500         
00501         #Everything shows up by default
00502         tabs = view.topLevelTabs()
00503         self.failUnless(tabs)
00504         self.assertEqual(len(tabs), 8)
00505         
00506         #Only the folders show up (Members, news, events, folder1, folder2)
00507         self.portal.portal_properties.site_properties.disable_nonfolderish_sections = True
00508         tabs = view.topLevelTabs()
00509         self.assertEqual(len(tabs), 5)
00510 
00511     def testTabsRespectFolderOrder(self):
00512         # See if reordering causes a change in the tab order
00513         view = self.view_class(self.portal, self.request)
00514         tabs1 = view.topLevelTabs()
00515         # Must be manager to change order on portal itself
00516         self.setRoles(['Manager','Member'])
00517         self.portal.folder_position('up', 'folder2')
00518         view = self.view_class(self.portal, self.request)
00519         tabs2 = view.topLevelTabs()
00520         #Same number of objects
00521         self.failUnlessEqual(len(tabs1), len(tabs2))
00522         #Different order
00523         self.failUnless(tabs1 != tabs2)
00524 
00525     def testCustomQuery(self):
00526         # Try a custom query script for the tabs that returns only published
00527         # objects
00528         self.portal._delObject('Members')
00529         self.portal._delObject('news')
00530         self.portal._delObject('events')
00531         workflow = self.portal.portal_workflow
00532         factory = self.portal.manage_addProduct['PythonScripts']
00533         factory.manage_addPythonScript('getCustomNavQuery')
00534         script = self.portal.getCustomNavQuery
00535         script.ZPythonScript_edit('', 'return {"review_state":"published"}')
00536         self.assertEqual(
00537             self.portal.getCustomNavQuery(), {"review_state":"published"})
00538         view = self.view_class(self.portal, self.request)
00539         tabs = view.topLevelTabs()
00540         #Should contain no folders
00541         self.assertEqual(len(tabs), 0)
00542         #change workflow for folder1
00543         workflow.doActionFor(self.portal.folder1, 'publish')
00544         self.portal.folder1.reindexObject()
00545         view = self.view_class(self.portal, self.request)
00546         tabs = view.topLevelTabs()
00547         #Should only contain the published folder
00548         self.assertEqual(len(tabs), 1)
00549 
00550     def testStateFiltering(self):
00551         # Test tabs workflow state filtering
00552         self.portal._delObject('Members')
00553         self.portal._delObject('news')
00554         self.portal._delObject('events')
00555         workflow = self.portal.portal_workflow
00556         ntp=self.portal.portal_properties.navtree_properties
00557         ntp.manage_changeProperties(wf_states_to_show=['published'])
00558         ntp.manage_changeProperties(enable_wf_state_filtering=True)
00559         view = self.view_class(self.portal, self.request)
00560         tabs = view.topLevelTabs()
00561         #Should contain no folders
00562         self.assertEqual(len(tabs), 0)
00563         #change workflow for folder1
00564         workflow.doActionFor(self.portal.folder1, 'publish')
00565         self.portal.folder1.reindexObject()
00566         view = self.view_class(self.portal, self.request)
00567         tabs = view.topLevelTabs()
00568         #Should only contain the published folder
00569         self.assertEqual(len(tabs), 1)
00570 
00571     def testDisableFolderTabs(self):
00572         # Setting the site_property disable_folder_sections should remove
00573         # all folder based tabs
00574         props = self.portal.portal_properties.site_properties
00575         props.manage_changeProperties(disable_folder_sections=True)
00576         view = self.view_class(self.portal, self.request)
00577         tabs = view.topLevelTabs()
00578         self.assertEqual(tabs, [])
00579 
00580     def testTabsExcludeItemsWithExcludeProperty(self):
00581         # Make sure that items witht he exclude_from_nav property are purged
00582         view = self.view_class(self.portal, self.request)
00583         tabs = view.topLevelTabs()
00584         orig_len = len(tabs)
00585         self.portal.folder2.setExcludeFromNav(True)
00586         self.portal.folder2.reindexObject()
00587         view = self.view_class(self.portal, self.request)
00588         tabs = view.topLevelTabs()
00589         self.failUnless(tabs)
00590         self.assertEqual(len(tabs), orig_len - 1)
00591         tab_names = [t['id'] for t in tabs]
00592         self.failIf('folder2' in tab_names)
00593 
00594     def testTabsRespectsTypesWithViewAction(self):
00595         # With a type in typesUseViewActionInListings as current action it
00596         # should return a tab which has '/view' appended to the url
00597         view = self.view_class(self.portal, self.request)
00598         tabs = view.topLevelTabs()
00599         self.failUnless(tabs)
00600         # Fail if 'view' is used for folder
00601         self.failIf(tabs[-1]['url'][-5:]=='/view')
00602         # Add Folder to site_property
00603         props = self.portal.portal_properties.site_properties
00604         props.manage_changeProperties(
00605             typesUseViewActionInListings=['Image','File','Folder'])
00606         # Verify that we have '/view'
00607         view = self.view_class(self.portal, self.request)
00608         tabs = view.topLevelTabs()
00609         self.failUnless(tabs)
00610         self.assertEqual(tabs[-1]['url'][-5:],'/view')
00611 
00612     def testTabsExcludeItemsInIdsNotToList(self):
00613         # Make sure that items whose ids are in the idsNotToList navTree
00614         # property get purged
00615         view = self.view_class(self.portal, self.request)
00616         tabs = view.topLevelTabs()
00617         orig_len = len(tabs)
00618         ntp=self.portal.portal_properties.navtree_properties
00619         ntp.manage_changeProperties(idsNotToList=['folder2'])
00620         view = self.view_class(self.portal, self.request)
00621         tabs = view.topLevelTabs()
00622         self.failUnless(tabs)
00623         self.assertEqual(len(tabs), orig_len - 1)
00624         tab_names = [t['id'] for t in tabs]
00625         self.failIf('folder2' in tab_names)
00626 
00627     def testTabsExcludeNonFolderishItems(self):
00628         self.portal.portal_properties.site_properties.disable_nonfolderish_sections = True
00629         view = self.view_class(self.portal, self.request)
00630         tabs = view.topLevelTabs()
00631         orig_len = len(tabs)
00632         self.setRoles(['Manager','Member'])
00633         self.portal.invokeFactory('Document','foo')
00634         
00635         view = self.view_class(self.portal, self.request)
00636         tabs = view.topLevelTabs()
00637         self.failUnless(tabs)
00638         self.assertEqual(len(tabs),orig_len)
00639 
00640     def testRootBelowPortalRoot(self):
00641         
00642         self.setRoles(['Manager'])
00643         self.portal.folder1.invokeFactory('Document', 'doc1')
00644         self.portal.folder1.invokeFactory('Document', 'doc2')
00645         self.portal.folder1.invokeFactory('Document', 'doc3')
00646         self.portal.folder1.invokeFactory('Folder', 'folder1')
00647         self.portal.folder1.invokeFactory('Folder', 'folder2')
00648         self.setRoles(['Member'])
00649         
00650         rootPath = '/'.join(self.portal.getPhysicalPath()) + '/folder1'
00651         self.portal.portal_properties.navtree_properties.root = '/folder1'
00652         self.portal.portal_properties.site_properties.disable_nonfolderish_sections = True
00653         
00654         view = self.view_class(self.portal, self.request)
00655         tabs = view.topLevelTabs()
00656         self.failUnless(tabs)
00657         self.assertEqual(len(tabs), 2)
00658         self.assertEqual(tabs[0]['id'], 'folder1')
00659         self.assertEqual(tabs[1]['id'], 'folder2')
00660         
00661 
00662 class TestCatalogPortalTabs(TestBasePortalTabs):
00663         view_class = CatalogNavigationTabs
00664 
00665 
00666 class TestBaseBreadCrumbs(PloneTestCase.PloneTestCase):
00667     """Tests for the portal tabs query
00668     """
00669 
00670     view_class = None
00671 
00672     def afterSetUp(self):
00673         self.request = self.app.REQUEST
00674         setDefaultSkin(self.request)
00675         self.populateSite()
00676 
00677     def populateSite(self):
00678         self.setRoles(['Manager'])
00679         self.portal.invokeFactory('Folder', 'folder1')
00680         folder1 = getattr(self.portal, 'folder1')
00681         folder1.invokeFactory('Document', 'doc11')
00682         folder1.invokeFactory('File', 'file11')
00683         self.setRoles(['Member'])
00684 
00685     def testCreateBreadCrumbs(self):
00686         # See if we can create one at all
00687         doc = self.portal.folder1.doc11
00688         view = self.view_class(doc, self.request)
00689         crumbs = view.breadcrumbs()
00690         self.failUnless(crumbs)
00691         self.assertEqual(len(crumbs), 2)
00692         self.assertEqual(crumbs[-1]['absolute_url'], doc.absolute_url())
00693         self.assertEqual(crumbs[-2]['absolute_url'], doc.aq_parent.absolute_url())
00694 
00695     def testBreadcrumbsRespectTypesWithViewAction(self):
00696         # With a type in typesUseViewActionInListings as current action it
00697         # should return a breadcrumb which has '/view' appended to the url
00698         file = self.portal.folder1.file11
00699         view = self.view_class(self.portal.folder1.file11, self.request)
00700         crumbs = view.breadcrumbs()
00701         self.failUnless(crumbs)
00702         self.assertEqual(crumbs[-1]['absolute_url'][-5:],'/view')
00703         
00704     def testBreadcrumbsStopAtNavigationRoot(self):
00705         ntp=self.portal.portal_properties.navtree_properties
00706         ntp.manage_changeProperties(topLevel=1, root='/folder1')
00707         view = self.view_class(self.portal.folder1.doc11, self.request)
00708         crumbs = view.breadcrumbs()
00709         self.failUnless(crumbs)
00710         self.assertEqual(crumbs[0]['absolute_url'], self.portal.folder1.doc11.absolute_url())
00711 
00712 
00713 class TestCatalogBreadCrumbs(TestBaseBreadCrumbs):
00714     view_class = CatalogNavigationBreadcrumbs
00715 
00716 
00717 class TestPhysicalBreadCrumbs(TestBaseBreadCrumbs):
00718     view_class = PhysicalNavigationBreadcrumbs
00719 
00720     def testBreadcrumbsFilterByInterface(self):
00721         view = self.view_class(self.portal.folder1.doc11, self.request)
00722         crumbs = view.breadcrumbs()
00723         directlyProvides(self.portal.folder1, IHideFromBreadcrumbs)
00724         newcrumbs = view.breadcrumbs()
00725         self.assertEqual(len(crumbs)-1, len(newcrumbs))
00726         self.assertEqual(newcrumbs[0]['absolute_url'], self.portal.folder1.doc11.absolute_url())
00727 
00728 
00729 def test_suite():
00730     from unittest import TestSuite, makeSuite
00731     suite = TestSuite()
00732     suite.addTest(makeSuite(TestCatalogPortalTabs))
00733     suite.addTest(makeSuite(TestCatalogNavTree))
00734     suite.addTest(makeSuite(TestSiteMap))
00735     suite.addTest(makeSuite(TestCatalogBreadCrumbs))
00736     suite.addTest(makeSuite(TestPhysicalBreadCrumbs))
00737     return suite