Skip to content

Commit

Permalink
Merge pull request #253 from collective/maurits/zope-interface-51x-fi…
Browse files Browse the repository at this point in the history
…eldset-problem

Fix zope interface 5.1.x fieldset problem
  • Loading branch information
mauritsvanrees committed Nov 11, 2020
2 parents 6892b29 + 4ac8018 commit 5585125
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 86 deletions.
4 changes: 4 additions & 0 deletions .travis.yml
Expand Up @@ -22,6 +22,10 @@ jobs:
env: PLONE_VERSION=5.2.x
dist: bionic
sudo: true
- python: "3.8"
env: PLONE_VERSION=5.2.3-pending
dist: bionic
sudo: true

cache:
pip: true
Expand Down
3 changes: 3 additions & 0 deletions news/252.bugfix
@@ -0,0 +1,3 @@
Fix validators in field sets with zope.interface 5.1+.
This fixes `issue 252 <https://github.com/collective/collective.easyform/issues/252>`_.
[maurits]
36 changes: 28 additions & 8 deletions src/collective/easyform/fields.py
Expand Up @@ -29,11 +29,24 @@

def superAdapter(specific_interface, adapter, objects, name=u""):
"""Find the next most specific adapter.
"""
# We are adjusting view object class to provide IForm rather than IEasyFormForm or IGroup to make
# one of the objects less specific. This allows us to find anotehr adapter other than our one. This allows us to
# find any custom adapters for any fields that we have overridden
This is called by a FieldExtenderValidator or FieldExtenderDefault instance.
This is passed in with the 'adapter' parameter.
This adapter itself is not a real validator or default factory,
but is used to find other real validators or default factories.
This may sound strange, but it solves a problem.
Problem is that validators and default were not always found for fields in field sets.
For example, a captcha field in the main form would get validated by its proper validator,
but when in a field set, only a basic validator would be found.
We are adjusting the view object class to provide IForm rather than
IEasyFormForm or IGroup to make one of the objects less specific.
Same for the default factory.
This allows us to find another adapter other than the current one.
This allows us to find any custom adapters for any fields that we have overridden
"""
new_obj = []
found = False
for obj in objects:
Expand All @@ -59,11 +72,18 @@ def __getattr__(self, item):
if not found:
return None

provided_by_declared = providedBy(adapter).declared
if not provided_by_declared:
return None
provided_by = providedBy(adapter)
# With zope.interface 5.0.2, the info we seek is in 'declared'.
# With 5.1.0+, it can also be in the 'interfaces()' iterator,
# especially for groups (field sets).
# But it looks like interfaces() works always.
# adapter_interfaces = provided_by.declared
# if not adapter_interfaces:
adapter_interfaces = list(provided_by.interfaces())
if not adapter_interfaces:
return

return queryMultiAdapter(new_obj, provided_by_declared[0], name=name)
return queryMultiAdapter(new_obj, adapter_interfaces[0], name=name)


@implementer(IValidator)
Expand Down
13 changes: 11 additions & 2 deletions src/collective/easyform/tests/base.py
@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
from __future__ import print_function

from email import message_from_string
from plone import api
from plone.app.contenttypes.testing import PLONE_APP_CONTENTTYPES_FIXTURE
from plone.app.robotframework.testing import REMOTE_LIBRARY_BUNDLE_FIXTURE
Expand All @@ -21,12 +20,22 @@
except ImportError:
from plone.testing.z2 import ZSERVER_FIXTURE as WSGI_SERVER_FIXTURE

try:
# Python 3
from email import message_from_bytes
except ImportError:
# Python 2
from email import message_from_string as message_from_bytes


class MailHostMock(MailHost):
def _send(self, mfrom, mto, messageText, immediate=False):
print("<sent mail from {0} to {1}>".format(mfrom, mto)) # noqa: T003
if hasattr(messageText, "encode"):
# It is text instead of bytes.
messageText = messageText.encode("utf-8")
self.msgtext = messageText
self.msg = message_from_string(messageText.lstrip())
self.msg = message_from_bytes(messageText.lstrip())


class Fixture(PloneSandboxLayer):
Expand Down
6 changes: 3 additions & 3 deletions src/collective/easyform/tests/serverside_field.rst
Expand Up @@ -44,9 +44,9 @@ thank you page::

Test for 'Subject' in the mail body::

>>> msgtext = portal.MailHost.msgtext[portal.MailHost.msgtext.index('\n\n'):]
>>> body = '\n\n'.join(portal.MailHost.msgtext.split('\n\n')[1:])
>>> 'Subject' in body
>>> msgtext = portal.MailHost.msgtext[portal.MailHost.msgtext.index(b'\n\n'):]
>>> body = b'\n\n'.join(portal.MailHost.msgtext.split(b'\n\n')[1:])
>>> b'Subject' in body
False

Specifically list the field as one that should be included in the thank
Expand Down

0 comments on commit 5585125

Please sign in to comment.