diff --git a/news/1810.bugfix b/news/1810.bugfix new file mode 100644 index 0000000000..af19b61056 --- /dev/null +++ b/news/1810.bugfix @@ -0,0 +1,2 @@ +Safely convert objects to IContentListingObject +[erral] diff --git a/src/plone/restapi/serializer/summary.py b/src/plone/restapi/serializer/summary.py index a18ed98a8c..8b8c36dc93 100644 --- a/src/plone/restapi/serializer/summary.py +++ b/src/plone/restapi/serializer/summary.py @@ -83,7 +83,10 @@ def __init__(self, context, request): self.blocklisted_attributes = metadata["blocklisted_attributes"] def __call__(self): - obj = IContentListingObject(self.context) + try: + obj = IContentListingObject(self.context) + except TypeError: + return {} summary = {} for field in self.metadata_fields(): diff --git a/src/plone/restapi/tests/test_serializer_summary.py b/src/plone/restapi/tests/test_serializer_summary.py index 16b54f7b0c..36296d78c8 100644 --- a/src/plone/restapi/tests/test_serializer_summary.py +++ b/src/plone/restapi/tests/test_serializer_summary.py @@ -1,14 +1,20 @@ +from datetime import datetime +from datetime import timedelta from DateTime import DateTime from plone.app.contentlisting.interfaces import IContentListingObject +from plone.app.event.dx.traverser import OccurrenceTraverser from plone.app.testing import popGlobalRegistry from plone.app.testing import pushGlobalRegistry from plone.dexterity.utils import createContentInContainer +from plone.event.interfaces import IEvent +from plone.event.interfaces import IEventRecurrence from plone.restapi.interfaces import ISerializeToJsonSummary from plone.restapi.testing import PLONE_RESTAPI_DX_INTEGRATION_TESTING from plone.restapi.testing import register_static_uuid_utility from Products.CMFCore.utils import getToolByName from zope.component import getMultiAdapter from zope.component.hooks import getSite +from zope.interface import alsoProvides import Missing import unittest @@ -203,3 +209,47 @@ def test_dx_type_summary(self): }, summary, ) + + +class TestSummarySerializerswithRecurrenceObjects(unittest.TestCase): + layer = PLONE_RESTAPI_DX_INTEGRATION_TESTING + + def setUp(self): + self.portal = self.layer["portal"] + self.request = self.layer["request"] + + pushGlobalRegistry(getSite()) + register_static_uuid_utility(prefix="c6dcbd55ab2746e199cd4ed458") + + behaviors = self.portal.portal_types.DXTestDocument.behaviors + behaviors = behaviors + ( + "plone.eventbasic", + "plone.eventrecurrence", + ) + self.portal.portal_types.DXTestDocument.behaviors = behaviors + + self.event = createContentInContainer( + self.portal, + "DXTestDocument", + id="doc1", + title="Lorem Ipsum event", + description="Description event", + start=datetime.now(), + end=datetime.now() + timedelta(hours=1), + recurrence="RRULE:FREQ=DAILY;COUNT=3", # see https://github.com/plone/plone.app.event/blob/master/plone/app/event/tests/base_setup.py + ) + + alsoProvides(self.event, IEvent) + alsoProvides(self.event, IEventRecurrence) + + def tearDown(self): + popGlobalRegistry(getSite()) + + def test_dx_event_with_recurrence(self): + tomorrow = datetime.now() + timedelta(days=1) + tomorrow_str = tomorrow.strftime("%Y-%m-%d") + ot = OccurrenceTraverser(self.event, self.request) + ocurrence = ot.publishTraverse(self.request, tomorrow_str) + summary = getMultiAdapter((ocurrence, self.request), ISerializeToJsonSummary)() + + self.assertEqual(summary, {})