[CMF-checkins] SVN: CMF/trunk/C CMFCore.FSSTXMethdo: Modernized, added tests, made customization possible.

Tres Seaver tseaver at palladion.com
Wed Oct 18 18:29:51 EDT 2006


Log message for revision 70793:
  CMFCore.FSSTXMethdo:  Modernized, added tests, made customization possible.
  
  

Changed:
  U   CMF/trunk/CHANGES.txt
  U   CMF/trunk/CMFCore/FSSTXMethod.py
  U   CMF/trunk/CMFCore/dtml/custstx.dtml
  A   CMF/trunk/CMFCore/tests/fake_skins/fake_skin/testSTX.stx
  A   CMF/trunk/CMFCore/tests/fake_skins/fake_skin/testSTX.stx.metadata
  A   CMF/trunk/CMFCore/tests/test_FSSTXMethod.py

-=-
Modified: CMF/trunk/CHANGES.txt
===================================================================
--- CMF/trunk/CHANGES.txt	2006-10-18 21:44:51 UTC (rev 70792)
+++ CMF/trunk/CHANGES.txt	2006-10-18 22:29:50 UTC (rev 70793)
@@ -2,6 +2,9 @@
 
   New Features
 
+    - CMFCore.FSSTXMethdo:  Modernized, added tests, made customization
+      possible.
+
     - Portal: Added 'email_charset' property.
 
     - CMFDefault utils: Added 'makeEmail' function.

Modified: CMF/trunk/CMFCore/FSSTXMethod.py
===================================================================
--- CMF/trunk/CMFCore/FSSTXMethod.py	2006-10-18 21:44:51 UTC (rev 70792)
+++ CMF/trunk/CMFCore/FSSTXMethod.py	2006-10-18 22:29:50 UTC (rev 70793)
@@ -15,44 +15,50 @@
 $Id$
 """
 
-import Globals
 from AccessControl import ClassSecurityInfo
-from StructuredText.StructuredText import HTML
+from DocumentTemplate.DT_HTML import HTML as DTML_HTML
+from Globals import DTMLFile
+from Globals import HTML as Global_HTML
+from Globals import InitializeClass
+from OFS.DTMLDocument import DTMLDocument
+from StructuredText.StructuredText import HTML as STX_HTML
 
-from DirectoryView import registerFileExtension
-from DirectoryView import registerMetaType
-from FSObject import FSObject
-from permissions import FTPAccess
-from permissions import View
-from permissions import ViewManagementScreens
-from utils import _dtmldir
+from Products.CMFCore.DirectoryView import registerFileExtension
+from Products.CMFCore.DirectoryView import registerMetaType
+from Products.CMFCore.FSObject import FSObject
+from Products.CMFCore.permissions import FTPAccess
+from Products.CMFCore.permissions import View
+from Products.CMFCore.permissions import ViewManagementScreens
+from Products.CMFCore.utils import _dtmldir
+from Products.CMFCore.utils import _checkConditionalGET
+from Products.CMFCore.utils import _setCacheHeaders
 
+_DEFAULT_TEMPLATE_DTML = """\
+<dtml-var standard_html_header>
+<dtml-var cooked>
+<dtml-var standard_html_footer>"""
 
+_CUSTOMIZED_TEMPLATE_DTML = """\
+<dtml-var standard_html_header>
+<dtml-var stx fmt="structured-text">
+<dtml-var standard_html_footer>"""
+
 class FSSTXMethod(FSObject):
-
+    """ A chunk of StructuredText, rendered as a skin method of a CMF site.
     """
-        A chunk of StructuredText, rendered as a skin method of a
-        CMFSite.
-    """
-
     meta_type = 'Filesystem STX Method'
+    _owner = None # unowned
 
-    manage_options=( { 'label'      : 'Customize'
-                     , 'action'     : 'manage_main'
-                     }
-                   , { 'label'      : 'View'
-                     , 'action'     : ''
-                     , 'help'       : ('OFSP'
-                                      ,'DTML-DocumentOrMethod_View.stx'
-                                      )
-                     }
+    manage_options=({'label' : 'Customize','action' : 'manage_main'},
+                    {'label' : 'View','action' : '',
+                     'help' : ('OFSP' ,'DTML-DocumentOrMethod_View.stx')},
                    )
 
     security = ClassSecurityInfo()
     security.declareObjectProtected(View)
 
     security.declareProtected(ViewManagementScreens, 'manage_main')
-    manage_main = Globals.DTMLFile('custstx', _dtmldir)
+    manage_main = DTMLFile('custstx', _dtmldir)
 
     #
     #   FSObject interface
@@ -61,7 +67,9 @@
         """
             Create a ZODB (editable) equivalent of this object.
         """
-        raise NotImplementedError, "See next week's model."
+        target = DTMLDocument(_CUSTOMIZED_TEMPLATE_DTML, __name__=self.getId())
+        target._setProperty('stx', self.raw, 'text')
+        return target
 
     def _readFile(self, reparse):
         """Read the data from the filesystem.
@@ -82,75 +90,79 @@
     class func_code:
         pass
 
-    func_code=func_code()
-    func_code.co_varnames= ()
-    func_code.co_argcount=0
-    func_code.__roles__=()
+    func_code = func_code()
+    func_code.co_varnames = ()
+    func_code.co_argcount = 0
+    func_code.__roles__ = ()
 
-    func_defaults__roles__=()
-    func_defaults=()
+    func_defaults__roles__ = ()
+    func_defaults = ()
 
     index_html = None   # No accidental acquisition
 
     default_content_type = 'text/html'
 
-    def cook( self ):
-        if not hasattr( self, '_v_cooked' ):
-            self._v_cooked = HTML(self.raw, level=1, header=0)
+    def cook(self):
+        if not hasattr(self, '_v_cooked'):
+            self._v_cooked = STX_HTML(self.raw, level=1, header=0)
         return self._v_cooked
 
-    _default_template = Globals.HTML( """\
-<dtml-var standard_html_header>
-<dtml-var cooked>
-<dtml-var standard_html_footer>""" )
+    _default_template = DTML_HTML(_DEFAULT_TEMPLATE_DTML)
 
     def __call__( self, REQUEST={}, RESPONSE=None, **kw ):
+        """ Return our rendered StructuredText.
         """
-            Return our rendered StructuredText.
-        """
         self._updateFromFS()
 
         if RESPONSE is not None:
             RESPONSE.setHeader( 'Content-Type', 'text/html' )
+
+        faux_wrapped = self.__of__(self) # we are our own "content"
+        if _checkConditionalGET(faux_wrapped, extra_context={}):
+            return ''
+
+        _setCacheHeaders(faux_wrapped, extra_context={})
+
         return self._render(REQUEST, RESPONSE, **kw)
 
-    security.declarePrivate( '_render' )
-    def _render( self, REQUEST={}, RESPONSE=None, **kw ):
+    security.declarePrivate('modified')
+    def modified(self):
+        return self.getModTime()
+
+    security.declarePrivate('_render')
+    def _render(self, REQUEST={}, RESPONSE=None, **kw):
+        """ Find the appropriate rendering template and use it to render us.
         """
-            Find the appropriate rendering template and use it to
-            render us.
-        """
-        template = getattr( self, 'stxmethod_view', self._default_template )
+        template = getattr(self, 'stxmethod_view', self._default_template)
 
-        if getattr( template, 'isDocTemp', 0 ):
-            posargs = ( self, REQUEST, RESPONSE )
+        if getattr(template, 'isDocTemp', 0):
+            #posargs = (self, REQUEST, RESPONSE)
+            posargs = (self, REQUEST)
         else:
             posargs = ()
 
-        return template(*posargs, **{ 'cooked' : self.cook() } )
+        kwargs = {'cooked': self.cook()}
+        return template(*posargs, **kwargs)
 
-    security.declareProtected( FTPAccess, 'manage_FTPget' )
-    def manage_FTPget( self ):
+    security.declareProtected(FTPAccess, 'manage_FTPget')
+    def manage_FTPget(self):
+        """ Fetch our source for delivery via FTP.
         """
-            Fetch our source for delivery via FTP.
-        """
         return self.raw
 
-    security.declareProtected( ViewManagementScreens, 'PrincipiaSearchSource' )
-    def PrincipiaSearchSource( self ):
+    security.declareProtected(ViewManagementScreens, 'PrincipiaSearchSource')
+    def PrincipiaSearchSource(self):
+        """ Fetch our source for indexing in a catalog.
         """
-            Fetch our source for indexing in a catalog.
-        """
         return self.raw
 
-    security.declareProtected( ViewManagementScreens, 'document_src' )
+    security.declareProtected(ViewManagementScreens, 'document_src')
     def document_src( self ):
+        """ Fetch our source for rendering in the ZMI.
         """
-            Fetch our source for indexing in a catalog.
-        """
         return self.raw
 
-Globals.InitializeClass( FSSTXMethod )
+InitializeClass(FSSTXMethod)
 
-registerFileExtension( 'stx', FSSTXMethod )
-registerMetaType( 'STX Method', FSSTXMethod )
+registerFileExtension('stx', FSSTXMethod)
+registerMetaType('STX Method', FSSTXMethod)

Modified: CMF/trunk/CMFCore/dtml/custstx.dtml
===================================================================
--- CMF/trunk/CMFCore/dtml/custstx.dtml	2006-10-18 21:44:51 UTC (rev 70792)
+++ CMF/trunk/CMFCore/dtml/custstx.dtml	2006-10-18 22:29:50 UTC (rev 70793)
@@ -13,13 +13,13 @@
 </dtml-let>
 <dtml-var manage_tabs>
 
-  <FORM ACTION="manage_doCustomize" METHOD="POST">
-    <TABLE CELLSPACING="2">
-      <TR>
-	<TH ALIGN="LEFT" VALIGN="TOP" class="form-label">Id</TH>
-	<TD ALIGN="LEFT" VALIGN="TOP" class="form-element"><dtml-var getId></TD>
-      </TR>
+  <form ACTION="manage_doCustomize" METHOD="POST">
+    <table CELLSPACING="2">
       <tr>
+	<th ALIGN="LEFT" VALIGN="TOP" class="form-label">Id</th>
+	<td ALIGN="LEFT" VALIGN="TOP" class="form-element"><dtml-var getId></td>
+      </tr>
+      <tr>
 	<th align="left" valign="top" class="form-label">
         <em>Size</em>
         </th>
@@ -58,8 +58,8 @@
           <input type="submit" name="submit" value=" Customize ">
         </td>
       </tr>
-    </TABLE>
-  </FORM>
+    </table>
+  </form>
 <table border="1" bgcolor="#cccccc"><tr><td>
 <pre>
 <dtml-var document_src>

Added: CMF/trunk/CMFCore/tests/fake_skins/fake_skin/testSTX.stx
===================================================================
--- CMF/trunk/CMFCore/tests/fake_skins/fake_skin/testSTX.stx	2006-10-18 21:44:51 UTC (rev 70792)
+++ CMF/trunk/CMFCore/tests/fake_skins/fake_skin/testSTX.stx	2006-10-18 22:29:50 UTC (rev 70793)
@@ -0,0 +1,6 @@
+Title Goes Here
+
+  Subhead Here
+
+    And this is a paragraph,
+    broken across lines.

Added: CMF/trunk/CMFCore/tests/fake_skins/fake_skin/testSTX.stx.metadata
===================================================================
--- CMF/trunk/CMFCore/tests/fake_skins/fake_skin/testSTX.stx.metadata	2006-10-18 21:44:51 UTC (rev 70792)
+++ CMF/trunk/CMFCore/tests/fake_skins/fake_skin/testSTX.stx.metadata	2006-10-18 22:29:50 UTC (rev 70793)
@@ -0,0 +1,2 @@
+[default]
+title=STX Method

Added: CMF/trunk/CMFCore/tests/test_FSSTXMethod.py
===================================================================
--- CMF/trunk/CMFCore/tests/test_FSSTXMethod.py	2006-10-18 21:44:51 UTC (rev 70792)
+++ CMF/trunk/CMFCore/tests/test_FSSTXMethod.py	2006-10-18 22:29:50 UTC (rev 70793)
@@ -0,0 +1,179 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation and Contributors. All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+""" Unit tests for FSSTXMethod module.
+
+$Id$
+"""
+import unittest
+import os
+
+#import Testing
+
+from Products.CMFCore.tests.base.testcase import FSDVTest
+from Products.CMFCore.tests.base.testcase import RequestTest
+from Products.CMFCore.tests.base.testcase import SecurityTest
+
+class FSSTXMaker(FSDVTest):
+
+    def _makeOne( self, id, filename ):
+        from Products.CMFCore.FSMetadata import FSMetadata
+        from Products.CMFCore.FSSTXMethod import FSSTXMethod
+        path = os.path.join(self.skin_path_name, filename)
+        metadata = FSMetadata(path)
+        metadata.read()
+        return FSSTXMethod( id, path, properties=metadata.getProperties() )
+
+_EXPECTED_HTML = """\
+<html>
+<body>
+
+<h1>Title Goes Here</h1>
+<h2>  Subhead Here</h2>
+<p>    And this is a paragraph,
+    broken across lines.</p>
+
+</body>
+</html>
+"""
+
+class FSSTXMethodTests(RequestTest, FSSTXMaker):
+
+    def setUp(self):
+        FSSTXMaker.setUp(self)
+        RequestTest.setUp(self)
+        self.root.standard_html_header = (
+                lambda *args, **kw: '<html>\n<body>\n')
+        self.root.standard_html_footer = (
+                lambda *args, **kw: '</body>\n</html>\n')
+
+    def tearDown(self):
+        RequestTest.tearDown(self)
+        FSSTXMaker.tearDown(self)
+
+    def test___call__( self ):
+        script = self._makeOne( 'testSTX', 'testSTX.stx' )
+        script = script.__of__(self.app)
+        self.assertEqual(script(self.REQUEST), _EXPECTED_HTML)
+
+    def test_caching( self ):
+        #   Test HTTP caching headers.
+        from Products.CMFCore.tests.base.dummy import DummyCachingManager
+        self.root.caching_policy_manager = DummyCachingManager()
+        original_len = len( self.RESPONSE.headers )
+        script = self._makeOne('testSTX', 'testSTX.stx')
+        script = script.__of__(self.root)
+        script(self.REQUEST, self.RESPONSE)
+        self.failUnless( len( self.RESPONSE.headers ) >= original_len + 2 )
+        self.failUnless( 'foo' in self.RESPONSE.headers.keys() )
+        self.failUnless( 'bar' in self.RESPONSE.headers.keys() )
+
+    def test_ownership( self ):
+        script = self._makeOne( 'testSTX', 'testSTX.stx' )
+        script = script.__of__(self.root)
+        # FSSTXMethod has no owner
+        owner_tuple = script.getOwnerTuple()
+        self.assertEqual(owner_tuple, None)
+
+        # and ownership is not acquired [CMF/450]
+        self.root._owner= ('/foobar', 'baz')
+        owner_tuple = script.getOwnerTuple()
+        self.assertEqual(owner_tuple, None)
+
+    def test_304_response_from_cpm( self ):
+        # test that we get a 304 response from the cpm via this template
+        from DateTime import DateTime
+        from webdav.common import rfc1123_date
+        from Products.CMFCore.tests.base.dummy \
+            import DummyCachingManagerWithPolicy
+        from Products.CMFCore.tests.base.dummy import DummyContent
+
+        mod_time = DateTime()
+        self.root.caching_policy_manager = DummyCachingManagerWithPolicy()
+        script = self._makeOne('testSTX', 'testSTX.stx')
+        script = script.__of__(self.root)
+        self.REQUEST.environ[ 'IF_MODIFIED_SINCE'
+                            ] = '%s;' % rfc1123_date( mod_time+3600 )
+        data = script(self.REQUEST, self.RESPONSE)
+
+        self.assertEqual( data, '' )
+        self.assertEqual( self.RESPONSE.getStatus(), 304 )
+
+class FSSTXMethodCustomizationTests( SecurityTest, FSSTXMaker ):
+
+    def setUp( self ):
+        from OFS.Folder import Folder
+        FSSTXMaker.setUp(self)
+        SecurityTest.setUp( self )
+
+        self.root._setObject( 'portal_skins', Folder( 'portal_skins' ) )
+        self.skins = self.root.portal_skins
+
+        self.skins._setObject( 'custom', Folder( 'custom' ) )
+        self.custom = self.skins.custom
+
+        self.skins._setObject( 'fsdir', Folder( 'fsdir' ) )
+        self.fsdir = self.skins.fsdir
+
+        self.fsdir._setObject( 'testSTX'
+                             , self._makeOne( 'testSTX', 'testSTX.stx' ) )
+
+        self.fsSTX = self.fsdir.testSTX
+
+    def test_customize( self ):
+        from OFS.DTMLDocument import DTMLDocument
+        from Products.CMFCore.FSSTXMethod import _CUSTOMIZED_TEMPLATE_DTML
+
+        self.fsSTX.manage_doCustomize(folder_path='custom')
+
+        self.assertEqual(len(self.custom.objectIds()), 1)
+        self.failUnless('testSTX' in self.custom.objectIds())
+        target = self.custom._getOb('testSTX')
+
+        self.failUnless(isinstance(target, DTMLDocument))
+
+        propinfo = target.propdict()['stx']
+        self.assertEqual(propinfo['type'], 'text')
+        self.assertEqual(target.stx, self.fsSTX.raw)
+
+        self.assertEqual(target.document_src(), _CUSTOMIZED_TEMPLATE_DTML)
+
+    def test_customize_caching(self):
+        # Test to ensure that cache manager associations survive customizing
+        from Products.StandardCacheManagers import RAMCacheManager
+        cache_id = 'gofast'
+        RAMCacheManager.manage_addRAMCacheManager( self.root
+                                                 , cache_id
+                                                 , REQUEST=None
+                                                 )
+        self.fsSTX.ZCacheable_setManagerId(cache_id, REQUEST=None)
+
+        self.assertEqual(self.fsSTX.ZCacheable_getManagerId(), cache_id)
+
+        self.fsSTX.manage_doCustomize(folder_path='custom')
+        custom_pt = self.custom.testSTX
+
+        self.assertEqual(custom_pt.ZCacheable_getManagerId(), cache_id)
+
+    def tearDown(self):
+        SecurityTest.tearDown(self)
+        FSSTXMaker.tearDown(self)
+
+
+def test_suite():
+    return unittest.TestSuite((
+        unittest.makeSuite(FSSTXMethodTests),
+        unittest.makeSuite(FSSTXMethodCustomizationTests),
+        ))
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')


Property changes on: CMF/trunk/CMFCore/tests/test_FSSTXMethod.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native



More information about the CMF-checkins mailing list