[Checkins] SVN: Products.CMFDefault/branches/charlie_formlib_for_folders/Products/CMFDefault/browser/ Added tests for batching and renamed some methods.

Charlie Clark charlie at begeistert.org
Sun Jun 7 11:00:00 EDT 2009


Log message for revision 100684:
  Added tests for batching and renamed some methods.

Changed:
  U   Products.CMFDefault/branches/charlie_formlib_for_folders/Products/CMFDefault/browser/configure.zcml
  U   Products.CMFDefault/branches/charlie_formlib_for_folders/Products/CMFDefault/browser/new_folder.py
  U   Products.CMFDefault/branches/charlie_formlib_for_folders/Products/CMFDefault/browser/templates/batch_widgets.pt
  U   Products.CMFDefault/branches/charlie_formlib_for_folders/Products/CMFDefault/browser/templates/contents.pt
  U   Products.CMFDefault/branches/charlie_formlib_for_folders/Products/CMFDefault/browser/tests/test_new_folder.py

-=-
Modified: Products.CMFDefault/branches/charlie_formlib_for_folders/Products/CMFDefault/browser/configure.zcml
===================================================================
--- Products.CMFDefault/branches/charlie_formlib_for_folders/Products/CMFDefault/browser/configure.zcml	2009-06-07 12:35:24 UTC (rev 100683)
+++ Products.CMFDefault/branches/charlie_formlib_for_folders/Products/CMFDefault/browser/configure.zcml	2009-06-07 15:00:00 UTC (rev 100684)
@@ -6,7 +6,7 @@
       for="Products.CMFCore.interfaces.IFolderish"
       layer="..interfaces.ICMFDefaultSkin"
       name="view.html"
-      class=".folder.FolderView"
+      class=".new_folder.FolderView"
       template="templates/folder.pt"
       permission="zope2.View"
       />

Modified: Products.CMFDefault/branches/charlie_formlib_for_folders/Products/CMFDefault/browser/new_folder.py
===================================================================
--- Products.CMFDefault/branches/charlie_formlib_for_folders/Products/CMFDefault/browser/new_folder.py	2009-06-07 12:35:24 UTC (rev 100683)
+++ Products.CMFDefault/branches/charlie_formlib_for_folders/Products/CMFDefault/browser/new_folder.py	2009-06-07 15:00:00 UTC (rev 100684)
@@ -31,6 +31,9 @@
 from utils import decode
 from utils import memoize
 
+import logging
+LOG = logging.getLogger("formlib for folders")
+
 def contents_delta_vocabulary(context):
     """Vocabulary for the pulldown for moving objects up
     and down."""
@@ -65,30 +68,30 @@
 
     # helpers
 
-    _BATCH_SIZE = 2
+    _BATCH_SIZE = 25
 
     @memoize
-    def _getBatchStart(self):
+    def _get_batch_start(self):
         return self.request.form.get('b_start', 0)
 
     @memoize
-    def _getBatchObj(self):
-        b_start = self._getBatchStart()
+    def _get_batch_obj(self):
+        b_start = self._get_batch_start()
         items = self._get_items()
         return Batch(items, self._BATCH_SIZE, b_start, orphan=0)
 
     @memoize
-    def _getHiddenVars(self):
+    def _get_hidden_vars(self):
         return {}
 
     @memoize
-    def _getNavigationVars(self):
-        return self._getHiddenVars()
+    def _get_navigation_vars(self):
+        return self._get_hidden_vars()
 
     @memoize
-    def _getNavigationURL(self, b_start):
+    def _get_navigation_url(self, b_start):
         target = self._getViewURL()
-        kw = self._getNavigationVars().copy()
+        kw = self._get_navigation_vars().copy()
 
         kw['b_start'] = b_start
         for k, v in kw.items():
@@ -102,8 +105,8 @@
 
     @memoize
     @decode
-    def listItemInfos(self):
-        batch_obj = self._getBatchObj()
+    def list_batch_items(self):
+        batch_obj = self._get_batch_obj()
         portal_url = self._getPortalURL()
 
         items = []
@@ -133,12 +136,12 @@
 
     @memoize
     def navigation_previous(self):
-        batch_obj = self._getBatchObj().previous
+        batch_obj = self._get_batch_obj().previous
         if batch_obj is None:
             return None
 
         length = len(batch_obj)
-        url = self._getNavigationURL(batch_obj.first)
+        url = self._get_navigation_url(batch_obj.first)
         if length == 1:
             title = _(u'Previous item')
         else:
@@ -147,12 +150,12 @@
 
     @memoize
     def navigation_next(self):
-        batch_obj = self._getBatchObj().next
+        batch_obj = self._get_batch_obj().next
         if batch_obj is None:
             return None
 
         length = len(batch_obj)
-        url = self._getNavigationURL(batch_obj.first)
+        url = self._get_navigation_url(batch_obj.first)
         if length == 1:
             title = _(u'Next item')
         else:
@@ -161,12 +164,12 @@
 
     @memoize
     def summary_length(self):
-        length = self._getBatchObj().sequence_length
+        length = self._get_batch_obj().sequence_length
         return length and thousands_commas(length) or ''
 
     @memoize
     def summary_type(self):
-        length = self._getBatchObj().sequence_length
+        length = self._get_batch_bj().sequence_length
         return (length == 1) and _(u'item') or _(u'items')
 
     @memoize
@@ -174,7 +177,8 @@
     def summary_match(self):
         return self.request.form.get('SearchableText')       
 
-class ContentsView(ContentEditFormBase, BatchViewBase):
+
+class ContentsView(BatchViewBase, ContentEditFormBase):
     """Folder contents view"""
     
     template = ViewPageTemplateFile('templates/contents.pt')
@@ -251,7 +255,6 @@
             )
             
     actions = object_actions + delta_actions + absolute_actions + sort_actions
-    
     errors = ()
     
     def __init__(self, *args, **kw):
@@ -330,10 +333,9 @@
         return sequence.sort(items,
                              ((key, 'cmp', reverse and 'desc' or 'asc'),))
     
-    def layout_fields(self):
+    def list_batch_items(self):
         """Return the widgets for the form in the interface field order"""
-        batch_obj = self._getBatchObj()
-        portal_url = self._getPortalURL()
+        batch_obj = self._get_batch_obj()
         fields = []
 
         for item in batch_obj:
@@ -343,16 +345,17 @@
             field['url'] = item.absolute_url()
             field['title'] = item.TitleOrId()
             field['icon'] = item.icon
-            field['position'] = self.context.contentIds().index(item.getId()) + 1
+            field['position'] = self.context.contentIds().index(
+                                                item.getId()) + 1
             field['type'] = item.Type() or None
             fields.append(field.copy())
         return fields
                 
     def _get_ids(self, data):
         """Strip prefixes from ids that have been selected"""
+        LOG.info(str(data))
         ids = [k.split(".")[0] for k, v in data.items() if v == True]
         return ids
-        
     
     #Action conditions
     @memoize
@@ -380,10 +383,12 @@
         (key, reverse) = self._get_sorting()        
         return key == 'position' and len(self.contents) > 1
 
-    #Actions validators
+    #Action validators
     def validate_items(self, action=None, data=None):
         """Check whether any items have been selected for 
         the requested action."""
+        LOG.info(str(data))
+        LOG.info(str(self.request.form))
         if data is None:
             data = {}
         if len(self._get_ids(data)) == 0:
@@ -399,7 +404,6 @@
     def handle_cut(self, action, data):
         """Cut the selected objects and put them in the clipboard"""
         ids = self._get_ids(data)
-        
         try:
             self.context.manage_cutObjects(ids, self.request)
             if len(ids) == 1:
@@ -415,7 +419,6 @@
     def handle_copy(self, action, data):
         """Copy the selected objects to the clipboard"""
         ids = self._get_ids(data)
-
         try:
             self.context.manage_copyObjects(ids, self.request)
             if len(ids) == 1:
@@ -533,4 +536,22 @@
         reverse = data.get('reverse', 0)
         self.context.setDefaultSorting(key, reverse)
         self.status = _(u"Sort order changed")
-        return self._setRedirect('portal_types', 'object/new_contents')
\ No newline at end of file
+        return self._setRedirect('portal_types', 'object/new_contents')
+        
+
+class FolderView(BatchViewBase):
+
+    """View for IFolderish.
+    """
+
+    @memoize
+    def _get_items(self):
+        (key, reverse) = self.context.getDefaultSorting()
+        items = self.context.contentValues()
+        items = sequence.sort(items,
+                              ((key, 'cmp', reverse and 'desc' or 'asc'),))
+        return LazyFilter(items, skip='View')
+
+    @memoize
+    def has_local(self):
+        return 'local_pt' in self.context.objectIds()
\ No newline at end of file

Modified: Products.CMFDefault/branches/charlie_formlib_for_folders/Products/CMFDefault/browser/templates/batch_widgets.pt
===================================================================
--- Products.CMFDefault/branches/charlie_formlib_for_folders/Products/CMFDefault/browser/templates/batch_widgets.pt	2009-06-07 12:35:24 UTC (rev 100683)
+++ Products.CMFDefault/branches/charlie_formlib_for_folders/Products/CMFDefault/browser/templates/batch_widgets.pt	2009-06-07 15:00:00 UTC (rev 100684)
@@ -14,7 +14,7 @@
 ></metal:macro>
 
  <metal:macro metal:define-macro="listing" i18n:domain="cmf_default">
- <p class="BatchListing" tal:repeat="item_info view/listItemInfos"
+ <p class="BatchListing" tal:repeat="item_info view/list_batch_items"
  ><a href="" tal:attributes="href item_info/url"
   ><img src="" alt="" title="" border="0" width="16" height="16"
       tal:attributes="src item_info/icon; alt item_info/type;

Modified: Products.CMFDefault/branches/charlie_formlib_for_folders/Products/CMFDefault/browser/templates/contents.pt
===================================================================
--- Products.CMFDefault/branches/charlie_formlib_for_folders/Products/CMFDefault/browser/templates/contents.pt	2009-06-07 12:35:24 UTC (rev 100683)
+++ Products.CMFDefault/branches/charlie_formlib_for_folders/Products/CMFDefault/browser/templates/contents.pt	2009-06-07 15:00:00 UTC (rev 100684)
@@ -33,7 +33,7 @@
          tal:attributes="href column/url"
          >Column Title</a></th>
      </tr>
-   <tr tal:repeat="item view/layout_fields" 
+   <tr tal:repeat="item view/list_batch_items" 
       tal:attributes="class python: (repeat['item'].even() and 'row-hilite') or ''">
      <td tal:content="structure item/select">Checkbox</td>
      <td><a href="" tal:attributes="href item/url"

Modified: Products.CMFDefault/branches/charlie_formlib_for_folders/Products/CMFDefault/browser/tests/test_new_folder.py
===================================================================
--- Products.CMFDefault/branches/charlie_formlib_for_folders/Products/CMFDefault/browser/tests/test_new_folder.py	2009-06-07 12:35:24 UTC (rev 100683)
+++ Products.CMFDefault/branches/charlie_formlib_for_folders/Products/CMFDefault/browser/tests/test_new_folder.py	2009-06-07 15:00:00 UTC (rev 100684)
@@ -17,14 +17,14 @@
 import unittest
 
 from AccessControl.SecurityManagement import newSecurityManager
+from AccessControl.User import UnrestrictedUser
 
 from zope.component import getSiteManager
 from zope.publisher.browser import TestRequest
 from zope.publisher.interfaces.browser import IBrowserPublisher
 
 from Products.CMFCore.PortalFolder import PortalFolder
-from Products.CMFCore.tests.base.dummy import DummySite
-from Products.CMFCore.tests.base.dummy import DummyTool
+from Products.CMFCore.tests.base.dummy import DummySite, DummyTool
 from Products.CMFCore.tests.base.dummy import DummyUserFolder, DummyContent
 from Products.CMFCore.interfaces import IPropertiesTool
 
@@ -44,6 +44,7 @@
         utool = site._setObject('portal_url', DummyTool())
         folder = PortalFolder('test_folder')
         self.folder = site._setObject('test_folder', folder)
+        self.uf = self.site._setObject('acl_users', DummyUserFolder())
     
     def test_view(self):
         view = ContentsView(self.folder, TestRequest())
@@ -51,11 +52,12 @@
         
     def test_up_info(self):
         view = ContentsView(self.folder, TestRequest())
-        self.assertEquals({'url':u'', 'id':u'Root', 'icon':u''}, view.up_info())
+        self.assertEquals({'url':u'', 'id':u'Root', 'icon':u''},
+                            view.up_info())
         
-    def test_layout_fields(self):
+    def test_list_batch_items(self):
         view = ContentsView(self.folder, TestRequest())
-        self.assertEquals(view.layout_fields(), [])
+        self.assertEquals(view.list_batch_items(), [])
     
     def test_is_orderable(self):
         view = ContentsView(self.folder, TestRequest())
@@ -75,9 +77,52 @@
     
     def test_check_validator(self):
         view = ContentsView(self.folder, TestRequest())
-        self.assertEquals(view.validate_items(), [u'Please select one or more items first.'])
+        self.assertEquals(view.validate_items(), 
+                    [u'Please select one or more items first.'])
         self.assertEquals(view.validate_items(data={'foo':True}), [])
+        
+    def _make_batch(self):
+        """Add enough objects to force pagination"""
+        batch_size = ContentsView._BATCH_SIZE
+        for i in range(batch_size + 2):
+            content_id = "Dummy%s" % i
+            content_obj = DummyContent(content_id)
+            content_obj.portal_type = "Dummy Content"
+            obj = self.folder._setObject(content_id, content_obj)
 
+    def site_login(self):
+        newSecurityManager(None, 
+                    UnrestrictedUser('god', '', ['Manager'], ''))
+                    
+    def test_no_batches(self):
+        """Empty folder should have no next or previous pages"""
+        self.site_login()
+        request = TestRequest(ACTUAL_URL='http://foo.com/bar')
+        view = ContentsView(self.folder, request)
+        self.failIf(view.navigation_next())
+        self.failIf(view.navigation_previous())
+    
+    def test_check_next_page(self):
+        """First page has a next but no previous page"""
+        self.site_login()
+        self._make_batch()
+        request = TestRequest(ACTUAL_URL='http://foo.com/bar')
+        view = ContentsView(self.folder, request)
+        self.assertEquals(view.navigation_next()['title'], 
+                            "Next ${count} items")
+        self.failIf(view.navigation_previous())
+                            
+    def test_check_prev_page(self):
+        """Last page has a previous but no next page"""
+        self.site_login()
+        self._make_batch()
+        request = TestRequest(ACTUAL_URL='http://foo.com/bar')
+        request.form = {'b_start':25}
+        view = ContentsView(self.folder, request)
+        self.assertEquals(view.navigation_previous()['title'], 
+                            "Previous ${count} items")
+        self.failIf(view.navigation_next())
+
 def test_suite():
     suite = unittest.TestSuite()
     suite.addTest(unittest.makeSuite(FolderBrowserViewTests))



More information about the Checkins mailing list