[Zope-Checkins] SVN: Products.Five/trunk/form/ Some fixes for
add/edit forms to ensure that events are fired as expected.
Alec Mitchell
apm13 at columbia.edu
Tue May 2 14:30:58 EDT 2006
Log message for revision 67845:
Some fixes for add/edit forms to ensure that events are fired as expected.
Changed:
U Products.Five/trunk/form/__init__.py
U Products.Five/trunk/form/tests/configure.zcml
U Products.Five/trunk/form/tests/forms.txt
U Products.Five/trunk/form/tests/schemacontent.py
-=-
Modified: Products.Five/trunk/form/__init__.py
===================================================================
--- Products.Five/trunk/form/__init__.py 2006-05-02 17:56:17 UTC (rev 67844)
+++ Products.Five/trunk/form/__init__.py 2006-05-02 18:30:57 UTC (rev 67845)
@@ -22,6 +22,7 @@
import transaction
from zope.event import notify
from zope.lifecycleevent import ObjectCreatedEvent, ObjectModifiedEvent
+from zope.lifecycleevent import Attributes
from zope.location.interfaces import ILocation
from zope.location import LocationProxy
from zope.schema.interfaces import ValidationError
@@ -100,9 +101,16 @@
changed = applyWidgetsChanges(self, self.schema,
target=content, names=self.fieldNames)
# We should not generate events when an adapter is used.
- # That's the adapter's job.
- if changed and self.context is self.adapted:
- notify(ObjectModifiedEvent(content))
+ # That's the adapter's job. We need to unwrap the objects to
+ # compare them, as they are wrapped differently.
+ # Additionally, we can't use Acquisition.aq_base() because
+ # it strangely returns different objects for these two even
+ # when they are identical. In particular
+ # aq_base(self.adapted) != self.adapted.aq_base :-(
+ if changed and getattr(self.context, 'aq_base', self.context)\
+ is getattr(self.adapted, 'aq_base', self.adapted):
+ description = Attributes(self.schema, *self.fieldNames)
+ notify(ObjectModifiedEvent(content, description))
except WidgetsError, errors:
self.errors = errors
status = _("An error occurred.")
@@ -158,7 +166,9 @@
def create(self, *args, **kw):
"""Do the actual instantiation."""
# hack to please typical Zope 2 factories, which expect id and title
- args = ('tmp_id', 'Temporary title') + args
+ # Any sane schema will use a unicode title, and may fail on a
+ # non-unicode one.
+ args = ('tmp_id', u'Temporary title') + args
return self._factory(*args, **kw)
def createAndAdd(self, data):
@@ -198,7 +208,6 @@
notify(ObjectCreatedEvent(content))
content = self.add(content)
-
adapted = self.schema(content)
if self._set_after_add:
@@ -209,6 +218,10 @@
field.set(adapted, data[name])
except ValidationError:
errors.append(sys.exc_info()[1])
+ # We have modified the object, so we need to publish an
+ # object-modified event:
+ description = Attributes(self.schema, *self._set_after_add)
+ notify(ObjectModifiedEvent(content, description))
if errors:
raise WidgetsError(*errors)
Modified: Products.Five/trunk/form/tests/configure.zcml
===================================================================
--- Products.Five/trunk/form/tests/configure.zcml 2006-05-02 17:56:17 UTC (rev 67844)
+++ Products.Five/trunk/form/tests/configure.zcml 2006-05-02 18:30:57 UTC (rev 67845)
@@ -62,7 +62,8 @@
schema=".schemacontent.IFieldContent"
content_factory=".schemacontent.FieldContent"
name="addwidgetoverride.html"
- permission="zope2.Public">
+ permission="zope2.Public"
+ set_before_add="title description somenumber somelist">
<widget
field="description"
@@ -78,6 +79,18 @@
permission="zope2.ViewManagementScreens"
/>
+ <subscriber
+ for=".schemacontent.IFieldContent
+ zope.lifecycleevent.interfaces.IObjectModifiedEvent"
+ handler=".schemacontent.modifiedSubscriber"
+ />
+
+ <subscriber
+ for=".schemacontent.IFieldContent
+ zope.lifecycleevent.interfaces.IObjectCreatedEvent"
+ handler=".schemacontent.createdSubscriber"
+ />
+
<i18n:registerTranslations directory="locales"/>
</configure>
Modified: Products.Five/trunk/form/tests/forms.txt
===================================================================
--- Products.Five/trunk/form/tests/forms.txt 2006-05-02 17:56:17 UTC (rev 67844)
+++ Products.Five/trunk/form/tests/forms.txt 2006-05-02 18:30:57 UTC (rev 67845)
@@ -77,7 +77,20 @@
u'title'
>>> edittest.description #XXX shouldn't we get a u'' here???
+We can also verify that the IObjectCreatedEvent was fired, and the test
+subscriber we registered set a flag indicating such:
+ >>> edittest._created_flag
+ True
+
+Because the process of adding an object often sets attributes after the
+object is created and added, and IObjectModified event should also have been
+fired:
+
+ >>> edittest._modified_flag
+ True
+ >>> del edittest._modified_flag
+
Edit forms
----------
@@ -104,6 +117,8 @@
>>> edittest.title
u'title'
>>> edittest.description #XXX shouldn't we get a u'' here???
+ >>> getattr(edittest, '_modified_flag', False)
+ False
However, when we specify the correct fields:
@@ -124,7 +139,70 @@
>>> edittest.description
u'FooDescription'
+And that the event has been fired:
+ >>> edittest._modified_flag
+ True
+ >>> del edittest._modified_flag
+
+Widget Overrides
+----------------
+
+We have an alternate add form for IFieldContent which uses a TextArea widget
+via and override in the zcml. Let's ensure that that works:
+
+ >>> print http(r"""
+ ... GET /test_folder_1_/ftf/+/addwidgetoverride.html HTTP/1.1
+ ... """, handle_errors=False)
+ HTTP/1.1 200 OK
+ ...
+ ...<textarea
+ ...
+
+ >>> print http(r"""
+ ... POST /test_folder_1_/ftf/+/addwidgetoverride.html HTTP/1.1
+ ... Authorization: Basic manager:r00t
+ ... Content-Type: multipart/form-data; boundary=---------------------------968064918930967154199105236
+ ... Content-Length: 527
+ ...
+ ... -----------------------------968064918930967154199105236
+ ... Content-Disposition: form-data; name="field.title"
+ ...
+ ... title2
+ ... -----------------------------968064918930967154199105236
+ ... Content-Disposition: form-data; name="field.description"
+ ...
+ ... Blah
+ ... -----------------------------968064918930967154199105236
+ ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+ ...
+ ... Add
+ ... -----------------------------968064918930967154199105236
+ ... Content-Disposition: form-data; name="add_input_name"
+ ...
+ ... edittest2
+ ... -----------------------------968064918930967154199105236--
+ ... """, handle_errors=False)
+ HTTP/1.1 302 Moved Temporarily
+ ...
+ Location: http://localhost/test_folder_1_/ftf/manage_main
+ ...
+
+We also indicated that all fields for this view should be set before adding
+the content, this means that no IObjectModified event should have been fired
+
+ >>> edittest2 = self.folder.ftf.edittest2
+ >>> edittest2.title
+ u'title2'
+ >>> edittest2.description
+ u'Blah'
+ >>> edittest2._created_flag
+ True
+
+ >>> getattr(edittest2, '_modified_flag', False)
+ False
+
+
Unicode-safety of forms
-----------------------
Modified: Products.Five/trunk/form/tests/schemacontent.py
===================================================================
--- Products.Five/trunk/form/tests/schemacontent.py 2006-05-02 17:56:17 UTC (rev 67844)
+++ Products.Five/trunk/form/tests/schemacontent.py 2006-05-02 18:30:57 UTC (rev 67845)
@@ -106,3 +106,11 @@
"""Add the complex schema content"""
id = self._setObject(id, ComplexSchemaContent(id))
return ''
+
+def modifiedSubscriber(content, ev):
+ """A simple event handler, which sets a flag on the object"""
+ content._modified_flag = True
+
+def createdSubscriber(content,ev):
+ """A simple event handler, which sets a flag on the object"""
+ content._created_flag = True
More information about the Zope-Checkins
mailing list