[Checkins] SVN: z3c.layer.ready2go/trunk/ Implemented ftesting.zcml based on z3c.layer.pagelet ftesting.zcml

Roger Ineichen roger at projekt01.ch
Fri Dec 28 20:55:09 EST 2007


Log message for revision 82528:
  Implemented ftesting.zcml based on z3c.layer.pagelet ftesting.zcml
  Added tests for IReady2GoBrowserLayer based on z3c.formui and z3c.layer.pagelet

Changed:
  U   z3c.layer.ready2go/trunk/buildout.cfg
  U   z3c.layer.ready2go/trunk/setup.py
  U   z3c.layer.ready2go/trunk/src/z3c/layer/ready2go/README.txt
  U   z3c.layer.ready2go/trunk/src/z3c/layer/ready2go/__init__.py
  A   z3c.layer.ready2go/trunk/src/z3c/layer/ready2go/ftesting.zcml
  D   z3c.layer.ready2go/trunk/src/z3c/layer/ready2go/tests/
  A   z3c.layer.ready2go/trunk/src/z3c/layer/ready2go/tests.py

-=-
Modified: z3c.layer.ready2go/trunk/buildout.cfg
===================================================================
--- z3c.layer.ready2go/trunk/buildout.cfg	2007-12-29 01:52:56 UTC (rev 82527)
+++ z3c.layer.ready2go/trunk/buildout.cfg	2007-12-29 01:55:09 UTC (rev 82528)
@@ -1,6 +1,8 @@
 [buildout]
 develop = .
           externals/z3c.layer.pagelet
+          externals/z3c.form
+          externals/z3c.formui
 parts = test checker coverage
 
 [test]

Modified: z3c.layer.ready2go/trunk/setup.py
===================================================================
--- z3c.layer.ready2go/trunk/setup.py	2007-12-29 01:52:56 UTC (rev 82527)
+++ z3c.layer.ready2go/trunk/setup.py	2007-12-29 01:55:09 UTC (rev 82528)
@@ -66,6 +66,7 @@
         'zope.app.http',
         'zope.app.publisher',
         'z3c.pagelet',
+        'z3c.viewlet',
         'z3c.layer.pagelet',
         'z3c.form',
         'z3c.formui',

Modified: z3c.layer.ready2go/trunk/src/z3c/layer/ready2go/README.txt
===================================================================
--- z3c.layer.ready2go/trunk/src/z3c/layer/ready2go/README.txt	2007-12-29 01:52:56 UTC (rev 82527)
+++ z3c.layer.ready2go/trunk/src/z3c/layer/ready2go/README.txt	2007-12-29 01:55:09 UTC (rev 82528)
@@ -4,3 +4,428 @@
 
 This package contains the ready2go layer. This layer supports a correct set of
 component registration and can be used for inheritation in custom skins.
+
+Important
+---------
+
+This layer supports the z3c.pagelet and the z3c.form pattern. This means every 
+page e.g. the error page is based on the z3c.pagelet concept. By default we use 
+the Div based layout for z3c forms.
+
+
+IReady2GoBrowserLayer
+---------------------
+
+The ready2go layer is useful for build custom presentation skins without access
+to ZMI menus like zmi_views etc. This means there is no menu item registred if
+you use this layer.
+
+For more information about what this layer offers, see z3c.layer.pagelet
+
+
+Testing
+-------
+
+For testing the IReady2GoBrowserLayer we use the testing skin defined in the
+tests package which uses the IReady2GoBrowserLayer as the only base layer.
+This means, that our testing skin provides only the views defined in the
+minimal package and it's testing views defined in tests.
+
+Login as manager first:
+
+  >>> from zope.testbrowser.testing import Browser
+  >>> manager = Browser()
+  >>> manager.addHeader('Authorization', 'Basic mgr:mgrpw')
+
+Check if we can access the page.html view which is registred in the
+ftesting.zcml file with our skin:
+
+  >>> manager = Browser()
+  >>> manager.addHeader('Authorization', 'Basic mgr:mgrpw')
+  >>> skinURL = 'http://localhost/++skin++Ready2GoTestSkin'
+  >>> manager.open(skinURL + '/page.html')
+  >>> manager.url
+  'http://localhost/++skin++Ready2GoTestSkin/page.html'
+
+
+Pagelet support
+---------------
+
+Check if we can access the test page given from the z3c.layer.pagelet 
+ftesting.zcml configuration.
+
+  >>> print manager.contents
+  <!DOCTYPE...
+  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+  <head>
+  <title>TestSkin</title>
+  </head>
+  <body>
+    test page
+  <BLANKLINE>
+  </body>
+  </html>
+  <BLANKLINE>
+
+Now check the not found page which is a exception view on the exception
+``zope.publisher.interfaces.INotFound``:
+
+  >>> manager.open(skinURL + '/foobar.html')
+  Traceback (most recent call last):
+  ...
+  httperror_seek_wrapper: HTTP Error 404: Not Found
+
+  >>> print manager.contents
+  <!DOCTYPE...
+  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+  <head>
+  <title>TestSkin</title>
+  </head>
+  <body>
+    <div>
+    <br />
+    <br />
+    <h3>
+      The page you are trying to access is not available
+    </h3>
+    <br />
+    <b>
+      Please try the following:
+    </b>
+    <br />
+    <ol>
+      <li>
+        Make sure that the Web site address is spelled correctly.
+      </li>
+      <li>
+        <a href="javascript:history.back(1);">
+          Go back and try another URL.
+        </a>
+      </li>
+    </ol>
+  </div>
+  <BLANKLINE>
+  </body>
+  </html>
+  <BLANKLINE>
+
+And check the user error page which is a view registred for
+``zope.exceptions.interfaces.IUserError`` exceptions:
+
+  >>> manager.open(skinURL + '/@@usererror.html')
+  >>> print manager.contents
+  <!DOCTYPE ...
+  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+  <head>
+  <title>TestSkin</title>
+  </head>
+  <body>
+    <div>
+    <div>simply user error</div>
+  </div>
+  <BLANKLINE>
+  </body>
+  </html>
+  <BLANKLINE>
+
+And check error view registred for
+``zope.interface.common.interfaces.IException``:
+
+  >>> manager.open(skinURL + '/@@systemerror.html')
+  >>> print manager.contents
+  <!DOCTYPE...
+  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+  <head>
+  <title>TestSkin</title>
+  </head>
+  <body>
+    <div>
+    <br />
+    <br />
+    <h3>A system error occurred</h3>
+    <br />
+    <b>Please contact the administrator.</b>
+    <a href="javascript:history.back(1);">
+      Go back and try another URL.
+    </a>
+  </div>
+  <BLANKLINE>
+  </body>
+  </html>
+  <BLANKLINE>
+
+And check the ``zope.security.interfaces.IUnauthorized`` view, use a new
+unregistred user (test browser) for this:
+
+  >>> unauthorized = Browser()
+  >>> unauthorized.open(skinURL + '/@@forbidden.html')
+  Traceback (most recent call last):
+  ...
+  httperror_seek_wrapper: HTTP Error 403: Forbidden
+
+  >>> print unauthorized.contents
+  <!DOCTYPE ...
+  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+  <head>
+  <title>TestSkin</title>
+  </head>
+  <body>
+    <div>
+    <br />
+    <br />
+    <h3>Unauthorized</h3>
+    <br />
+    <b>You are not authorized.</b>
+  </div>
+  <BLANKLINE>
+  </body>
+  </html>
+  <BLANKLINE>
+
+
+Form and form layout support
+----------------------------
+
+This layer offers also form macros given from z3c.formui. Let's create a simple
+form:
+
+  >>> from z3c.form import testing
+  >>> testing.setupFormDefaults()
+
+Before we can start writing forms, we must have the content to work with:
+
+  >>> import zope.interface
+  >>> import zope.schema
+  >>> class IPerson(zope.interface.Interface):
+  ...
+  ...     name = zope.schema.TextLine(
+  ...         title=u'Name',
+  ...         required=True)
+  ...
+  ...     age = zope.schema.Int(
+  ...         title=u'Age',
+  ...         description=u"The person's age.",
+  ...         min=0,
+  ...         default=20,
+  ...         required=False)
+
+  >>> from zope.schema.fieldproperty import FieldProperty
+  >>> class Person(object):
+  ...     zope.interface.implements(IPerson)
+  ... 
+  ...     name = FieldProperty(IPerson['name'])
+  ...     age = FieldProperty(IPerson['age'])
+  ...
+  ...     def __init__(self, name, age):
+  ...         self.name = name
+  ...         self.age = age
+  ...
+  ...     def __repr__(self):
+  ...         return '<%s %r>' % (self.__class__.__name__, self.name)
+
+Okay, that should suffice for now. Let's now create a working add form:
+
+  >>> from z3c.form import field
+  >>> from z3c.formui import form, layout
+  >>> class PersonAddForm(form.AddForm):
+  ...
+  ...     fields = field.Fields(IPerson)
+  ...
+  ...     def create(self, data):
+  ...         return Person(**data)
+  ...
+  ...     def add(self, object):
+  ...         self.context[object.id] = object
+  ...
+  ...     def nextURL(self):
+  ...         return 'index.html'
+
+Let's create a request:
+
+  >>> from z3c.form.testing import TestRequest
+  >>> from zope.interface import alsoProvides
+  >>> divRequest = TestRequest()
+
+And support the div form layer for our request:
+
+  >>> from z3c.formui.interfaces import IDivFormLayer
+  >>> alsoProvides(divRequest, IDivFormLayer)
+
+Now create the form:
+
+  >>> root = getRootFolder()
+  >>> addForm = PersonAddForm(root, divRequest)
+
+Since we have not specified a template yet, we have to do this now. We use our 
+div based form template:
+
+  >>> import os
+  >>> import z3c.formui
+  >>> divFormTemplate = os.path.join(os.path.dirname(z3c.formui.__file__),
+  ...     'div-form.pt')
+
+  >>> from z3c.template.template import TemplateFactory
+  >>> divFormFactory = TemplateFactory(divFormTemplate, 'text/html')
+
+Now register the form (content) template:
+
+  >>> import zope.interface
+  >>> import zope.component
+  >>> from z3c.template.interfaces import IContentTemplate
+  >>> zope.component.provideAdapter(divFormFactory,
+  ...     (zope.interface.Interface, IDivFormLayer),
+  ...     IContentTemplate)
+
+And let's define a layout template which simply calls the render method. For a 
+more adavanced content/layout render concept see z3c.pagelet.
+
+  >>> import tempfile
+  >>> temp_dir = tempfile.mkdtemp()
+
+  >>> myLayout = os.path.join(temp_dir, 'myLayout.pt')
+  >>> open(myLayout, 'w').write('''<html>
+  ...   <body>
+  ...     <tal:block content="structure view/render">
+  ...       content
+  ...     </tal:block>
+  ...   </body>
+  ... </html>''')
+  >>> myLayoutFactory = TemplateFactory(myLayout, 'text/html')
+
+  >>> from z3c.template.interfaces import ILayoutTemplate
+  >>> zope.component.provideAdapter(myLayoutFactory,
+  ...     (zope.interface.Interface, zope.interface.Interface), ILayoutTemplate)
+
+Now we can get our layout template:
+
+  >>> layout = zope.component.getMultiAdapter((addForm, divRequest),
+  ...     ILayoutTemplate)
+
+  >>> layout
+  <zope.app.pagetemplate.viewpagetemplatefile.ViewPageTemplateFile object at ...>
+
+
+DIV-based Layout
+----------------
+
+Let's now render the page. Note the output doesn't contain the layout template:
+
+  >>> addForm.update()
+  >>> print addForm.render()
+  <form action="http://127.0.0.1" method="post"
+          enctype="multipart/form-data" class="edit-form"
+          name="form" id="form">
+    <div class="viewspace">
+      <div class="required-info">
+        <span class="required">*</span> &ndash; required
+      </div>
+      <div>
+        <div id="form-widgets-name-row" class="row">
+          <div class="label">
+            <label for="form-widgets-name">
+              <span>Name</span>
+              <span class="required">*</span>
+            </label>
+          </div>
+          <div class="widget"><input type="text" id="form-widgets-name"
+                   name="form.widgets.name"
+                   class="text-widget required textline-field" value="" />
+          </div>
+        </div>
+        <div id="form-widgets-age-row" class="row">
+          <div class="label">
+            <label for="form-widgets-age">
+              <span>Age</span>
+            </label>
+          </div>
+          <div class="widget"><input type="text" id="form-widgets-age"
+                   name="form.widgets.age" class="text-widget int-field"
+                   value="20" />
+          </div>
+        </div>
+      </div>
+    </div>
+    <div>
+      <div class="buttons">
+        <input type="submit" id="form-buttons-add"
+               name="form.buttons.add"
+               class="submit-widget button-field" value="Add" />
+      </div>
+    </div>
+  </form>
+
+Form Macros
+-----------
+
+Try at least to load the confguration, which will make sure that all macros
+get registered correctly.
+
+  >>> from zope.configuration import xmlconfig
+  >>> import zope.component
+  >>> import zope.viewlet
+  >>> import zope.app.component
+  >>> import zope.app.publisher.browser
+  >>> import z3c.macro
+  >>> import z3c.template
+  >>> import z3c.formui
+  >>> xmlconfig.XMLConfig('meta.zcml', zope.component)()
+  >>> xmlconfig.XMLConfig('meta.zcml', zope.viewlet)()
+  >>> xmlconfig.XMLConfig('meta.zcml', zope.app.component)()
+  >>> xmlconfig.XMLConfig('meta.zcml', zope.app.publisher.browser)()
+  >>> xmlconfig.XMLConfig('meta.zcml', z3c.macro)()
+  >>> xmlconfig.XMLConfig('meta.zcml', z3c.template)()
+  >>> xmlconfig.XMLConfig('configure.zcml', z3c.formui)()
+
+
+Div layout macros
+-----------------
+
+Now we can see that we have different form macros available:
+
+  >>> from z3c.macro.interfaces import IMacroTemplate
+  >>> objects = (None, addForm, divRequest)
+  >>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form')
+  [...div-form.pt'), ...metal:define-macro': u'form'...
+
+
+  >>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'subform')
+  [...div-form.pt'), ...define-macro': u'subform'...
+
+
+  >>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-label')
+  [...div-form.pt'), ...define-macro': u'label'...
+
+
+  >>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-required-info')
+  [...div-form.pt'), ...define-macro', u'required-info'...
+
+
+  >>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-header')
+  [...div-form.pt'), ...define-macro': u'header'...
+
+
+  >>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-errors')
+  [...div-form.pt'), ...define-macro': u'errors'...
+
+
+  >>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'widget-rows')
+  [...div-form.pt'), ...define-macro': u'widget-rows'...
+
+
+  >>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'widget-row')
+  [...div-form.pt'), ...define-macro': u'widget-row'...
+
+
+  >>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-groups')
+  [...div-form.pt'), ...define-macro': u'groups'...
+
+
+  >>> zope.component.getMultiAdapter(objects, IMacroTemplate, 'form-buttons')
+  [...div-form.pt'), ...define-macro', u'buttons'...
+
+
+Cleanup
+-------
+
+  >>> import shutil
+  >>> shutil.rmtree(temp_dir)

Modified: z3c.layer.ready2go/trunk/src/z3c/layer/ready2go/__init__.py
===================================================================
--- z3c.layer.ready2go/trunk/src/z3c/layer/ready2go/__init__.py	2007-12-29 01:52:56 UTC (rev 82527)
+++ z3c.layer.ready2go/trunk/src/z3c/layer/ready2go/__init__.py	2007-12-29 01:55:09 UTC (rev 82528)
@@ -21,6 +21,5 @@
 
 
 class IReady2GoBrowserLayer(z3c.layer.pagelet.IPageletBrowserLayer,
-    z3c.formui.interfaces.IDivFormLayer,
-    z3c.form.interfaces.IFormLayer):
+    z3c.formui.interfaces.IDivFormLayer, z3c.form.interfaces.IFormLayer):
     """A ready 2 go layer useful for custom applications."""

Added: z3c.layer.ready2go/trunk/src/z3c/layer/ready2go/ftesting.zcml
===================================================================
--- z3c.layer.ready2go/trunk/src/z3c/layer/ready2go/ftesting.zcml	                        (rev 0)
+++ z3c.layer.ready2go/trunk/src/z3c/layer/ready2go/ftesting.zcml	2007-12-29 01:55:09 UTC (rev 82528)
@@ -0,0 +1,25 @@
+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:meta="http://namespaces.zope.org/meta"
+    xmlns:browser="http://namespaces.zope.org/browser"
+    xmlns:z3c="http://namespaces.zope.org/z3c"
+    i18n_domain="zope">
+
+  <!-- use z3c.layer.pagelet as base config -->
+  <include package="z3c.layer.pagelet.tests" file="ftesting.zcml"/>
+
+  <!-- load additional configuration -->
+  <include package="zope.viewlet" file="meta.zcml" />
+
+  <include package="z3c.macro" file="meta.zcml" />
+  <include package="z3c.form" file="meta.zcml" />
+  <include package="z3c.form" />
+  <include package="z3c.formui" />
+
+  <interface
+      interface="z3c.layer.ready2go.tests.IReady2GoTestSkin"
+      type="zope.publisher.interfaces.browser.IBrowserSkinType"
+      name="Ready2GoTestSkin"
+      />
+
+</configure>


Property changes on: z3c.layer.ready2go/trunk/src/z3c/layer/ready2go/ftesting.zcml
___________________________________________________________________
Name: svn:eol-style
   + native

Added: z3c.layer.ready2go/trunk/src/z3c/layer/ready2go/tests.py
===================================================================
--- z3c.layer.ready2go/trunk/src/z3c/layer/ready2go/tests.py	                        (rev 0)
+++ z3c.layer.ready2go/trunk/src/z3c/layer/ready2go/tests.py	2007-12-29 01:55:09 UTC (rev 82528)
@@ -0,0 +1,51 @@
+##############################################################################
+#
+# Copyright (c) 2005 Zope Foundation 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.
+#
+##############################################################################
+"""
+$Id: tests.py 82519 2007-12-29 00:55:45Z rogerineichen $
+"""
+import re
+import unittest
+from zope.testing import renormalizing
+from zope.app.testing import functional
+
+import z3c.layer.ready2go
+
+layer = functional.defineLayer('TestLayer', 'ftesting.zcml')
+
+
+class IReady2GoTestSkin(z3c.layer.ready2go.IReady2GoBrowserLayer):
+    """The ready2go layer test skin."""
+
+
+def getRootFolder():
+    return functional.FunctionalTestSetup().getRootFolder()
+
+
+def test_suite():
+    suite = unittest.TestSuite()
+
+    s = functional.FunctionalDocFileSuite(
+        'README.txt',
+        globs={'getRootFolder': getRootFolder},
+        checker = renormalizing.RENormalizing([
+            (re.compile(r'httperror_seek_wrapper:', re.M), 'HTTPError:'),
+            ])
+        )
+    s.layer = TestLayer
+    suite.addTest(s)
+
+    return suite
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')


Property changes on: z3c.layer.ready2go/trunk/src/z3c/layer/ready2go/tests.py
___________________________________________________________________
Name: svn:eol-style
   + native



More information about the Checkins mailing list