diff --git a/CHANGES.rst b/CHANGES.rst index 0aeee92a23..c3b5a8a6bc 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -18,7 +18,7 @@ Changelog Bug fixes: -- Deprecate the portal_properties tool (#125) +- Deprecate the portal_properties tool, remove obsolete code (#125) - Require Python 3.8 or higher. [maurits] (#3635) - Actually load theme-specified styles CSS in TinyMCE. [Rudd-O] (#3638) - Minor visual fixes in admin UI [jensens] (#3640) diff --git a/Products/CMFPlone/tests/testNavigationView.py b/Products/CMFPlone/tests/testNavigationView.py index d7db6964c9..77500d052a 100644 --- a/Products/CMFPlone/tests/testNavigationView.py +++ b/Products/CMFPlone/tests/testNavigationView.py @@ -6,333 +6,16 @@ from Products.CMFPlone.browser.navigation import CatalogNavigationTabs from Products.CMFPlone.browser.navigation import CatalogSiteMap from Products.CMFPlone.browser.navigation import PhysicalNavigationBreadcrumbs -from Products.CMFPlone.tests import dummy from Products.CMFPlone.tests import PloneTestCase from Products.CMFPlone.tests.utils import folder_position from Products.CMFPlone.tests.utils import validateCSSIdentifier from zope.component import getUtility from zope.interface import directlyProvides -import random -import string - portal_name = PloneTestCase.portal_name -class TestBaseNavTree(PloneTestCase.PloneTestCase): - """Tests for the navigation tree . This base test is a little geared toward - a catalog based implementation for now. - """ - - view_class = None - - def afterSetUp(self): - self.request = self.app.REQUEST - self.populateSite() - self.setupAuthenticator() - registry = getUtility(IRegistry) - self.navigation_settings = registry.forInterface( - INavigationSchema, - prefix='plone' - ) - - def populateSite(self): - self.setRoles(['Manager']) - self.portal.invokeFactory('Document', 'doc1') - self.portal.invokeFactory('Document', 'doc2') - self.portal.invokeFactory('Document', 'doc3') - self.portal.invokeFactory('Folder', 'folder1') - self.portal.invokeFactory('Link', 'link1') - self.portal.link1.remoteUrl = 'http://plone.org' - self.portal.link1.reindexObject() - folder1 = getattr(self.portal, 'folder1') - folder1.invokeFactory('Document', 'doc11') - folder1.invokeFactory('Document', 'doc12') - folder1.invokeFactory('Document', 'doc13') - self.portal.invokeFactory('Folder', 'folder2') - folder2 = getattr(self.portal, 'folder2') - folder2.invokeFactory('Document', 'doc21') - folder2.invokeFactory('Document', 'doc22') - folder2.invokeFactory('Document', 'doc23') - folder2.invokeFactory('File', 'file21') - self.setRoles(['Member']) - - def testCreateNavTree(self): - # See if we can create one at all - view = self.view_class(self.portal, self.request) - tree = view.navigationTree() - self.assertTrue(tree) - self.assertTrue('children' in tree) - - def testCreateNavTreeCurrentItem(self): - # With the context set to folder2 it should return a dict with - # currentItem set to True - view = self.view_class(self.portal.folder2, self.request) - tree = view.navigationTree() - self.assertTrue(tree) - self.assertEqual(tree['children'][-1]['currentItem'], True) - - def testNavTreeExcludesItemsWithExcludeProperty(self): - # Make sure that items witht he exclude_from_nav property set get - # no_display set to True - self.portal.folder2.exclude_from_nav = True - self.portal.folder2.reindexObject() - view = self.view_class(self.portal.folder1.doc11, self.request) - tree = view.navigationTree() - self.assertTrue(tree) - for c in tree['children']: - if c['item'].getPath() == '/plone/folder2': - self.fail() - - def testShowAllParentsOverridesNavTreeExcludesItemsWithExcludeProp(self): - # Make sure excluded items are not included in the navtree - self.portal.folder2.exclude_from_nav = True - self.portal.folder2.reindexObject() - self.navigation_settings.show_excluded_items = True - - view = self.view_class(self.portal.folder2.doc21, self.request) - tree = view.navigationTree() - self.assertTrue(tree) - found = False - for c in tree['children']: - if c['item'].getPath() == '/plone/folder2': - found = True - break - self.assertTrue(found) - - def testNavTreeExcludesDefaultPage(self): - # Make sure that items which are the default page are excluded - self.portal.folder2.setDefaultPage('doc21') - view = self.view_class(self.portal.folder1.doc11, self.request) - tree = view.navigationTree() - self.assertTrue(tree) - # Ensure that our 'doc21' default page is not in the tree. - self.assertEqual( - [c for c in tree['children'][-1]['children'] - if c['item'].getPath()[-5:] == 'doc21'], - [] - ) - - def testCreateNavTreeWithLink(self): - # BBB getRemoteURL deprecated, remove in Plone 4 - view = self.view_class(self.portal, self.request) - tree = view.navigationTree() - for child in tree['children']: - if child['portal_type'] != 'Link': - self.assertFalse(child['item'].getRemoteUrl) - if child['Title'] == 'link1': - self.assertEqual( - child['item'].getRemoteUrl, - 'http://plone.org' - ) - - def testNonStructuralFolderHidesChildren(self): - # Make sure NonStructuralFolders act as if parent_types_not_to_query - # is set. - f = dummy.NonStructuralFolder('ns_folder') - self.folder._setObject('ns_folder', f) - self.portal.portal_catalog.reindexObject(self.folder.ns_folder) - self.portal.portal_catalog.reindexObject(self.folder) - self.navigation_settings.root = '/Members/test_user_1_' - view = self.view_class(self.folder.ns_folder, self.request) - tree = view.navigationTree() - self.assertEqual( - tree['children'][0]['item'].getPath(), - '/plone/Members/test_user_1_/ns_folder' - ) - self.assertEqual(len(tree['children'][0]['children']), 0) - - def testTopLevel(self): - ntp = self.portal.portal_properties.navtree_properties - ntp.manage_changeProperties(topLevel=1) - view = self.view_class(self.portal.folder2.file21, self.request) - tree = view.navigationTree() - self.assertTrue(tree) - self.assertEqual( - tree['children'][-1]['item'].getPath(), - '/plone/folder2/file21' - ) - - def testTopLevelWithContextAboveLevel(self): - ntp = self.portal.portal_properties.navtree_properties - ntp.manage_changeProperties(topLevel=1) - view = self.view_class(self.portal, self.request) - tree = view.navigationTree() - self.assertTrue(tree) - self.assertEqual(len(tree['children']), 0) - - def testTopLevelTooDeep(self): - ntp = self.portal.portal_properties.navtree_properties - ntp.manage_changeProperties(topLevel=5) - view = self.view_class(self.portal, self.request) - tree = view.navigationTree() - self.assertTrue(tree) - self.assertEqual(len(tree['children']), 0) - - def testTopLevelWithNavigationRoot(self): - self.portal.folder2.invokeFactory('Folder', 'folder21') - self.portal.folder2.folder21.invokeFactory('Document', 'doc211') - self.navigation_settings.root = '/folder2' - ntp = self.portal.portal_properties.navtree_properties - ntp.manage_changeProperties(topLevel=1) - view = self.view_class(self.portal.folder2.folder21, self.request) - tree = view.navigationTree() - self.assertTrue(tree) - self.assertEqual(len(tree['children']), 1) - self.assertEqual(tree['children'][0]['item'].getPath(), - '/plone/folder2/folder21/doc211') - - def testTopLevelWithPortalFactory(self): - cid = ''.join( - [random.choice(string.ascii_lowercase) for x in range(10)] - ) - typeName = 'Document' - newObject = self.portal.folder1.restrictedTraverse( - 'portal_factory/' + typeName + '/' + cid) - # Will raise a KeyError unless bug is fixed - view = self.view_class(newObject, self.request) - view.navigationTree() - - def testShowAllParentsOverridesBottomLevel(self): - ntp = self.portal.portal_properties.navtree_properties - ntp.manage_changeProperties(bottomLevel=1) - view = self.view_class(self.portal.folder2.file21, self.request) - tree = view.navigationTree() - self.assertTrue(tree) - # Note: showAllParents makes sure we actually return items on the, - # path to the context, but the portlet will not display anything - # below bottomLevel. - self.assertEqual(tree['children'][-1]['item'].getPath(), - '/plone/folder2') - self.assertEqual(len(tree['children'][-1]['children']), 1) - self.assertEqual(tree['children'][-1]['children'][0]['item'].getPath(), - '/plone/folder2/file21') - - def testBottomLevelStopsAtFolder(self): - ntp = self.portal.portal_properties.navtree_properties - ntp.manage_changeProperties(bottomLevel=1) - view = self.view_class(self.portal.folder2, self.request) - tree = view.navigationTree() - self.assertTrue(tree) - self.assertEqual(tree['children'][-1]['item'].getPath(), - '/plone/folder2') - self.assertEqual(len(tree['children'][-1]['children']), 0) - - def testNoRootSet(self): - self.navigation_settings.root = '' - view = self.view_class(self.portal.folder2.file21, self.request) - tree = view.navigationTree() - self.assertTrue(tree) - self.assertEqual(tree['children'][-1]['item'].getPath(), - '/plone/folder2') - - def testRootIsPortal(self): - self.navigation_settings.root = '/' - view = self.view_class(self.portal.folder2.file21, self.request) - tree = view.navigationTree() - self.assertTrue(tree) - self.assertEqual(tree['children'][-1]['item'].getPath(), - '/plone/folder2') - - def testRootIsNotPortal(self): - self.navigation_settings.root = '/folder2' - view = self.view_class(self.portal.folder2.file21, self.request) - tree = view.navigationTree() - self.assertTrue(tree) - self.assertEqual(tree['children'][0]['item'].getPath(), - '/plone/folder2/doc21') - - def testRootDoesNotExist(self): - self.navigation_settings.root = '/dodo' - view = self.view_class(self.portal.folder2.file21, self.request) - tree = view.navigationTree() - self.assertTrue(tree) - self.assertEqual(tree.get('item', None), None) - self.assertEqual(len(tree['children']), 0) - - def testAboveRoot(self): - self.navigation_settings.root = '/folder2' - view = self.view_class(self.portal, self.request) - tree = view.navigationTree() - self.assertTrue(tree) - self.assertEqual( - tree['children'][0]['item'].getPath(), - '/plone/folder2/doc21' - ) - - def testOutsideRoot(self): - self.navigation_settings.root = '/folder2' - view = self.view_class(self.portal.folder1, self.request) - tree = view.navigationTree() - self.assertTrue(tree) - self.assertEqual( - tree['children'][0]['item'].getPath(), - '/plone/folder2/doc21' - ) - - def testRootIsCurrent(self): - view = self.view_class(self.portal.folder2, - self.request, - currentFolderOnly=True) - tree = view.navigationTree() - self.assertTrue(tree) - self.assertEqual( - tree['children'][0]['item'].getPath(), - '/plone/folder2/doc21' - ) - - def testCustomQuery(self): - # Try a custom query script for the navtree that returns only published - # objects - self.portal._delObject('Members') - self.portal._delObject('news') - self.portal._delObject('events') - workflow = self.portal.portal_workflow - factory = self.portal.manage_addProduct['PythonScripts'] - factory.manage_addPythonScript('getCustomNavQuery') - script = self.portal.getCustomNavQuery - script.ZPythonScript_edit('', 'return {"review_state":"published"}') - self.assertEqual(self.portal.getCustomNavQuery(), - {"review_state": "published"}) - view = self.view_class(self.portal.folder2, self.request) - tree = view.navigationTree() - self.assertTrue(tree) - self.assertTrue('children' in tree) - # Should only contain current object - self.assertEqual(len(tree['children']), 1) - # change workflow for folder1 - workflow.doActionFor(self.portal.folder1, 'publish') - self.portal.folder1.reindexObject() - view = self.view_class(self.portal.folder2, self.request) - tree = view.navigationTree() - # Should only contain current object and published folder - self.assertEqual(len(tree['children']), 2) - - def testStateFiltering(self): - # Test Navtree workflow state filtering - self.portal._delObject('Members') - self.portal._delObject('news') - self.portal._delObject('events') - workflow = self.portal.portal_workflow - - self.navigation_settings.workflow_states_to_show = ('published',) - self.navigation_settings.filter_on_workflow = True - view = self.view_class(self.portal.folder2, self.request) - tree = view.navigationTree() - self.assertTrue(tree) - self.assertTrue('children' in tree) - # Should only contain current object - self.assertEqual(len(tree['children']), 1) - # change workflow for folder1 - workflow.doActionFor(self.portal.folder1, 'publish') - self.portal.folder1.reindexObject() - view = self.view_class(self.portal.folder2, self.request) - tree = view.navigationTree() - # Should only contain current object and published folder - self.assertEqual(len(tree['children']), 2) - - class TestSiteMap(PloneTestCase.PloneTestCase): """Tests for the sitemap view implementations. This base test is a little geared toward a catalog based implementation for now.