[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> – 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